blob: 50199b9ee1f0bb9e65123b50b5b759ee1a13c6d5 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./av1_rtcd.h"
17#include "./aom_dsp_rtcd.h"
18#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "aom_ports/system_state.h"
24
25#include "av1/common/common.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconintra.h"
33#include "av1/common/reconinter.h"
34#include "av1/common/seg_common.h"
35#include "av1/common/tile_common.h"
36
37#include "av1/encoder/aq_complexity.h"
38#include "av1/encoder/aq_cyclicrefresh.h"
39#include "av1/encoder/aq_variance.h"
40#if CONFIG_SUPERTX
41#include "av1/encoder/cost.h"
42#endif
Yue Chen69f18e12016-09-08 14:48:15 -070043#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -070044#include "av1/common/warped_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070045#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
46#if CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/encoder/global_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070048#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070049#include "av1/encoder/encodeframe.h"
50#include "av1/encoder/encodemb.h"
51#include "av1/encoder/encodemv.h"
52#include "av1/encoder/ethread.h"
53#include "av1/encoder/extend.h"
54#include "av1/encoder/rd.h"
55#include "av1/encoder/rdopt.h"
56#include "av1/encoder/segmentation.h"
57#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070058#if CONFIG_PVQ
59#include "av1/encoder/pvq_encoder.h"
60#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070061#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070062#define IF_HBD(...) __VA_ARGS__
63#else
64#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070065#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070066
Urvang Joshi52648442016-10-13 17:27:51 -070067static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
68 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
69 int mi_col, BLOCK_SIZE bsize,
70 PICK_MODE_CONTEXT *ctx, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070071
72#if CONFIG_SUPERTX
73static int check_intra_b(PICK_MODE_CONTEXT *ctx);
74
Urvang Joshi52648442016-10-13 17:27:51 -070075static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
76 int mi_row, int mi_col, BLOCK_SIZE bsize,
77 PC_TREE *pc_tree);
78static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070079#if CONFIG_EXT_INTER
80 int mi_row_ori, int mi_col_ori,
81#endif // CONFIG_EXT_INTER
82 int mi_row_pred, int mi_col_pred,
83 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
84static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
85 PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070086static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070087 const TileInfo *const tile, int mi_row,
88 int mi_col, int mi_row_ori, int mi_col_ori,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070089 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070090 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
91 int dst_stride[3], PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070092static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070093 const TileInfo *const tile, int mi_row,
94 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070095 RUN_TYPE dry_run, PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070096static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070097 const TileInfo *const tile, int mi_row, int mi_col,
98 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
99 TX_TYPE *best_tx, PC_TREE *pc_tree);
100#endif // CONFIG_SUPERTX
101
102// This is used as a reference when computing the source variance for the
103// purposes of activity masking.
104// Eventually this should be replaced by custom no-reference routines,
105// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700106static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107 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, 128,
110 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
111 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112#if CONFIG_EXT_PARTITION
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, 128,
116 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
117 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
118#endif // CONFIG_EXT_PARTITION
119};
120
Yaowu Xuf883b422016-08-30 14:01:10 -0700121#if CONFIG_AOM_HIGHBITDEPTH
122static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700123 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, 128,
126 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
127 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128#if CONFIG_EXT_PARTITION
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, 128,
132 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
133 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
134#endif // CONFIG_EXT_PARTITION
135};
136
Yaowu Xuf883b422016-08-30 14:01:10 -0700137static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 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 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
145 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
146#if CONFIG_EXT_PARTITION
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 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
154 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
155#endif // CONFIG_EXT_PARTITION
156};
157
Yaowu Xuf883b422016-08-30 14:01:10 -0700158static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700159 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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
167 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
168 128 * 16,
169#if CONFIG_EXT_PARTITION
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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
178 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
179 128 * 16
180#endif // CONFIG_EXT_PARTITION
181};
Yaowu Xuf883b422016-08-30 14:01:10 -0700182#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183
Urvang Joshi52648442016-10-13 17:27:51 -0700184unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700185 const struct buf_2d *ref,
186 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700187 unsigned int sse;
188 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700189 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
191}
192
Yaowu Xuf883b422016-08-30 14:01:10 -0700193#if CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700194unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700195 const struct buf_2d *ref,
196 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197 unsigned int var, sse;
198 switch (bd) {
199 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700200 var =
201 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
202 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700203 break;
204 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700205 var =
206 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
207 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700208 break;
209 case 8:
210 default:
211 var =
212 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700213 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700214 break;
215 }
216 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
217}
Yaowu Xuf883b422016-08-30 14:01:10 -0700218#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700219
Urvang Joshi52648442016-10-13 17:27:51 -0700220static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700221 const struct buf_2d *ref,
222 int mi_row, int mi_col,
223 BLOCK_SIZE bs) {
224 unsigned int sse, var;
225 uint8_t *last_y;
226 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
227
228 assert(last != NULL);
229 last_y =
230 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
231 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
232 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
233}
234
Yaowu Xuf883b422016-08-30 14:01:10 -0700235static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
236 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700237 unsigned int var = get_sby_perpixel_diff_variance(
238 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
239 if (var < 8)
240 return BLOCK_64X64;
241 else if (var < 128)
242 return BLOCK_32X32;
243 else if (var < 2048)
244 return BLOCK_16X16;
245 else
246 return BLOCK_8X8;
247}
248
249// Lighter version of set_offsets that only sets the mode info
250// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700251static void set_mode_info_offsets(const AV1_COMP *const cpi,
252 MACROBLOCK *const x, MACROBLOCKD *const xd,
253 int mi_row, int mi_col) {
254 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700255 const int idx_str = xd->mi_stride * mi_row + mi_col;
256 xd->mi = cm->mi_grid_visible + idx_str;
257 xd->mi[0] = cm->mi + idx_str;
258 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
259}
260
Urvang Joshi52648442016-10-13 17:27:51 -0700261static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262 const TileInfo *const tile,
263 MACROBLOCK *const x, int mi_row,
264 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700265 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700266 MACROBLOCKD *const xd = &x->e_mbd;
267 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
268 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Hana6923f72016-07-15 08:50:14 -0700269 const int bwl = b_width_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
270 const int bhl = b_height_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700271
272 set_skip_context(xd, mi_row, mi_col);
273
274 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
275
276#if CONFIG_VAR_TX
277 xd->above_txfm_context = cm->above_txfm_context + mi_col;
278 xd->left_txfm_context =
279 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
280 xd->max_tx_size = max_txsize_lookup[bsize];
281#endif
282
283 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700284 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700285
286 // Set up limit values for MV components.
287 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700288 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
289 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
290 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
291 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292
Jingning Hana6923f72016-07-15 08:50:14 -0700293 set_plane_n4(xd, mi_width, mi_height, bwl, bhl);
294
Yaowu Xuc27fc142016-08-22 16:08:15 -0700295 // Set up distance of MB to edge of frame in 1/8th pel units.
296 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
297 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
298 cm->mi_cols);
299
300 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700301 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700302
303 // R/D setup.
304 x->rddiv = cpi->rd.RDDIV;
305 x->rdmult = cpi->rd.RDMULT;
306
Yaowu Xuf883b422016-08-30 14:01:10 -0700307 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700308 xd->tile = *tile;
309}
310
Urvang Joshi52648442016-10-13 17:27:51 -0700311static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 MACROBLOCK *const x, int mi_row, int mi_col,
313 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700314 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700315 MACROBLOCKD *const xd = &x->e_mbd;
316 MB_MODE_INFO *mbmi;
317 const struct segmentation *const seg = &cm->seg;
318
319 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
320
321 mbmi = &xd->mi[0]->mbmi;
322
323 // Setup segment ID.
324 if (seg->enabled) {
325 if (!cpi->vaq_refresh) {
326 const uint8_t *const map =
327 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
328 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
329 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700330 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700331 } else {
332 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700333 }
334
335#if CONFIG_SUPERTX
336 mbmi->segment_id_supertx = MAX_SEGMENTS;
337#endif // CONFIG_SUPERTX
338}
339
340#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700341static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700342 const TileInfo *const tile, int mi_row,
343 int mi_col, BLOCK_SIZE bsize) {
344 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700345 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 MACROBLOCKD *const xd = &x->e_mbd;
347 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
348 const int mi_height = num_8x8_blocks_high_lookup[bsize];
349
350 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
351
352 // Set up distance of MB to edge of frame in 1/8th pel units.
353 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
354 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
355 cm->mi_cols);
356}
357
Urvang Joshi52648442016-10-13 17:27:51 -0700358static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700359 const TileInfo *const tile, int mi_row_pred,
360 int mi_col_pred, int mi_row_ori, int mi_col_ori,
361 BLOCK_SIZE bsize_pred) {
362 // Used in supertx
363 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
364 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
365 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700366 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700367 MACROBLOCKD *const xd = &x->e_mbd;
368 const int mi_width = num_8x8_blocks_wide_lookup[bsize_pred];
369 const int mi_height = num_8x8_blocks_high_lookup[bsize_pred];
370
371 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
372
373 // Set up limit values for MV components.
374 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700375 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
376 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
377 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
378 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700379
380 // Set up distance of MB to edge of frame in 1/8th pel units.
381 assert(!(mi_col_pred & (mi_width - 1)) && !(mi_row_pred & (mi_height - 1)));
382 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
383 cm->mi_rows, cm->mi_cols);
384 xd->up_available = (mi_row_ori > tile->mi_row_start);
385 xd->left_available = (mi_col_ori > tile->mi_col_start);
386
387 // R/D setup.
388 x->rddiv = cpi->rd.RDDIV;
389 x->rdmult = cpi->rd.RDMULT;
390}
391
Yaowu Xuf883b422016-08-30 14:01:10 -0700392static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700393 MACROBLOCK *const x, const int mi_row,
394 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700395 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700396 const struct segmentation *seg = &cm->seg;
397 const int miw =
Yaowu Xuf883b422016-08-30 14:01:10 -0700398 AOMMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399 const int mih =
Yaowu Xuf883b422016-08-30 14:01:10 -0700400 AOMMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700401 const int mi_offset = mi_row * cm->mi_stride + mi_col;
402 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
403 int r, c;
404 int seg_id_supertx = MAX_SEGMENTS;
405
406 if (!seg->enabled) {
407 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 } else {
409 // Find the minimum segment_id
410 for (r = 0; r < mih; r++)
411 for (c = 0; c < miw; c++)
412 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700413 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
415
416 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700417 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700418 }
419
420 // Assign the the segment_id back to segment_id_supertx
421 for (r = 0; r < mih; r++)
422 for (c = 0; c < miw; c++)
423 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
424}
425#endif // CONFIG_SUPERTX
426
Yaowu Xuf883b422016-08-30 14:01:10 -0700427static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700428 MACROBLOCKD *const xd, int mi_row, int mi_col,
429 BLOCK_SIZE bsize) {
430 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
431 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
432 xd->mi[0]->mbmi.sb_type = bsize;
433 }
434}
435
Yaowu Xuf883b422016-08-30 14:01:10 -0700436static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
438 int mi_col, const int64_t *const threshold,
439 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700440 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 const int hbw = num_8x8_blocks_wide_lookup[vt->bsize] / 2;
442 const int hbh = num_8x8_blocks_high_lookup[vt->bsize] / 2;
443 const int has_cols = mi_col + hbw < cm->mi_cols;
444 const int has_rows = mi_row + hbh < cm->mi_rows;
445
446 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
447
448 assert(vt->bsize >= BLOCK_8X8);
449
450 assert(hbh == hbw);
451
452 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
453 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
454 return;
455 }
456
457 if (vt->force_split || (!has_cols && !has_rows)) goto split;
458
459 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
460 // variance is below threshold, otherwise split will be selected.
461 // No check for vert/horiz split as too few samples for variance.
462 if (vt->bsize == bsize_min[0]) {
463 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
464 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
465 return;
466 } else {
467 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
468 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
469 if (vt->bsize > BLOCK_8X8) {
470 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
471 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
472 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
473 }
474 return;
475 }
476 } else if (vt->bsize > bsize_min[0]) {
477 // For key frame: take split for bsize above 32X32 or very high variance.
478 if (cm->frame_type == KEY_FRAME &&
479 (vt->bsize > BLOCK_32X32 ||
480 vt->variances.none.variance > (threshold[0] << 4))) {
481 goto split;
482 }
483 // If variance is low, take the bsize (no split).
484 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
485 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
486 return;
487 }
488
489 // Check vertical split.
490 if (has_rows) {
491 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
492 if (vt->variances.vert[0].variance < threshold[0] &&
493 vt->variances.vert[1].variance < threshold[0] &&
494 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
495 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
496 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
497 return;
498 }
499 }
500 // Check horizontal split.
501 if (has_cols) {
502 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
503 if (vt->variances.horz[0].variance < threshold[0] &&
504 vt->variances.horz[1].variance < threshold[0] &&
505 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
506 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
507 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
508 return;
509 }
510 }
511 }
512
513split : {
514 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
515 bsize_min + 1);
516 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
517 threshold + 1, bsize_min + 1);
518 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
519 threshold + 1, bsize_min + 1);
520 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
521 threshold + 1, bsize_min + 1);
522 return;
523}
524}
525
526// Set the variance split thresholds for following the block sizes:
527// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
528// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
529// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700530static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
531 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700532 const int is_key_frame = (cm->frame_type == KEY_FRAME);
533 const int threshold_multiplier = is_key_frame ? 20 : 1;
534 const int64_t threshold_base =
535 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
536 if (is_key_frame) {
537 thresholds[1] = threshold_base;
538 thresholds[2] = threshold_base >> 2;
539 thresholds[3] = threshold_base >> 2;
540 thresholds[4] = threshold_base << 2;
541 } else {
542 thresholds[2] = threshold_base;
543 if (cm->width <= 352 && cm->height <= 288) {
544 thresholds[1] = threshold_base >> 2;
545 thresholds[3] = threshold_base << 3;
546 } else {
547 thresholds[1] = threshold_base;
548 thresholds[2] = (5 * threshold_base) >> 2;
549 if (cm->width >= 1920 && cm->height >= 1080)
550 thresholds[2] = (7 * threshold_base) >> 2;
551 thresholds[3] = threshold_base << cpi->oxcf.speed;
552 }
553 }
554 thresholds[0] = INT64_MIN;
555}
556
Yaowu Xuf883b422016-08-30 14:01:10 -0700557void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
558 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559 SPEED_FEATURES *const sf = &cpi->sf;
560 const int is_key_frame = (cm->frame_type == KEY_FRAME);
561 if (sf->partition_search_type != VAR_BASED_PARTITION &&
562 sf->partition_search_type != REFERENCE_PARTITION) {
563 return;
564 } else {
565 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
566 // The thresholds below are not changed locally.
567 if (is_key_frame) {
568 cpi->vbp_threshold_sad = 0;
569 cpi->vbp_bsize_min = BLOCK_8X8;
570 } else {
571 if (cm->width <= 352 && cm->height <= 288)
572 cpi->vbp_threshold_sad = 100;
573 else
574 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
575 ? (cpi->y_dequant[q][1] << 1)
576 : 1000;
577 cpi->vbp_bsize_min = BLOCK_16X16;
578 }
579 cpi->vbp_threshold_minmax = 15 + (q >> 3);
580 }
581}
582
583// Compute the minmax over the 8x8 subblocks.
584static int compute_minmax_8x8(const uint8_t *src, int src_stride,
585 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700586#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587 int highbd,
588#endif
589 int pixels_wide, int pixels_high) {
590 int k;
591 int minmax_max = 0;
592 int minmax_min = 255;
593 // Loop over the 4 8x8 subblocks.
594 for (k = 0; k < 4; k++) {
595 const int x8_idx = ((k & 1) << 3);
596 const int y8_idx = ((k >> 1) << 3);
597 int min = 0;
598 int max = 0;
599 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
600 const int src_offset = y8_idx * src_stride + x8_idx;
601 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700602#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700604 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700605 ref_stride, &min, &max);
606 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700607 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608 ref_stride, &min, &max);
609 }
610#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700611 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612 &min, &max);
613#endif
614 if ((max - min) > minmax_max) minmax_max = (max - min);
615 if ((max - min) < minmax_min) minmax_min = (max - min);
616 }
617 }
618 return (minmax_max - minmax_min);
619}
620
Yaowu Xuf883b422016-08-30 14:01:10 -0700621#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700622static INLINE int avg_4x4(const uint8_t *const src, const int stride,
623 const int highbd) {
624 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700625 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700627 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628 }
629}
630#else
631static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700632 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633}
634#endif
635
Yaowu Xuf883b422016-08-30 14:01:10 -0700636#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700637static INLINE int avg_8x8(const uint8_t *const src, const int stride,
638 const int highbd) {
639 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700640 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700642 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643 }
644}
645#else
646static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700647 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648}
649#endif
650
651static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700652#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653 const int highbd,
654#endif
655 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
656 const int width, const int height,
657 const uint8_t *const src, const int src_stride,
658 const uint8_t *const ref, const int ref_stride) {
659 assert(bsize >= leaf_size);
660
661 vt->bsize = bsize;
662
663 vt->force_split = 0;
664
665 vt->src = src;
666 vt->src_stride = src_stride;
667 vt->ref = ref;
668 vt->ref_stride = ref_stride;
669
670 vt->width = width;
671 vt->height = height;
672
Yaowu Xuf883b422016-08-30 14:01:10 -0700673#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700675#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676
677 if (bsize > leaf_size) {
678 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800679 const int px = block_size_wide[subsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700680
681 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700682#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700684#endif // CONFIG_AOM_HIGHBITDEPTH
685 subsize, leaf_size, AOMMIN(px, width),
686 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700690#endif // CONFIG_AOM_HIGHBITDEPTH
691 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692 src + px, src_stride, ref + px, ref_stride);
693 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700694#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700696#endif // CONFIG_AOM_HIGHBITDEPTH
697 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700698 src + px * src_stride, src_stride, ref + px * ref_stride,
699 ref_stride);
700 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700701#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700703#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700704 subsize, leaf_size, width - px, height - px,
705 src + px * src_stride + px, src_stride,
706 ref + px * ref_stride + px, ref_stride);
707 }
708}
709
710// Fill the variance tree based on averaging pixel values (sub-sampling), at
711// the leaf node size.
712static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
713 if (vt->bsize > leaf_size) {
714 fill_variance_tree(vt->split[0], leaf_size);
715 fill_variance_tree(vt->split[1], leaf_size);
716 fill_variance_tree(vt->split[2], leaf_size);
717 fill_variance_tree(vt->split[3], leaf_size);
718 fill_variance_node(vt);
719 } else if (vt->width <= 0 || vt->height <= 0) {
720 fill_variance(0, 0, 0, &vt->variances.none);
721 } else {
722 unsigned int sse = 0;
723 int sum = 0;
724 int src_avg;
725 int ref_avg;
726 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
727 if (leaf_size == BLOCK_4X4) {
728 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
729 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
730 } else {
731 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
732 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
733 }
734 sum = src_avg - ref_avg;
735 sse = sum * sum;
736 fill_variance(sse, sum, 0, &vt->variances.none);
737 }
738}
739
740static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
741 if (vt->bsize >= BLOCK_8X8) {
742 if (vt->bsize == BLOCK_16X16) {
743 if (vt->variances.none.variance <= threshold)
744 return;
745 else
746 vt->force_split = 0;
747 }
748
749 refine_variance_tree(vt->split[0], threshold);
750 refine_variance_tree(vt->split[1], threshold);
751 refine_variance_tree(vt->split[2], threshold);
752 refine_variance_tree(vt->split[3], threshold);
753
754 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
755 } else if (vt->width <= 0 || vt->height <= 0) {
756 fill_variance(0, 0, 0, &vt->variances.none);
757 } else {
758 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
759 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
760 const int sum = src_avg - ref_avg;
761 const unsigned int sse = sum * sum;
762 assert(vt->bsize == BLOCK_4X4);
763 fill_variance(sse, sum, 0, &vt->variances.none);
764 }
765}
766
767static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
768 if (vt->bsize == BLOCK_32X32) {
769 vt->force_split = vt->variances.none.variance > threshold;
770 } else {
771 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
772 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
773 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
774 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
775 }
776 return vt->force_split;
777}
778
Yaowu Xuf883b422016-08-30 14:01:10 -0700779static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700780 const int segment_id, const int64_t *const thresholds) {
781 if (vt->bsize == BLOCK_16X16) {
782 vt->force_split = vt->variances.none.variance > thresholds[0];
783 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
784 !cyclic_refresh_segment_id_boosted(segment_id)) {
785 // We have some nominal amount of 16x16 variance (based on average),
786 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
787 // force split to 8x8 block for this 16x16 block.
788 int minmax =
789 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700790#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791 vt->highbd,
792#endif
793 vt->width, vt->height);
794 vt->force_split = minmax > cpi->vbp_threshold_minmax;
795 }
796 } else {
797 vt->force_split |=
798 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
799 vt->force_split |=
800 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
801 vt->force_split |=
802 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
803 vt->force_split |=
804 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
805
806 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
807 vt->force_split = vt->variances.none.variance > thresholds[0];
808 }
809 }
810
811 return vt->force_split;
812}
813
814// This function chooses partitioning based on the variance between source and
815// reconstructed last (or golden), where variance is computed for down-sampled
816// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700817static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700818 const TileInfo *const tile, MACROBLOCK *const x,
819 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700820 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700821 MACROBLOCKD *const xd = &x->e_mbd;
822 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700823#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700825#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700826 const uint8_t *src;
827 const uint8_t *ref;
828 int src_stride;
829 int ref_stride;
830 int pixels_wide = 8 * num_8x8_blocks_wide_lookup[cm->sb_size];
831 int pixels_high = 8 * num_8x8_blocks_high_lookup[cm->sb_size];
832 int64_t thresholds[5] = {
833 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
834 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
835 };
836 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
837 cpi->vbp_bsize_min, BLOCK_8X8 };
838 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
839 const int64_t *const thre = thresholds + start_level;
840 const BLOCK_SIZE *const bmin = bsize_min + start_level;
841
842 const int is_key_frame = (cm->frame_type == KEY_FRAME);
843 const int low_res = (cm->width <= 352 && cm->height <= 288);
844
845 int segment_id = CR_SEGMENT_ID_BASE;
846
847 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
848 const uint8_t *const map =
849 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
850 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
851
852 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700853 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854 set_vbp_thresholds(cpi, thresholds, q);
855 }
856 }
857
858 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
859
860 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
861 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
862
863 src = x->plane[0].src.buf;
864 src_stride = x->plane[0].src.stride;
865
866 if (!is_key_frame) {
867 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
869 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
870 unsigned int y_sad, y_sad_g;
871
872 const int hbs = cm->mib_size / 2;
873 const int split_vert = mi_col + hbs >= cm->mi_cols;
874 const int split_horz = mi_row + hbs >= cm->mi_rows;
875 BLOCK_SIZE bsize;
876
877 if (split_vert && split_horz)
878 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
879 else if (split_vert)
880 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
881 else if (split_horz)
882 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
883 else
884 bsize = cm->sb_size;
885
886 assert(yv12 != NULL);
887
888 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700889 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
890 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700891 y_sad_g = cpi->fn_ptr[bsize].sdf(
892 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
893 xd->plane[0].pre[0].stride);
894 } else {
895 y_sad_g = UINT_MAX;
896 }
897
Yaowu Xuf883b422016-08-30 14:01:10 -0700898 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
899 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 mbmi->ref_frame[0] = LAST_FRAME;
901 mbmi->ref_frame[1] = NONE;
902 mbmi->sb_type = cm->sb_size;
903 mbmi->mv[0].as_int = 0;
904#if CONFIG_DUAL_FILTER
905 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
906#else
907 mbmi->interp_filter = BILINEAR;
908#endif
909
Yaowu Xuf883b422016-08-30 14:01:10 -0700910 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911
912 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700913 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
914 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 mbmi->ref_frame[0] = GOLDEN_FRAME;
916 mbmi->mv[0].as_int = 0;
917 y_sad = y_sad_g;
918 } else {
919 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
920 }
921
Yaowu Xuf883b422016-08-30 14:01:10 -0700922 av1_build_inter_predictors_sb(xd, mi_row, mi_col, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700923
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924 ref = xd->plane[0].dst.buf;
925 ref_stride = xd->plane[0].dst.stride;
926
927 // If the y_sad is very small, take the largest partition and exit.
928 // Don't check on boosted segment for now, as largest is suppressed there.
929 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
930 if (!split_vert && !split_horz) {
931 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
932 return;
933 }
934 }
935 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700936 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700938#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
940 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700941 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
942 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700944 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 }
946 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700947#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 }
949
950 init_variance_tree(
951 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700952#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700954#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
956 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
957
958 // Fill in the entire tree of variances and compute splits.
959 if (is_key_frame) {
960 fill_variance_tree(vt, BLOCK_4X4);
961 check_split_key_frame(vt, thre[1]);
962 } else {
963 fill_variance_tree(vt, BLOCK_8X8);
964 check_split(cpi, vt, segment_id, thre);
965 if (low_res) {
966 refine_variance_tree(vt, thre[1] << 1);
967 }
968 }
969
970 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
971 mi_row + cm->mib_size > cm->mi_rows;
972
973 // Now go through the entire structure, splitting every block size until
974 // we get to one that's got a variance lower than our threshold.
975 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
976}
977
978#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700979static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 MB_MODE_INFO *mbmi) {
981 int dir;
982 for (dir = 0; dir < 2; ++dir) {
983 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
984 (mbmi->ref_frame[1] == NONE ||
985 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
986 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
987 ? EIGHTTAP_REGULAR
988 : cm->interp_filter;
989 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
990 }
991}
992
993static void update_filter_type_count(FRAME_COUNTS *counts,
994 const MACROBLOCKD *xd,
995 const MB_MODE_INFO *mbmi) {
996 int dir;
997 for (dir = 0; dir < 2; ++dir) {
998 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
999 (mbmi->ref_frame[1] > INTRA_FRAME &&
1000 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001001 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001002 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1003 }
1004 }
1005}
1006#endif
1007#if CONFIG_GLOBAL_MOTION
1008static void update_global_motion_used(PREDICTION_MODE mode,
Yaowu Xuf883b422016-08-30 14:01:10 -07001009 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 if (mode == ZEROMV) {
1011 ++cpi->global_motion_used[mbmi->ref_frame[0]];
1012 if (has_second_ref(mbmi)) ++cpi->global_motion_used[mbmi->ref_frame[1]];
1013 }
1014}
1015#endif // CONFIG_GLOBAL_MOTION
1016
Urvang Joshi52648442016-10-13 17:27:51 -07001017static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1018 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1019 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001020 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001021 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022 RD_COUNTS *const rdc = &td->rd_counts;
1023 MACROBLOCK *const x = &td->mb;
1024 MACROBLOCKD *const xd = &x->e_mbd;
1025 struct macroblock_plane *const p = x->plane;
1026 struct macroblockd_plane *const pd = xd->plane;
1027 MODE_INFO *mi = &ctx->mic;
1028 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1029 MODE_INFO *mi_addr = xd->mi[0];
1030 const struct segmentation *const seg = &cm->seg;
1031 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
1032 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001033 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1034 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001035 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1036 int w, h;
1037
1038 const int mis = cm->mi_stride;
1039 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1040 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001041
1042#if CONFIG_REF_MV
1043 int8_t rf_type;
1044#endif
1045
1046#if !CONFIG_SUPERTX
1047 assert(mi->mbmi.sb_type == bsize);
1048#endif
1049
1050 *mi_addr = *mi;
1051 *x->mbmi_ext = ctx->mbmi_ext;
1052
1053#if CONFIG_DUAL_FILTER
1054 reset_intmv_filter_type(cm, xd, mbmi);
1055#endif
1056
1057#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001058 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1060 mbmi->mode == NEWMV) {
1061 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1062 int_mv this_mv =
1063 (i == 0)
1064 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1065 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1066 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1067 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1068 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001069 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001070 }
1071 }
1072#endif
1073
1074 // If segmentation in use
1075 if (seg->enabled) {
1076 // For in frame complexity AQ copy the segment id from the segment map.
1077 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1078 const uint8_t *const map =
1079 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1080 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1081 }
1082 // Else for cyclic refresh mode update the segment map, set the segment id
1083 // and then update the quantizer.
1084 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001085 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1086 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087 }
1088 }
1089
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001090 for (i = 0; i < MAX_MB_PLANE; ++i) {
1091 p[i].coeff = ctx->coeff[i];
1092 p[i].qcoeff = ctx->qcoeff[i];
1093 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001094#if CONFIG_PVQ
1095 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1096#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001097 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 }
Urvang Joshib100db72016-10-12 16:28:56 -07001099#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001100 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001101#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001102
1103 // Restore the coding context of the MB to that that was in place
1104 // when the mode was picked for it
1105 for (y = 0; y < mi_height; y++)
1106 for (x_idx = 0; x_idx < mi_width; x_idx++)
1107 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1108 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1109 xd->mi[x_idx + y * mis] = mi_addr;
1110 }
1111
Arild Fuldseth07441162016-08-15 15:07:52 +02001112#if CONFIG_DELTA_Q
1113 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001114 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001115#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001117 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001118#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119
1120 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1121 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1122 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1123 }
1124
1125 x->skip = ctx->skip;
1126
1127#if CONFIG_VAR_TX
1128 for (i = 0; i < 1; ++i)
1129 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1130 sizeof(uint8_t) * ctx->num_4x4_blk);
1131#endif
1132
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001133 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001134
1135#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001136 {
1137 unsigned int *const mode_chosen_counts =
1138 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1139 if (frame_is_intra_only(cm)) {
1140 static const int kf_mode_index[] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -07001141 THR_DC /*DC_PRED*/,
1142 THR_V_PRED /*V_PRED*/,
1143 THR_H_PRED /*H_PRED*/,
1144 THR_D45_PRED /*D45_PRED*/,
1145 THR_D135_PRED /*D135_PRED*/,
1146 THR_D117_PRED /*D117_PRED*/,
1147 THR_D153_PRED /*D153_PRED*/,
1148 THR_D207_PRED /*D207_PRED*/,
1149 THR_D63_PRED /*D63_PRED*/,
1150#if CONFIG_ALT_INTRA
1151 THR_SMOOTH, /*SMOOTH_PRED*/
1152#endif // CONFIG_ALT_INTRA
1153 THR_TM /*TM_PRED*/,
Urvang Joshi52648442016-10-13 17:27:51 -07001154 };
1155 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1156 } else {
1157 // Note how often each mode chosen as best
1158 ++mode_chosen_counts[ctx->best_mode_index];
1159 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 }
1161#endif
1162 if (!frame_is_intra_only(cm)) {
1163 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001164 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001165#if CONFIG_GLOBAL_MOTION
1166 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001167 // TODO(sarahparker): global motion stats need to be handled per-tile
1168 // to be compatible with tile-based threading.
1169 update_global_motion_used(mbmi->mode, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 } else {
1171 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1172 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1173 int idx, idy;
1174 for (idy = 0; idy < 2; idy += num_4x4_h) {
1175 for (idx = 0; idx < 2; idx += num_4x4_w) {
1176 const int j = idy * 2 + idx;
James Zernaf322e12016-10-22 12:43:15 -07001177 update_global_motion_used(mi->bmi[j].as_mode, mbmi,
1178 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179 }
1180 }
1181 }
1182#endif // CONFIG_GLOBAL_MOTION
1183 if (cm->interp_filter == SWITCHABLE
1184#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001185 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186#endif
Yue Chen69f18e12016-09-08 14:48:15 -07001187#if CONFIG_WARPED_MOTION
1188 && mbmi->motion_mode != WARPED_CAUSAL
1189#endif // CONFIG_WARPED_MOTION
1190 ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001191#if CONFIG_DUAL_FILTER
1192 update_filter_type_count(td->counts, xd, mbmi);
1193#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001194 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1195 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001196#endif
1197 }
1198 }
1199
1200 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1201 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1202 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1203 }
1204
1205 for (h = 0; h < y_mis; ++h) {
1206 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1207 for (w = 0; w < x_mis; ++w) {
1208 MV_REF *const mv = frame_mv + w;
1209 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1210 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1211 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1212 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1213 }
1214 }
1215}
1216
1217#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001218static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001219 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001220 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001221 int y, x_idx;
1222#if CONFIG_VAR_TX || CONFIG_REF_MV
1223 int i;
1224#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001225 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226 RD_COUNTS *const rdc = &td->rd_counts;
1227 MACROBLOCK *const x = &td->mb;
1228 MACROBLOCKD *const xd = &x->e_mbd;
1229 MODE_INFO *mi = &ctx->mic;
1230 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1231 MODE_INFO *mi_addr = xd->mi[0];
1232 const struct segmentation *const seg = &cm->seg;
1233 const int mis = cm->mi_stride;
1234 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1235 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001236 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1237 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1239 int w, h;
1240
1241#if CONFIG_REF_MV
1242 int8_t rf_type;
1243#endif
1244
1245 *mi_addr = *mi;
1246 *x->mbmi_ext = ctx->mbmi_ext;
1247 assert(is_inter_block(mbmi));
1248 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1249
1250#if CONFIG_DUAL_FILTER
1251 reset_intmv_filter_type(cm, xd, mbmi);
1252#endif
1253
1254#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001255 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001256 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1257 mbmi->mode == NEWMV) {
1258 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1259 int_mv this_mv =
1260 (i == 0)
1261 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1262 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1263 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1264 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1265 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1266 mbmi->pred_mv[i] = this_mv;
1267 }
1268 }
1269#endif
1270
1271 // If segmentation in use
1272 if (seg->enabled) {
1273 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001274 const int energy =
1275 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1276 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1278 // For cyclic refresh mode, now update the segment map
1279 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001280 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1281 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282 } else {
1283 // Otherwise just set the segment id based on the current segment map
1284 const uint8_t *const map =
1285 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1286 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1287 }
1288 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1289 }
1290
1291 // Restore the coding context of the MB to that that was in place
1292 // when the mode was picked for it
1293 for (y = 0; y < mi_height; y++)
1294 for (x_idx = 0; x_idx < mi_width; x_idx++)
1295 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1296 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1297 xd->mi[x_idx + y * mis] = mi_addr;
1298 }
1299
1300 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1301 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1302 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1303 }
1304
1305 x->skip = ctx->skip;
1306
1307#if CONFIG_VAR_TX
1308 for (i = 0; i < 1; ++i)
1309 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1310 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001311
1312 if (!is_inter_block(mbmi) || mbmi->skip)
1313 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001314#endif // CONFIG_VAR_TX
1315
1316#if CONFIG_VAR_TX
1317 {
1318 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001319 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1320 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001321 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001322 mbmi->inter_tx_size[0][0] = mtx;
1323 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1324 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1325 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001326 }
1327#endif // CONFIG_VAR_TX
1328 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001329 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001331 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332
1333 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001334 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001335
David Barker03bd2102016-11-17 14:55:04 +00001336#if CONFIG_GLOBAL_MOTION
1337 if (is_inter_block(mbmi)) {
1338 if (bsize >= BLOCK_8X8) {
1339 // TODO(sarahparker): global motion stats need to be handled per-tile
1340 // to be compatible with tile-based threading.
1341 update_global_motion_used(mbmi->mode, mbmi, (AV1_COMP *)cpi);
1342 } else {
1343 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1344 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1345 int idx, idy;
1346 for (idy = 0; idy < 2; idy += num_4x4_h) {
1347 for (idx = 0; idx < 2; idx += num_4x4_w) {
1348 const int j = idy * 2 + idx;
1349 update_global_motion_used(mi->bmi[j].as_mode, mbmi,
1350 (AV1_COMP *)cpi);
1351 }
1352 }
1353 }
1354 }
1355#endif // CONFIG_GLOBAL_MOTION
1356
Yaowu Xuc27fc142016-08-22 16:08:15 -07001357 if (cm->interp_filter == SWITCHABLE
1358#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001359 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360#endif
1361 ) {
1362#if CONFIG_DUAL_FILTER
1363 update_filter_type_count(td->counts, xd, mbmi);
1364#else
James Zern9ca190c2016-10-22 12:42:43 -07001365 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1366 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367#endif
1368 }
1369
1370 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1371 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1372 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1373 }
1374
1375 for (h = 0; h < y_mis; ++h) {
1376 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1377 for (w = 0; w < x_mis; ++w) {
1378 MV_REF *const mv = frame_mv + w;
1379 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1380 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1381 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1382 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1383 }
1384 }
1385}
1386
Urvang Joshi52648442016-10-13 17:27:51 -07001387static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 const TileInfo *const tile, int mi_row,
1389 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001390 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001391 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001392 MACROBLOCK *const x = &td->mb;
1393 MACROBLOCKD *const xd = &x->e_mbd;
1394 struct macroblock_plane *const p = x->plane;
1395 struct macroblockd_plane *const pd = xd->plane;
1396 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1397 PARTITION_TYPE partition = pc_tree->partitioning;
1398 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1399 int i;
1400#if CONFIG_EXT_PARTITION_TYPES
1401 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1402#endif
1403 PICK_MODE_CONTEXT *pmc = NULL;
1404
1405 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1406
1407 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001408 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001409
1410 switch (partition) {
1411 case PARTITION_NONE:
1412 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1413 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001414 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 break;
1416 case PARTITION_VERT:
1417 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1418 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001419 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1421 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1422 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001423 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001424 }
1425 pmc = &pc_tree->vertical_supertx;
1426 break;
1427 case PARTITION_HORZ:
1428 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1429 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001430 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001431 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1432 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1433 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001434 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435 }
1436 pmc = &pc_tree->horizontal_supertx;
1437 break;
1438 case PARTITION_SPLIT:
1439 if (bsize == BLOCK_8X8) {
1440 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1441 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001442 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001443 } else {
1444 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001445 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1446 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001447 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1448 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001449 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1451 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001452 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001453 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1454 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001455 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456 }
1457 pmc = &pc_tree->split_supertx;
1458 break;
1459#if CONFIG_EXT_PARTITION_TYPES
1460 case PARTITION_HORZ_A:
1461 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1462 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001463 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1465 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001466 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001467 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1468 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001469 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001470 pmc = &pc_tree->horizontala_supertx;
1471 break;
1472 case PARTITION_HORZ_B:
1473 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1474 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001475 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001476 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1477 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001478 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001479 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1480 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001481 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482 pmc = &pc_tree->horizontalb_supertx;
1483 break;
1484 case PARTITION_VERT_A:
1485 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1486 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001487 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001488 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1489 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001490 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001491 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1492 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001493 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001494 pmc = &pc_tree->verticala_supertx;
1495 break;
1496 case PARTITION_VERT_B:
1497 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1498 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001499 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001500 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1501 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001502 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001503 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1504 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001505 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001506 pmc = &pc_tree->verticalb_supertx;
1507 break;
1508#endif // CONFIG_EXT_PARTITION_TYPES
1509 default: assert(0);
1510 }
1511
1512 for (i = 0; i < MAX_MB_PLANE; ++i) {
1513 if (pmc != NULL) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001514 p[i].coeff = pmc->coeff[i];
1515 p[i].qcoeff = pmc->qcoeff[i];
1516 pd[i].dqcoeff = pmc->dqcoeff[i];
1517 p[i].eobs = pmc->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518 } else {
1519 // These should never be used
1520 p[i].coeff = NULL;
1521 p[i].qcoeff = NULL;
1522 pd[i].dqcoeff = NULL;
1523 p[i].eobs = NULL;
1524 }
1525 }
1526}
1527
1528static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1529 int best_tx, TX_SIZE supertx_size) {
1530 MACROBLOCK *const x = &td->mb;
1531#if CONFIG_VAR_TX
1532 int i;
1533
1534 for (i = 0; i < 1; ++i)
1535 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1536 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001537 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001538#endif // CONFIG_VAR_TX
1539 ctx->mic.mbmi.tx_size = supertx_size;
1540 ctx->skip = x->skip;
1541 ctx->mic.mbmi.tx_type = best_tx;
1542}
1543
Urvang Joshi52648442016-10-13 17:27:51 -07001544static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1545 int mi_row, int mi_col, BLOCK_SIZE bsize,
1546 int best_tx, TX_SIZE supertx_size,
1547 PC_TREE *pc_tree) {
1548 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001549 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1550 PARTITION_TYPE partition = pc_tree->partitioning;
1551 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1552#if CONFIG_EXT_PARTITION_TYPES
1553 int i;
1554#endif
1555
1556 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1557
1558 switch (partition) {
1559 case PARTITION_NONE:
1560 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1561 break;
1562 case PARTITION_VERT:
1563 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
1564 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8)
1565 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1566 break;
1567 case PARTITION_HORZ:
1568 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
1569 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8)
1570 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1571 supertx_size);
1572 break;
1573 case PARTITION_SPLIT:
1574 if (bsize == BLOCK_8X8) {
1575 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1576 } else {
1577 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1578 supertx_size, pc_tree->split[0]);
1579 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1580 supertx_size, pc_tree->split[1]);
1581 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1582 supertx_size, pc_tree->split[2]);
1583 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1584 best_tx, supertx_size, pc_tree->split[3]);
1585 }
1586 break;
1587#if CONFIG_EXT_PARTITION_TYPES
1588 case PARTITION_HORZ_A:
1589 for (i = 0; i < 3; i++)
1590 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1591 supertx_size);
1592 break;
1593 case PARTITION_HORZ_B:
1594 for (i = 0; i < 3; i++)
1595 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1596 supertx_size);
1597 break;
1598 case PARTITION_VERT_A:
1599 for (i = 0; i < 3; i++)
1600 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1601 break;
1602 case PARTITION_VERT_B:
1603 for (i = 0; i < 3; i++)
1604 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1605 break;
1606#endif // CONFIG_EXT_PARTITION_TYPES
1607 default: assert(0);
1608 }
1609}
1610#endif // CONFIG_SUPERTX
1611
Yaowu Xuf883b422016-08-30 14:01:10 -07001612void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1613 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001614 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1615 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1616 src->uv_crop_width };
1617 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1618 src->uv_crop_height };
1619 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1620 int i;
1621
1622 // Set current frame pointer.
1623 x->e_mbd.cur_buf = src;
1624
1625 for (i = 0; i < MAX_MB_PLANE; i++)
1626 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1627 strides[i], mi_row, mi_col, NULL,
1628 x->e_mbd.plane[i].subsampling_x,
1629 x->e_mbd.plane[i].subsampling_y);
1630}
1631
Urvang Joshi52648442016-10-13 17:27:51 -07001632static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001633 int8_t segment_id) {
1634 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001635 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001636 av1_init_plane_quantizers(cpi, x, segment_id);
1637 aom_clear_system_state();
1638 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1639 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001640}
1641
Urvang Joshi52648442016-10-13 17:27:51 -07001642static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001643 MACROBLOCK *const x, int mi_row, int mi_col,
1644 RD_COST *rd_cost,
1645#if CONFIG_SUPERTX
1646 int *totalrate_nocoef,
1647#endif
1648#if CONFIG_EXT_PARTITION_TYPES
1649 PARTITION_TYPE partition,
1650#endif
1651 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1652 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001653 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654 TileInfo *const tile_info = &tile_data->tile_info;
1655 MACROBLOCKD *const xd = &x->e_mbd;
1656 MB_MODE_INFO *mbmi;
1657 struct macroblock_plane *const p = x->plane;
1658 struct macroblockd_plane *const pd = xd->plane;
1659 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1660 int i, orig_rdmult;
1661
Yaowu Xuf883b422016-08-30 14:01:10 -07001662 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001663
1664 // Use the lower precision, but faster, 32x32 fdct for mode selection.
1665 x->use_lp32x32fdct = 1;
1666
Yushin Cho77bba8d2016-11-04 16:36:56 -07001667#if CONFIG_PVQ
1668 x->pvq_speed = 1;
1669 x->pvq_coded = 0;
1670#endif
1671
Yaowu Xuc27fc142016-08-22 16:08:15 -07001672 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1673 mbmi = &xd->mi[0]->mbmi;
1674 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001675#if CONFIG_RD_DEBUG
1676 mbmi->mi_row = mi_row;
1677 mbmi->mi_col = mi_col;
1678#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679#if CONFIG_SUPERTX
1680 // We set tx_size here as skip blocks would otherwise not set it.
1681 // tx_size needs to be set at this point as supertx_enable in
1682 // write_modes_sb is computed based on this, and if the garbage in memory
1683 // just happens to be the supertx_size, then the packer will code this
1684 // block as a supertx block, even if rdopt did not pick it as such.
1685 mbmi->tx_size = max_txsize_lookup[bsize];
1686#endif
1687#if CONFIG_EXT_PARTITION_TYPES
1688 mbmi->partition = partition;
1689#endif
1690
1691 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001692 p[i].coeff = ctx->coeff[i];
1693 p[i].qcoeff = ctx->qcoeff[i];
1694 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001695#if CONFIG_PVQ
1696 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1697#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001698 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001699 }
1700
Urvang Joshib100db72016-10-12 16:28:56 -07001701#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001703#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001704
Yaowu Xuc27fc142016-08-22 16:08:15 -07001705 ctx->skippable = 0;
1706 ctx->pred_pixel_ready = 0;
1707
1708 // Set to zero to make sure we do not use the previous encoded frame stats
1709 mbmi->skip = 0;
1710
Yaowu Xuf883b422016-08-30 14:01:10 -07001711#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001713 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001714 cpi, &x->plane[0].src, bsize, xd->bd);
1715 } else {
1716 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001717 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001718 }
1719#else
1720 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001721 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1722#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723
1724 // Save rdmult before it might be changed, so it can be restored later.
1725 orig_rdmult = x->rdmult;
1726
1727 if (aq_mode == VARIANCE_AQ) {
1728 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001729 const int energy =
1730 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1731 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001733 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001734 }
1735 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1736 } else if (aq_mode == COMPLEXITY_AQ) {
1737 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1738 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1739 // If segment is boosted, use rdmult for that segment.
1740 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001741 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001742 }
1743
1744 // Find best coding mode & reconstruct the MB so it is available
1745 // as a predictor for MBs that follow in the SB
1746 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001747 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001748#if CONFIG_SUPERTX
1749 *totalrate_nocoef = 0;
1750#endif // CONFIG_SUPERTX
1751 } else {
1752 if (bsize >= BLOCK_8X8) {
1753 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001754 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1755 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001756#if CONFIG_SUPERTX
1757 *totalrate_nocoef = rd_cost->rate;
1758#endif // CONFIG_SUPERTX
1759 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001760 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001761#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001762 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001763#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001764 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765#if CONFIG_SUPERTX
1766 assert(*totalrate_nocoef >= 0);
1767#endif // CONFIG_SUPERTX
1768 }
1769 } else {
1770 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1771 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1772 rd_cost->rate = INT_MAX;
1773 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001774 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1775 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001776#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001777 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001778#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001779 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780#if CONFIG_SUPERTX
1781 assert(*totalrate_nocoef >= 0);
1782#endif // CONFIG_SUPERTX
1783 }
1784 }
1785 }
1786
1787 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1788 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1789 (bsize >= BLOCK_16X16) &&
1790 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1791 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001792 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001793 }
1794
1795 x->rdmult = orig_rdmult;
1796
1797 // TODO(jingning) The rate-distortion optimization flow needs to be
1798 // refactored to provide proper exit/return handle.
1799 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1800
1801 ctx->rate = rd_cost->rate;
1802 ctx->dist = rd_cost->dist;
1803}
1804
1805#if CONFIG_REF_MV
1806static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1807#if CONFIG_EXT_INTER
1808 int is_compound,
1809#endif // CONFIG_EXT_INTER
1810 int16_t mode_context) {
1811 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1812#if CONFIG_EXT_INTER
1813 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1814 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1815#else
1816 if (mode == NEWMV) {
1817#endif // CONFIG_EXT_INTER
1818 ++counts->newmv_mode[mode_ctx][0];
1819 return;
1820 } else {
1821 ++counts->newmv_mode[mode_ctx][1];
1822
1823 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1824 return;
1825 }
1826
1827 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1828 if (mode == ZEROMV) {
1829 ++counts->zeromv_mode[mode_ctx][0];
1830 return;
1831 } else {
1832 ++counts->zeromv_mode[mode_ctx][1];
1833 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1834
1835 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1836 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1837 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1838
1839 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1840 }
1841 }
1842}
1843#endif
1844
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001845static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1846 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07001847#if CONFIG_SUPERTX
1848 ,
1849 int supertx_enabled
1850#endif
1851 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01001852#if CONFIG_DELTA_Q
1853 MACROBLOCK *x = &td->mb;
1854 MACROBLOCKD *const xd = &x->e_mbd;
1855#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001856 const MACROBLOCK *x = &td->mb;
1857 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01001858#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 const MODE_INFO *const mi = xd->mi[0];
1860 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1861 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1862 const BLOCK_SIZE bsize = mbmi->sb_type;
1863
Thomas Daviesf6936102016-09-05 16:51:31 +01001864#if CONFIG_DELTA_Q
1865 // delta quant applies to both intra and inter
1866 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
1867
1868 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
1869 super_block_upper_left) {
1870 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1871 const int absdq = abs(dq);
1872 int i;
1873 for (i = 0; i < absdq; ++i) {
1874 td->counts->delta_q[i][1]++;
1875 }
1876 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1877 xd->prev_qindex = mbmi->current_q_index;
1878 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001879#else
1880 (void)mi_row;
1881 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01001882#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 if (!frame_is_intra_only(cm)) {
1884 FRAME_COUNTS *const counts = td->counts;
1885 const int inter_block = is_inter_block(mbmi);
1886 const int seg_ref_active =
1887 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1888 if (!seg_ref_active) {
1889#if CONFIG_SUPERTX
1890 if (!supertx_enabled)
1891#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001892 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001893 // If the segment reference feature is enabled we have only a single
1894 // reference frame allowed for the segment so exclude it from
1895 // the reference frame counts used to work out probabilities.
1896 if (inter_block) {
1897 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1898#if CONFIG_EXT_REFS
1899 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1900#endif // CONFIG_EXT_REFS
1901
1902 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07001903 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1904 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905
1906 if (has_second_ref(mbmi)) {
1907#if CONFIG_EXT_REFS
1908 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1909
Yaowu Xuf883b422016-08-30 14:01:10 -07001910 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001911 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07001912 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1913 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 } else {
clang-format67948d32016-09-07 22:40:40 -07001915 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1916 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917 }
1918
clang-format67948d32016-09-07 22:40:40 -07001919 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1920 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921#else
clang-format67948d32016-09-07 22:40:40 -07001922 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1923 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924#endif // CONFIG_EXT_REFS
1925 } else {
1926#if CONFIG_EXT_REFS
1927 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
1928
Yaowu Xuf883b422016-08-30 14:01:10 -07001929 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001930 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07001931 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1932 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001933 } else {
1934 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001935 counts->single_ref[av1_get_pred_context_single_ref_p3(xd)][2]
1936 [bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001938 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1939 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001940 } else {
clang-format67948d32016-09-07 22:40:40 -07001941 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1942 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001943 }
1944 }
1945#else
clang-format67948d32016-09-07 22:40:40 -07001946 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1947 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001948 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07001949 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1950 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001951 }
1952#endif // CONFIG_EXT_REFS
1953 }
1954
1955#if CONFIG_EXT_INTER
1956 if (cm->reference_mode != COMPOUND_REFERENCE &&
1957#if CONFIG_SUPERTX
1958 !supertx_enabled &&
1959#endif
1960 is_interintra_allowed(mbmi)) {
1961 const int bsize_group = size_group_lookup[bsize];
1962 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1963 counts->interintra[bsize_group][1]++;
1964 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1965 if (is_interintra_wedge_used(bsize))
1966 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1967 } else {
1968 counts->interintra[bsize_group][0]++;
1969 }
1970 }
1971#endif // CONFIG_EXT_INTER
1972
Yue Chencb60b182016-10-13 15:18:22 -07001973#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001974#if CONFIG_SUPERTX
1975 if (!supertx_enabled)
1976#endif // CONFIG_SUPERTX
1977#if CONFIG_EXT_INTER
1978 if (mbmi->ref_frame[1] != INTRA_FRAME)
1979#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001980#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
1981 {
1982 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -07001983 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
Yue Chen69f18e12016-09-08 14:48:15 -07001984 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
1985 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
1986 }
1987#else
1988 if (motion_mode_allowed(mbmi) > SIMPLE_TRANSLATION)
1989 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1990#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07001991#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001992
1993#if CONFIG_EXT_INTER
1994 if (cm->reference_mode != SINGLE_REFERENCE &&
Sarah Parker6fdc8532016-11-16 17:47:13 -08001995 is_inter_compound_mode(mbmi->mode)
Yue Chencb60b182016-10-13 15:18:22 -07001996#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08001997 && mbmi->motion_mode == SIMPLE_TRANSLATION
Yue Chencb60b182016-10-13 15:18:22 -07001998#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08001999 ) {
2000 counts->compound_interinter[bsize]
2001 [mbmi->interinter_compound_data.type]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002 }
2003#endif // CONFIG_EXT_INTER
2004 }
2005 }
2006
2007 if (inter_block &&
2008 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08002009 int16_t mode_ctx;
2010#if !CONFIG_REF_MV
2011 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
2012#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002013 if (bsize >= BLOCK_8X8) {
2014 const PREDICTION_MODE mode = mbmi->mode;
2015#if CONFIG_REF_MV
2016#if CONFIG_EXT_INTER
2017 if (has_second_ref(mbmi)) {
2018 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
2019 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2020 } else {
2021#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002022 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2023 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002024 update_inter_mode_stats(counts, mode,
2025#if CONFIG_EXT_INTER
2026 has_second_ref(mbmi),
2027#endif // CONFIG_EXT_INTER
2028 mode_ctx);
2029
2030 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002031 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002032 int idx;
2033
2034 for (idx = 0; idx < 2; ++idx) {
2035 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2036 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002037 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002038 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
2039
2040 if (mbmi->ref_mv_idx == idx) break;
2041 }
2042 }
2043 }
2044
2045 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002046 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002047 int idx;
2048
2049 for (idx = 1; idx < 3; ++idx) {
2050 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2051 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002052 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002053 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2054
2055 if (mbmi->ref_mv_idx == idx - 1) break;
2056 }
2057 }
2058 }
2059#if CONFIG_EXT_INTER
2060 }
2061#endif // CONFIG_EXT_INTER
2062#else
2063#if CONFIG_EXT_INTER
2064 if (is_inter_compound_mode(mode))
2065 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2066 else
2067#endif // CONFIG_EXT_INTER
2068 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2069#endif
2070 } else {
2071 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2072 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2073 int idx, idy;
2074 for (idy = 0; idy < 2; idy += num_4x4_h) {
2075 for (idx = 0; idx < 2; idx += num_4x4_w) {
2076 const int j = idy * 2 + idx;
2077 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2078#if CONFIG_REF_MV
2079#if CONFIG_EXT_INTER
2080 if (has_second_ref(mbmi)) {
2081 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002082 ++counts->inter_compound_mode[mode_ctx]
2083 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002084 } else {
2085#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002086 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2087 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002088 update_inter_mode_stats(counts, b_mode,
2089#if CONFIG_EXT_INTER
2090 has_second_ref(mbmi),
2091#endif // CONFIG_EXT_INTER
2092 mode_ctx);
2093#if CONFIG_EXT_INTER
2094 }
2095#endif // CONFIG_EXT_INTER
2096#else
2097#if CONFIG_EXT_INTER
2098 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002099 ++counts->inter_compound_mode[mode_ctx]
2100 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101 else
2102#endif // CONFIG_EXT_INTER
2103 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2104#endif
2105 }
2106 }
2107 }
2108 }
2109 }
2110}
2111
2112typedef struct {
2113 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2114 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2115 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2116 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2117#if CONFIG_VAR_TX
2118 TXFM_CONTEXT *p_ta;
2119 TXFM_CONTEXT *p_tl;
2120 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2121 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2122#endif
2123} RD_SEARCH_MACROBLOCK_CONTEXT;
2124
2125static void restore_context(MACROBLOCK *x,
2126 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002127 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002128#if CONFIG_PVQ
2129 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002130#endif
2131 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002132 MACROBLOCKD *xd = &x->e_mbd;
2133 int p;
2134 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2135 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2136 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2137 int mi_height = num_8x8_blocks_high_lookup[bsize];
2138 for (p = 0; p < MAX_MB_PLANE; p++) {
2139 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2140 ctx->a + num_4x4_blocks_wide * p,
2141 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2142 xd->plane[p].subsampling_x);
2143 memcpy(xd->left_context[p] +
2144 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2145 ctx->l + num_4x4_blocks_high * p,
2146 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2147 xd->plane[p].subsampling_y);
2148 }
2149 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2150 sizeof(*xd->above_seg_context) * mi_width);
2151 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2152 sizeof(xd->left_seg_context[0]) * mi_height);
2153#if CONFIG_VAR_TX
2154 xd->above_txfm_context = ctx->p_ta;
2155 xd->left_txfm_context = ctx->p_tl;
2156 memcpy(xd->above_txfm_context, ctx->ta,
2157 sizeof(*xd->above_txfm_context) * mi_width);
2158 memcpy(xd->left_txfm_context, ctx->tl,
2159 sizeof(*xd->left_txfm_context) * mi_height);
2160#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002161#if CONFIG_PVQ
2162 od_encode_rollback(&x->daala_enc, rdo_buf);
2163#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002164}
2165
2166static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002167 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002168#if CONFIG_PVQ
2169 od_rollback_buffer *rdo_buf,
2170#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002171 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002172 const MACROBLOCKD *xd = &x->e_mbd;
2173 int p;
2174 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2175 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2176 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2177 int mi_height = num_8x8_blocks_high_lookup[bsize];
2178
2179 // buffer the above/left context information of the block in search.
2180 for (p = 0; p < MAX_MB_PLANE; ++p) {
2181 memcpy(ctx->a + num_4x4_blocks_wide * p,
2182 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2183 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2184 xd->plane[p].subsampling_x);
2185 memcpy(ctx->l + num_4x4_blocks_high * p,
2186 xd->left_context[p] +
2187 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2188 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2189 xd->plane[p].subsampling_y);
2190 }
2191 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2192 sizeof(*xd->above_seg_context) * mi_width);
2193 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2194 sizeof(xd->left_seg_context[0]) * mi_height);
2195#if CONFIG_VAR_TX
2196 memcpy(ctx->ta, xd->above_txfm_context,
2197 sizeof(*xd->above_txfm_context) * mi_width);
2198 memcpy(ctx->tl, xd->left_txfm_context,
2199 sizeof(*xd->left_txfm_context) * mi_height);
2200 ctx->p_ta = xd->above_txfm_context;
2201 ctx->p_tl = xd->left_txfm_context;
2202#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002203#if CONFIG_PVQ
2204 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2205#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002206}
2207
Urvang Joshi52648442016-10-13 17:27:51 -07002208static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2209 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2210 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002211#if CONFIG_EXT_PARTITION_TYPES
2212 PARTITION_TYPE partition,
2213#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002214 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002215 MACROBLOCK *const x = &td->mb;
2216 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2217#if CONFIG_EXT_PARTITION_TYPES
2218 x->e_mbd.mi[0]->mbmi.partition = partition;
2219#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002220 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2221 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002222
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002223 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002224#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002225 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002227 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002228#endif
2229 }
2230}
2231
Urvang Joshi52648442016-10-13 17:27:51 -07002232static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2233 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2234 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2235 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002236 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002237 MACROBLOCK *const x = &td->mb;
2238 MACROBLOCKD *const xd = &x->e_mbd;
2239
2240 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
2241 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
2242 const PARTITION_TYPE partition = pc_tree->partitioning;
2243 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2244#if CONFIG_EXT_PARTITION_TYPES
2245 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2246#endif
2247
2248 assert(bsize >= BLOCK_8X8);
2249
2250 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2251
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002252 if (!dry_run) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253
2254#if CONFIG_SUPERTX
2255 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2256 partition != PARTITION_NONE && !xd->lossless[0]) {
2257 int supertx_enabled;
2258 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2259 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2260 if (supertx_enabled) {
2261 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2262 const int mi_height = num_8x8_blocks_high_lookup[bsize];
2263 int x_idx, y_idx, i;
2264 uint8_t *dst_buf[3];
2265 int dst_stride[3];
2266 set_skip_context(xd, mi_row, mi_col);
2267 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002268 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2269 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002270
Yaowu Xuf883b422016-08-30 14:01:10 -07002271 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002272 for (i = 0; i < MAX_MB_PLANE; i++) {
2273 dst_buf[i] = xd->plane[i].dst.buf;
2274 dst_stride[i] = xd->plane[i].dst.stride;
2275 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002276 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2277 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002278
2279 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2280 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2281
2282 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002283 int this_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002284 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2285
Angie Chiangff6d8902016-10-21 11:02:09 -07002286 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002287 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2288 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002289 } else {
2290 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002291 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292 reset_skip_context(xd, bsize);
2293 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002294 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002295 for (y_idx = 0; y_idx < mi_height; y_idx++)
2296 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2297 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2298 x_idx &&
2299 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2300 y_idx) {
2301 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2302 xd->mi[0]->mbmi.skip;
2303 }
2304 }
2305 td->counts->supertx[partition_supertx_context_lookup[partition]]
2306 [supertx_size][1]++;
2307 td->counts->supertx_size[supertx_size]++;
2308#if CONFIG_EXT_TX
2309 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2310 !xd->mi[0]->mbmi.skip) {
2311 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2312 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002313 ++td->counts->inter_ext_tx[eset][supertx_size]
2314 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315 }
2316 }
2317#else
2318 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2319 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2320 }
2321#endif // CONFIG_EXT_TX
2322 }
2323#if CONFIG_EXT_PARTITION_TYPES
2324 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2325 partition);
2326#else
2327 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2328 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2329#endif
2330#if CONFIG_VAR_TX
Yaowu Xu52a17632016-11-17 15:48:21 -08002331 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2332 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002333#endif // CONFIG_VAR_TX
2334 return;
2335 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002336 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002337 td->counts->supertx[partition_supertx_context_lookup[partition]]
2338 [supertx_size][0]++;
2339 }
2340 }
2341 }
2342#endif // CONFIG_SUPERTX
2343
2344 switch (partition) {
2345 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002346 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002347#if CONFIG_EXT_PARTITION_TYPES
2348 partition,
2349#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002350 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351 break;
2352 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002353 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002354#if CONFIG_EXT_PARTITION_TYPES
2355 partition,
2356#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002357 &pc_tree->vertical[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002358 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002359 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002360#if CONFIG_EXT_PARTITION_TYPES
2361 partition,
2362#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002363 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002364 }
2365 break;
2366 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002367 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002368#if CONFIG_EXT_PARTITION_TYPES
2369 partition,
2370#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002371 &pc_tree->horizontal[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002372 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002373 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002374#if CONFIG_EXT_PARTITION_TYPES
2375 partition,
2376#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002377 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002378 }
2379 break;
2380 case PARTITION_SPLIT:
2381 if (bsize == BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002382 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383#if CONFIG_EXT_PARTITION_TYPES
2384 partition,
2385#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002386 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002387 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002388 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2389 pc_tree->split[0], rate);
2390 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2391 pc_tree->split[1], rate);
2392 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2393 pc_tree->split[2], rate);
2394 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2395 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002396 }
2397 break;
2398#if CONFIG_EXT_PARTITION_TYPES
2399 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002400 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2401 &pc_tree->horizontala[0], rate);
2402 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2403 partition, &pc_tree->horizontala[1], rate);
2404 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2405 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002406 break;
2407 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002408 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2409 &pc_tree->horizontalb[0], rate);
2410 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2411 partition, &pc_tree->horizontalb[1], rate);
2412 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2413 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002414 break;
2415 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002416 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2417 &pc_tree->verticala[0], rate);
2418 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2419 partition, &pc_tree->verticala[1], rate);
2420 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2421 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002422
2423 break;
2424 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002425 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2426 &pc_tree->verticalb[0], rate);
2427 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2428 partition, &pc_tree->verticalb[1], rate);
2429 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2430 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 break;
2432#endif // CONFIG_EXT_PARTITION_TYPES
2433 default: assert(0 && "Invalid partition type."); break;
2434 }
2435
2436#if CONFIG_EXT_PARTITION_TYPES
2437 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2438#else
2439 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2440 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2441#endif // CONFIG_EXT_PARTITION_TYPES
2442}
2443
2444// Check to see if the given partition size is allowed for a specified number
2445// of mi block rows and columns remaining in the image.
2446// If not then return the largest allowed partition size
2447static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2448 int cols_left, int *bh, int *bw) {
2449 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002450 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002451 } else {
2452 for (; bsize > 0; bsize -= 3) {
2453 *bh = num_8x8_blocks_high_lookup[bsize];
2454 *bw = num_8x8_blocks_wide_lookup[bsize];
2455 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2456 break;
2457 }
2458 }
2459 }
2460 return bsize;
2461}
2462
Yaowu Xuf883b422016-08-30 14:01:10 -07002463static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002464 int bh_in, int bw_in,
2465 int mi_rows_remaining,
2466 int mi_cols_remaining, BLOCK_SIZE bsize,
2467 MODE_INFO **mib) {
2468 int bh = bh_in;
2469 int r, c;
2470 for (r = 0; r < cm->mib_size; r += bh) {
2471 int bw = bw_in;
2472 for (c = 0; c < cm->mib_size; c += bw) {
2473 const int index = r * cm->mi_stride + c;
2474 mib[index] = mi + index;
2475 mib[index]->mbmi.sb_type = find_partition_size(
2476 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2477 }
2478 }
2479}
2480
2481// This function attempts to set all mode info entries in a given superblock
2482// to the same block partition size.
2483// However, at the bottom and right borders of the image the requested size
2484// may not be allowed in which case this code attempts to choose the largest
2485// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002486static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002487 MODE_INFO **mib, int mi_row, int mi_col,
2488 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002489 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002490 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2491 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2492 int block_row, block_col;
2493 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2494 int bh = num_8x8_blocks_high_lookup[bsize];
2495 int bw = num_8x8_blocks_wide_lookup[bsize];
2496
2497 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2498
2499 // Apply the requested partition size to the SB if it is all "in image"
2500 if ((mi_cols_remaining >= cm->mib_size) &&
2501 (mi_rows_remaining >= cm->mib_size)) {
2502 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2503 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2504 int index = block_row * cm->mi_stride + block_col;
2505 mib[index] = mi_upper_left + index;
2506 mib[index]->mbmi.sb_type = bsize;
2507 }
2508 }
2509 } else {
2510 // Else this is a partial SB.
2511 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2512 mi_cols_remaining, bsize, mib);
2513 }
2514}
2515
Yaowu Xuf883b422016-08-30 14:01:10 -07002516static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002517 TileDataEnc *tile_data, MODE_INFO **mib,
2518 TOKENEXTRA **tp, int mi_row, int mi_col,
2519 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2520#if CONFIG_SUPERTX
2521 int *rate_nocoef,
2522#endif
2523 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002524 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002525 TileInfo *const tile_info = &tile_data->tile_info;
2526 MACROBLOCK *const x = &td->mb;
2527 MACROBLOCKD *const xd = &x->e_mbd;
2528 const int bs = num_8x8_blocks_wide_lookup[bsize];
2529 const int hbs = bs / 2;
2530 int i;
2531 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2532 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2533 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2534 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2535 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2536 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2537 int splits_below = 0;
2538 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2539 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002540 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541#if CONFIG_SUPERTX
2542 int last_part_rate_nocoef = INT_MAX;
2543 int none_rate_nocoef = INT_MAX;
2544 int chosen_rate_nocoef = INT_MAX;
2545#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002546#if CONFIG_PVQ
2547 od_rollback_buffer pre_rdo_buf;
2548#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2550
2551 assert(num_4x4_blocks_wide_lookup[bsize] ==
2552 num_4x4_blocks_high_lookup[bsize]);
2553
Yaowu Xuf883b422016-08-30 14:01:10 -07002554 av1_rd_cost_reset(&last_part_rdc);
2555 av1_rd_cost_reset(&none_rdc);
2556 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002557
2558 pc_tree->partitioning = partition;
2559
2560#if CONFIG_VAR_TX
2561 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2562 xd->left_txfm_context =
2563 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2564#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002565#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002566 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002567#else
2568 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2569#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570
2571 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2572 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002573 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002574 }
2575
2576 if (do_partition_search &&
2577 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2578 cpi->sf.adjust_partitioning_from_last_frame) {
2579 // Check if any of the sub blocks are further split.
2580 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2581 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2582 splits_below = 1;
2583 for (i = 0; i < 4; i++) {
2584 int jj = i >> 1, ii = i & 0x01;
2585 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2586 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2587 splits_below = 0;
2588 }
2589 }
2590 }
2591
2592 // If partition is not none try none unless each of the 4 splits are split
2593 // even further..
2594 if (partition != PARTITION_NONE && !splits_below &&
2595 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2596 pc_tree->partitioning = PARTITION_NONE;
2597 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2598#if CONFIG_SUPERTX
2599 &none_rate_nocoef,
2600#endif
2601#if CONFIG_EXT_PARTITION_TYPES
2602 PARTITION_NONE,
2603#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002604 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002605
2606 if (none_rdc.rate < INT_MAX) {
2607 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2608 none_rdc.rdcost =
2609 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2610#if CONFIG_SUPERTX
2611 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2612#endif
2613 }
2614
Yushin Cho77bba8d2016-11-04 16:36:56 -07002615#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002616 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002617#else
2618 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2619#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002620 mib[0]->mbmi.sb_type = bs_type;
2621 pc_tree->partitioning = partition;
2622 }
2623 }
2624
2625 switch (partition) {
2626 case PARTITION_NONE:
2627 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2628#if CONFIG_SUPERTX
2629 &last_part_rate_nocoef,
2630#endif
2631#if CONFIG_EXT_PARTITION_TYPES
2632 PARTITION_NONE,
2633#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002634 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002635 break;
2636 case PARTITION_HORZ:
2637 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2638#if CONFIG_SUPERTX
2639 &last_part_rate_nocoef,
2640#endif
2641#if CONFIG_EXT_PARTITION_TYPES
2642 PARTITION_HORZ,
2643#endif
2644 subsize, &pc_tree->horizontal[0], INT64_MAX);
2645 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2646 mi_row + hbs < cm->mi_rows) {
2647 RD_COST tmp_rdc;
2648#if CONFIG_SUPERTX
2649 int rt_nocoef = 0;
2650#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002651 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002652 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002653 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002654 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002655 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002656 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2657#if CONFIG_SUPERTX
2658 &rt_nocoef,
2659#endif
2660#if CONFIG_EXT_PARTITION_TYPES
2661 PARTITION_HORZ,
2662#endif
2663 subsize, &pc_tree->horizontal[1], INT64_MAX);
2664 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002665 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002666#if CONFIG_SUPERTX
2667 last_part_rate_nocoef = INT_MAX;
2668#endif
2669 break;
2670 }
2671 last_part_rdc.rate += tmp_rdc.rate;
2672 last_part_rdc.dist += tmp_rdc.dist;
2673 last_part_rdc.rdcost += tmp_rdc.rdcost;
2674#if CONFIG_SUPERTX
2675 last_part_rate_nocoef += rt_nocoef;
2676#endif
2677 }
2678 break;
2679 case PARTITION_VERT:
2680 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2681#if CONFIG_SUPERTX
2682 &last_part_rate_nocoef,
2683#endif
2684#if CONFIG_EXT_PARTITION_TYPES
2685 PARTITION_VERT,
2686#endif
2687 subsize, &pc_tree->vertical[0], INT64_MAX);
2688 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2689 mi_col + hbs < cm->mi_cols) {
2690 RD_COST tmp_rdc;
2691#if CONFIG_SUPERTX
2692 int rt_nocoef = 0;
2693#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002694 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002695 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002696 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002697 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002698 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002699 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2700#if CONFIG_SUPERTX
2701 &rt_nocoef,
2702#endif
2703#if CONFIG_EXT_PARTITION_TYPES
2704 PARTITION_VERT,
2705#endif
2706 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2707 INT64_MAX);
2708 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002709 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002710#if CONFIG_SUPERTX
2711 last_part_rate_nocoef = INT_MAX;
2712#endif
2713 break;
2714 }
2715 last_part_rdc.rate += tmp_rdc.rate;
2716 last_part_rdc.dist += tmp_rdc.dist;
2717 last_part_rdc.rdcost += tmp_rdc.rdcost;
2718#if CONFIG_SUPERTX
2719 last_part_rate_nocoef += rt_nocoef;
2720#endif
2721 }
2722 break;
2723 case PARTITION_SPLIT:
2724 if (bsize == BLOCK_8X8) {
2725 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2726#if CONFIG_SUPERTX
2727 &last_part_rate_nocoef,
2728#endif
2729#if CONFIG_EXT_PARTITION_TYPES
2730 PARTITION_SPLIT,
2731#endif
2732 subsize, pc_tree->leaf_split[0], INT64_MAX);
2733 break;
2734 }
2735 last_part_rdc.rate = 0;
2736 last_part_rdc.dist = 0;
2737 last_part_rdc.rdcost = 0;
2738#if CONFIG_SUPERTX
2739 last_part_rate_nocoef = 0;
2740#endif
2741 for (i = 0; i < 4; i++) {
2742 int x_idx = (i & 1) * hbs;
2743 int y_idx = (i >> 1) * hbs;
2744 int jj = i >> 1, ii = i & 0x01;
2745 RD_COST tmp_rdc;
2746#if CONFIG_SUPERTX
2747 int rt_nocoef;
2748#endif
2749 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2750 continue;
2751
Yaowu Xuf883b422016-08-30 14:01:10 -07002752 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002753 rd_use_partition(cpi, td, tile_data,
2754 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2755 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2756 &tmp_rdc.dist,
2757#if CONFIG_SUPERTX
2758 &rt_nocoef,
2759#endif
2760 i != 3, pc_tree->split[i]);
2761 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002762 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002763#if CONFIG_SUPERTX
2764 last_part_rate_nocoef = INT_MAX;
2765#endif
2766 break;
2767 }
2768 last_part_rdc.rate += tmp_rdc.rate;
2769 last_part_rdc.dist += tmp_rdc.dist;
2770#if CONFIG_SUPERTX
2771 last_part_rate_nocoef += rt_nocoef;
2772#endif
2773 }
2774 break;
2775#if CONFIG_EXT_PARTITION_TYPES
2776 case PARTITION_VERT_A:
2777 case PARTITION_VERT_B:
2778 case PARTITION_HORZ_A:
2779 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2780#endif // CONFIG_EXT_PARTITION_TYPES
2781 default: assert(0); break;
2782 }
2783
2784 if (last_part_rdc.rate < INT_MAX) {
2785 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2786 last_part_rdc.rdcost =
2787 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2788#if CONFIG_SUPERTX
2789 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2790#endif
2791 }
2792
2793 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2794 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2795 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2796 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2797 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2798 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2799 chosen_rdc.rate = 0;
2800 chosen_rdc.dist = 0;
2801#if CONFIG_SUPERTX
2802 chosen_rate_nocoef = 0;
2803#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002804#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002805 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002806#else
2807 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2808#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002809 pc_tree->partitioning = PARTITION_SPLIT;
2810
2811 // Split partition.
2812 for (i = 0; i < 4; i++) {
2813 int x_idx = (i & 1) * hbs;
2814 int y_idx = (i >> 1) * hbs;
2815 RD_COST tmp_rdc;
2816#if CONFIG_SUPERTX
2817 int rt_nocoef = 0;
2818#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002819#if CONFIG_PVQ
2820 od_rollback_buffer buf;
2821#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2823 continue;
2824
Yushin Cho77bba8d2016-11-04 16:36:56 -07002825#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002826 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002827#else
2828 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2829#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002830 pc_tree->split[i]->partitioning = PARTITION_NONE;
2831 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2832 &tmp_rdc,
2833#if CONFIG_SUPERTX
2834 &rt_nocoef,
2835#endif
2836#if CONFIG_EXT_PARTITION_TYPES
2837 PARTITION_SPLIT,
2838#endif
2839 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2840
Yushin Cho77bba8d2016-11-04 16:36:56 -07002841#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002842 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002843#else
2844 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2845#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002847 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002848#if CONFIG_SUPERTX
2849 chosen_rate_nocoef = INT_MAX;
2850#endif
2851 break;
2852 }
2853
2854 chosen_rdc.rate += tmp_rdc.rate;
2855 chosen_rdc.dist += tmp_rdc.dist;
2856#if CONFIG_SUPERTX
2857 chosen_rate_nocoef += rt_nocoef;
2858#endif
2859
2860 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002861 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2862 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002863
2864 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2865#if CONFIG_SUPERTX
2866 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2867#endif
2868 }
2869 if (chosen_rdc.rate < INT_MAX) {
2870 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2871 chosen_rdc.rdcost =
2872 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2873#if CONFIG_SUPERTX
2874 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2875#endif
2876 }
2877 }
2878
2879 // If last_part is better set the partitioning to that.
2880 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2881 mib[0]->mbmi.sb_type = bsize;
2882 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2883 chosen_rdc = last_part_rdc;
2884#if CONFIG_SUPERTX
2885 chosen_rate_nocoef = last_part_rate_nocoef;
2886#endif
2887 }
2888 // If none was better set the partitioning to that.
2889 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2890 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2891 chosen_rdc = none_rdc;
2892#if CONFIG_SUPERTX
2893 chosen_rate_nocoef = none_rate_nocoef;
2894#endif
2895 }
2896
Yushin Cho77bba8d2016-11-04 16:36:56 -07002897#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002898 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002899#else
2900 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2901#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002902
2903 // We must have chosen a partitioning and encoding or we'll fail later on.
2904 // No other opportunities for success.
2905 if (bsize == cm->sb_size)
2906 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2907
2908 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002909 if (bsize == cm->sb_size) {
2910 // NOTE: To get estimate for rate due to the tokens, use:
2911 // int rate_coeffs = 0;
2912 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2913 // bsize, pc_tree, &rate_coeffs);
2914 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2915 pc_tree, NULL);
2916 } else {
2917 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2918 pc_tree, NULL);
2919 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002920 }
2921
2922 *rate = chosen_rdc.rate;
2923 *dist = chosen_rdc.dist;
2924#if CONFIG_SUPERTX
2925 *rate_nocoef = chosen_rate_nocoef;
2926#endif
2927}
2928
2929/* clang-format off */
2930static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2931 BLOCK_4X4, // 4x4
2932 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2933 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2934 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2935 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2936#if CONFIG_EXT_PARTITION
2937 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2938#endif // CONFIG_EXT_PARTITION
2939};
2940
2941static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2942 BLOCK_8X8, // 4x4
2943 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2944 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2945 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2946 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2947#if CONFIG_EXT_PARTITION
2948 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2949#endif // CONFIG_EXT_PARTITION
2950};
2951
2952// Next square block size less or equal than current block size.
2953static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2954 BLOCK_4X4, // 4x4
2955 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2956 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2957 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2958 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2959#if CONFIG_EXT_PARTITION
2960 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
2961#endif // CONFIG_EXT_PARTITION
2962};
2963/* clang-format on */
2964
2965// Look at all the mode_info entries for blocks that are part of this
2966// partition and find the min and max values for sb_type.
2967// At the moment this is designed to work on a superblock but could be
2968// adjusted to use a size parameter.
2969//
2970// The min and max are assumed to have been initialized prior to calling this
2971// function so repeat calls can accumulate a min and max of more than one
2972// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002973static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002974 MACROBLOCKD *xd, MODE_INFO **mib,
2975 BLOCK_SIZE *min_block_size,
2976 BLOCK_SIZE *max_block_size) {
2977 int i, j;
2978 int index = 0;
2979
2980 // Check the sb_type for each block that belongs to this region.
2981 for (i = 0; i < cm->mib_size; ++i) {
2982 for (j = 0; j < cm->mib_size; ++j) {
2983 MODE_INFO *mi = mib[index + j];
2984 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002985 *min_block_size = AOMMIN(*min_block_size, sb_type);
2986 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987 }
2988 index += xd->mi_stride;
2989 }
2990}
2991
2992// Look at neighboring blocks and set a min and max partition size based on
2993// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002994static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002995 MACROBLOCKD *const xd, int mi_row,
2996 int mi_col, BLOCK_SIZE *min_block_size,
2997 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002998 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002999 MODE_INFO **mi = xd->mi;
3000 const int left_in_image = xd->left_available && mi[-1];
3001 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3002 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3003 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3004 int bh, bw;
3005 BLOCK_SIZE min_size = BLOCK_4X4;
3006 BLOCK_SIZE max_size = BLOCK_LARGEST;
3007
3008 // Trap case where we do not have a prediction.
3009 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3010 // Default "min to max" and "max to min"
3011 min_size = BLOCK_LARGEST;
3012 max_size = BLOCK_4X4;
3013
3014 // NOTE: each call to get_sb_partition_size_range() uses the previous
3015 // passed in values for min and max as a starting point.
3016 // Find the min and max partition used in previous frame at this location
3017 if (cm->frame_type != KEY_FRAME) {
3018 MODE_INFO **prev_mi =
3019 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3020 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3021 }
3022 // Find the min and max partition sizes used in the left superblock
3023 if (left_in_image) {
3024 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3025 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3026 }
3027 // Find the min and max partition sizes used in the above suprblock.
3028 if (above_in_image) {
3029 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3030 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3031 }
3032
3033 // Adjust observed min and max for "relaxed" auto partition case.
3034 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3035 min_size = min_partition_size[min_size];
3036 max_size = max_partition_size[max_size];
3037 }
3038 }
3039
3040 // Check border cases where max and min from neighbors may not be legal.
3041 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3042 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07003043 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003044
3045 // Test for blocks at the edge of the active image.
3046 // This may be the actual edge of the image or where there are formatting
3047 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003048 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003049 min_size = BLOCK_4X4;
3050 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003051 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003052 }
3053
3054 // When use_square_partition_only is true, make sure at least one square
3055 // partition is allowed by selecting the next smaller square size as
3056 // *min_block_size.
3057 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003058 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059 }
3060
Yaowu Xuf883b422016-08-30 14:01:10 -07003061 *min_block_size = AOMMIN(min_size, cm->sb_size);
3062 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003063}
3064
3065// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003066static void set_partition_range(const AV1_COMMON *const cm,
3067 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003068 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003069 BLOCK_SIZE *const min_bs,
3070 BLOCK_SIZE *const max_bs) {
3071 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3072 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073 int idx, idy;
3074
Yaowu Xuc27fc142016-08-22 16:08:15 -07003075 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003076 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3077 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3078 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003079
3080 if (prev_mi) {
3081 for (idy = 0; idy < mi_height; ++idy) {
3082 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003083 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3084 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003085 min_size = AOMMIN(min_size, bs);
3086 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003087 }
3088 }
3089 }
3090
3091 if (xd->left_available) {
3092 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003093 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3094 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003095 min_size = AOMMIN(min_size, bs);
3096 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003097 }
3098 }
3099
3100 if (xd->up_available) {
3101 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003102 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3103 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003104 min_size = AOMMIN(min_size, bs);
3105 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003106 }
3107 }
3108
3109 if (min_size == max_size) {
3110 min_size = min_partition_size[min_size];
3111 max_size = max_partition_size[max_size];
3112 }
3113
Yaowu Xuf883b422016-08-30 14:01:10 -07003114 *min_bs = AOMMIN(min_size, cm->sb_size);
3115 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003116}
3117
3118static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3119 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3120}
3121
3122static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3123 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3124}
3125
3126#if CONFIG_FP_MB_STATS
3127const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3128 0,
3129 10,
3130 10,
3131 30,
3132 40,
3133 40,
3134 60,
3135 80,
3136 80,
3137 90,
3138 100,
3139 100,
3140 120,
3141#if CONFIG_EXT_PARTITION
3142 // TODO(debargha): What are the correct numbers here?
3143 130,
3144 130,
3145 150
3146#endif // CONFIG_EXT_PARTITION
3147};
3148const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3149 0,
3150 3,
3151 3,
3152 7,
3153 15,
3154 15,
3155 30,
3156 40,
3157 40,
3158 60,
3159 80,
3160 80,
3161 120,
3162#if CONFIG_EXT_PARTITION
3163 // TODO(debargha): What are the correct numbers here?
3164 160,
3165 160,
3166 240
3167#endif // CONFIG_EXT_PARTITION
3168};
3169const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3170 1,
3171 1,
3172 1,
3173 1,
3174 1,
3175 1,
3176 1,
3177 1,
3178 1,
3179 1,
3180 4,
3181 4,
Yaowu Xu17fd2f22016-11-17 18:23:28 -08003182 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003183#if CONFIG_EXT_PARTITION
3184 // TODO(debargha): What are the correct numbers here?
3185 8,
3186 8,
3187 10
3188#endif // CONFIG_EXT_PARTITION
3189};
3190
3191typedef enum {
3192 MV_ZERO = 0,
3193 MV_LEFT = 1,
3194 MV_UP = 2,
3195 MV_RIGHT = 3,
3196 MV_DOWN = 4,
3197 MV_INVALID
3198} MOTION_DIRECTION;
3199
3200static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3201 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3202 return MV_ZERO;
3203 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3204 return MV_LEFT;
3205 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3206 return MV_RIGHT;
3207 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3208 return MV_UP;
3209 } else {
3210 return MV_DOWN;
3211 }
3212}
3213
3214static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3215 MOTION_DIRECTION that_mv) {
3216 if (this_mv == that_mv) {
3217 return 0;
3218 } else {
3219 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3220 }
3221}
3222#endif
3223
3224#if CONFIG_EXT_PARTITION_TYPES
3225static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003226 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3227 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3228 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3229 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003230#if CONFIG_SUPERTX
3231 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3232#endif
3233 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3234 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3235 MACROBLOCK *const x = &td->mb;
3236 MACROBLOCKD *const xd = &x->e_mbd;
3237 RD_COST this_rdc, sum_rdc;
3238#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003239 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003240 TileInfo *const tile_info = &tile_data->tile_info;
3241 int this_rate_nocoef, sum_rate_nocoef;
3242 int abort_flag;
3243 const int supertx_allowed = !frame_is_intra_only(cm) &&
3244 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3245 !xd->lossless[0];
3246#endif
3247 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3248
3249 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3250#if CONFIG_SUPERTX
3251 &sum_rate_nocoef,
3252#endif
3253#if CONFIG_EXT_PARTITION_TYPES
3254 partition,
3255#endif
3256 subsize0, &ctxs[0], best_rdc->rdcost);
3257#if CONFIG_SUPERTX
3258 abort_flag = sum_rdc.rdcost >= best_rd;
3259#endif
3260
3261#if CONFIG_SUPERTX
3262 if (sum_rdc.rdcost < INT64_MAX) {
3263#else
3264 if (sum_rdc.rdcost < best_rdc->rdcost) {
3265#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003266 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3267 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003268 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003269 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003270
Urvang Joshi368fbc92016-10-17 16:31:34 -07003271 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003272
3273#if CONFIG_SUPERTX
3274 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3275 &this_rate_nocoef,
3276#if CONFIG_EXT_PARTITION_TYPES
3277 partition,
3278#endif
3279 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3280#else
3281 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3282#if CONFIG_EXT_PARTITION_TYPES
3283 partition,
3284#endif
3285 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3286#endif // CONFIG_SUPERTX
3287
3288 if (this_rdc.rate == INT_MAX) {
3289 sum_rdc.rdcost = INT64_MAX;
3290#if CONFIG_SUPERTX
3291 sum_rate_nocoef = INT_MAX;
3292#endif
3293 } else {
3294 sum_rdc.rate += this_rdc.rate;
3295 sum_rdc.dist += this_rdc.dist;
3296 sum_rdc.rdcost += this_rdc.rdcost;
3297#if CONFIG_SUPERTX
3298 sum_rate_nocoef += this_rate_nocoef;
3299#endif
3300 }
3301
3302#if CONFIG_SUPERTX
3303 if (sum_rdc.rdcost < INT64_MAX) {
3304#else
3305 if (sum_rdc.rdcost < best_rdc->rdcost) {
3306#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003307 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3308 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003309 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003310 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003311
Urvang Joshi368fbc92016-10-17 16:31:34 -07003312 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003313
3314#if CONFIG_SUPERTX
3315 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3316 &this_rate_nocoef,
3317#if CONFIG_EXT_PARTITION_TYPES
3318 partition,
3319#endif
3320 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3321#else
3322 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3323#if CONFIG_EXT_PARTITION_TYPES
3324 partition,
3325#endif
3326 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3327#endif // CONFIG_SUPERTX
3328
3329 if (this_rdc.rate == INT_MAX) {
3330 sum_rdc.rdcost = INT64_MAX;
3331#if CONFIG_SUPERTX
3332 sum_rate_nocoef = INT_MAX;
3333#endif
3334 } else {
3335 sum_rdc.rate += this_rdc.rate;
3336 sum_rdc.dist += this_rdc.dist;
3337 sum_rdc.rdcost += this_rdc.rdcost;
3338#if CONFIG_SUPERTX
3339 sum_rate_nocoef += this_rate_nocoef;
3340#endif
3341 }
3342
3343#if CONFIG_SUPERTX
3344 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3345 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3346 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3347 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003348 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003349 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3350 [supertx_size],
3351 0);
3352 sum_rdc.rdcost =
3353 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3354
3355 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3356 TX_TYPE best_tx = DCT_DCT;
3357 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3358
3359 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3360
3361 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3362 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3363
Yaowu Xuf883b422016-08-30 14:01:10 -07003364 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003365 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3366 [supertx_size],
3367 1);
3368 tmp_rdc.rdcost =
3369 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3370 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3371 sum_rdc = tmp_rdc;
3372 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3373 supertx_size, pc_tree);
3374 }
3375 }
3376
3377 pc_tree->partitioning = best_partition;
3378 }
3379#endif // CONFIG_SUPERTX
3380
3381 if (sum_rdc.rdcost < best_rdc->rdcost) {
3382 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3383 sum_rdc.rate += cpi->partition_cost[pl][partition];
3384 sum_rdc.rdcost =
3385 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3386#if CONFIG_SUPERTX
3387 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3388#endif
3389 if (sum_rdc.rdcost < best_rdc->rdcost) {
3390#if CONFIG_SUPERTX
3391 *best_rate_nocoef = sum_rate_nocoef;
3392 assert(*best_rate_nocoef >= 0);
3393#endif
3394 *best_rdc = sum_rdc;
3395 pc_tree->partitioning = partition;
3396 }
3397 }
3398 }
3399 }
3400}
3401#endif // CONFIG_EXT_PARTITION_TYPES
3402
3403// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3404// unlikely to be selected depending on previous rate-distortion optimization
3405// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003406static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003407 TileDataEnc *tile_data, TOKENEXTRA **tp,
3408 int mi_row, int mi_col, BLOCK_SIZE bsize,
3409 RD_COST *rd_cost,
3410#if CONFIG_SUPERTX
3411 int *rate_nocoef,
3412#endif
3413 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003414 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003415 TileInfo *const tile_info = &tile_data->tile_info;
3416 MACROBLOCK *const x = &td->mb;
3417 MACROBLOCKD *const xd = &x->e_mbd;
3418 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
3419 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003420 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003421 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003422 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
Urvang Joshi52648442016-10-13 17:27:51 -07003423 const int *partition_cost = cpi->partition_cost[pl];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003424 int tmp_partition_cost[PARTITION_TYPES];
3425 BLOCK_SIZE subsize;
3426 RD_COST this_rdc, sum_rdc, best_rdc;
3427#if CONFIG_SUPERTX
3428 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3429 int abort_flag;
3430 const int supertx_allowed = !frame_is_intra_only(cm) &&
3431 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3432 !xd->lossless[0];
3433#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003434 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3435 int do_square_split = bsize_at_least_8x8;
3436 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003437#if CONFIG_EXT_PARTITION_TYPES
3438 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3439#endif
3440
3441 // Override skipping rectangular partition operations for edge blocks
3442 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3443 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3444 const int xss = x->e_mbd.plane[1].subsampling_x;
3445 const int yss = x->e_mbd.plane[1].subsampling_y;
3446
3447 BLOCK_SIZE min_size = x->min_partition_size;
3448 BLOCK_SIZE max_size = x->max_partition_size;
3449
3450#if CONFIG_FP_MB_STATS
3451 unsigned int src_diff_var = UINT_MAX;
3452 int none_complexity = 0;
3453#endif
3454
3455 int partition_none_allowed = !force_horz_split && !force_vert_split;
3456 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003457 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003458 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003459 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003460
3461#if CONFIG_PVQ
3462 od_rollback_buffer pre_rdo_buf;
3463#endif
3464
Yaowu Xuc27fc142016-08-22 16:08:15 -07003465 (void)*tp_orig;
3466
3467 if (force_horz_split || force_vert_split) {
3468 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3469
3470 if (!force_vert_split) { // force_horz_split only
3471 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3472 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003473 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003474 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003475 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003476 } else if (!force_horz_split) { // force_vert_split only
3477 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3478 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003479 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003480 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003481 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003482 } else { // force_ horz_split && force_vert_split horz_split
3483 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3484 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3485 tmp_partition_cost[PARTITION_SPLIT] = 0;
3486 }
3487
3488 partition_cost = tmp_partition_cost;
3489 }
3490
3491#if CONFIG_VAR_TX
3492#ifndef NDEBUG
3493 // Nothing should rely on the default value of this array (which is just
3494 // leftover from encoding the previous block. Setting it to magic number
3495 // when debugging.
3496 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3497#endif // NDEBUG
3498#endif // CONFIG_VAR_TX
3499
3500 assert(num_8x8_blocks_wide_lookup[bsize] ==
3501 num_8x8_blocks_high_lookup[bsize]);
3502
Yaowu Xuf883b422016-08-30 14:01:10 -07003503 av1_rd_cost_init(&this_rdc);
3504 av1_rd_cost_init(&sum_rdc);
3505 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003506 best_rdc.rdcost = best_rd;
3507
3508 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3509
3510 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003511 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003512
3513 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003514 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515 ((pc_tree->index == 0 || pc_tree->index == 3) +
3516 get_chessboard_index(cm->current_video_frame)) &
3517 0x1;
3518
3519 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3520 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3521 }
3522
3523 // Determine partition types in search according to the speed features.
3524 // The threshold set here has to be of square block size.
3525 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003526 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3527 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3528 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3529 partition_none_allowed &= no_partition_allowed;
3530 partition_horz_allowed &= partition_allowed || force_horz_split;
3531 partition_vert_allowed &= partition_allowed || force_vert_split;
3532 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003533 }
3534 if (cpi->sf.use_square_partition_only) {
3535 partition_horz_allowed &= force_horz_split;
3536 partition_vert_allowed &= force_vert_split;
3537 }
3538
3539#if CONFIG_VAR_TX
3540 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3541 xd->left_txfm_context =
3542 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3543#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003544#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003546#else
3547 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3548#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003549
3550#if CONFIG_FP_MB_STATS
3551 if (cpi->use_fp_mb_stats) {
3552 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3553 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3554 mi_col, bsize);
3555 }
3556#endif
3557
3558#if CONFIG_FP_MB_STATS
3559 // Decide whether we shall split directly and skip searching NONE by using
3560 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003561 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003562 partition_none_allowed && src_diff_var > 4 &&
3563 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3564 int mb_row = mi_row >> 1;
3565 int mb_col = mi_col >> 1;
3566 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003567 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003568 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003569 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 int r, c;
3571
3572 // compute a complexity measure, basically measure inconsistency of motion
3573 // vectors obtained from the first pass in the current block
3574 for (r = mb_row; r < mb_row_end; r++) {
3575 for (c = mb_col; c < mb_col_end; c++) {
3576 const int mb_index = r * cm->mb_cols + c;
3577
3578 MOTION_DIRECTION this_mv;
3579 MOTION_DIRECTION right_mv;
3580 MOTION_DIRECTION bottom_mv;
3581
3582 this_mv =
3583 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3584
3585 // to its right
3586 if (c != mb_col_end - 1) {
3587 right_mv = get_motion_direction_fp(
3588 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3589 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3590 }
3591
3592 // to its bottom
3593 if (r != mb_row_end - 1) {
3594 bottom_mv = get_motion_direction_fp(
3595 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3596 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3597 }
3598
3599 // do not count its left and top neighbors to avoid double counting
3600 }
3601 }
3602
3603 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3604 partition_none_allowed = 0;
3605 }
3606 }
3607#endif
3608
3609 // PARTITION_NONE
3610 if (partition_none_allowed) {
3611 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3612#if CONFIG_SUPERTX
3613 &this_rate_nocoef,
3614#endif
3615#if CONFIG_EXT_PARTITION_TYPES
3616 PARTITION_NONE,
3617#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003618 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003619 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003620 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003621 this_rdc.rate += partition_cost[PARTITION_NONE];
3622 this_rdc.rdcost =
3623 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3624#if CONFIG_SUPERTX
3625 this_rate_nocoef += partition_cost[PARTITION_NONE];
3626#endif
3627 }
3628
3629 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003630 // Adjust dist breakout threshold according to the partition size.
3631 const int64_t dist_breakout_thr =
3632 cpi->sf.partition_search_breakout_dist_thr >>
3633 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3634 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3635 const int rate_breakout_thr =
3636 cpi->sf.partition_search_breakout_rate_thr *
3637 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638
3639 best_rdc = this_rdc;
3640#if CONFIG_SUPERTX
3641 best_rate_nocoef = this_rate_nocoef;
3642 assert(best_rate_nocoef >= 0);
3643#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003644 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003645
3646 // If all y, u, v transform blocks in this partition are skippable, and
3647 // the dist & rate are within the thresholds, the partition search is
3648 // terminated for current branch of the partition search tree.
3649 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3650 // early termination at that speed.
3651 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003652 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003653 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003654 do_square_split = 0;
3655 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003656 }
3657
3658#if CONFIG_FP_MB_STATS
3659 // Check if every 16x16 first pass block statistics has zero
3660 // motion and the corresponding first pass residue is small enough.
3661 // If that is the case, check the difference variance between the
3662 // current frame and the last frame. If the variance is small enough,
3663 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003664 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003665 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3666 int mb_row = mi_row >> 1;
3667 int mb_col = mi_col >> 1;
3668 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003669 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003670 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003671 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003672 int r, c;
3673
3674 int skip = 1;
3675 for (r = mb_row; r < mb_row_end; r++) {
3676 for (c = mb_col; c < mb_col_end; c++) {
3677 const int mb_index = r * cm->mb_cols + c;
3678 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3679 FPMB_MOTION_ZERO_MASK) ||
3680 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3681 FPMB_ERROR_SMALL_MASK)) {
3682 skip = 0;
3683 break;
3684 }
3685 }
3686 if (skip == 0) {
3687 break;
3688 }
3689 }
3690 if (skip) {
3691 if (src_diff_var == UINT_MAX) {
3692 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3693 src_diff_var = get_sby_perpixel_diff_variance(
3694 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3695 }
3696 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003697 do_square_split = 0;
3698 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699 }
3700 }
3701 }
3702#endif
3703 }
3704 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003705#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003707#else
3708 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3709#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003710 }
3711
3712 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003713 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714
3715 // PARTITION_SPLIT
3716 // TODO(jingning): use the motion vectors given by the above search as
3717 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003718 if (do_square_split) {
3719 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720 subsize = get_subsize(bsize, PARTITION_SPLIT);
3721 if (bsize == BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003722#if CONFIG_DUAL_FILTER
3723 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3724 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003725 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003726#else
3727 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3728 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003729 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003730#endif
3731#if CONFIG_SUPERTX
3732 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3733 &sum_rate_nocoef,
3734#if CONFIG_EXT_PARTITION_TYPES
3735 PARTITION_SPLIT,
3736#endif
3737 subsize, pc_tree->leaf_split[0], INT64_MAX);
3738#else
3739 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3740#if CONFIG_EXT_PARTITION_TYPES
3741 PARTITION_SPLIT,
3742#endif
3743 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3744#endif // CONFIG_SUPERTX
3745 if (sum_rdc.rate == INT_MAX) {
3746 sum_rdc.rdcost = INT64_MAX;
3747#if CONFIG_SUPERTX
3748 sum_rate_nocoef = INT_MAX;
3749#endif
3750 }
3751#if CONFIG_SUPERTX
3752 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3753 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3754 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3755
3756 pc_tree->partitioning = PARTITION_SPLIT;
3757
clang-format67948d32016-09-07 22:40:40 -07003758 sum_rdc.rate +=
3759 av1_cost_bit(cm->fc->supertx_prob
3760 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3761 [supertx_size],
3762 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003763 sum_rdc.rdcost =
3764 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3765
3766 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3767 TX_TYPE best_tx = DCT_DCT;
3768 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3769
3770 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3771
3772 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3773 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3774
Yaowu Xuf883b422016-08-30 14:01:10 -07003775 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003776 cm->fc->supertx_prob
3777 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3778 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003779 1);
3780 tmp_rdc.rdcost =
3781 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3782 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3783 sum_rdc = tmp_rdc;
3784 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3785 supertx_size, pc_tree);
3786 }
3787 }
3788
3789 pc_tree->partitioning = best_partition;
3790 }
3791#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003792 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003793 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07003794 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003795#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003796 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003797#else
Urvang Joshi52648442016-10-13 17:27:51 -07003798 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003799#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003800 const int x_idx = (idx & 1) * mi_step;
3801 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003802
3803 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3804 continue;
3805
Urvang Joshi454280d2016-10-14 16:51:44 -07003806 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003807
Urvang Joshi52648442016-10-13 17:27:51 -07003808 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003809#if CONFIG_SUPERTX
3810 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3811 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07003812 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003813#else
Urvang Joshi52648442016-10-13 17:27:51 -07003814 rd_pick_partition(
3815 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
3816 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003817#endif // CONFIG_SUPERTX
3818
3819 if (this_rdc.rate == INT_MAX) {
3820 sum_rdc.rdcost = INT64_MAX;
3821#if CONFIG_SUPERTX
3822 sum_rate_nocoef = INT_MAX;
3823#endif // CONFIG_SUPERTX
3824 break;
3825 } else {
3826 sum_rdc.rate += this_rdc.rate;
3827 sum_rdc.dist += this_rdc.dist;
3828 sum_rdc.rdcost += this_rdc.rdcost;
3829#if CONFIG_SUPERTX
3830 sum_rate_nocoef += this_rate_nocoef;
3831#endif // CONFIG_SUPERTX
3832 }
3833 }
Urvang Joshi52648442016-10-13 17:27:51 -07003834 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003836 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003837 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3838 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3839
3840 pc_tree->partitioning = PARTITION_SPLIT;
3841
clang-format67948d32016-09-07 22:40:40 -07003842 sum_rdc.rate +=
3843 av1_cost_bit(cm->fc->supertx_prob
3844 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3845 [supertx_size],
3846 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847 sum_rdc.rdcost =
3848 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3849
3850 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3851 TX_TYPE best_tx = DCT_DCT;
3852 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3853
3854 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3855
3856 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3857 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3858
Yaowu Xuf883b422016-08-30 14:01:10 -07003859 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003860 cm->fc->supertx_prob
3861 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3862 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863 1);
3864 tmp_rdc.rdcost =
3865 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3866 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3867 sum_rdc = tmp_rdc;
3868 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3869 supertx_size, pc_tree);
3870 }
3871 }
3872
3873 pc_tree->partitioning = best_partition;
3874 }
3875#endif // CONFIG_SUPERTX
3876 }
3877
Urvang Joshi52648442016-10-13 17:27:51 -07003878 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3880 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3881#if CONFIG_SUPERTX
3882 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3883#endif // CONFIG_SUPERTX
3884
3885 if (sum_rdc.rdcost < best_rdc.rdcost) {
3886 best_rdc = sum_rdc;
3887#if CONFIG_SUPERTX
3888 best_rate_nocoef = sum_rate_nocoef;
3889 assert(best_rate_nocoef >= 0);
3890#endif // CONFIG_SUPERTX
3891 pc_tree->partitioning = PARTITION_SPLIT;
3892 }
Urvang Joshi52648442016-10-13 17:27:51 -07003893 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 // skip rectangular partition test when larger block size
3895 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07003896 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003897 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003898#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003899 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003900#else
3901 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3902#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 } // if (do_split)
3904
3905 // PARTITION_HORZ
3906 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003907 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003908 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07003909 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910#if CONFIG_DUAL_FILTER
3911 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3912 partition_none_allowed)
3913 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003914 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003915#else
3916 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3917 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003918 pc_tree->horizontal[0].pred_interp_filter =
3919 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003920#endif
3921 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3922#if CONFIG_SUPERTX
3923 &sum_rate_nocoef,
3924#endif // CONFIG_SUPERTX
3925#if CONFIG_EXT_PARTITION_TYPES
3926 PARTITION_HORZ,
3927#endif
3928 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3929
3930#if CONFIG_SUPERTX
3931 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3932 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3933 if (sum_rdc.rdcost < INT64_MAX &&
3934#else
3935 if (sum_rdc.rdcost < best_rdc.rdcost &&
3936#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003937 !force_horz_split && bsize > BLOCK_8X8) {
Urvang Joshi454280d2016-10-14 16:51:44 -07003938 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
3939 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003940 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07003941 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942
Urvang Joshi454280d2016-10-14 16:51:44 -07003943 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003944
3945#if CONFIG_DUAL_FILTER
3946 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3947 partition_none_allowed)
3948 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003949 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003950#else
3951 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3952 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003953 pc_tree->horizontal[1].pred_interp_filter =
3954 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955#endif
3956#if CONFIG_SUPERTX
3957 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3958 &this_rate_nocoef,
3959#if CONFIG_EXT_PARTITION_TYPES
3960 PARTITION_HORZ,
3961#endif
3962 subsize, &pc_tree->horizontal[1], INT64_MAX);
3963#else
3964 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3965#if CONFIG_EXT_PARTITION_TYPES
3966 PARTITION_HORZ,
3967#endif
3968 subsize, &pc_tree->horizontal[1],
3969 best_rdc.rdcost - sum_rdc.rdcost);
3970#endif // CONFIG_SUPERTX
3971 if (this_rdc.rate == INT_MAX) {
3972 sum_rdc.rdcost = INT64_MAX;
3973#if CONFIG_SUPERTX
3974 sum_rate_nocoef = INT_MAX;
3975#endif // CONFIG_SUPERTX
3976 } else {
3977 sum_rdc.rate += this_rdc.rate;
3978 sum_rdc.dist += this_rdc.dist;
3979 sum_rdc.rdcost += this_rdc.rdcost;
3980#if CONFIG_SUPERTX
3981 sum_rate_nocoef += this_rate_nocoef;
3982#endif // CONFIG_SUPERTX
3983 }
3984 }
3985
3986#if CONFIG_SUPERTX
3987 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3988 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3989 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3990
3991 pc_tree->partitioning = PARTITION_HORZ;
3992
Yaowu Xuf883b422016-08-30 14:01:10 -07003993 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003994 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3995 [supertx_size],
3996 0);
3997 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3998
3999 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4000 TX_TYPE best_tx = DCT_DCT;
4001 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4002
4003 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4004
4005 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4006 &tmp_rdc.dist, &best_tx, pc_tree);
4007
Yaowu Xuf883b422016-08-30 14:01:10 -07004008 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004009 cm->fc
4010 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4011 [supertx_size],
4012 1);
4013 tmp_rdc.rdcost =
4014 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4015 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4016 sum_rdc = tmp_rdc;
4017 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4018 supertx_size, pc_tree);
4019 }
4020 }
4021
4022 pc_tree->partitioning = best_partition;
4023 }
4024#endif // CONFIG_SUPERTX
4025
4026 if (sum_rdc.rdcost < best_rdc.rdcost) {
4027 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4028 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4029#if CONFIG_SUPERTX
4030 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4031#endif // CONFIG_SUPERTX
4032 if (sum_rdc.rdcost < best_rdc.rdcost) {
4033 best_rdc = sum_rdc;
4034#if CONFIG_SUPERTX
4035 best_rate_nocoef = sum_rate_nocoef;
4036 assert(best_rate_nocoef >= 0);
4037#endif // CONFIG_SUPERTX
4038 pc_tree->partitioning = PARTITION_HORZ;
4039 }
4040 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004041#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004042 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004043#else
4044 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4045#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 }
4047
4048 // PARTITION_VERT
4049 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004050 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004051 subsize = get_subsize(bsize, PARTITION_VERT);
4052
Urvang Joshi454280d2016-10-14 16:51:44 -07004053 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054
4055#if CONFIG_DUAL_FILTER
4056 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4057 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004058 pc_tree->vertical[0].pred_interp_filter =
4059 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004060#else
4061 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4062 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004063 pc_tree->vertical[0].pred_interp_filter =
4064 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004065#endif
4066 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4067#if CONFIG_SUPERTX
4068 &sum_rate_nocoef,
4069#endif // CONFIG_SUPERTX
4070#if CONFIG_EXT_PARTITION_TYPES
4071 PARTITION_VERT,
4072#endif
4073 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4074#if CONFIG_SUPERTX
4075 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
4076 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
4077 if (sum_rdc.rdcost < INT64_MAX &&
4078#else
4079 if (sum_rdc.rdcost < best_rdc.rdcost &&
4080#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004081 !force_vert_split && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004082 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4083 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4084 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004085
Urvang Joshi454280d2016-10-14 16:51:44 -07004086 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004087
4088#if CONFIG_DUAL_FILTER
4089 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4090 partition_none_allowed)
4091 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004092 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004093#else
4094 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4095 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004096 pc_tree->vertical[1].pred_interp_filter =
4097 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004098#endif
4099#if CONFIG_SUPERTX
4100 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4101 &this_rate_nocoef,
4102#if CONFIG_EXT_PARTITION_TYPES
4103 PARTITION_VERT,
4104#endif
4105 subsize, &pc_tree->vertical[1],
4106 INT64_MAX - sum_rdc.rdcost);
4107#else
4108 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4109#if CONFIG_EXT_PARTITION_TYPES
4110 PARTITION_VERT,
4111#endif
4112 subsize, &pc_tree->vertical[1],
4113 best_rdc.rdcost - sum_rdc.rdcost);
4114#endif // CONFIG_SUPERTX
4115 if (this_rdc.rate == INT_MAX) {
4116 sum_rdc.rdcost = INT64_MAX;
4117#if CONFIG_SUPERTX
4118 sum_rate_nocoef = INT_MAX;
4119#endif // CONFIG_SUPERTX
4120 } else {
4121 sum_rdc.rate += this_rdc.rate;
4122 sum_rdc.dist += this_rdc.dist;
4123 sum_rdc.rdcost += this_rdc.rdcost;
4124#if CONFIG_SUPERTX
4125 sum_rate_nocoef += this_rate_nocoef;
4126#endif // CONFIG_SUPERTX
4127 }
4128 }
4129#if CONFIG_SUPERTX
4130 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4131 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4132 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4133
4134 pc_tree->partitioning = PARTITION_VERT;
4135
Yaowu Xuf883b422016-08-30 14:01:10 -07004136 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004137 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4138 [supertx_size],
4139 0);
4140 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4141
4142 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4143 TX_TYPE best_tx = DCT_DCT;
4144 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4145
4146 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4147
4148 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4149 &tmp_rdc.dist, &best_tx, pc_tree);
4150
Yaowu Xuf883b422016-08-30 14:01:10 -07004151 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004152 cm->fc
4153 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4154 [supertx_size],
4155 1);
4156 tmp_rdc.rdcost =
4157 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4158 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4159 sum_rdc = tmp_rdc;
4160 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4161 supertx_size, pc_tree);
4162 }
4163 }
4164
4165 pc_tree->partitioning = best_partition;
4166 }
4167#endif // CONFIG_SUPERTX
4168
4169 if (sum_rdc.rdcost < best_rdc.rdcost) {
4170 sum_rdc.rate += partition_cost[PARTITION_VERT];
4171 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4172#if CONFIG_SUPERTX
4173 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4174#endif // CONFIG_SUPERTX
4175 if (sum_rdc.rdcost < best_rdc.rdcost) {
4176 best_rdc = sum_rdc;
4177#if CONFIG_SUPERTX
4178 best_rate_nocoef = sum_rate_nocoef;
4179 assert(best_rate_nocoef >= 0);
4180#endif // CONFIG_SUPERTX
4181 pc_tree->partitioning = PARTITION_VERT;
4182 }
4183 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004184#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004185 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004186#else
4187 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4188#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 }
4190
4191#if CONFIG_EXT_PARTITION_TYPES
4192 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004193 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004194 partition_none_allowed) {
4195 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4196 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004197 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004198 PARTITION_HORZ_A,
4199#if CONFIG_SUPERTX
4200 best_rd, &best_rate_nocoef, &x_ctx,
4201#endif
4202 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4203 mi_row + mi_step, mi_col, subsize);
4204 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4205 }
4206 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004207 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004208 partition_none_allowed) {
4209 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4210 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004211 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004212 PARTITION_HORZ_B,
4213#if CONFIG_SUPERTX
4214 best_rd, &best_rate_nocoef, &x_ctx,
4215#endif
4216 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4217 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4218 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4219 }
4220 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004221 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004222 partition_none_allowed) {
4223 subsize = get_subsize(bsize, PARTITION_VERT_A);
4224 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004225 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226 PARTITION_VERT_A,
4227#if CONFIG_SUPERTX
4228 best_rd, &best_rate_nocoef, &x_ctx,
4229#endif
4230 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4231 mi_row, mi_col + mi_step, subsize);
4232 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4233 }
4234 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004235 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236 partition_none_allowed) {
4237 subsize = get_subsize(bsize, PARTITION_VERT_B);
4238 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004239 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004240 PARTITION_VERT_B,
4241#if CONFIG_SUPERTX
4242 best_rd, &best_rate_nocoef, &x_ctx,
4243#endif
4244 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4245 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4246 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4247 }
4248#endif // CONFIG_EXT_PARTITION_TYPES
4249
4250 // TODO(jbb): This code added so that we avoid static analysis
4251 // warning related to the fact that best_rd isn't used after this
4252 // point. This code should be refactored so that the duplicate
4253 // checks occur in some sub function and thus are used...
4254 (void)best_rd;
4255 *rd_cost = best_rdc;
4256#if CONFIG_SUPERTX
4257 *rate_nocoef = best_rate_nocoef;
4258#endif // CONFIG_SUPERTX
4259
4260 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4261 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004262 if (bsize == cm->sb_size) {
4263 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4264 pc_tree, NULL);
4265 } else {
4266 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4267 pc_tree, NULL);
4268 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004269 }
4270
4271 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004272#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004273 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004274#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004275 assert(best_rdc.rate < INT_MAX);
4276 assert(best_rdc.dist < INT64_MAX);
4277 } else {
4278 assert(tp_orig == *tp);
4279 }
4280}
4281
Yaowu Xuf883b422016-08-30 14:01:10 -07004282static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004283 TileDataEnc *tile_data, int mi_row,
4284 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004285 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286 const TileInfo *const tile_info = &tile_data->tile_info;
4287 MACROBLOCK *const x = &td->mb;
4288 MACROBLOCKD *const xd = &x->e_mbd;
4289 SPEED_FEATURES *const sf = &cpi->sf;
4290 int mi_col;
4291#if CONFIG_EXT_PARTITION
4292 const int leaf_nodes = 256;
4293#else
4294 const int leaf_nodes = 64;
4295#endif // CONFIG_EXT_PARTITION
4296
4297 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004298 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004299
Thomas Daviesf6936102016-09-05 16:51:31 +01004300#if CONFIG_DELTA_Q
4301 // Reset delta for every tile
4302 if (cm->delta_q_present_flag)
4303 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4304#endif
4305
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 // Code each SB in the row
4307 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4308 mi_col += cm->mib_size) {
4309 const struct segmentation *const seg = &cm->seg;
4310 int dummy_rate;
4311 int64_t dummy_dist;
4312 RD_COST dummy_rdc;
4313#if CONFIG_SUPERTX
4314 int dummy_rate_nocoef;
4315#endif // CONFIG_SUPERTX
4316 int i;
4317 int seg_skip = 0;
4318
4319 const int idx_str = cm->mi_stride * mi_row + mi_col;
4320 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4321 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4322
4323 if (sf->adaptive_pred_interp_filter) {
4324 for (i = 0; i < leaf_nodes; ++i)
4325 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4326
4327 for (i = 0; i < leaf_nodes; ++i) {
4328 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4329 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4330 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4331 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4332 }
4333 }
4334
Yaowu Xuf883b422016-08-30 14:01:10 -07004335 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004336 pc_root->index = 0;
4337
4338 if (seg->enabled) {
4339 const uint8_t *const map =
4340 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4341 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4342 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4343 }
4344
Arild Fuldseth07441162016-08-15 15:07:52 +02004345#if CONFIG_DELTA_Q
4346 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004347 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004348 int sb_row = mi_row >> 3;
4349 int sb_col = mi_col >> 3;
4350 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4351 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004352
4353 // Ensure divisibility of delta_qindex by delta_q_res
4354 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4355 int qmask = ~(cm->delta_q_res - 1);
4356 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4357 cm->delta_q_res, 256 - cm->delta_q_res);
4358 current_qindex =
4359 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4360 cm->base_qindex;
4361
Arild Fuldseth07441162016-08-15 15:07:52 +02004362 xd->delta_qindex = current_qindex - cm->base_qindex;
4363 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4364 xd->mi[0]->mbmi.current_q_index = current_qindex;
4365 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004366 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004367 }
4368#endif
4369
Yaowu Xuc27fc142016-08-22 16:08:15 -07004370 x->source_variance = UINT_MAX;
4371 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4372 BLOCK_SIZE bsize;
4373 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4374 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4375 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4376 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4377 &dummy_rate, &dummy_dist,
4378#if CONFIG_SUPERTX
4379 &dummy_rate_nocoef,
4380#endif // CONFIG_SUPERTX
4381 1, pc_root);
4382 } else if (cpi->partition_search_skippable_frame) {
4383 BLOCK_SIZE bsize;
4384 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4385 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4386 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4387 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4388 &dummy_rate, &dummy_dist,
4389#if CONFIG_SUPERTX
4390 &dummy_rate_nocoef,
4391#endif // CONFIG_SUPERTX
4392 1, pc_root);
4393 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4394 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4395 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4396 &dummy_rate, &dummy_dist,
4397#if CONFIG_SUPERTX
4398 &dummy_rate_nocoef,
4399#endif // CONFIG_SUPERTX
4400 1, pc_root);
4401 } else {
4402 // If required set upper and lower partition size limits
4403 if (sf->auto_min_max_partition_size) {
4404 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4405 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4406 &x->min_partition_size, &x->max_partition_size);
4407 }
4408 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4409 &dummy_rdc,
4410#if CONFIG_SUPERTX
4411 &dummy_rate_nocoef,
4412#endif // CONFIG_SUPERTX
4413 INT64_MAX, pc_root);
4414 }
4415 }
4416#if CONFIG_ENTROPY
4417 if (cm->do_subframe_update &&
4418 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4419 if ((mi_row + MI_SIZE) %
4420 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004421 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004422 0 &&
4423 mi_row + MI_SIZE < cm->mi_rows &&
4424 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4425 TX_SIZE t;
4426 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4427
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08004428 for (t = TX_4X4; t < TX_SIZES; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004429 av1_full_to_model_counts(cpi->td.counts->coef[t],
4430 cpi->td.rd_counts.coef_counts[t]);
4431 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004432 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004433 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4434 cm->fc->coef_probs);
4435 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4436 cpi->td.rd_counts.coef_counts);
4437 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4438 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004439 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440 }
4441 }
4442#endif // CONFIG_ENTROPY
4443}
4444
Yaowu Xuf883b422016-08-30 14:01:10 -07004445static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004446 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004447 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004448 MACROBLOCKD *const xd = &x->e_mbd;
4449
4450 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004451 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004452
Yaowu Xuf883b422016-08-30 14:01:10 -07004453 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004454}
4455
Yaowu Xuf883b422016-08-30 14:01:10 -07004456static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004457 const int ref_flags = cpi->ref_frame_flags;
4458
4459 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4460 return 0;
4461 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004462 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004464 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4465 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004466#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004467 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004468 }
4469}
4470
4471#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004472static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004473 int mi_row, mi_col;
4474 const int mis = cm->mi_stride;
4475 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4476
4477 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4478 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4479 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4480 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4481 }
4482 }
4483}
4484#endif
4485
Yaowu Xuf883b422016-08-30 14:01:10 -07004486static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004487 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4488#if CONFIG_EXT_REFS
4489 // We will not update the golden frame with an internal overlay frame
4490 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4491 cpi->rc.is_src_frame_ext_arf)
4492#else
4493 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4494#endif
4495 return ALTREF_FRAME;
4496 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4497 return GOLDEN_FRAME;
4498 else
4499 // TODO(zoeliu): To investigate whether a frame_type other than
4500 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4501 return LAST_FRAME;
4502}
4503
Yaowu Xuf883b422016-08-30 14:01:10 -07004504static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004505 if (xd->lossless[0]) return ONLY_4X4;
4506 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004507 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4509 cpi->sf.tx_size_search_method == USE_TX_8X8)
4510 return TX_MODE_SELECT;
4511 else
4512 return cpi->common.tx_mode;
4513}
4514
Yaowu Xuf883b422016-08-30 14:01:10 -07004515void av1_init_tile_data(AV1_COMP *cpi) {
4516 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004517 const int tile_cols = cm->tile_cols;
4518 const int tile_rows = cm->tile_rows;
4519 int tile_col, tile_row;
4520 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4521 unsigned int tile_tok = 0;
4522
4523 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004524 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4525 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526 sizeof(*cpi->tile_data)));
4527 cpi->allocated_tiles = tile_cols * tile_rows;
4528
4529 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4530 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4531 TileDataEnc *const tile_data =
4532 &cpi->tile_data[tile_row * tile_cols + tile_col];
4533 int i, j;
4534 for (i = 0; i < BLOCK_SIZES; ++i) {
4535 for (j = 0; j < MAX_MODES; ++j) {
4536 tile_data->thresh_freq_fact[i][j] = 32;
4537 tile_data->mode_map[i][j] = j;
4538 }
4539 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004540#if CONFIG_PVQ
4541 // This will be dynamically increased as more pvq block is encoded.
4542 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004543 CHECK_MEM_ERROR(
4544 cm, tile_data->pvq_q.buf,
4545 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004546 tile_data->pvq_q.curr_pos = 0;
4547#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004548 }
4549 }
4550
4551 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4552 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4553 TileInfo *const tile_info =
4554 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004555 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004556
4557 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4558 pre_tok = cpi->tile_tok[tile_row][tile_col];
4559 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004560#if CONFIG_PVQ
4561 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4562#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004563 }
4564 }
4565}
4566
Yaowu Xuf883b422016-08-30 14:01:10 -07004567void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4568 int tile_col) {
4569 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004570 TileDataEnc *const this_tile =
4571 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4572 const TileInfo *const tile_info = &this_tile->tile_info;
4573 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4574 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004575#if CONFIG_PVQ
4576 od_adapt_ctx *adapt;
4577#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004578
Yaowu Xuf883b422016-08-30 14:01:10 -07004579 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004580
4581 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004582 this_tile->m_search_count = 0; // Count of motion search hits.
4583 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4584 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4585 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004586
Yushin Cho77bba8d2016-11-04 16:36:56 -07004587#if CONFIG_PVQ
4588 td->mb.pvq_q = &this_tile->pvq_q;
4589
4590 // TODO(yushin)
4591 // If activity masking is enabled, change below to OD_HVS_QM
4592 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4593 {
4594 // FIXME: Multiple segments support
4595 int segment_id = 0;
4596 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4597 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4598 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4599 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4600 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4601 td->mb.daala_enc.pvq_norm_lambda =
4602 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4603 td->mb.daala_enc.pvq_norm_lambda_dc =
4604 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4605 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4606 }
4607 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4608 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
4609 od_ec_enc_init(&td->mb.daala_enc.ec, 65025);
4610
4611 adapt = &td->mb.daala_enc.state.adapt;
4612 od_ec_enc_reset(&td->mb.daala_enc.ec);
4613 od_adapt_ctx_reset(adapt, 0);
4614#endif
4615
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4617 mi_row += cm->mib_size) {
4618 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4619 }
4620
4621 cpi->tok_count[tile_row][tile_col] =
4622 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4623 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004624#if CONFIG_PVQ
4625 od_ec_enc_clear(&td->mb.daala_enc.ec);
4626
4627 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4628 // rewind current position so that bitstream can be written
4629 // from the 1st pvq block
4630 td->mb.pvq_q->curr_pos = 0;
4631
4632 td->mb.pvq_q = NULL;
4633#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004634}
4635
Yaowu Xuf883b422016-08-30 14:01:10 -07004636static void encode_tiles(AV1_COMP *cpi) {
4637 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638 int tile_col, tile_row;
4639
Yaowu Xuf883b422016-08-30 14:01:10 -07004640 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004641
4642 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4643 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004644 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004645}
4646
4647#if CONFIG_FP_MB_STATS
4648static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004649 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004650 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4651 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4652
4653 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4654
4655 *this_frame_mb_stats = mb_stats_in;
4656
4657 return 1;
4658}
4659#endif
4660
4661#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004662#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004663
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004664// Border over which to compute the global motion
4665#define ERRORADV_BORDER 0
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004666
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004667static const double gm_advantage_thresh[TRANS_TYPES] = {
4668 1.00, // Identity (not used)
4669 0.85, // Translation
4670 0.75, // Rot zoom
4671 0.65, // Affine
4672 0.50, // Homography
4673};
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004674
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004675static void convert_to_params(const double *params, int32_t *model) {
4676 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004677 int alpha_present = 0;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004678 model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4679 model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4680 model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004681 GM_TRANS_DECODE_FACTOR;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004682 model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004683 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004684
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004685 for (i = 2; i < 6; ++i) {
4686 const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004687 model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004688 model[i] =
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004689 (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
4690 alpha_present |= (model[i] != 0);
4691 model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
4692 }
4693 for (; i < 8; ++i) {
4694 model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
4695 model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
4696 GM_ROW3HOMO_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004697 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 }
4699
4700 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004701 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4702 model[0] = 0;
4703 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004704 }
4705 }
4706}
4707
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004708static void convert_model_to_params(const double *params,
David Barkercf3d0b02016-11-10 10:14:49 +00004709 WarpedMotionParams *model) {
4710 convert_to_params(params, model->wmmat);
4711 model->wmtype = get_gmtype(model);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004712}
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004713
4714// Adds some offset to a global motion parameter and handles
4715// all of the necessary precision shifts, clamping, and
4716// zero-centering.
4717static int32_t add_param_offset(int param_index, int32_t param_value,
4718 int32_t offset) {
4719 const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
4720 GM_ROW3HOMO_PREC_DIFF };
4721 const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
4722 // type of param: 0 - translation, 1 - affine, 2 - homography
4723 const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
4724 const int is_one_centered = (param_index == 2 || param_index == 5);
4725
4726 // Make parameter zero-centered and offset the shift that was done to make
4727 // it compatible with the warped model
4728 param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
4729 scale_vals[param_type];
4730 // Add desired offset to the rescaled/zero-centered parameter
4731 param_value += offset;
4732 // Clamp the parameter so it does not overflow the number of bits allotted
4733 // to it in the bitstream
4734 param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
4735 clamp_vals[param_type]);
4736 // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
4737 // with the warped motion library
4738 param_value *= (1 << scale_vals[param_type]);
4739
4740 // Undo the zero-centering step if necessary
4741 return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
4742}
4743
4744static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
4745 switch (wmtype) {
4746 case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
4747 case TRANSLATION:
4748 wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
4749 wm->wmmat[3] = 0;
4750 case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
4751 case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
4752 case HOMOGRAPHY: break;
4753 default: assert(0);
4754 }
4755 wm->wmtype = wmtype;
4756}
4757
4758static double refine_integerized_param(WarpedMotionParams *wm,
4759 TransformationType wmtype,
4760#if CONFIG_AOM_HIGHBITDEPTH
4761 int use_hbd, int bd,
4762#endif // CONFIG_AOM_HIGHBITDEPTH
4763 uint8_t *ref, int r_width, int r_height,
4764 int r_stride, uint8_t *dst, int d_width,
4765 int d_height, int d_stride,
4766 int n_refinements) {
4767 const int border = ERRORADV_BORDER;
4768 int i = 0, p;
4769 int n_params = n_trans_model_params[wmtype];
4770 int32_t *param_mat = wm->wmmat;
4771 double step_error;
4772 int32_t step;
4773 int32_t *param;
4774 int32_t curr_param;
4775 int32_t best_param;
4776 double best_error;
4777
4778 force_wmtype(wm, wmtype);
4779 best_error = av1_warp_erroradv(wm,
4780#if CONFIG_AOM_HIGHBITDEPTH
4781 use_hbd, bd,
4782#endif // CONFIG_AOM_HIGHBITDEPTH
4783 ref, r_width, r_height, r_stride,
4784 dst + border * d_stride + border, border,
4785 border, d_width - 2 * border,
4786 d_height - 2 * border, d_stride, 0, 0, 16, 16);
4787 for (p = 0; p < n_params; ++p) {
4788 param = param_mat + p;
4789 step = 1 << (n_refinements + 1);
4790 curr_param = *param;
4791 best_param = curr_param;
4792 for (i = 0; i < n_refinements; i++) {
4793 // look to the left
4794 *param = add_param_offset(p, curr_param, -step);
4795 step_error = av1_warp_erroradv(
4796 wm,
4797#if CONFIG_AOM_HIGHBITDEPTH
4798 use_hbd, bd,
4799#endif // CONFIG_AOM_HIGHBITDEPTH
4800 ref, r_width, r_height, r_stride, dst + border * d_stride + border,
4801 border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
4802 0, 0, 16, 16);
4803 if (step_error < best_error) {
4804 step >>= 1;
4805 best_error = step_error;
4806 best_param = *param;
4807 curr_param = best_param;
4808 continue;
4809 }
4810
4811 // look to the right
4812 *param = add_param_offset(p, curr_param, step);
4813 step_error = av1_warp_erroradv(
4814 wm,
4815#if CONFIG_AOM_HIGHBITDEPTH
4816 use_hbd, bd,
4817#endif // CONFIG_AOM_HIGHBITDEPTH
4818 ref, r_width, r_height, r_stride, dst + border * d_stride + border,
4819 border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
4820 0, 0, 16, 16);
4821 if (step_error < best_error) {
4822 step >>= 1;
4823 best_error = step_error;
4824 best_param = *param;
4825 curr_param = best_param;
4826 continue;
4827 }
4828
4829 // no improvement found-> means we're either already at a minimum or
4830 // step is too wide
4831 step >>= 1;
4832 }
4833 *param = best_param;
4834 }
4835 force_wmtype(wm, wmtype);
4836 wm->wmtype = get_gmtype(wm);
4837 return best_error;
4838}
Yaowu Xuc27fc142016-08-22 16:08:15 -07004839#endif // CONFIG_GLOBAL_MOTION
4840
Yaowu Xuf883b422016-08-30 14:01:10 -07004841static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 ThreadData *const td = &cpi->td;
4843 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004844 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004845 MACROBLOCKD *const xd = &x->e_mbd;
4846 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4847 int i;
4848
Yaowu Xuf883b422016-08-30 14:01:10 -07004849 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4850 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Jingning Han24e0a182016-11-20 22:34:12 -08004851#if CONFIG_REF_MV
Dengca8d24d2016-10-17 14:06:35 +08004852 cm->setup_mi(cm);
4853#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004854
4855 xd->mi = cm->mi_grid_visible;
4856 xd->mi[0] = cm->mi;
4857
Yaowu Xuf883b422016-08-30 14:01:10 -07004858 av1_zero(*td->counts);
4859 av1_zero(rdc->coef_counts);
4860 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861
4862#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004863 av1_zero(cpi->global_motion_used);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004864 if (cpi->common.frame_type == INTER_FRAME && cpi->Source &&
4865 !cpi->global_motion_search_done) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 YV12_BUFFER_CONFIG *ref_buf;
4867 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004868 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004869 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004870 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4871 ref_buf = get_ref_frame_buffer(cpi, frame);
4872 if (ref_buf) {
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004873 aom_clear_system_state();
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004874 if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
David Barker557ce7b2016-11-16 10:22:24 +00004875 cpi->Source, ref_buf,
4876#if CONFIG_AOM_HIGHBITDEPTH
4877 cpi->common.bit_depth,
4878#endif // CONFIG_AOM_HIGHBITDEPTH
4879 params)) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004880 convert_model_to_params(params, &cm->global_motion[frame]);
David Barkercf3d0b02016-11-10 10:14:49 +00004881 if (cm->global_motion[frame].wmtype != IDENTITY) {
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004882 erroradvantage = refine_integerized_param(
4883 &cm->global_motion[frame], cm->global_motion[frame].wmtype,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004884#if CONFIG_AOM_HIGHBITDEPTH
4885 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4886#endif // CONFIG_AOM_HIGHBITDEPTH
4887 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4888 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4889 cpi->Source->y_height, cpi->Source->y_stride, 3);
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004890 if (erroradvantage >
4891 gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004892 set_default_gmparams(&cm->global_motion[frame]);
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004893 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004894 }
4895 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004896 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004897 }
4898 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004899 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004900 }
4901#endif // CONFIG_GLOBAL_MOTION
4902
4903 for (i = 0; i < MAX_SEGMENTS; ++i) {
4904 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004905 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004906 : cm->base_qindex;
4907 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4908 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4909 }
4910
4911 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4912
4913 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004914 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004915
Yaowu Xuf883b422016-08-30 14:01:10 -07004916 av1_initialize_rd_consts(cpi);
4917 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004918 init_encode_frame_mb_context(cpi);
4919
4920 cm->use_prev_frame_mvs =
4921 !cm->error_resilient_mode && cm->width == cm->last_width &&
4922 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004923
4924#if CONFIG_DELTA_Q
4925 // Fix delta q resolution for the moment
4926 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4927#endif
4928
Yaowu Xuc27fc142016-08-22 16:08:15 -07004929#if CONFIG_EXT_REFS
4930 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4931 // show_exisiting_frame=1, nor can it take a frame not used as
4932 // a reference, it is probable that by the time it is being
4933 // referred to, the frame buffer it originally points to may
4934 // already get expired and have been reassigned to the current
4935 // newly coded frame. Hence, we need to check whether this is
4936 // the case, and if yes, we have 2 choices:
4937 // (1) Simply disable the use of previous frame mvs; or
4938 // (2) Have cm->prev_frame point to one reference frame buffer,
4939 // e.g. LAST_FRAME.
4940 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4941 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4942 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4943 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4944 }
4945#endif // CONFIG_EXT_REFS
4946
4947 // Special case: set prev_mi to NULL when the previous mode info
4948 // context cannot be used.
4949 cm->prev_mi =
4950 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4951
4952#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004953 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004954#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004955 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004956#endif
4957#endif
4958
4959 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4960 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004961 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004962
4963 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004964 struct aom_usec_timer emr_timer;
4965 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004966
4967#if CONFIG_FP_MB_STATS
4968 if (cpi->use_fp_mb_stats) {
4969 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4970 &cpi->twopass.this_frame_mb_stats);
4971 }
4972#endif
4973
4974 // If allowed, encoding tiles in parallel with one thread handling one tile.
4975 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4976 // 1 tile rows, as it uses the single above_context et al arrays from
4977 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004978 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4979 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004980 else
4981 encode_tiles(cpi);
4982
Yaowu Xuf883b422016-08-30 14:01:10 -07004983 aom_usec_timer_mark(&emr_timer);
4984 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004985 }
4986
4987#if 0
4988 // Keep record of the total distortion this time around for future use
4989 cpi->last_frame_distortion = cpi->frame_distortion;
4990#endif
4991}
4992
Yaowu Xuf883b422016-08-30 14:01:10 -07004993void av1_encode_frame(AV1_COMP *cpi) {
4994 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004995
4996 // In the longer term the encoder should be generalized to match the
4997 // decoder such that we allow compound where one of the 3 buffers has a
4998 // different sign bias and that buffer is then the fixed ref. However, this
4999 // requires further work in the rd loop. For now the only supported encoder
5000 // side behavior is where the ALT ref buffer has opposite sign bias to
5001 // the other two.
5002 if (!frame_is_intra_only(cm)) {
5003 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5004 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
5005 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5006 cm->ref_frame_sign_bias[LAST_FRAME])) {
5007 cpi->allow_comp_inter_inter = 0;
5008 } else {
5009 cpi->allow_comp_inter_inter = 1;
5010
5011#if CONFIG_EXT_REFS
5012 cm->comp_fwd_ref[0] = LAST_FRAME;
5013 cm->comp_fwd_ref[1] = LAST2_FRAME;
5014 cm->comp_fwd_ref[2] = LAST3_FRAME;
5015 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
5016 cm->comp_bwd_ref[0] = BWDREF_FRAME;
5017 cm->comp_bwd_ref[1] = ALTREF_FRAME;
5018#else
5019 cm->comp_fixed_ref = ALTREF_FRAME;
5020 cm->comp_var_ref[0] = LAST_FRAME;
5021 cm->comp_var_ref[1] = GOLDEN_FRAME;
5022#endif // CONFIG_EXT_REFS
5023 }
5024 } else {
5025 cpi->allow_comp_inter_inter = 0;
5026 }
5027
5028 if (cpi->sf.frame_parameter_update) {
5029 int i;
5030 RD_OPT *const rd_opt = &cpi->rd;
5031 FRAME_COUNTS *counts = cpi->td.counts;
5032 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5033
5034 // This code does a single RD pass over the whole frame assuming
5035 // either compound, single or hybrid prediction as per whatever has
5036 // worked best for that type of frame in the past.
5037 // It also predicts whether another coding mode would have worked
5038 // better than this coding mode. If that is the case, it remembers
5039 // that for subsequent frames.
5040 // It does the same analysis for transform size selection also.
5041 //
5042 // TODO(zoeliu): To investigate whether a frame_type other than
5043 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
5044 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
5045 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
5046 const int is_alt_ref = frame_type == ALTREF_FRAME;
5047
5048 /* prediction (compound, single or hybrid) mode selection */
5049 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5050 cm->reference_mode = SINGLE_REFERENCE;
5051 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
5052 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
5053 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
5054 cm->reference_mode = COMPOUND_REFERENCE;
5055 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
5056 cm->reference_mode = SINGLE_REFERENCE;
5057 else
5058 cm->reference_mode = REFERENCE_MODE_SELECT;
5059
5060#if CONFIG_DUAL_FILTER
5061 cm->interp_filter = SWITCHABLE;
5062#endif
5063
5064 encode_frame_internal(cpi);
5065
5066 for (i = 0; i < REFERENCE_MODES; ++i)
5067 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
5068
5069 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5070 int single_count_zero = 0;
5071 int comp_count_zero = 0;
5072
5073 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5074 single_count_zero += counts->comp_inter[i][0];
5075 comp_count_zero += counts->comp_inter[i][1];
5076 }
5077
5078 if (comp_count_zero == 0) {
5079 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005080 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 } else if (single_count_zero == 0) {
5082 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005083 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005084 }
5085 }
5086
Jingning Han9777afc2016-10-20 15:17:43 -07005087#if CONFIG_VAR_TX
5088 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005089 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Jingning Han9777afc2016-10-20 15:17:43 -07005090#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005091 if (cm->tx_mode == TX_MODE_SELECT) {
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005092#if CONFIG_TX64X64
5093 int count4x4 = 0;
5094 int count8x8_8x8p = 0, count8x8_lp = 0;
5095 int count16x16_16x16p = 0, count16x16_lp = 0;
5096 int count32x32_32x32p = 0, count32x32_lp = 0;
5097 int count64x64_64x64p = 0;
5098 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5099 // counts->tx_size[max_depth][context_idx][this_depth_level]
5100 count4x4 += counts->tx_size[0][i][0];
5101 count4x4 += counts->tx_size[1][i][0];
5102 count4x4 += counts->tx_size[2][i][0];
5103 count4x4 += counts->tx_size[3][i][0];
5104
5105 count8x8_8x8p += counts->tx_size[0][i][1];
5106 count8x8_lp += counts->tx_size[1][i][1];
5107 count8x8_lp += counts->tx_size[2][i][1];
5108 count8x8_lp += counts->tx_size[3][i][1];
5109
5110 count16x16_16x16p += counts->tx_size[1][i][2];
5111 count16x16_lp += counts->tx_size[2][i][2];
5112 count16x16_lp += counts->tx_size[3][i][2];
5113
5114 count32x32_32x32p += counts->tx_size[2][i][3];
5115 count32x32_lp += counts->tx_size[3][i][3];
5116
5117 count64x64_64x64p += counts->tx_size[3][i][4];
5118 }
5119#if CONFIG_EXT_TX && CONFIG_RECT_TX
5120 count4x4 += counts->tx_size_implied[0][TX_4X4];
5121 count4x4 += counts->tx_size_implied[1][TX_4X4];
5122 count4x4 += counts->tx_size_implied[2][TX_4X4];
5123 count4x4 += counts->tx_size_implied[3][TX_4X4];
5124 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5125 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5126 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5127 count8x8_lp += counts->tx_size_implied[4][TX_8X8];
5128 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5129 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5130 count16x16_lp += counts->tx_size_implied[4][TX_16X16];
5131 count32x32_32x32p += counts->tx_size_implied[3][TX_32X32];
5132 count32x32_lp += counts->tx_size_implied[4][TX_32X32];
Debargha Mukherjee5a488a62016-11-22 22:24:10 -08005133 count64x64_64x64p += counts->tx_size_implied[4][TX_64X64];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005134#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5135 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5136 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5137#if CONFIG_SUPERTX
5138 cm->counts.supertx_size[TX_16X16] == 0 &&
5139 cm->counts.supertx_size[TX_32X32] == 0 &&
5140 cm->counts.supertx_size[TX_64X64] == 0 &&
5141#endif
5142 count64x64_64x64p == 0) {
5143 cm->tx_mode = ALLOW_8X8;
5144 reset_skip_tx_size(cm, TX_8X8);
5145 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5146 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5147 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5148#if CONFIG_SUPERTX
5149 cm->counts.supertx_size[TX_8X8] == 0 &&
5150 cm->counts.supertx_size[TX_16X16] == 0 &&
5151 cm->counts.supertx_size[TX_32X32] == 0 &&
5152 cm->counts.supertx_size[TX_64X64] == 0 &&
5153#endif
5154 count64x64_64x64p == 0) {
5155 cm->tx_mode = ONLY_4X4;
5156 reset_skip_tx_size(cm, TX_4X4);
5157 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5158 count32x32_lp == 0) {
5159 cm->tx_mode = ALLOW_64X64;
5160 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5161#if CONFIG_SUPERTX
5162 cm->counts.supertx_size[TX_64X64] == 0 &&
5163#endif
5164 count64x64_64x64p == 0) {
5165 cm->tx_mode = ALLOW_32X32;
5166 reset_skip_tx_size(cm, TX_32X32);
5167 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5168 count32x32_32x32p == 0 &&
5169#if CONFIG_SUPERTX
5170 cm->counts.supertx_size[TX_32X32] == 0 &&
5171 cm->counts.supertx_size[TX_64X64] == 0 &&
5172#endif
5173 count64x64_64x64p == 0) {
5174 cm->tx_mode = ALLOW_16X16;
5175 reset_skip_tx_size(cm, TX_16X16);
5176 }
5177
5178#else // CONFIG_TX64X64
5179
Yaowu Xuc27fc142016-08-22 16:08:15 -07005180 int count4x4 = 0;
5181 int count8x8_lp = 0, count8x8_8x8p = 0;
5182 int count16x16_16x16p = 0, count16x16_lp = 0;
5183 int count32x32 = 0;
5184 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005185 // counts->tx_size[max_depth][context_idx][this_depth_level]
5186 count4x4 += counts->tx_size[0][i][0];
5187 count4x4 += counts->tx_size[1][i][0];
5188 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005189
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005190 count8x8_8x8p += counts->tx_size[0][i][1];
Jingning Han2adcfb12016-10-27 11:19:53 -07005191 count8x8_lp += counts->tx_size[1][i][1];
5192 count8x8_lp += counts->tx_size[2][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005193
Jingning Han2adcfb12016-10-27 11:19:53 -07005194 count16x16_16x16p += counts->tx_size[1][i][2];
5195 count16x16_lp += counts->tx_size[2][i][2];
5196 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197 }
5198#if CONFIG_EXT_TX && CONFIG_RECT_TX
5199 count4x4 += counts->tx_size_implied[0][TX_4X4];
5200 count4x4 += counts->tx_size_implied[1][TX_4X4];
5201 count4x4 += counts->tx_size_implied[2][TX_4X4];
5202 count4x4 += counts->tx_size_implied[3][TX_4X4];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005203 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005204 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5205 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005206 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5207 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5208 count32x32 += counts->tx_size_implied[3][TX_32X32];
5209#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5210 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5211#if CONFIG_SUPERTX
5212 cm->counts.supertx_size[TX_16X16] == 0 &&
5213 cm->counts.supertx_size[TX_32X32] == 0 &&
5214#endif // CONFIG_SUPERTX
5215 count32x32 == 0) {
5216 cm->tx_mode = ALLOW_8X8;
5217 reset_skip_tx_size(cm, TX_8X8);
5218 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5219 count8x8_lp == 0 && count16x16_lp == 0 &&
5220#if CONFIG_SUPERTX
5221 cm->counts.supertx_size[TX_8X8] == 0 &&
5222 cm->counts.supertx_size[TX_16X16] == 0 &&
5223 cm->counts.supertx_size[TX_32X32] == 0 &&
5224#endif // CONFIG_SUPERTX
5225 count32x32 == 0) {
5226 cm->tx_mode = ONLY_4X4;
5227 reset_skip_tx_size(cm, TX_4X4);
5228 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5229 cm->tx_mode = ALLOW_32X32;
5230 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5231#if CONFIG_SUPERTX
5232 cm->counts.supertx_size[TX_32X32] == 0 &&
5233#endif // CONFIG_SUPERTX
5234 count4x4 == 0) {
5235 cm->tx_mode = ALLOW_16X16;
5236 reset_skip_tx_size(cm, TX_16X16);
5237 }
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005238#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239 }
5240#endif
5241 } else {
5242 encode_frame_internal(cpi);
5243 }
5244}
5245
5246static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5247 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
5248 const int intraonly) {
5249 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5250 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5251 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
5252
5253 if (bsize < BLOCK_8X8) {
5254 int idx, idy;
5255 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5256 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5257 for (idy = 0; idy < 2; idy += num_4x4_h)
5258 for (idx = 0; idx < 2; idx += num_4x4_w) {
5259 const int bidx = idy * 2 + idx;
5260 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5261 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005262 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5263 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005264 ++counts->kf_y_mode[a][l][bmode];
5265 } else {
5266 ++counts->y_mode[0][bmode];
5267 }
5268 }
5269 } else {
5270 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005271 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5272 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005273 ++counts->kf_y_mode[above][left][y_mode];
5274 } else {
5275 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5276 }
5277 }
5278
5279 ++counts->uv_mode[y_mode][uv_mode];
5280}
5281
5282#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005283static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005284 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005285 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005286 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5287 const int tx_row = blk_row >> 1;
5288 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005289 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5290 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005291 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005292 xd->left_txfm_context + tx_row,
5293 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005294 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5295
Yaowu Xuc27fc142016-08-22 16:08:15 -07005296 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5297
5298 if (tx_size == plane_tx_size) {
5299 ++counts->txfm_partition[ctx][0];
5300 mbmi->tx_size = tx_size;
5301 txfm_partition_update(xd->above_txfm_context + tx_col,
5302 xd->left_txfm_context + tx_row, tx_size);
5303 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005304 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5305 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005306 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005307
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005309 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310
5311 if (tx_size == TX_8X8) {
5312 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5313 mbmi->tx_size = TX_4X4;
5314 txfm_partition_update(xd->above_txfm_context + tx_col,
5315 xd->left_txfm_context + tx_row, TX_4X4);
5316 return;
5317 }
5318
5319 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005320 int offsetr = (i >> 1) * bs;
5321 int offsetc = (i & 0x01) * bs;
5322 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5323 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005324 }
5325 }
5326}
5327
Jingning Han9777afc2016-10-20 15:17:43 -07005328static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5329 BLOCK_SIZE plane_bsize, int mi_row,
5330 int mi_col, FRAME_COUNTS *td_counts) {
5331 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005332 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5333 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005334 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005335 const int bh = tx_size_high_unit[max_tx_size];
5336 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005337 int idx, idy;
5338
5339 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5340 xd->left_txfm_context =
5341 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5342
5343 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005344 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005345 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5346 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005347}
5348
5349static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5350 int blk_col) {
5351 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5352 const int tx_row = blk_row >> 1;
5353 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005354 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5355 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005356 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5357
Yaowu Xuc27fc142016-08-22 16:08:15 -07005358 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5359
5360 if (tx_size == plane_tx_size) {
5361 mbmi->tx_size = tx_size;
5362 txfm_partition_update(xd->above_txfm_context + tx_col,
5363 xd->left_txfm_context + tx_row, tx_size);
5364
5365 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005366 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5367 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368 int i;
5369
5370 if (tx_size == TX_8X8) {
5371 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5372 mbmi->tx_size = TX_4X4;
5373 txfm_partition_update(xd->above_txfm_context + tx_col,
5374 xd->left_txfm_context + tx_row, TX_4X4);
5375 return;
5376 }
5377
5378 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005379 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005380 int offsetr = (i >> 1) * bsl;
5381 int offsetc = (i & 0x01) * bsl;
5382 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005383 }
5384 }
5385}
5386
Urvang Joshi52648442016-10-13 17:27:51 -07005387static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5388 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5389 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005390 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5391 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005392 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005393 const int bh = tx_size_high_unit[max_tx_size];
5394 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005395 int idx, idy;
5396
5397 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5398 xd->left_txfm_context =
5399 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5400
5401 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005402 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005403 set_txfm_context(xd, max_tx_size, idy, idx);
5404}
5405#endif
5406
Urvang Joshi52648442016-10-13 17:27:51 -07005407static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5408 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5409 int mi_col, BLOCK_SIZE bsize,
5410 PICK_MODE_CONTEXT *ctx, int *rate) {
5411 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005412 MACROBLOCK *const x = &td->mb;
5413 MACROBLOCKD *const xd = &x->e_mbd;
5414 MODE_INFO **mi_8x8 = xd->mi;
5415 MODE_INFO *mi = mi_8x8[0];
5416 MB_MODE_INFO *mbmi = &mi->mbmi;
5417 const int seg_skip =
5418 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5419 const int mis = cm->mi_stride;
5420 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5421 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005422 const int is_inter = is_inter_block(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005423
Yaowu Xuc27fc142016-08-22 16:08:15 -07005424 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5425
Yushin Cho77bba8d2016-11-04 16:36:56 -07005426#if CONFIG_PVQ
5427 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005428 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005429#endif
5430
Jingning Han94ea1aa2016-11-08 12:10:46 -08005431 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005432 int plane;
5433 mbmi->skip = 1;
5434 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Angie Chiangff6d8902016-10-21 11:02:09 -07005435 av1_encode_intra_block_plane((AV1_COMMON *)cm, x,
5436 AOMMAX(bsize, BLOCK_8X8), plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005437 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005438 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5439 frame_is_intra_only(cm));
5440
hui su5db97432016-10-14 16:10:14 -07005441 // TODO(huisu): move this into sum_intra_stats().
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005442 if (!dry_run && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005443 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005444 (void)counts;
5445#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005446 if (mbmi->mode == DC_PRED
5447#if CONFIG_PALETTE
5448 && mbmi->palette_mode_info.palette_size[0] == 0
5449#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005450 ) {
5451 const int use_filter_intra_mode =
5452 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5453 ++counts->filter_intra[0][use_filter_intra_mode];
5454 }
Urvang Joshib100db72016-10-12 16:28:56 -07005455 if (mbmi->uv_mode == DC_PRED
5456#if CONFIG_PALETTE
5457 && mbmi->palette_mode_info.palette_size[1] == 0
5458#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005459 ) {
5460 const int use_filter_intra_mode =
5461 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5462 ++counts->filter_intra[1][use_filter_intra_mode];
5463 }
5464#endif // CONFIG_FILTER_INTRA
5465#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005466 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5467 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005468 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005469 p_angle =
5470 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005471 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005472 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5473 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005474#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005475 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005476
Urvang Joshib100db72016-10-12 16:28:56 -07005477#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005478 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005479 for (plane = 0; plane <= 1; ++plane) {
5480 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5481 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5482 xd->plane[plane].color_index_map[0];
5483 // TODO(huisu): this increases the use of token buffer. Needs stretch
5484 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005485 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486 }
5487 }
5488 }
Urvang Joshib100db72016-10-12 16:28:56 -07005489#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005490#if CONFIG_VAR_TX
5491 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5492#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005493 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005494 } else {
5495 int ref;
5496 const int is_compound = has_second_ref(mbmi);
5497
5498 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5499 for (ref = 0; ref < 1 + is_compound; ++ref) {
5500 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5501 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005502 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5503 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005504 }
Yue Chen69f18e12016-09-08 14:48:15 -07005505#if CONFIG_WARPED_MOTION
5506 if (mbmi->motion_mode == WARPED_CAUSAL) {
5507 int i;
5508#if CONFIG_AOM_HIGHBITDEPTH
5509 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
5510#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005511
Yue Chen69f18e12016-09-08 14:48:15 -07005512 for (i = 0; i < 3; ++i) {
5513 const struct macroblockd_plane *pd = &xd->plane[i];
5514
5515 av1_warp_plane(&mbmi->wm_params[0],
5516#if CONFIG_AOM_HIGHBITDEPTH
5517 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5518#endif // CONFIG_AOM_HIGHBITDEPTH
5519 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
5520 pd->pre[0].stride, pd->dst.buf,
5521 ((mi_col * MI_SIZE) >> pd->subsampling_x),
5522 ((mi_row * MI_SIZE) >> pd->subsampling_y),
5523 xd->n8_w * (8 >> pd->subsampling_x),
5524 xd->n8_h * (8 >> pd->subsampling_y), pd->dst.stride,
5525 pd->subsampling_x, pd->subsampling_y, 16, 16, 0);
5526 }
5527 } else {
5528#endif // CONFIG_WARPED_MOTION
5529 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
5530 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5531 AOMMAX(bsize, BLOCK_8X8));
5532
5533 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5534 AOMMAX(bsize, BLOCK_8X8));
5535#if CONFIG_WARPED_MOTION
5536 }
5537#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005538
Yue Chencb60b182016-10-13 15:18:22 -07005539#if CONFIG_MOTION_VAR
5540 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005541 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005542 }
Yue Chencb60b182016-10-13 15:18:22 -07005543#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005544
Angie Chiangff6d8902016-10-21 11:02:09 -07005545 av1_encode_sb((AV1_COMMON *)cm, x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005546#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005547 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Hanfe45b212016-11-22 10:30:23 -08005548 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5549 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550#else
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005551 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552#endif
5553 }
5554
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005555 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005556#if CONFIG_VAR_TX
5557 TX_SIZE tx_size =
5558 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5559#else
5560 TX_SIZE tx_size = mbmi->tx_size;
5561#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005562 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
Jingning Han94ea1aa2016-11-08 12:10:46 -08005563 !(is_inter && (mbmi->skip || seg_skip))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005564 const int tx_size_ctx = get_tx_size_context(xd);
5565 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5566 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005567 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005568 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005569#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005570 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005571#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5572#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -08005573 if (is_inter) {
5574 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5575 } else {
5576 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5577 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Yue Chena1e48dc2016-08-29 17:29:33 -07005578 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005579#else
Jingning Han4e1737a2016-10-25 16:05:02 -07005580 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005581#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005582 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005583 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005584 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005586 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005588 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005590 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005591 }
5592#if CONFIG_EXT_TX && CONFIG_RECT_TX
5593 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
Jingning Hane67b38a2016-11-04 10:30:00 -07005594 [txsize_sqr_up_map[tx_size]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005595#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5596 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005597 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005598 }
5599
Urvang Joshi454280d2016-10-14 16:51:44 -07005600 for (j = 0; j < mi_height; j++)
5601 for (i = 0; i < mi_width; i++)
5602 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005603 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005604
5605#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005606 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5607 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005608#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609 }
Jingning Han9777afc2016-10-20 15:17:43 -07005610
Jingning Hane67b38a2016-11-04 10:30:00 -07005611 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005612 ++td->counts
5613 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614#if CONFIG_EXT_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005615 if (get_ext_tx_types(tx_size, bsize, is_inter) > 1 && cm->base_qindex > 0 &&
5616 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005618 int eset = get_ext_tx_set(tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005619 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005620 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005621 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
Yaowu Xuc27fc142016-08-22 16:08:15 -07005622 [mbmi->tx_type];
5623 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005624 ++td->counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005625 }
5626 }
5627 }
5628#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005629 if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005631 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005632 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005633 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005634 ++td->counts->intra_ext_tx[tx_size]
clang-format67948d32016-09-07 22:40:40 -07005635 [intra_mode_to_tx_type_context[mbmi->mode]]
5636 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637 }
5638 }
5639#endif // CONFIG_EXT_TX
5640 }
5641
5642#if CONFIG_VAR_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005643 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 && is_inter &&
5644 !(mbmi->skip || seg_skip)) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005645 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005647 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005648 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005649 if (is_inter)
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005650 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 else
Jingning Hane67b38a2016-11-04 10:30:00 -07005652 tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005653 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005654 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005656#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005657}
5658
5659#if CONFIG_SUPERTX
5660static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5661 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5662#if CONFIG_EXT_INTER
5663 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5664#endif // CONFIG_EXT_INTER
5665 return 0;
5666}
5667
Urvang Joshi52648442016-10-13 17:27:51 -07005668static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5669 int mi_row, int mi_col, BLOCK_SIZE bsize,
5670 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005671 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005672
5673 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5674 const PARTITION_TYPE partition = pc_tree->partitioning;
5675 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5676#if CONFIG_EXT_PARTITION_TYPES
5677 int i;
5678#endif
5679
5680 assert(bsize >= BLOCK_8X8);
5681
5682 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5683
5684 switch (partition) {
5685 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5686 case PARTITION_VERT:
5687 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5688 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5689 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5690 }
5691 break;
5692 case PARTITION_HORZ:
5693 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5694 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5695 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5696 }
5697 break;
5698 case PARTITION_SPLIT:
5699 if (bsize == BLOCK_8X8) {
5700 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5701 } else {
5702 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5703 pc_tree->split[0]))
5704 return 1;
5705 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5706 pc_tree->split[1]))
5707 return 1;
5708 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5709 pc_tree->split[2]))
5710 return 1;
5711 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5712 pc_tree->split[3]))
5713 return 1;
5714 }
5715 break;
5716#if CONFIG_EXT_PARTITION_TYPES
5717 case PARTITION_HORZ_A:
5718 for (i = 0; i < 3; i++) {
5719 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5720 }
5721 break;
5722 case PARTITION_HORZ_B:
5723 for (i = 0; i < 3; i++) {
5724 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5725 }
5726 break;
5727 case PARTITION_VERT_A:
5728 for (i = 0; i < 3; i++) {
5729 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5730 }
5731 break;
5732 case PARTITION_VERT_B:
5733 for (i = 0; i < 3; i++) {
5734 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5735 }
5736 break;
5737#endif // CONFIG_EXT_PARTITION_TYPES
5738 default: assert(0);
5739 }
5740 return 0;
5741}
5742
5743static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5744 return ctx->mic.mbmi.tx_size == supertx_size;
5745}
5746
5747static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5748 PC_TREE *pc_tree) {
5749 PARTITION_TYPE partition;
5750 BLOCK_SIZE subsize;
5751
5752 partition = pc_tree->partitioning;
5753 subsize = get_subsize(bsize, partition);
5754 switch (partition) {
5755 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5756 case PARTITION_VERT:
5757 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5758 case PARTITION_HORZ:
5759 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5760 case PARTITION_SPLIT:
5761 if (bsize == BLOCK_8X8)
5762 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5763 else
5764 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5765#if CONFIG_EXT_PARTITION_TYPES
5766 case PARTITION_HORZ_A:
5767 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5768 case PARTITION_HORZ_B:
5769 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5770 case PARTITION_VERT_A:
5771 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5772 case PARTITION_VERT_B:
5773 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5774#endif // CONFIG_EXT_PARTITION_TYPES
5775 default: assert(0); return 0;
5776 }
5777}
5778
Urvang Joshi52648442016-10-13 17:27:51 -07005779static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005780#if CONFIG_EXT_INTER
5781 int mi_row_ori, int mi_col_ori,
5782#endif // CONFIG_EXT_INTER
5783 int mi_row_pred, int mi_col_pred,
5784 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5785 // Used in supertx
5786 // (mi_row_ori, mi_col_ori): location for mv
5787 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005788 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005789 MACROBLOCK *const x = &td->mb;
5790 MACROBLOCKD *const xd = &x->e_mbd;
5791 MODE_INFO *mi_8x8 = xd->mi[0];
5792 MODE_INFO *mi = mi_8x8;
5793 MB_MODE_INFO *mbmi = &mi->mbmi;
5794 int ref;
5795 const int is_compound = has_second_ref(mbmi);
5796
5797 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5798
5799 for (ref = 0; ref < 1 + is_compound; ++ref) {
5800 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005801 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5802 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803 }
5804
5805 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005806 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005807#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005808 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005810 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005812 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005813#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005814 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005815#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005816 mi_row_pred, mi_col_pred,
5817 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005818}
5819
Urvang Joshi52648442016-10-13 17:27:51 -07005820static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821 const TileInfo *const tile, int block,
5822 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5823 int mi_col_pred, int mi_row_top, int mi_col_top,
5824 uint8_t *dst_buf[3], int dst_stride[3],
5825 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005826 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005827 // Used in supertx
5828 // (mi_row_ori, mi_col_ori): location for mv
5829 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5830 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5831 // block: sub location of sub8x8 blocks
5832 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5833 // bextend: 1: region to predict is an extension of ori; 0: not
5834
5835 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005836 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005837 MACROBLOCKD *const xd = &x->e_mbd;
5838 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5839 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5840 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5841 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5842
5843 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5844 mi_row_pred >= mi_row_top + mi_height_top ||
5845 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5846 mi_col_pred >= cm->mi_cols)
5847 return;
5848
5849 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5850 mi_col_ori, bsize_pred);
5851 xd->plane[0].dst.stride = dst_stride[0];
5852 xd->plane[1].dst.stride = dst_stride[1];
5853 xd->plane[2].dst.stride = dst_stride[2];
5854 xd->plane[0].dst.buf = dst_buf[0] +
5855 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5856 (c >> xd->plane[0].subsampling_x);
5857 xd->plane[1].dst.buf = dst_buf[1] +
5858 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5859 (c >> xd->plane[1].subsampling_x);
5860 xd->plane[2].dst.buf = dst_buf[2] +
5861 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5862 (c >> xd->plane[2].subsampling_x);
5863
5864 predict_superblock(cpi, td,
5865#if CONFIG_EXT_INTER
5866 mi_row_ori, mi_col_ori,
5867#endif // CONFIG_EXT_INTER
5868 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5869
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005870 if (!dry_run && !bextend) {
5871#if CONFIG_SUPERTX
5872 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
5873#else
5874 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred);
5875#endif
5876 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005877}
5878
Urvang Joshi52648442016-10-13 17:27:51 -07005879static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005880 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5881 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005882 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005883 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5884 // dir: 0-lower, 1-upper, 2-left, 3-right
5885 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5886 MACROBLOCKD *xd = &td->mb.e_mbd;
5887 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5888 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5889 int xss = xd->plane[1].subsampling_x;
5890 int yss = xd->plane[1].subsampling_y;
5891 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5892
5893 BLOCK_SIZE extend_bsize;
5894 int unit, mi_row_pred, mi_col_pred;
5895
5896 if (dir == 0 || dir == 1) { // lower and upper
5897 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5898 ? BLOCK_8X8
5899 : BLOCK_16X8;
5900 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5901 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5902 mi_col_pred = mi_col;
5903
5904 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5905 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005906 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907
5908 if (mi_width > unit) {
5909 int i;
5910 for (i = 0; i < mi_width / unit - 1; i++) {
5911 mi_col_pred += unit;
5912 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5913 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005914 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5915 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005916 }
5917 }
5918 } else if (dir == 2 || dir == 3) { // left and right
5919 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5920 ? BLOCK_8X8
5921 : BLOCK_8X16;
5922 unit = num_8x8_blocks_high_lookup[extend_bsize];
5923 mi_row_pred = mi_row;
5924 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5925
5926 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5927 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005928 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005929
5930 if (mi_height > unit) {
5931 int i;
5932 for (i = 0; i < mi_height / unit - 1; i++) {
5933 mi_row_pred += unit;
5934 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5935 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005936 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5937 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005938 }
5939 }
5940 } else {
5941 extend_bsize = BLOCK_8X8;
5942 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5943 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5944
5945 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5946 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005947 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005948 }
5949}
5950
Urvang Joshi52648442016-10-13 17:27:51 -07005951static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005952 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5953 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005954 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005955 uint8_t *dst_buf[3], int dst_stride[3]) {
5956 assert(block >= 0 && block < 4);
5957 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005958 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005959 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005960 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005961 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005962 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005963 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005964 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005966 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005967 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005968 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005969 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005970 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005972 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005973}
5974
5975// This function generates prediction for multiple blocks, between which
5976// discontinuity around boundary is reduced by smoothing masks. The basic
5977// smoothing mask is a soft step function along horz/vert direction. In more
5978// complicated case when a block is split into 4 subblocks, the basic mask is
5979// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5980// then applied to the 2 masked prediction mentioned above in vertical direction
5981// If the block is split into more than one level, at every stage, masked
5982// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005983static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005984 const TileInfo *const tile, int mi_row,
5985 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005986 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005987 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5988 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005989 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005990 MACROBLOCK *const x = &td->mb;
5991 MACROBLOCKD *const xd = &x->e_mbd;
5992
5993 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5994 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5995 const PARTITION_TYPE partition = pc_tree->partitioning;
5996 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5997#if CONFIG_EXT_PARTITION_TYPES
5998 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5999#endif
6000
6001 int i;
6002 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
6003 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6004 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6005 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6006 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6007 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6008 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6009
6010 assert(bsize >= BLOCK_8X8);
6011
6012 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
6013
Yaowu Xuf883b422016-08-30 14:01:10 -07006014#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6016 int len = sizeof(uint16_t);
6017 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6018 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
6019 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
6020 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6021 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
6022 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
6023 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
6024 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
6025 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
6026 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006027#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006028 dst_buf1[0] = tmp_buf1;
6029 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
6030 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
6031 dst_buf2[0] = tmp_buf2;
6032 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
6033 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
6034 dst_buf3[0] = tmp_buf3;
6035 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
6036 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006037#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006038 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006039#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040
Urvang Joshi52648442016-10-13 17:27:51 -07006041 if (!dry_run && bsize < top_bsize) {
6042 // Explicitly cast away const.
6043 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6044 frame_counts->partition[ctx][partition]++;
6045 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006046
6047 for (i = 0; i < MAX_MB_PLANE; i++) {
6048 xd->plane[i].dst.buf = dst_buf[i];
6049 xd->plane[i].dst.stride = dst_stride[i];
6050 }
6051
6052 switch (partition) {
6053 case PARTITION_NONE:
6054 assert(bsize < top_bsize);
6055 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6056 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006057 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006058 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006059 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 break;
6061 case PARTITION_HORZ:
6062 if (bsize == BLOCK_8X8) {
6063 // Fisrt half
6064 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6065 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006066 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006067 if (bsize < top_bsize)
6068 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006069 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006070
6071 // Second half
6072 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6073 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006074 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006075 if (bsize < top_bsize)
6076 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006077 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006078
6079 // Smooth
6080 xd->plane[0].dst.buf = dst_buf[0];
6081 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006082 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006083 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6084 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6085 0);
6086 } else {
6087 // First half
6088 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6089 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006090 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006091 if (bsize < top_bsize)
6092 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006093 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094 else
6095 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006096 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006097
6098 if (mi_row + hbs < cm->mi_rows) {
6099 // Second half
6100 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6101 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006102 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006103 if (bsize < top_bsize)
6104 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006105 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006106 dst_stride1);
6107 else
6108 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006109 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006110 dst_stride1, 1);
6111
6112 // Smooth
6113 for (i = 0; i < MAX_MB_PLANE; i++) {
6114 xd->plane[i].dst.buf = dst_buf[i];
6115 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006116 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6118 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6119 PARTITION_HORZ, i);
6120 }
6121 }
6122 }
6123 break;
6124 case PARTITION_VERT:
6125 if (bsize == BLOCK_8X8) {
6126 // First half
6127 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6128 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006129 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006130 if (bsize < top_bsize)
6131 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006132 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006133
6134 // Second half
6135 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6136 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006137 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006138 if (bsize < top_bsize)
6139 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006140 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006141
6142 // Smooth
6143 xd->plane[0].dst.buf = dst_buf[0];
6144 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006145 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006146 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6147 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6148 0);
6149 } else {
6150 // bsize: not important, not useful
6151 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6152 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006153 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006154 if (bsize < top_bsize)
6155 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006156 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157 else
6158 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006159 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006160
6161 if (mi_col + hbs < cm->mi_cols) {
6162 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6163 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006164 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165 if (bsize < top_bsize)
6166 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006167 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6168 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006169 else
6170 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006171 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6172 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006173
6174 for (i = 0; i < MAX_MB_PLANE; i++) {
6175 xd->plane[i].dst.buf = dst_buf[i];
6176 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006177 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006178 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6179 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6180 PARTITION_VERT, i);
6181 }
6182 }
6183 }
6184 break;
6185 case PARTITION_SPLIT:
6186 if (bsize == BLOCK_8X8) {
6187 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6188 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006189 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6191 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006192 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6194 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006195 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6197 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006198 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006199
6200 if (bsize < top_bsize) {
6201 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006202 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006204 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006205 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006206 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006207 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006208 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209 }
6210 } else {
6211 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006212 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6213 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006214 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6215 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006216 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6217 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006218 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6219 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006220 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6221 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006222 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6223 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006224 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006225 top_bsize, dst_buf3, dst_stride3,
6226 pc_tree->split[3]);
6227 }
6228 for (i = 0; i < MAX_MB_PLANE; i++) {
6229 if (bsize == BLOCK_8X8 && i != 0)
6230 continue; // Skip <4x4 chroma smoothing
6231 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006232 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006233 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6234 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6235 PARTITION_VERT, i);
6236 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006237 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006238 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6239 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6240 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006241 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006242 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6243 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6244 PARTITION_HORZ, i);
6245 }
6246 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006247 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006248 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6249 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6250 PARTITION_HORZ, i);
6251 }
6252 }
6253 break;
6254#if CONFIG_EXT_PARTITION_TYPES
6255 case PARTITION_HORZ_A:
6256 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6257 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006258 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006259 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006260 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006261
6262 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6263 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006264 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006265 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006266 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006267
6268 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6269 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006270 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006271 if (bsize < top_bsize)
6272 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006273 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006274 else
6275 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006276 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006277
6278 for (i = 0; i < MAX_MB_PLANE; i++) {
6279 xd->plane[i].dst.buf = dst_buf[i];
6280 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006281 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006282 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6283 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6284 i);
6285 }
6286 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006287 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006288 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6289 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6290 i);
6291 }
6292
6293 break;
6294 case PARTITION_VERT_A:
6295
6296 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6297 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006298 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006299 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006300 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006301
6302 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6303 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006304 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006305 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006306 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006307
6308 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6309 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006310 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006311 if (bsize < top_bsize)
6312 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006313 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006314 else
6315 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006316 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006317
6318 for (i = 0; i < MAX_MB_PLANE; i++) {
6319 xd->plane[i].dst.buf = dst_buf[i];
6320 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006321 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006322 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6323 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6324 i);
6325 }
6326 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006327 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006328 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6329 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6330 i);
6331 }
6332 break;
6333 case PARTITION_HORZ_B:
6334
6335 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6336 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006337 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006338 if (bsize < top_bsize)
6339 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006340 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006341 else
6342 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006343 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006344
6345 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6346 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006347 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006348 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006349 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006350
6351 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6352 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006353 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006355 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006356 dst_stride2);
6357
6358 for (i = 0; i < MAX_MB_PLANE; i++) {
6359 xd->plane[i].dst.buf = dst_buf1[i];
6360 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006361 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006362 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6363 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6364 PARTITION_VERT, i);
6365 }
6366 for (i = 0; i < MAX_MB_PLANE; i++) {
6367 xd->plane[i].dst.buf = dst_buf[i];
6368 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006369 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006370 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6371 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6372 i);
6373 }
6374 break;
6375 case PARTITION_VERT_B:
6376
6377 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6378 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006379 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006380 if (bsize < top_bsize)
6381 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006382 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383 else
6384 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006385 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006386
6387 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6388 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006389 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006391 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006392
6393 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6394 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006395 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006396 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006397 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006398 dst_stride2);
6399
6400 for (i = 0; i < MAX_MB_PLANE; i++) {
6401 xd->plane[i].dst.buf = dst_buf1[i];
6402 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006403 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006404 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6405 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6406 PARTITION_HORZ, i);
6407 }
6408 for (i = 0; i < MAX_MB_PLANE; i++) {
6409 xd->plane[i].dst.buf = dst_buf[i];
6410 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006411 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006412 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6413 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6414 i);
6415 }
6416 break;
6417#endif // CONFIG_EXT_PARTITION_TYPES
6418 default: assert(0);
6419 }
6420
6421#if CONFIG_EXT_PARTITION_TYPES
6422 if (bsize < top_bsize)
6423 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6424#else
6425 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6426 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6427#endif // CONFIG_EXT_PARTITION_TYPES
6428}
6429
Urvang Joshi52648442016-10-13 17:27:51 -07006430static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431 const TileInfo *const tile, int mi_row, int mi_col,
6432 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6433 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006434 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006435 MACROBLOCK *const x = &td->mb;
6436 MACROBLOCKD *const xd = &x->e_mbd;
6437 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6438 base_rate = *tmp_rate;
6439 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6440 uint8_t *dst_buf[3];
6441 int dst_stride[3];
6442 TX_SIZE tx_size;
6443 MB_MODE_INFO *mbmi;
6444 TX_TYPE tx_type, best_tx_nostx;
6445#if CONFIG_EXT_TX
6446 int ext_tx_set;
6447#endif // CONFIG_EXT_TX
6448 int tmp_rate_tx = 0, skip_tx = 0;
6449 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6450
6451 set_skip_context(xd, mi_row, mi_col);
6452 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006453 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006454 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006455 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6456 dst_buf[plane] = xd->plane[plane].dst.buf;
6457 dst_stride[plane] = xd->plane[plane].dst.stride;
6458 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006459 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006460 bsize, dst_buf, dst_stride, pc_tree);
6461
6462 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6463 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6464
6465 mbmi = &xd->mi[0]->mbmi;
6466 best_tx_nostx = mbmi->tx_type;
6467
6468 *best_tx = DCT_DCT;
6469
6470 // chroma
6471 skippable_uv = 1;
6472 rate_uv = 0;
6473 dist_uv = 0;
6474 sse_uv = 0;
6475 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6476#if CONFIG_VAR_TX
6477 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6478 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6479 const struct macroblockd_plane *const pd = &xd->plane[plane];
6480 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006481 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006482 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006483
6484 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006485 tx_size =
6486 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006487 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006488 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6489
Yaowu Xuf883b422016-08-30 14:01:10 -07006490 av1_subtract_plane(x, bsize, plane);
6491 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006492 get_plane_block_size(bsize, pd), coeff_ctx,
6493 &this_rd_stats);
6494
6495 this_rate = this_rd_stats.rate;
6496 this_dist = this_rd_stats.dist;
6497 pnsse = this_rd_stats.sse;
6498 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006499#else
6500 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006501 tx_size =
6502 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006503 av1_subtract_plane(x, bsize, plane);
6504 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6505 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006506#endif // CONFIG_VAR_TX
6507
6508 rate_uv += this_rate;
6509 dist_uv += this_dist;
6510 sse_uv += pnsse;
6511 skippable_uv &= pnskip;
6512 }
6513
6514 // luma
6515 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006516 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006517#if CONFIG_EXT_TX
6518 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6519#endif // CONFIG_EXT_TX
6520 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6521#if CONFIG_VAR_TX
6522 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6523 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6524 const struct macroblockd_plane *const pd = &xd->plane[0];
6525 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006526 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006527#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006528
Yaowu Xuc27fc142016-08-22 16:08:15 -07006529#if CONFIG_EXT_TX
6530 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6531#else
6532 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6533#endif // CONFIG_EXT_TX
6534 mbmi->tx_type = tx_type;
6535
6536#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006537 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006538
Yaowu Xuf883b422016-08-30 14:01:10 -07006539 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006541 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6542 &this_rd_stats);
6543
6544 this_rate = this_rd_stats.rate;
6545 this_dist = this_rd_stats.dist;
6546 pnsse = this_rd_stats.sse;
6547 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006548#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006549 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6550 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006551#endif // CONFIG_VAR_TX
6552
6553#if CONFIG_EXT_TX
6554 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6555 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6556 if (ext_tx_set > 0)
6557 this_rate +=
6558 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6559 }
6560#else
6561 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6562 this_rate != INT_MAX) {
6563 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6564 }
6565#endif // CONFIG_EXT_TX
6566 *tmp_rate = rate_uv + this_rate;
6567 *tmp_dist = dist_uv + this_dist;
6568 sse = sse_uv + pnsse;
6569 skippable = skippable_uv && pnskip;
6570 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006571 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006572 x->skip = 1;
6573 } else {
6574 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6575 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006576 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006577 x->skip = 0;
6578 } else {
6579 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006580 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006581 x->skip = 1;
6582 }
6583 }
6584 *tmp_rate += base_rate;
6585 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6586 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6587 *best_tx = tx_type;
6588 bestrd_tx = rd_tx;
6589 tmp_rate_tx = *tmp_rate;
6590 tmp_dist_tx = *tmp_dist;
6591 skip_tx = x->skip;
6592 }
6593 }
6594 *tmp_rate = tmp_rate_tx;
6595 *tmp_dist = tmp_dist_tx;
6596 x->skip = skip_tx;
6597#if CONFIG_VAR_TX
6598 for (plane = 0; plane < 1; ++plane)
6599 memset(x->blk_skip[plane], x->skip,
6600 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6601#endif // CONFIG_VAR_TX
6602 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6603}
6604#endif // CONFIG_SUPERTX