blob: a768c1c43097b7fd81f01923f2726788cca984a9 [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 &&
1995 is_inter_compound_mode(mbmi->mode) &&
Yue Chencb60b182016-10-13 15:18:22 -07001996#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07001997 mbmi->motion_mode == SIMPLE_TRANSLATION &&
Yue Chencb60b182016-10-13 15:18:22 -07001998#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001999 is_interinter_wedge_used(bsize)) {
Sarah Parker6fddd182016-11-10 20:57:20 -08002000 counts->compound_interinter[bsize][mbmi->interinter_compound]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001 }
2002#endif // CONFIG_EXT_INTER
2003 }
2004 }
2005
2006 if (inter_block &&
2007 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08002008 int16_t mode_ctx;
2009#if !CONFIG_REF_MV
2010 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
2011#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002012 if (bsize >= BLOCK_8X8) {
2013 const PREDICTION_MODE mode = mbmi->mode;
2014#if CONFIG_REF_MV
2015#if CONFIG_EXT_INTER
2016 if (has_second_ref(mbmi)) {
2017 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
2018 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2019 } else {
2020#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002021 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2022 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002023 update_inter_mode_stats(counts, mode,
2024#if CONFIG_EXT_INTER
2025 has_second_ref(mbmi),
2026#endif // CONFIG_EXT_INTER
2027 mode_ctx);
2028
2029 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002030 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031 int idx;
2032
2033 for (idx = 0; idx < 2; ++idx) {
2034 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2035 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002036 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002037 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
2038
2039 if (mbmi->ref_mv_idx == idx) break;
2040 }
2041 }
2042 }
2043
2044 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002045 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002046 int idx;
2047
2048 for (idx = 1; idx < 3; ++idx) {
2049 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2050 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002051 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2053
2054 if (mbmi->ref_mv_idx == idx - 1) break;
2055 }
2056 }
2057 }
2058#if CONFIG_EXT_INTER
2059 }
2060#endif // CONFIG_EXT_INTER
2061#else
2062#if CONFIG_EXT_INTER
2063 if (is_inter_compound_mode(mode))
2064 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2065 else
2066#endif // CONFIG_EXT_INTER
2067 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2068#endif
2069 } else {
2070 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2071 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2072 int idx, idy;
2073 for (idy = 0; idy < 2; idy += num_4x4_h) {
2074 for (idx = 0; idx < 2; idx += num_4x4_w) {
2075 const int j = idy * 2 + idx;
2076 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2077#if CONFIG_REF_MV
2078#if CONFIG_EXT_INTER
2079 if (has_second_ref(mbmi)) {
2080 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002081 ++counts->inter_compound_mode[mode_ctx]
2082 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 } else {
2084#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002085 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2086 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002087 update_inter_mode_stats(counts, b_mode,
2088#if CONFIG_EXT_INTER
2089 has_second_ref(mbmi),
2090#endif // CONFIG_EXT_INTER
2091 mode_ctx);
2092#if CONFIG_EXT_INTER
2093 }
2094#endif // CONFIG_EXT_INTER
2095#else
2096#if CONFIG_EXT_INTER
2097 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002098 ++counts->inter_compound_mode[mode_ctx]
2099 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002100 else
2101#endif // CONFIG_EXT_INTER
2102 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2103#endif
2104 }
2105 }
2106 }
2107 }
2108 }
2109}
2110
2111typedef struct {
2112 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2113 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2114 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2115 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2116#if CONFIG_VAR_TX
2117 TXFM_CONTEXT *p_ta;
2118 TXFM_CONTEXT *p_tl;
2119 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2120 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2121#endif
2122} RD_SEARCH_MACROBLOCK_CONTEXT;
2123
2124static void restore_context(MACROBLOCK *x,
2125 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002126 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002127#if CONFIG_PVQ
2128 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002129#endif
2130 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002131 MACROBLOCKD *xd = &x->e_mbd;
2132 int p;
2133 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2134 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2135 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2136 int mi_height = num_8x8_blocks_high_lookup[bsize];
2137 for (p = 0; p < MAX_MB_PLANE; p++) {
2138 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2139 ctx->a + num_4x4_blocks_wide * p,
2140 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2141 xd->plane[p].subsampling_x);
2142 memcpy(xd->left_context[p] +
2143 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2144 ctx->l + num_4x4_blocks_high * p,
2145 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2146 xd->plane[p].subsampling_y);
2147 }
2148 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2149 sizeof(*xd->above_seg_context) * mi_width);
2150 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2151 sizeof(xd->left_seg_context[0]) * mi_height);
2152#if CONFIG_VAR_TX
2153 xd->above_txfm_context = ctx->p_ta;
2154 xd->left_txfm_context = ctx->p_tl;
2155 memcpy(xd->above_txfm_context, ctx->ta,
2156 sizeof(*xd->above_txfm_context) * mi_width);
2157 memcpy(xd->left_txfm_context, ctx->tl,
2158 sizeof(*xd->left_txfm_context) * mi_height);
2159#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002160#if CONFIG_PVQ
2161 od_encode_rollback(&x->daala_enc, rdo_buf);
2162#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002163}
2164
2165static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002166 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002167#if CONFIG_PVQ
2168 od_rollback_buffer *rdo_buf,
2169#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002170 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002171 const MACROBLOCKD *xd = &x->e_mbd;
2172 int p;
2173 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2174 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2175 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2176 int mi_height = num_8x8_blocks_high_lookup[bsize];
2177
2178 // buffer the above/left context information of the block in search.
2179 for (p = 0; p < MAX_MB_PLANE; ++p) {
2180 memcpy(ctx->a + num_4x4_blocks_wide * p,
2181 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2182 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2183 xd->plane[p].subsampling_x);
2184 memcpy(ctx->l + num_4x4_blocks_high * p,
2185 xd->left_context[p] +
2186 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2187 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2188 xd->plane[p].subsampling_y);
2189 }
2190 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2191 sizeof(*xd->above_seg_context) * mi_width);
2192 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2193 sizeof(xd->left_seg_context[0]) * mi_height);
2194#if CONFIG_VAR_TX
2195 memcpy(ctx->ta, xd->above_txfm_context,
2196 sizeof(*xd->above_txfm_context) * mi_width);
2197 memcpy(ctx->tl, xd->left_txfm_context,
2198 sizeof(*xd->left_txfm_context) * mi_height);
2199 ctx->p_ta = xd->above_txfm_context;
2200 ctx->p_tl = xd->left_txfm_context;
2201#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002202#if CONFIG_PVQ
2203 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2204#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002205}
2206
Urvang Joshi52648442016-10-13 17:27:51 -07002207static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2208 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2209 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002210#if CONFIG_EXT_PARTITION_TYPES
2211 PARTITION_TYPE partition,
2212#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002213 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002214 MACROBLOCK *const x = &td->mb;
2215 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2216#if CONFIG_EXT_PARTITION_TYPES
2217 x->e_mbd.mi[0]->mbmi.partition = partition;
2218#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002219 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2220 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002221
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002222 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002223#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002224 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002225#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002226 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002227#endif
2228 }
2229}
2230
Urvang Joshi52648442016-10-13 17:27:51 -07002231static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2232 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2233 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2234 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002235 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002236 MACROBLOCK *const x = &td->mb;
2237 MACROBLOCKD *const xd = &x->e_mbd;
2238
2239 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
2240 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
2241 const PARTITION_TYPE partition = pc_tree->partitioning;
2242 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2243#if CONFIG_EXT_PARTITION_TYPES
2244 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2245#endif
2246
2247 assert(bsize >= BLOCK_8X8);
2248
2249 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2250
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002251 if (!dry_run) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002252
2253#if CONFIG_SUPERTX
2254 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2255 partition != PARTITION_NONE && !xd->lossless[0]) {
2256 int supertx_enabled;
2257 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2258 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2259 if (supertx_enabled) {
2260 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2261 const int mi_height = num_8x8_blocks_high_lookup[bsize];
2262 int x_idx, y_idx, i;
2263 uint8_t *dst_buf[3];
2264 int dst_stride[3];
2265 set_skip_context(xd, mi_row, mi_col);
2266 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002267 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2268 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002269
Yaowu Xuf883b422016-08-30 14:01:10 -07002270 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002271 for (i = 0; i < MAX_MB_PLANE; i++) {
2272 dst_buf[i] = xd->plane[i].dst.buf;
2273 dst_stride[i] = xd->plane[i].dst.stride;
2274 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002275 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2276 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002277
2278 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2279 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2280
2281 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002282 int this_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002283 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2284
Angie Chiangff6d8902016-10-21 11:02:09 -07002285 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002286 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2287 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288 } else {
2289 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002290 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002291 reset_skip_context(xd, bsize);
2292 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002293 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002294 for (y_idx = 0; y_idx < mi_height; y_idx++)
2295 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2296 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2297 x_idx &&
2298 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2299 y_idx) {
2300 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2301 xd->mi[0]->mbmi.skip;
2302 }
2303 }
2304 td->counts->supertx[partition_supertx_context_lookup[partition]]
2305 [supertx_size][1]++;
2306 td->counts->supertx_size[supertx_size]++;
2307#if CONFIG_EXT_TX
2308 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2309 !xd->mi[0]->mbmi.skip) {
2310 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2311 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002312 ++td->counts->inter_ext_tx[eset][supertx_size]
2313 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002314 }
2315 }
2316#else
2317 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2318 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2319 }
2320#endif // CONFIG_EXT_TX
2321 }
2322#if CONFIG_EXT_PARTITION_TYPES
2323 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2324 partition);
2325#else
2326 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2327 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2328#endif
2329#if CONFIG_VAR_TX
Yaowu Xu52a17632016-11-17 15:48:21 -08002330 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2331 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002332#endif // CONFIG_VAR_TX
2333 return;
2334 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002335 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002336 td->counts->supertx[partition_supertx_context_lookup[partition]]
2337 [supertx_size][0]++;
2338 }
2339 }
2340 }
2341#endif // CONFIG_SUPERTX
2342
2343 switch (partition) {
2344 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002345 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002346#if CONFIG_EXT_PARTITION_TYPES
2347 partition,
2348#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002349 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002350 break;
2351 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002352 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002353#if CONFIG_EXT_PARTITION_TYPES
2354 partition,
2355#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002356 &pc_tree->vertical[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002357 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002358 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002359#if CONFIG_EXT_PARTITION_TYPES
2360 partition,
2361#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002362 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002363 }
2364 break;
2365 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002366 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002367#if CONFIG_EXT_PARTITION_TYPES
2368 partition,
2369#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002370 &pc_tree->horizontal[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002372 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002373#if CONFIG_EXT_PARTITION_TYPES
2374 partition,
2375#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002376 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002377 }
2378 break;
2379 case PARTITION_SPLIT:
2380 if (bsize == BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002381 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002382#if CONFIG_EXT_PARTITION_TYPES
2383 partition,
2384#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002385 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002386 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002387 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2388 pc_tree->split[0], rate);
2389 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2390 pc_tree->split[1], rate);
2391 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2392 pc_tree->split[2], rate);
2393 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2394 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002395 }
2396 break;
2397#if CONFIG_EXT_PARTITION_TYPES
2398 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002399 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2400 &pc_tree->horizontala[0], rate);
2401 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2402 partition, &pc_tree->horizontala[1], rate);
2403 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2404 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002405 break;
2406 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002407 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2408 &pc_tree->horizontalb[0], rate);
2409 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2410 partition, &pc_tree->horizontalb[1], rate);
2411 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2412 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413 break;
2414 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002415 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2416 &pc_tree->verticala[0], rate);
2417 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2418 partition, &pc_tree->verticala[1], rate);
2419 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2420 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002421
2422 break;
2423 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002424 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2425 &pc_tree->verticalb[0], rate);
2426 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2427 partition, &pc_tree->verticalb[1], rate);
2428 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2429 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002430 break;
2431#endif // CONFIG_EXT_PARTITION_TYPES
2432 default: assert(0 && "Invalid partition type."); break;
2433 }
2434
2435#if CONFIG_EXT_PARTITION_TYPES
2436 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2437#else
2438 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2439 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2440#endif // CONFIG_EXT_PARTITION_TYPES
2441}
2442
2443// Check to see if the given partition size is allowed for a specified number
2444// of mi block rows and columns remaining in the image.
2445// If not then return the largest allowed partition size
2446static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2447 int cols_left, int *bh, int *bw) {
2448 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002449 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450 } else {
2451 for (; bsize > 0; bsize -= 3) {
2452 *bh = num_8x8_blocks_high_lookup[bsize];
2453 *bw = num_8x8_blocks_wide_lookup[bsize];
2454 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2455 break;
2456 }
2457 }
2458 }
2459 return bsize;
2460}
2461
Yaowu Xuf883b422016-08-30 14:01:10 -07002462static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002463 int bh_in, int bw_in,
2464 int mi_rows_remaining,
2465 int mi_cols_remaining, BLOCK_SIZE bsize,
2466 MODE_INFO **mib) {
2467 int bh = bh_in;
2468 int r, c;
2469 for (r = 0; r < cm->mib_size; r += bh) {
2470 int bw = bw_in;
2471 for (c = 0; c < cm->mib_size; c += bw) {
2472 const int index = r * cm->mi_stride + c;
2473 mib[index] = mi + index;
2474 mib[index]->mbmi.sb_type = find_partition_size(
2475 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2476 }
2477 }
2478}
2479
2480// This function attempts to set all mode info entries in a given superblock
2481// to the same block partition size.
2482// However, at the bottom and right borders of the image the requested size
2483// may not be allowed in which case this code attempts to choose the largest
2484// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002485static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002486 MODE_INFO **mib, int mi_row, int mi_col,
2487 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002488 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002489 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2490 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2491 int block_row, block_col;
2492 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2493 int bh = num_8x8_blocks_high_lookup[bsize];
2494 int bw = num_8x8_blocks_wide_lookup[bsize];
2495
2496 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2497
2498 // Apply the requested partition size to the SB if it is all "in image"
2499 if ((mi_cols_remaining >= cm->mib_size) &&
2500 (mi_rows_remaining >= cm->mib_size)) {
2501 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2502 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2503 int index = block_row * cm->mi_stride + block_col;
2504 mib[index] = mi_upper_left + index;
2505 mib[index]->mbmi.sb_type = bsize;
2506 }
2507 }
2508 } else {
2509 // Else this is a partial SB.
2510 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2511 mi_cols_remaining, bsize, mib);
2512 }
2513}
2514
Yaowu Xuf883b422016-08-30 14:01:10 -07002515static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002516 TileDataEnc *tile_data, MODE_INFO **mib,
2517 TOKENEXTRA **tp, int mi_row, int mi_col,
2518 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2519#if CONFIG_SUPERTX
2520 int *rate_nocoef,
2521#endif
2522 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002523 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002524 TileInfo *const tile_info = &tile_data->tile_info;
2525 MACROBLOCK *const x = &td->mb;
2526 MACROBLOCKD *const xd = &x->e_mbd;
2527 const int bs = num_8x8_blocks_wide_lookup[bsize];
2528 const int hbs = bs / 2;
2529 int i;
2530 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2531 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2532 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2533 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2534 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2535 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2536 int splits_below = 0;
2537 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2538 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002539 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002540#if CONFIG_SUPERTX
2541 int last_part_rate_nocoef = INT_MAX;
2542 int none_rate_nocoef = INT_MAX;
2543 int chosen_rate_nocoef = INT_MAX;
2544#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002545#if CONFIG_PVQ
2546 od_rollback_buffer pre_rdo_buf;
2547#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2549
2550 assert(num_4x4_blocks_wide_lookup[bsize] ==
2551 num_4x4_blocks_high_lookup[bsize]);
2552
Yaowu Xuf883b422016-08-30 14:01:10 -07002553 av1_rd_cost_reset(&last_part_rdc);
2554 av1_rd_cost_reset(&none_rdc);
2555 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556
2557 pc_tree->partitioning = partition;
2558
2559#if CONFIG_VAR_TX
2560 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2561 xd->left_txfm_context =
2562 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2563#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002564#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002565 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002566#else
2567 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2568#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569
2570 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2571 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002572 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002573 }
2574
2575 if (do_partition_search &&
2576 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2577 cpi->sf.adjust_partitioning_from_last_frame) {
2578 // Check if any of the sub blocks are further split.
2579 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2580 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2581 splits_below = 1;
2582 for (i = 0; i < 4; i++) {
2583 int jj = i >> 1, ii = i & 0x01;
2584 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2585 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2586 splits_below = 0;
2587 }
2588 }
2589 }
2590
2591 // If partition is not none try none unless each of the 4 splits are split
2592 // even further..
2593 if (partition != PARTITION_NONE && !splits_below &&
2594 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2595 pc_tree->partitioning = PARTITION_NONE;
2596 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2597#if CONFIG_SUPERTX
2598 &none_rate_nocoef,
2599#endif
2600#if CONFIG_EXT_PARTITION_TYPES
2601 PARTITION_NONE,
2602#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002603 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002604
2605 if (none_rdc.rate < INT_MAX) {
2606 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2607 none_rdc.rdcost =
2608 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2609#if CONFIG_SUPERTX
2610 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2611#endif
2612 }
2613
Yushin Cho77bba8d2016-11-04 16:36:56 -07002614#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002616#else
2617 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2618#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002619 mib[0]->mbmi.sb_type = bs_type;
2620 pc_tree->partitioning = partition;
2621 }
2622 }
2623
2624 switch (partition) {
2625 case PARTITION_NONE:
2626 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2627#if CONFIG_SUPERTX
2628 &last_part_rate_nocoef,
2629#endif
2630#if CONFIG_EXT_PARTITION_TYPES
2631 PARTITION_NONE,
2632#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002633 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634 break;
2635 case PARTITION_HORZ:
2636 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2637#if CONFIG_SUPERTX
2638 &last_part_rate_nocoef,
2639#endif
2640#if CONFIG_EXT_PARTITION_TYPES
2641 PARTITION_HORZ,
2642#endif
2643 subsize, &pc_tree->horizontal[0], INT64_MAX);
2644 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2645 mi_row + hbs < cm->mi_rows) {
2646 RD_COST tmp_rdc;
2647#if CONFIG_SUPERTX
2648 int rt_nocoef = 0;
2649#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002650 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002651 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002652 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002653 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002654 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002655 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2656#if CONFIG_SUPERTX
2657 &rt_nocoef,
2658#endif
2659#if CONFIG_EXT_PARTITION_TYPES
2660 PARTITION_HORZ,
2661#endif
2662 subsize, &pc_tree->horizontal[1], INT64_MAX);
2663 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002664 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002665#if CONFIG_SUPERTX
2666 last_part_rate_nocoef = INT_MAX;
2667#endif
2668 break;
2669 }
2670 last_part_rdc.rate += tmp_rdc.rate;
2671 last_part_rdc.dist += tmp_rdc.dist;
2672 last_part_rdc.rdcost += tmp_rdc.rdcost;
2673#if CONFIG_SUPERTX
2674 last_part_rate_nocoef += rt_nocoef;
2675#endif
2676 }
2677 break;
2678 case PARTITION_VERT:
2679 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2680#if CONFIG_SUPERTX
2681 &last_part_rate_nocoef,
2682#endif
2683#if CONFIG_EXT_PARTITION_TYPES
2684 PARTITION_VERT,
2685#endif
2686 subsize, &pc_tree->vertical[0], INT64_MAX);
2687 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2688 mi_col + hbs < cm->mi_cols) {
2689 RD_COST tmp_rdc;
2690#if CONFIG_SUPERTX
2691 int rt_nocoef = 0;
2692#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002693 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002694 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002695 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002696 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002697 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2699#if CONFIG_SUPERTX
2700 &rt_nocoef,
2701#endif
2702#if CONFIG_EXT_PARTITION_TYPES
2703 PARTITION_VERT,
2704#endif
2705 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2706 INT64_MAX);
2707 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002708 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002709#if CONFIG_SUPERTX
2710 last_part_rate_nocoef = INT_MAX;
2711#endif
2712 break;
2713 }
2714 last_part_rdc.rate += tmp_rdc.rate;
2715 last_part_rdc.dist += tmp_rdc.dist;
2716 last_part_rdc.rdcost += tmp_rdc.rdcost;
2717#if CONFIG_SUPERTX
2718 last_part_rate_nocoef += rt_nocoef;
2719#endif
2720 }
2721 break;
2722 case PARTITION_SPLIT:
2723 if (bsize == BLOCK_8X8) {
2724 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2725#if CONFIG_SUPERTX
2726 &last_part_rate_nocoef,
2727#endif
2728#if CONFIG_EXT_PARTITION_TYPES
2729 PARTITION_SPLIT,
2730#endif
2731 subsize, pc_tree->leaf_split[0], INT64_MAX);
2732 break;
2733 }
2734 last_part_rdc.rate = 0;
2735 last_part_rdc.dist = 0;
2736 last_part_rdc.rdcost = 0;
2737#if CONFIG_SUPERTX
2738 last_part_rate_nocoef = 0;
2739#endif
2740 for (i = 0; i < 4; i++) {
2741 int x_idx = (i & 1) * hbs;
2742 int y_idx = (i >> 1) * hbs;
2743 int jj = i >> 1, ii = i & 0x01;
2744 RD_COST tmp_rdc;
2745#if CONFIG_SUPERTX
2746 int rt_nocoef;
2747#endif
2748 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2749 continue;
2750
Yaowu Xuf883b422016-08-30 14:01:10 -07002751 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002752 rd_use_partition(cpi, td, tile_data,
2753 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2754 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2755 &tmp_rdc.dist,
2756#if CONFIG_SUPERTX
2757 &rt_nocoef,
2758#endif
2759 i != 3, pc_tree->split[i]);
2760 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002761 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762#if CONFIG_SUPERTX
2763 last_part_rate_nocoef = INT_MAX;
2764#endif
2765 break;
2766 }
2767 last_part_rdc.rate += tmp_rdc.rate;
2768 last_part_rdc.dist += tmp_rdc.dist;
2769#if CONFIG_SUPERTX
2770 last_part_rate_nocoef += rt_nocoef;
2771#endif
2772 }
2773 break;
2774#if CONFIG_EXT_PARTITION_TYPES
2775 case PARTITION_VERT_A:
2776 case PARTITION_VERT_B:
2777 case PARTITION_HORZ_A:
2778 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2779#endif // CONFIG_EXT_PARTITION_TYPES
2780 default: assert(0); break;
2781 }
2782
2783 if (last_part_rdc.rate < INT_MAX) {
2784 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2785 last_part_rdc.rdcost =
2786 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2787#if CONFIG_SUPERTX
2788 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2789#endif
2790 }
2791
2792 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2793 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2794 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2795 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2796 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2797 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2798 chosen_rdc.rate = 0;
2799 chosen_rdc.dist = 0;
2800#if CONFIG_SUPERTX
2801 chosen_rate_nocoef = 0;
2802#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002803#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002804 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002805#else
2806 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2807#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002808 pc_tree->partitioning = PARTITION_SPLIT;
2809
2810 // Split partition.
2811 for (i = 0; i < 4; i++) {
2812 int x_idx = (i & 1) * hbs;
2813 int y_idx = (i >> 1) * hbs;
2814 RD_COST tmp_rdc;
2815#if CONFIG_SUPERTX
2816 int rt_nocoef = 0;
2817#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002818#if CONFIG_PVQ
2819 od_rollback_buffer buf;
2820#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002821 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2822 continue;
2823
Yushin Cho77bba8d2016-11-04 16:36:56 -07002824#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002826#else
2827 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2828#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829 pc_tree->split[i]->partitioning = PARTITION_NONE;
2830 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2831 &tmp_rdc,
2832#if CONFIG_SUPERTX
2833 &rt_nocoef,
2834#endif
2835#if CONFIG_EXT_PARTITION_TYPES
2836 PARTITION_SPLIT,
2837#endif
2838 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2839
Yushin Cho77bba8d2016-11-04 16:36:56 -07002840#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002841 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002842#else
2843 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2844#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002846 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847#if CONFIG_SUPERTX
2848 chosen_rate_nocoef = INT_MAX;
2849#endif
2850 break;
2851 }
2852
2853 chosen_rdc.rate += tmp_rdc.rate;
2854 chosen_rdc.dist += tmp_rdc.dist;
2855#if CONFIG_SUPERTX
2856 chosen_rate_nocoef += rt_nocoef;
2857#endif
2858
2859 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002860 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2861 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002862
2863 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2864#if CONFIG_SUPERTX
2865 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2866#endif
2867 }
2868 if (chosen_rdc.rate < INT_MAX) {
2869 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2870 chosen_rdc.rdcost =
2871 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2872#if CONFIG_SUPERTX
2873 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2874#endif
2875 }
2876 }
2877
2878 // If last_part is better set the partitioning to that.
2879 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2880 mib[0]->mbmi.sb_type = bsize;
2881 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2882 chosen_rdc = last_part_rdc;
2883#if CONFIG_SUPERTX
2884 chosen_rate_nocoef = last_part_rate_nocoef;
2885#endif
2886 }
2887 // If none was better set the partitioning to that.
2888 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2889 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2890 chosen_rdc = none_rdc;
2891#if CONFIG_SUPERTX
2892 chosen_rate_nocoef = none_rate_nocoef;
2893#endif
2894 }
2895
Yushin Cho77bba8d2016-11-04 16:36:56 -07002896#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002897 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002898#else
2899 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2900#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002901
2902 // We must have chosen a partitioning and encoding or we'll fail later on.
2903 // No other opportunities for success.
2904 if (bsize == cm->sb_size)
2905 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2906
2907 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002908 if (bsize == cm->sb_size) {
2909 // NOTE: To get estimate for rate due to the tokens, use:
2910 // int rate_coeffs = 0;
2911 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2912 // bsize, pc_tree, &rate_coeffs);
2913 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2914 pc_tree, NULL);
2915 } else {
2916 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2917 pc_tree, NULL);
2918 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002919 }
2920
2921 *rate = chosen_rdc.rate;
2922 *dist = chosen_rdc.dist;
2923#if CONFIG_SUPERTX
2924 *rate_nocoef = chosen_rate_nocoef;
2925#endif
2926}
2927
2928/* clang-format off */
2929static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2930 BLOCK_4X4, // 4x4
2931 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2932 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2933 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2934 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2935#if CONFIG_EXT_PARTITION
2936 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2937#endif // CONFIG_EXT_PARTITION
2938};
2939
2940static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2941 BLOCK_8X8, // 4x4
2942 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2943 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2944 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2945 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2946#if CONFIG_EXT_PARTITION
2947 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2948#endif // CONFIG_EXT_PARTITION
2949};
2950
2951// Next square block size less or equal than current block size.
2952static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2953 BLOCK_4X4, // 4x4
2954 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2955 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2956 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2957 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2958#if CONFIG_EXT_PARTITION
2959 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
2960#endif // CONFIG_EXT_PARTITION
2961};
2962/* clang-format on */
2963
2964// Look at all the mode_info entries for blocks that are part of this
2965// partition and find the min and max values for sb_type.
2966// At the moment this is designed to work on a superblock but could be
2967// adjusted to use a size parameter.
2968//
2969// The min and max are assumed to have been initialized prior to calling this
2970// function so repeat calls can accumulate a min and max of more than one
2971// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002972static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002973 MACROBLOCKD *xd, MODE_INFO **mib,
2974 BLOCK_SIZE *min_block_size,
2975 BLOCK_SIZE *max_block_size) {
2976 int i, j;
2977 int index = 0;
2978
2979 // Check the sb_type for each block that belongs to this region.
2980 for (i = 0; i < cm->mib_size; ++i) {
2981 for (j = 0; j < cm->mib_size; ++j) {
2982 MODE_INFO *mi = mib[index + j];
2983 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002984 *min_block_size = AOMMIN(*min_block_size, sb_type);
2985 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002986 }
2987 index += xd->mi_stride;
2988 }
2989}
2990
2991// Look at neighboring blocks and set a min and max partition size based on
2992// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002993static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002994 MACROBLOCKD *const xd, int mi_row,
2995 int mi_col, BLOCK_SIZE *min_block_size,
2996 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002997 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002998 MODE_INFO **mi = xd->mi;
2999 const int left_in_image = xd->left_available && mi[-1];
3000 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3001 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3002 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3003 int bh, bw;
3004 BLOCK_SIZE min_size = BLOCK_4X4;
3005 BLOCK_SIZE max_size = BLOCK_LARGEST;
3006
3007 // Trap case where we do not have a prediction.
3008 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3009 // Default "min to max" and "max to min"
3010 min_size = BLOCK_LARGEST;
3011 max_size = BLOCK_4X4;
3012
3013 // NOTE: each call to get_sb_partition_size_range() uses the previous
3014 // passed in values for min and max as a starting point.
3015 // Find the min and max partition used in previous frame at this location
3016 if (cm->frame_type != KEY_FRAME) {
3017 MODE_INFO **prev_mi =
3018 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3019 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3020 }
3021 // Find the min and max partition sizes used in the left superblock
3022 if (left_in_image) {
3023 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3024 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3025 }
3026 // Find the min and max partition sizes used in the above suprblock.
3027 if (above_in_image) {
3028 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3029 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3030 }
3031
3032 // Adjust observed min and max for "relaxed" auto partition case.
3033 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3034 min_size = min_partition_size[min_size];
3035 max_size = max_partition_size[max_size];
3036 }
3037 }
3038
3039 // Check border cases where max and min from neighbors may not be legal.
3040 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3041 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07003042 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043
3044 // Test for blocks at the edge of the active image.
3045 // This may be the actual edge of the image or where there are formatting
3046 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003047 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003048 min_size = BLOCK_4X4;
3049 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003050 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003051 }
3052
3053 // When use_square_partition_only is true, make sure at least one square
3054 // partition is allowed by selecting the next smaller square size as
3055 // *min_block_size.
3056 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003057 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003058 }
3059
Yaowu Xuf883b422016-08-30 14:01:10 -07003060 *min_block_size = AOMMIN(min_size, cm->sb_size);
3061 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003062}
3063
3064// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003065static void set_partition_range(const AV1_COMMON *const cm,
3066 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003067 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003068 BLOCK_SIZE *const min_bs,
3069 BLOCK_SIZE *const max_bs) {
3070 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3071 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003072 int idx, idy;
3073
Yaowu Xuc27fc142016-08-22 16:08:15 -07003074 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003075 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3076 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3077 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003078
3079 if (prev_mi) {
3080 for (idy = 0; idy < mi_height; ++idy) {
3081 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003082 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3083 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003084 min_size = AOMMIN(min_size, bs);
3085 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003086 }
3087 }
3088 }
3089
3090 if (xd->left_available) {
3091 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003092 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3093 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003094 min_size = AOMMIN(min_size, bs);
3095 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003096 }
3097 }
3098
3099 if (xd->up_available) {
3100 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003101 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3102 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003103 min_size = AOMMIN(min_size, bs);
3104 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003105 }
3106 }
3107
3108 if (min_size == max_size) {
3109 min_size = min_partition_size[min_size];
3110 max_size = max_partition_size[max_size];
3111 }
3112
Yaowu Xuf883b422016-08-30 14:01:10 -07003113 *min_bs = AOMMIN(min_size, cm->sb_size);
3114 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003115}
3116
3117static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3118 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3119}
3120
3121static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3122 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3123}
3124
3125#if CONFIG_FP_MB_STATS
3126const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3127 0,
3128 10,
3129 10,
3130 30,
3131 40,
3132 40,
3133 60,
3134 80,
3135 80,
3136 90,
3137 100,
3138 100,
3139 120,
3140#if CONFIG_EXT_PARTITION
3141 // TODO(debargha): What are the correct numbers here?
3142 130,
3143 130,
3144 150
3145#endif // CONFIG_EXT_PARTITION
3146};
3147const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3148 0,
3149 3,
3150 3,
3151 7,
3152 15,
3153 15,
3154 30,
3155 40,
3156 40,
3157 60,
3158 80,
3159 80,
3160 120,
3161#if CONFIG_EXT_PARTITION
3162 // TODO(debargha): What are the correct numbers here?
3163 160,
3164 160,
3165 240
3166#endif // CONFIG_EXT_PARTITION
3167};
3168const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3169 1,
3170 1,
3171 1,
3172 1,
3173 1,
3174 1,
3175 1,
3176 1,
3177 1,
3178 1,
3179 4,
3180 4,
Yaowu Xu17fd2f22016-11-17 18:23:28 -08003181 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003182#if CONFIG_EXT_PARTITION
3183 // TODO(debargha): What are the correct numbers here?
3184 8,
3185 8,
3186 10
3187#endif // CONFIG_EXT_PARTITION
3188};
3189
3190typedef enum {
3191 MV_ZERO = 0,
3192 MV_LEFT = 1,
3193 MV_UP = 2,
3194 MV_RIGHT = 3,
3195 MV_DOWN = 4,
3196 MV_INVALID
3197} MOTION_DIRECTION;
3198
3199static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3200 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3201 return MV_ZERO;
3202 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3203 return MV_LEFT;
3204 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3205 return MV_RIGHT;
3206 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3207 return MV_UP;
3208 } else {
3209 return MV_DOWN;
3210 }
3211}
3212
3213static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3214 MOTION_DIRECTION that_mv) {
3215 if (this_mv == that_mv) {
3216 return 0;
3217 } else {
3218 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3219 }
3220}
3221#endif
3222
3223#if CONFIG_EXT_PARTITION_TYPES
3224static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003225 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3226 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3227 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3228 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003229#if CONFIG_SUPERTX
3230 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3231#endif
3232 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3233 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3234 MACROBLOCK *const x = &td->mb;
3235 MACROBLOCKD *const xd = &x->e_mbd;
3236 RD_COST this_rdc, sum_rdc;
3237#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003238 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003239 TileInfo *const tile_info = &tile_data->tile_info;
3240 int this_rate_nocoef, sum_rate_nocoef;
3241 int abort_flag;
3242 const int supertx_allowed = !frame_is_intra_only(cm) &&
3243 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3244 !xd->lossless[0];
3245#endif
3246 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3247
3248 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3249#if CONFIG_SUPERTX
3250 &sum_rate_nocoef,
3251#endif
3252#if CONFIG_EXT_PARTITION_TYPES
3253 partition,
3254#endif
3255 subsize0, &ctxs[0], best_rdc->rdcost);
3256#if CONFIG_SUPERTX
3257 abort_flag = sum_rdc.rdcost >= best_rd;
3258#endif
3259
3260#if CONFIG_SUPERTX
3261 if (sum_rdc.rdcost < INT64_MAX) {
3262#else
3263 if (sum_rdc.rdcost < best_rdc->rdcost) {
3264#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003265 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3266 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003267 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003268 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003269
Urvang Joshi368fbc92016-10-17 16:31:34 -07003270 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271
3272#if CONFIG_SUPERTX
3273 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3274 &this_rate_nocoef,
3275#if CONFIG_EXT_PARTITION_TYPES
3276 partition,
3277#endif
3278 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3279#else
3280 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3281#if CONFIG_EXT_PARTITION_TYPES
3282 partition,
3283#endif
3284 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3285#endif // CONFIG_SUPERTX
3286
3287 if (this_rdc.rate == INT_MAX) {
3288 sum_rdc.rdcost = INT64_MAX;
3289#if CONFIG_SUPERTX
3290 sum_rate_nocoef = INT_MAX;
3291#endif
3292 } else {
3293 sum_rdc.rate += this_rdc.rate;
3294 sum_rdc.dist += this_rdc.dist;
3295 sum_rdc.rdcost += this_rdc.rdcost;
3296#if CONFIG_SUPERTX
3297 sum_rate_nocoef += this_rate_nocoef;
3298#endif
3299 }
3300
3301#if CONFIG_SUPERTX
3302 if (sum_rdc.rdcost < INT64_MAX) {
3303#else
3304 if (sum_rdc.rdcost < best_rdc->rdcost) {
3305#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003306 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3307 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003308 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003309 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003310
Urvang Joshi368fbc92016-10-17 16:31:34 -07003311 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003312
3313#if CONFIG_SUPERTX
3314 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3315 &this_rate_nocoef,
3316#if CONFIG_EXT_PARTITION_TYPES
3317 partition,
3318#endif
3319 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3320#else
3321 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3322#if CONFIG_EXT_PARTITION_TYPES
3323 partition,
3324#endif
3325 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3326#endif // CONFIG_SUPERTX
3327
3328 if (this_rdc.rate == INT_MAX) {
3329 sum_rdc.rdcost = INT64_MAX;
3330#if CONFIG_SUPERTX
3331 sum_rate_nocoef = INT_MAX;
3332#endif
3333 } else {
3334 sum_rdc.rate += this_rdc.rate;
3335 sum_rdc.dist += this_rdc.dist;
3336 sum_rdc.rdcost += this_rdc.rdcost;
3337#if CONFIG_SUPERTX
3338 sum_rate_nocoef += this_rate_nocoef;
3339#endif
3340 }
3341
3342#if CONFIG_SUPERTX
3343 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3344 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3345 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3346 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003347 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003348 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3349 [supertx_size],
3350 0);
3351 sum_rdc.rdcost =
3352 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3353
3354 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3355 TX_TYPE best_tx = DCT_DCT;
3356 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3357
3358 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3359
3360 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3361 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3362
Yaowu Xuf883b422016-08-30 14:01:10 -07003363 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003364 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3365 [supertx_size],
3366 1);
3367 tmp_rdc.rdcost =
3368 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3369 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3370 sum_rdc = tmp_rdc;
3371 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3372 supertx_size, pc_tree);
3373 }
3374 }
3375
3376 pc_tree->partitioning = best_partition;
3377 }
3378#endif // CONFIG_SUPERTX
3379
3380 if (sum_rdc.rdcost < best_rdc->rdcost) {
3381 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3382 sum_rdc.rate += cpi->partition_cost[pl][partition];
3383 sum_rdc.rdcost =
3384 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3385#if CONFIG_SUPERTX
3386 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3387#endif
3388 if (sum_rdc.rdcost < best_rdc->rdcost) {
3389#if CONFIG_SUPERTX
3390 *best_rate_nocoef = sum_rate_nocoef;
3391 assert(*best_rate_nocoef >= 0);
3392#endif
3393 *best_rdc = sum_rdc;
3394 pc_tree->partitioning = partition;
3395 }
3396 }
3397 }
3398 }
3399}
3400#endif // CONFIG_EXT_PARTITION_TYPES
3401
3402// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3403// unlikely to be selected depending on previous rate-distortion optimization
3404// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003405static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003406 TileDataEnc *tile_data, TOKENEXTRA **tp,
3407 int mi_row, int mi_col, BLOCK_SIZE bsize,
3408 RD_COST *rd_cost,
3409#if CONFIG_SUPERTX
3410 int *rate_nocoef,
3411#endif
3412 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003413 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003414 TileInfo *const tile_info = &tile_data->tile_info;
3415 MACROBLOCK *const x = &td->mb;
3416 MACROBLOCKD *const xd = &x->e_mbd;
3417 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
3418 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003419 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003420 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003421 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
Urvang Joshi52648442016-10-13 17:27:51 -07003422 const int *partition_cost = cpi->partition_cost[pl];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003423 int tmp_partition_cost[PARTITION_TYPES];
3424 BLOCK_SIZE subsize;
3425 RD_COST this_rdc, sum_rdc, best_rdc;
3426#if CONFIG_SUPERTX
3427 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3428 int abort_flag;
3429 const int supertx_allowed = !frame_is_intra_only(cm) &&
3430 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3431 !xd->lossless[0];
3432#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003433 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3434 int do_square_split = bsize_at_least_8x8;
3435 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003436#if CONFIG_EXT_PARTITION_TYPES
3437 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3438#endif
3439
3440 // Override skipping rectangular partition operations for edge blocks
3441 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3442 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3443 const int xss = x->e_mbd.plane[1].subsampling_x;
3444 const int yss = x->e_mbd.plane[1].subsampling_y;
3445
3446 BLOCK_SIZE min_size = x->min_partition_size;
3447 BLOCK_SIZE max_size = x->max_partition_size;
3448
3449#if CONFIG_FP_MB_STATS
3450 unsigned int src_diff_var = UINT_MAX;
3451 int none_complexity = 0;
3452#endif
3453
3454 int partition_none_allowed = !force_horz_split && !force_vert_split;
3455 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003456 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003457 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003458 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003459
3460#if CONFIG_PVQ
3461 od_rollback_buffer pre_rdo_buf;
3462#endif
3463
Yaowu Xuc27fc142016-08-22 16:08:15 -07003464 (void)*tp_orig;
3465
3466 if (force_horz_split || force_vert_split) {
3467 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3468
3469 if (!force_vert_split) { // force_horz_split only
3470 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3471 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003472 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003474 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003475 } else if (!force_horz_split) { // force_vert_split only
3476 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3477 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003478 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003479 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003480 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003481 } else { // force_ horz_split && force_vert_split horz_split
3482 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3483 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3484 tmp_partition_cost[PARTITION_SPLIT] = 0;
3485 }
3486
3487 partition_cost = tmp_partition_cost;
3488 }
3489
3490#if CONFIG_VAR_TX
3491#ifndef NDEBUG
3492 // Nothing should rely on the default value of this array (which is just
3493 // leftover from encoding the previous block. Setting it to magic number
3494 // when debugging.
3495 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3496#endif // NDEBUG
3497#endif // CONFIG_VAR_TX
3498
3499 assert(num_8x8_blocks_wide_lookup[bsize] ==
3500 num_8x8_blocks_high_lookup[bsize]);
3501
Yaowu Xuf883b422016-08-30 14:01:10 -07003502 av1_rd_cost_init(&this_rdc);
3503 av1_rd_cost_init(&sum_rdc);
3504 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003505 best_rdc.rdcost = best_rd;
3506
3507 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3508
3509 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003510 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003511
3512 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003513 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003514 ((pc_tree->index == 0 || pc_tree->index == 3) +
3515 get_chessboard_index(cm->current_video_frame)) &
3516 0x1;
3517
3518 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3519 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3520 }
3521
3522 // Determine partition types in search according to the speed features.
3523 // The threshold set here has to be of square block size.
3524 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003525 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3526 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3527 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3528 partition_none_allowed &= no_partition_allowed;
3529 partition_horz_allowed &= partition_allowed || force_horz_split;
3530 partition_vert_allowed &= partition_allowed || force_vert_split;
3531 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 }
3533 if (cpi->sf.use_square_partition_only) {
3534 partition_horz_allowed &= force_horz_split;
3535 partition_vert_allowed &= force_vert_split;
3536 }
3537
3538#if CONFIG_VAR_TX
3539 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3540 xd->left_txfm_context =
3541 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3542#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003543#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003544 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003545#else
3546 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3547#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003548
3549#if CONFIG_FP_MB_STATS
3550 if (cpi->use_fp_mb_stats) {
3551 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3552 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3553 mi_col, bsize);
3554 }
3555#endif
3556
3557#if CONFIG_FP_MB_STATS
3558 // Decide whether we shall split directly and skip searching NONE by using
3559 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003560 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003561 partition_none_allowed && src_diff_var > 4 &&
3562 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3563 int mb_row = mi_row >> 1;
3564 int mb_col = mi_col >> 1;
3565 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003566 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003567 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003568 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569 int r, c;
3570
3571 // compute a complexity measure, basically measure inconsistency of motion
3572 // vectors obtained from the first pass in the current block
3573 for (r = mb_row; r < mb_row_end; r++) {
3574 for (c = mb_col; c < mb_col_end; c++) {
3575 const int mb_index = r * cm->mb_cols + c;
3576
3577 MOTION_DIRECTION this_mv;
3578 MOTION_DIRECTION right_mv;
3579 MOTION_DIRECTION bottom_mv;
3580
3581 this_mv =
3582 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3583
3584 // to its right
3585 if (c != mb_col_end - 1) {
3586 right_mv = get_motion_direction_fp(
3587 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3588 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3589 }
3590
3591 // to its bottom
3592 if (r != mb_row_end - 1) {
3593 bottom_mv = get_motion_direction_fp(
3594 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3595 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3596 }
3597
3598 // do not count its left and top neighbors to avoid double counting
3599 }
3600 }
3601
3602 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3603 partition_none_allowed = 0;
3604 }
3605 }
3606#endif
3607
3608 // PARTITION_NONE
3609 if (partition_none_allowed) {
3610 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3611#if CONFIG_SUPERTX
3612 &this_rate_nocoef,
3613#endif
3614#if CONFIG_EXT_PARTITION_TYPES
3615 PARTITION_NONE,
3616#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003617 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003619 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 this_rdc.rate += partition_cost[PARTITION_NONE];
3621 this_rdc.rdcost =
3622 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3623#if CONFIG_SUPERTX
3624 this_rate_nocoef += partition_cost[PARTITION_NONE];
3625#endif
3626 }
3627
3628 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003629 // Adjust dist breakout threshold according to the partition size.
3630 const int64_t dist_breakout_thr =
3631 cpi->sf.partition_search_breakout_dist_thr >>
3632 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3633 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3634 const int rate_breakout_thr =
3635 cpi->sf.partition_search_breakout_rate_thr *
3636 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003637
3638 best_rdc = this_rdc;
3639#if CONFIG_SUPERTX
3640 best_rate_nocoef = this_rate_nocoef;
3641 assert(best_rate_nocoef >= 0);
3642#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003643 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003644
3645 // If all y, u, v transform blocks in this partition are skippable, and
3646 // the dist & rate are within the thresholds, the partition search is
3647 // terminated for current branch of the partition search tree.
3648 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3649 // early termination at that speed.
3650 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003651 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003652 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003653 do_square_split = 0;
3654 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003655 }
3656
3657#if CONFIG_FP_MB_STATS
3658 // Check if every 16x16 first pass block statistics has zero
3659 // motion and the corresponding first pass residue is small enough.
3660 // If that is the case, check the difference variance between the
3661 // current frame and the last frame. If the variance is small enough,
3662 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003663 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003664 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3665 int mb_row = mi_row >> 1;
3666 int mb_col = mi_col >> 1;
3667 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003668 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003669 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003670 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003671 int r, c;
3672
3673 int skip = 1;
3674 for (r = mb_row; r < mb_row_end; r++) {
3675 for (c = mb_col; c < mb_col_end; c++) {
3676 const int mb_index = r * cm->mb_cols + c;
3677 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3678 FPMB_MOTION_ZERO_MASK) ||
3679 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3680 FPMB_ERROR_SMALL_MASK)) {
3681 skip = 0;
3682 break;
3683 }
3684 }
3685 if (skip == 0) {
3686 break;
3687 }
3688 }
3689 if (skip) {
3690 if (src_diff_var == UINT_MAX) {
3691 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3692 src_diff_var = get_sby_perpixel_diff_variance(
3693 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3694 }
3695 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003696 do_square_split = 0;
3697 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003698 }
3699 }
3700 }
3701#endif
3702 }
3703 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003704#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003705 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003706#else
3707 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3708#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003709 }
3710
3711 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003712 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003713
3714 // PARTITION_SPLIT
3715 // TODO(jingning): use the motion vectors given by the above search as
3716 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003717 if (do_square_split) {
3718 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 subsize = get_subsize(bsize, PARTITION_SPLIT);
3720 if (bsize == BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003721#if CONFIG_DUAL_FILTER
3722 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3723 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003724 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003725#else
3726 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3727 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003728 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003729#endif
3730#if CONFIG_SUPERTX
3731 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3732 &sum_rate_nocoef,
3733#if CONFIG_EXT_PARTITION_TYPES
3734 PARTITION_SPLIT,
3735#endif
3736 subsize, pc_tree->leaf_split[0], INT64_MAX);
3737#else
3738 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3739#if CONFIG_EXT_PARTITION_TYPES
3740 PARTITION_SPLIT,
3741#endif
3742 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3743#endif // CONFIG_SUPERTX
3744 if (sum_rdc.rate == INT_MAX) {
3745 sum_rdc.rdcost = INT64_MAX;
3746#if CONFIG_SUPERTX
3747 sum_rate_nocoef = INT_MAX;
3748#endif
3749 }
3750#if CONFIG_SUPERTX
3751 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3752 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3753 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3754
3755 pc_tree->partitioning = PARTITION_SPLIT;
3756
clang-format67948d32016-09-07 22:40:40 -07003757 sum_rdc.rate +=
3758 av1_cost_bit(cm->fc->supertx_prob
3759 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3760 [supertx_size],
3761 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003762 sum_rdc.rdcost =
3763 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3764
3765 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3766 TX_TYPE best_tx = DCT_DCT;
3767 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3768
3769 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3770
3771 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3772 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3773
Yaowu Xuf883b422016-08-30 14:01:10 -07003774 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003775 cm->fc->supertx_prob
3776 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3777 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003778 1);
3779 tmp_rdc.rdcost =
3780 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3781 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3782 sum_rdc = tmp_rdc;
3783 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3784 supertx_size, pc_tree);
3785 }
3786 }
3787
3788 pc_tree->partitioning = best_partition;
3789 }
3790#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003791 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003792 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07003793 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003794#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003795 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003796#else
Urvang Joshi52648442016-10-13 17:27:51 -07003797 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003798#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003799 const int x_idx = (idx & 1) * mi_step;
3800 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003801
3802 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3803 continue;
3804
Urvang Joshi454280d2016-10-14 16:51:44 -07003805 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003806
Urvang Joshi52648442016-10-13 17:27:51 -07003807 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003808#if CONFIG_SUPERTX
3809 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3810 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07003811 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003812#else
Urvang Joshi52648442016-10-13 17:27:51 -07003813 rd_pick_partition(
3814 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
3815 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003816#endif // CONFIG_SUPERTX
3817
3818 if (this_rdc.rate == INT_MAX) {
3819 sum_rdc.rdcost = INT64_MAX;
3820#if CONFIG_SUPERTX
3821 sum_rate_nocoef = INT_MAX;
3822#endif // CONFIG_SUPERTX
3823 break;
3824 } else {
3825 sum_rdc.rate += this_rdc.rate;
3826 sum_rdc.dist += this_rdc.dist;
3827 sum_rdc.rdcost += this_rdc.rdcost;
3828#if CONFIG_SUPERTX
3829 sum_rate_nocoef += this_rate_nocoef;
3830#endif // CONFIG_SUPERTX
3831 }
3832 }
Urvang Joshi52648442016-10-13 17:27:51 -07003833 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003834#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003835 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003836 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3837 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3838
3839 pc_tree->partitioning = PARTITION_SPLIT;
3840
clang-format67948d32016-09-07 22:40:40 -07003841 sum_rdc.rate +=
3842 av1_cost_bit(cm->fc->supertx_prob
3843 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3844 [supertx_size],
3845 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003846 sum_rdc.rdcost =
3847 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3848
3849 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3850 TX_TYPE best_tx = DCT_DCT;
3851 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3852
3853 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3854
3855 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3856 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3857
Yaowu Xuf883b422016-08-30 14:01:10 -07003858 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003859 cm->fc->supertx_prob
3860 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3861 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003862 1);
3863 tmp_rdc.rdcost =
3864 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3865 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3866 sum_rdc = tmp_rdc;
3867 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3868 supertx_size, pc_tree);
3869 }
3870 }
3871
3872 pc_tree->partitioning = best_partition;
3873 }
3874#endif // CONFIG_SUPERTX
3875 }
3876
Urvang Joshi52648442016-10-13 17:27:51 -07003877 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3879 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3880#if CONFIG_SUPERTX
3881 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3882#endif // CONFIG_SUPERTX
3883
3884 if (sum_rdc.rdcost < best_rdc.rdcost) {
3885 best_rdc = sum_rdc;
3886#if CONFIG_SUPERTX
3887 best_rate_nocoef = sum_rate_nocoef;
3888 assert(best_rate_nocoef >= 0);
3889#endif // CONFIG_SUPERTX
3890 pc_tree->partitioning = PARTITION_SPLIT;
3891 }
Urvang Joshi52648442016-10-13 17:27:51 -07003892 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003893 // skip rectangular partition test when larger block size
3894 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07003895 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003896 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003897#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003899#else
3900 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3901#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003902 } // if (do_split)
3903
3904 // PARTITION_HORZ
3905 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003906 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003907 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07003908 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003909#if CONFIG_DUAL_FILTER
3910 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3911 partition_none_allowed)
3912 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003913 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003914#else
3915 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3916 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003917 pc_tree->horizontal[0].pred_interp_filter =
3918 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919#endif
3920 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3921#if CONFIG_SUPERTX
3922 &sum_rate_nocoef,
3923#endif // CONFIG_SUPERTX
3924#if CONFIG_EXT_PARTITION_TYPES
3925 PARTITION_HORZ,
3926#endif
3927 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3928
3929#if CONFIG_SUPERTX
3930 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3931 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3932 if (sum_rdc.rdcost < INT64_MAX &&
3933#else
3934 if (sum_rdc.rdcost < best_rdc.rdcost &&
3935#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003936 !force_horz_split && bsize > BLOCK_8X8) {
Urvang Joshi454280d2016-10-14 16:51:44 -07003937 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
3938 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003939 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07003940 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003941
Urvang Joshi454280d2016-10-14 16:51:44 -07003942 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003943
3944#if CONFIG_DUAL_FILTER
3945 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3946 partition_none_allowed)
3947 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003948 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003949#else
3950 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3951 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003952 pc_tree->horizontal[1].pred_interp_filter =
3953 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954#endif
3955#if CONFIG_SUPERTX
3956 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3957 &this_rate_nocoef,
3958#if CONFIG_EXT_PARTITION_TYPES
3959 PARTITION_HORZ,
3960#endif
3961 subsize, &pc_tree->horizontal[1], INT64_MAX);
3962#else
3963 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3964#if CONFIG_EXT_PARTITION_TYPES
3965 PARTITION_HORZ,
3966#endif
3967 subsize, &pc_tree->horizontal[1],
3968 best_rdc.rdcost - sum_rdc.rdcost);
3969#endif // CONFIG_SUPERTX
3970 if (this_rdc.rate == INT_MAX) {
3971 sum_rdc.rdcost = INT64_MAX;
3972#if CONFIG_SUPERTX
3973 sum_rate_nocoef = INT_MAX;
3974#endif // CONFIG_SUPERTX
3975 } else {
3976 sum_rdc.rate += this_rdc.rate;
3977 sum_rdc.dist += this_rdc.dist;
3978 sum_rdc.rdcost += this_rdc.rdcost;
3979#if CONFIG_SUPERTX
3980 sum_rate_nocoef += this_rate_nocoef;
3981#endif // CONFIG_SUPERTX
3982 }
3983 }
3984
3985#if CONFIG_SUPERTX
3986 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3987 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3988 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3989
3990 pc_tree->partitioning = PARTITION_HORZ;
3991
Yaowu Xuf883b422016-08-30 14:01:10 -07003992 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3994 [supertx_size],
3995 0);
3996 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3997
3998 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3999 TX_TYPE best_tx = DCT_DCT;
4000 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4001
4002 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4003
4004 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4005 &tmp_rdc.dist, &best_tx, pc_tree);
4006
Yaowu Xuf883b422016-08-30 14:01:10 -07004007 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004008 cm->fc
4009 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4010 [supertx_size],
4011 1);
4012 tmp_rdc.rdcost =
4013 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4014 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4015 sum_rdc = tmp_rdc;
4016 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4017 supertx_size, pc_tree);
4018 }
4019 }
4020
4021 pc_tree->partitioning = best_partition;
4022 }
4023#endif // CONFIG_SUPERTX
4024
4025 if (sum_rdc.rdcost < best_rdc.rdcost) {
4026 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4027 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4028#if CONFIG_SUPERTX
4029 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4030#endif // CONFIG_SUPERTX
4031 if (sum_rdc.rdcost < best_rdc.rdcost) {
4032 best_rdc = sum_rdc;
4033#if CONFIG_SUPERTX
4034 best_rate_nocoef = sum_rate_nocoef;
4035 assert(best_rate_nocoef >= 0);
4036#endif // CONFIG_SUPERTX
4037 pc_tree->partitioning = PARTITION_HORZ;
4038 }
4039 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004040#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004041 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004042#else
4043 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4044#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045 }
4046
4047 // PARTITION_VERT
4048 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004049 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004050 subsize = get_subsize(bsize, PARTITION_VERT);
4051
Urvang Joshi454280d2016-10-14 16:51:44 -07004052 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004053
4054#if CONFIG_DUAL_FILTER
4055 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4056 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004057 pc_tree->vertical[0].pred_interp_filter =
4058 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059#else
4060 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4061 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004062 pc_tree->vertical[0].pred_interp_filter =
4063 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064#endif
4065 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4066#if CONFIG_SUPERTX
4067 &sum_rate_nocoef,
4068#endif // CONFIG_SUPERTX
4069#if CONFIG_EXT_PARTITION_TYPES
4070 PARTITION_VERT,
4071#endif
4072 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4073#if CONFIG_SUPERTX
4074 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
4075 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
4076 if (sum_rdc.rdcost < INT64_MAX &&
4077#else
4078 if (sum_rdc.rdcost < best_rdc.rdcost &&
4079#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004080 !force_vert_split && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004081 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4082 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4083 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004084
Urvang Joshi454280d2016-10-14 16:51:44 -07004085 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004086
4087#if CONFIG_DUAL_FILTER
4088 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4089 partition_none_allowed)
4090 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004091 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092#else
4093 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4094 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004095 pc_tree->vertical[1].pred_interp_filter =
4096 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097#endif
4098#if CONFIG_SUPERTX
4099 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4100 &this_rate_nocoef,
4101#if CONFIG_EXT_PARTITION_TYPES
4102 PARTITION_VERT,
4103#endif
4104 subsize, &pc_tree->vertical[1],
4105 INT64_MAX - sum_rdc.rdcost);
4106#else
4107 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4108#if CONFIG_EXT_PARTITION_TYPES
4109 PARTITION_VERT,
4110#endif
4111 subsize, &pc_tree->vertical[1],
4112 best_rdc.rdcost - sum_rdc.rdcost);
4113#endif // CONFIG_SUPERTX
4114 if (this_rdc.rate == INT_MAX) {
4115 sum_rdc.rdcost = INT64_MAX;
4116#if CONFIG_SUPERTX
4117 sum_rate_nocoef = INT_MAX;
4118#endif // CONFIG_SUPERTX
4119 } else {
4120 sum_rdc.rate += this_rdc.rate;
4121 sum_rdc.dist += this_rdc.dist;
4122 sum_rdc.rdcost += this_rdc.rdcost;
4123#if CONFIG_SUPERTX
4124 sum_rate_nocoef += this_rate_nocoef;
4125#endif // CONFIG_SUPERTX
4126 }
4127 }
4128#if CONFIG_SUPERTX
4129 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4130 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4131 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4132
4133 pc_tree->partitioning = PARTITION_VERT;
4134
Yaowu Xuf883b422016-08-30 14:01:10 -07004135 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004136 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4137 [supertx_size],
4138 0);
4139 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4140
4141 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4142 TX_TYPE best_tx = DCT_DCT;
4143 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4144
4145 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4146
4147 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4148 &tmp_rdc.dist, &best_tx, pc_tree);
4149
Yaowu Xuf883b422016-08-30 14:01:10 -07004150 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151 cm->fc
4152 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4153 [supertx_size],
4154 1);
4155 tmp_rdc.rdcost =
4156 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4157 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4158 sum_rdc = tmp_rdc;
4159 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4160 supertx_size, pc_tree);
4161 }
4162 }
4163
4164 pc_tree->partitioning = best_partition;
4165 }
4166#endif // CONFIG_SUPERTX
4167
4168 if (sum_rdc.rdcost < best_rdc.rdcost) {
4169 sum_rdc.rate += partition_cost[PARTITION_VERT];
4170 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4171#if CONFIG_SUPERTX
4172 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4173#endif // CONFIG_SUPERTX
4174 if (sum_rdc.rdcost < best_rdc.rdcost) {
4175 best_rdc = sum_rdc;
4176#if CONFIG_SUPERTX
4177 best_rate_nocoef = sum_rate_nocoef;
4178 assert(best_rate_nocoef >= 0);
4179#endif // CONFIG_SUPERTX
4180 pc_tree->partitioning = PARTITION_VERT;
4181 }
4182 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004183#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004184 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004185#else
4186 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4187#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004188 }
4189
4190#if CONFIG_EXT_PARTITION_TYPES
4191 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004192 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004193 partition_none_allowed) {
4194 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4195 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004196 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197 PARTITION_HORZ_A,
4198#if CONFIG_SUPERTX
4199 best_rd, &best_rate_nocoef, &x_ctx,
4200#endif
4201 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4202 mi_row + mi_step, mi_col, subsize);
4203 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4204 }
4205 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004206 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004207 partition_none_allowed) {
4208 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4209 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004210 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004211 PARTITION_HORZ_B,
4212#if CONFIG_SUPERTX
4213 best_rd, &best_rate_nocoef, &x_ctx,
4214#endif
4215 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4216 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4217 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4218 }
4219 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004220 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004221 partition_none_allowed) {
4222 subsize = get_subsize(bsize, PARTITION_VERT_A);
4223 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004224 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225 PARTITION_VERT_A,
4226#if CONFIG_SUPERTX
4227 best_rd, &best_rate_nocoef, &x_ctx,
4228#endif
4229 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4230 mi_row, mi_col + mi_step, subsize);
4231 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4232 }
4233 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004234 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004235 partition_none_allowed) {
4236 subsize = get_subsize(bsize, PARTITION_VERT_B);
4237 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004238 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004239 PARTITION_VERT_B,
4240#if CONFIG_SUPERTX
4241 best_rd, &best_rate_nocoef, &x_ctx,
4242#endif
4243 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4244 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4245 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4246 }
4247#endif // CONFIG_EXT_PARTITION_TYPES
4248
4249 // TODO(jbb): This code added so that we avoid static analysis
4250 // warning related to the fact that best_rd isn't used after this
4251 // point. This code should be refactored so that the duplicate
4252 // checks occur in some sub function and thus are used...
4253 (void)best_rd;
4254 *rd_cost = best_rdc;
4255#if CONFIG_SUPERTX
4256 *rate_nocoef = best_rate_nocoef;
4257#endif // CONFIG_SUPERTX
4258
4259 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4260 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004261 if (bsize == cm->sb_size) {
4262 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4263 pc_tree, NULL);
4264 } else {
4265 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4266 pc_tree, NULL);
4267 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004268 }
4269
4270 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004271#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004272 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004273#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004274 assert(best_rdc.rate < INT_MAX);
4275 assert(best_rdc.dist < INT64_MAX);
4276 } else {
4277 assert(tp_orig == *tp);
4278 }
4279}
4280
Yaowu Xuf883b422016-08-30 14:01:10 -07004281static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 TileDataEnc *tile_data, int mi_row,
4283 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004284 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004285 const TileInfo *const tile_info = &tile_data->tile_info;
4286 MACROBLOCK *const x = &td->mb;
4287 MACROBLOCKD *const xd = &x->e_mbd;
4288 SPEED_FEATURES *const sf = &cpi->sf;
4289 int mi_col;
4290#if CONFIG_EXT_PARTITION
4291 const int leaf_nodes = 256;
4292#else
4293 const int leaf_nodes = 64;
4294#endif // CONFIG_EXT_PARTITION
4295
4296 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004297 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004298
Thomas Daviesf6936102016-09-05 16:51:31 +01004299#if CONFIG_DELTA_Q
4300 // Reset delta for every tile
4301 if (cm->delta_q_present_flag)
4302 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4303#endif
4304
Yaowu Xuc27fc142016-08-22 16:08:15 -07004305 // Code each SB in the row
4306 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4307 mi_col += cm->mib_size) {
4308 const struct segmentation *const seg = &cm->seg;
4309 int dummy_rate;
4310 int64_t dummy_dist;
4311 RD_COST dummy_rdc;
4312#if CONFIG_SUPERTX
4313 int dummy_rate_nocoef;
4314#endif // CONFIG_SUPERTX
4315 int i;
4316 int seg_skip = 0;
4317
4318 const int idx_str = cm->mi_stride * mi_row + mi_col;
4319 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4320 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4321
4322 if (sf->adaptive_pred_interp_filter) {
4323 for (i = 0; i < leaf_nodes; ++i)
4324 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4325
4326 for (i = 0; i < leaf_nodes; ++i) {
4327 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4328 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4329 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4330 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4331 }
4332 }
4333
Yaowu Xuf883b422016-08-30 14:01:10 -07004334 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004335 pc_root->index = 0;
4336
4337 if (seg->enabled) {
4338 const uint8_t *const map =
4339 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4340 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4341 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4342 }
4343
Arild Fuldseth07441162016-08-15 15:07:52 +02004344#if CONFIG_DELTA_Q
4345 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004346 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004347 int sb_row = mi_row >> 3;
4348 int sb_col = mi_col >> 3;
4349 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4350 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004351
4352 // Ensure divisibility of delta_qindex by delta_q_res
4353 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4354 int qmask = ~(cm->delta_q_res - 1);
4355 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4356 cm->delta_q_res, 256 - cm->delta_q_res);
4357 current_qindex =
4358 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4359 cm->base_qindex;
4360
Arild Fuldseth07441162016-08-15 15:07:52 +02004361 xd->delta_qindex = current_qindex - cm->base_qindex;
4362 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4363 xd->mi[0]->mbmi.current_q_index = current_qindex;
4364 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004365 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004366 }
4367#endif
4368
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369 x->source_variance = UINT_MAX;
4370 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4371 BLOCK_SIZE bsize;
4372 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4373 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4374 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4375 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4376 &dummy_rate, &dummy_dist,
4377#if CONFIG_SUPERTX
4378 &dummy_rate_nocoef,
4379#endif // CONFIG_SUPERTX
4380 1, pc_root);
4381 } else if (cpi->partition_search_skippable_frame) {
4382 BLOCK_SIZE bsize;
4383 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4384 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4385 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4386 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4387 &dummy_rate, &dummy_dist,
4388#if CONFIG_SUPERTX
4389 &dummy_rate_nocoef,
4390#endif // CONFIG_SUPERTX
4391 1, pc_root);
4392 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4393 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4394 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4395 &dummy_rate, &dummy_dist,
4396#if CONFIG_SUPERTX
4397 &dummy_rate_nocoef,
4398#endif // CONFIG_SUPERTX
4399 1, pc_root);
4400 } else {
4401 // If required set upper and lower partition size limits
4402 if (sf->auto_min_max_partition_size) {
4403 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4404 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4405 &x->min_partition_size, &x->max_partition_size);
4406 }
4407 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4408 &dummy_rdc,
4409#if CONFIG_SUPERTX
4410 &dummy_rate_nocoef,
4411#endif // CONFIG_SUPERTX
4412 INT64_MAX, pc_root);
4413 }
4414 }
4415#if CONFIG_ENTROPY
4416 if (cm->do_subframe_update &&
4417 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4418 if ((mi_row + MI_SIZE) %
4419 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004420 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004421 0 &&
4422 mi_row + MI_SIZE < cm->mi_rows &&
4423 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4424 TX_SIZE t;
4425 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4426
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08004427 for (t = TX_4X4; t < TX_SIZES; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004428 av1_full_to_model_counts(cpi->td.counts->coef[t],
4429 cpi->td.rd_counts.coef_counts[t]);
4430 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004431 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004432 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4433 cm->fc->coef_probs);
4434 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4435 cpi->td.rd_counts.coef_counts);
4436 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4437 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004438 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004439 }
4440 }
4441#endif // CONFIG_ENTROPY
4442}
4443
Yaowu Xuf883b422016-08-30 14:01:10 -07004444static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004445 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004446 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004447 MACROBLOCKD *const xd = &x->e_mbd;
4448
4449 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004450 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004451
Yaowu Xuf883b422016-08-30 14:01:10 -07004452 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004453}
4454
Yaowu Xuf883b422016-08-30 14:01:10 -07004455static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004456 const int ref_flags = cpi->ref_frame_flags;
4457
4458 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4459 return 0;
4460 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004461 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004462#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004463 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4464 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004465#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004466 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004467 }
4468}
4469
4470#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004471static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004472 int mi_row, mi_col;
4473 const int mis = cm->mi_stride;
4474 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4475
4476 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4477 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4478 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4479 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4480 }
4481 }
4482}
4483#endif
4484
Yaowu Xuf883b422016-08-30 14:01:10 -07004485static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004486 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4487#if CONFIG_EXT_REFS
4488 // We will not update the golden frame with an internal overlay frame
4489 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4490 cpi->rc.is_src_frame_ext_arf)
4491#else
4492 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4493#endif
4494 return ALTREF_FRAME;
4495 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4496 return GOLDEN_FRAME;
4497 else
4498 // TODO(zoeliu): To investigate whether a frame_type other than
4499 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4500 return LAST_FRAME;
4501}
4502
Yaowu Xuf883b422016-08-30 14:01:10 -07004503static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004504 if (xd->lossless[0]) return ONLY_4X4;
4505 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004506 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004507 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4508 cpi->sf.tx_size_search_method == USE_TX_8X8)
4509 return TX_MODE_SELECT;
4510 else
4511 return cpi->common.tx_mode;
4512}
4513
Yaowu Xuf883b422016-08-30 14:01:10 -07004514void av1_init_tile_data(AV1_COMP *cpi) {
4515 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516 const int tile_cols = cm->tile_cols;
4517 const int tile_rows = cm->tile_rows;
4518 int tile_col, tile_row;
4519 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4520 unsigned int tile_tok = 0;
4521
4522 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004523 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4524 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004525 sizeof(*cpi->tile_data)));
4526 cpi->allocated_tiles = tile_cols * tile_rows;
4527
4528 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4529 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4530 TileDataEnc *const tile_data =
4531 &cpi->tile_data[tile_row * tile_cols + tile_col];
4532 int i, j;
4533 for (i = 0; i < BLOCK_SIZES; ++i) {
4534 for (j = 0; j < MAX_MODES; ++j) {
4535 tile_data->thresh_freq_fact[i][j] = 32;
4536 tile_data->mode_map[i][j] = j;
4537 }
4538 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004539#if CONFIG_PVQ
4540 // This will be dynamically increased as more pvq block is encoded.
4541 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004542 CHECK_MEM_ERROR(
4543 cm, tile_data->pvq_q.buf,
4544 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004545 tile_data->pvq_q.curr_pos = 0;
4546#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004547 }
4548 }
4549
4550 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4551 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4552 TileInfo *const tile_info =
4553 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004554 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004555
4556 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4557 pre_tok = cpi->tile_tok[tile_row][tile_col];
4558 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004559#if CONFIG_PVQ
4560 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4561#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004562 }
4563 }
4564}
4565
Yaowu Xuf883b422016-08-30 14:01:10 -07004566void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4567 int tile_col) {
4568 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004569 TileDataEnc *const this_tile =
4570 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4571 const TileInfo *const tile_info = &this_tile->tile_info;
4572 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4573 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004574#if CONFIG_PVQ
4575 od_adapt_ctx *adapt;
4576#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577
Yaowu Xuf883b422016-08-30 14:01:10 -07004578 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004579
4580 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004581 this_tile->m_search_count = 0; // Count of motion search hits.
4582 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4583 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4584 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004585
Yushin Cho77bba8d2016-11-04 16:36:56 -07004586#if CONFIG_PVQ
4587 td->mb.pvq_q = &this_tile->pvq_q;
4588
4589 // TODO(yushin)
4590 // If activity masking is enabled, change below to OD_HVS_QM
4591 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4592 {
4593 // FIXME: Multiple segments support
4594 int segment_id = 0;
4595 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4596 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4597 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4598 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4599 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4600 td->mb.daala_enc.pvq_norm_lambda =
4601 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4602 td->mb.daala_enc.pvq_norm_lambda_dc =
4603 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4604 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4605 }
4606 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4607 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
4608 od_ec_enc_init(&td->mb.daala_enc.ec, 65025);
4609
4610 adapt = &td->mb.daala_enc.state.adapt;
4611 od_ec_enc_reset(&td->mb.daala_enc.ec);
4612 od_adapt_ctx_reset(adapt, 0);
4613#endif
4614
Yaowu Xuc27fc142016-08-22 16:08:15 -07004615 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4616 mi_row += cm->mib_size) {
4617 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4618 }
4619
4620 cpi->tok_count[tile_row][tile_col] =
4621 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4622 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004623#if CONFIG_PVQ
4624 od_ec_enc_clear(&td->mb.daala_enc.ec);
4625
4626 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4627 // rewind current position so that bitstream can be written
4628 // from the 1st pvq block
4629 td->mb.pvq_q->curr_pos = 0;
4630
4631 td->mb.pvq_q = NULL;
4632#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004633}
4634
Yaowu Xuf883b422016-08-30 14:01:10 -07004635static void encode_tiles(AV1_COMP *cpi) {
4636 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004637 int tile_col, tile_row;
4638
Yaowu Xuf883b422016-08-30 14:01:10 -07004639 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004640
4641 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4642 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004643 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644}
4645
4646#if CONFIG_FP_MB_STATS
4647static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004648 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4650 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4651
4652 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4653
4654 *this_frame_mb_stats = mb_stats_in;
4655
4656 return 1;
4657}
4658#endif
4659
4660#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004661#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004662
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004663// Border over which to compute the global motion
4664#define ERRORADV_BORDER 0
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004665
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004666static const double gm_advantage_thresh[TRANS_TYPES] = {
4667 1.00, // Identity (not used)
4668 0.85, // Translation
4669 0.75, // Rot zoom
4670 0.65, // Affine
4671 0.50, // Homography
4672};
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004673
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004674static void convert_to_params(const double *params, int32_t *model) {
4675 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004676 int alpha_present = 0;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004677 model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4678 model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4679 model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004680 GM_TRANS_DECODE_FACTOR;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004681 model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004682 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004683
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004684 for (i = 2; i < 6; ++i) {
4685 const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004686 model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004687 model[i] =
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004688 (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
4689 alpha_present |= (model[i] != 0);
4690 model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
4691 }
4692 for (; i < 8; ++i) {
4693 model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
4694 model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
4695 GM_ROW3HOMO_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004696 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004697 }
4698
4699 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004700 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4701 model[0] = 0;
4702 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004703 }
4704 }
4705}
4706
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004707static void convert_model_to_params(const double *params,
David Barkercf3d0b02016-11-10 10:14:49 +00004708 WarpedMotionParams *model) {
4709 convert_to_params(params, model->wmmat);
4710 model->wmtype = get_gmtype(model);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004711}
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004712
4713// Adds some offset to a global motion parameter and handles
4714// all of the necessary precision shifts, clamping, and
4715// zero-centering.
4716static int32_t add_param_offset(int param_index, int32_t param_value,
4717 int32_t offset) {
4718 const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
4719 GM_ROW3HOMO_PREC_DIFF };
4720 const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
4721 // type of param: 0 - translation, 1 - affine, 2 - homography
4722 const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
4723 const int is_one_centered = (param_index == 2 || param_index == 5);
4724
4725 // Make parameter zero-centered and offset the shift that was done to make
4726 // it compatible with the warped model
4727 param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
4728 scale_vals[param_type];
4729 // Add desired offset to the rescaled/zero-centered parameter
4730 param_value += offset;
4731 // Clamp the parameter so it does not overflow the number of bits allotted
4732 // to it in the bitstream
4733 param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
4734 clamp_vals[param_type]);
4735 // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
4736 // with the warped motion library
4737 param_value *= (1 << scale_vals[param_type]);
4738
4739 // Undo the zero-centering step if necessary
4740 return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
4741}
4742
4743static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
4744 switch (wmtype) {
4745 case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
4746 case TRANSLATION:
4747 wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
4748 wm->wmmat[3] = 0;
4749 case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
4750 case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
4751 case HOMOGRAPHY: break;
4752 default: assert(0);
4753 }
4754 wm->wmtype = wmtype;
4755}
4756
4757static double refine_integerized_param(WarpedMotionParams *wm,
4758 TransformationType wmtype,
4759#if CONFIG_AOM_HIGHBITDEPTH
4760 int use_hbd, int bd,
4761#endif // CONFIG_AOM_HIGHBITDEPTH
4762 uint8_t *ref, int r_width, int r_height,
4763 int r_stride, uint8_t *dst, int d_width,
4764 int d_height, int d_stride,
4765 int n_refinements) {
4766 const int border = ERRORADV_BORDER;
4767 int i = 0, p;
4768 int n_params = n_trans_model_params[wmtype];
4769 int32_t *param_mat = wm->wmmat;
4770 double step_error;
4771 int32_t step;
4772 int32_t *param;
4773 int32_t curr_param;
4774 int32_t best_param;
4775 double best_error;
4776
4777 force_wmtype(wm, wmtype);
4778 best_error = av1_warp_erroradv(wm,
4779#if CONFIG_AOM_HIGHBITDEPTH
4780 use_hbd, bd,
4781#endif // CONFIG_AOM_HIGHBITDEPTH
4782 ref, r_width, r_height, r_stride,
4783 dst + border * d_stride + border, border,
4784 border, d_width - 2 * border,
4785 d_height - 2 * border, d_stride, 0, 0, 16, 16);
4786 for (p = 0; p < n_params; ++p) {
4787 param = param_mat + p;
4788 step = 1 << (n_refinements + 1);
4789 curr_param = *param;
4790 best_param = curr_param;
4791 for (i = 0; i < n_refinements; i++) {
4792 // look to the left
4793 *param = add_param_offset(p, curr_param, -step);
4794 step_error = av1_warp_erroradv(
4795 wm,
4796#if CONFIG_AOM_HIGHBITDEPTH
4797 use_hbd, bd,
4798#endif // CONFIG_AOM_HIGHBITDEPTH
4799 ref, r_width, r_height, r_stride, dst + border * d_stride + border,
4800 border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
4801 0, 0, 16, 16);
4802 if (step_error < best_error) {
4803 step >>= 1;
4804 best_error = step_error;
4805 best_param = *param;
4806 curr_param = best_param;
4807 continue;
4808 }
4809
4810 // look to the right
4811 *param = add_param_offset(p, curr_param, step);
4812 step_error = av1_warp_erroradv(
4813 wm,
4814#if CONFIG_AOM_HIGHBITDEPTH
4815 use_hbd, bd,
4816#endif // CONFIG_AOM_HIGHBITDEPTH
4817 ref, r_width, r_height, r_stride, dst + border * d_stride + border,
4818 border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
4819 0, 0, 16, 16);
4820 if (step_error < best_error) {
4821 step >>= 1;
4822 best_error = step_error;
4823 best_param = *param;
4824 curr_param = best_param;
4825 continue;
4826 }
4827
4828 // no improvement found-> means we're either already at a minimum or
4829 // step is too wide
4830 step >>= 1;
4831 }
4832 *param = best_param;
4833 }
4834 force_wmtype(wm, wmtype);
4835 wm->wmtype = get_gmtype(wm);
4836 return best_error;
4837}
Yaowu Xuc27fc142016-08-22 16:08:15 -07004838#endif // CONFIG_GLOBAL_MOTION
4839
Yaowu Xuf883b422016-08-30 14:01:10 -07004840static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004841 ThreadData *const td = &cpi->td;
4842 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004843 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004844 MACROBLOCKD *const xd = &x->e_mbd;
4845 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4846 int i;
4847
Yaowu Xuf883b422016-08-30 14:01:10 -07004848 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4849 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Jingning Han24e0a182016-11-20 22:34:12 -08004850#if CONFIG_REF_MV
Dengca8d24d2016-10-17 14:06:35 +08004851 cm->setup_mi(cm);
4852#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853
4854 xd->mi = cm->mi_grid_visible;
4855 xd->mi[0] = cm->mi;
4856
Yaowu Xuf883b422016-08-30 14:01:10 -07004857 av1_zero(*td->counts);
4858 av1_zero(rdc->coef_counts);
4859 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004860
4861#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004862 av1_zero(cpi->global_motion_used);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004863 if (cpi->common.frame_type == INTER_FRAME && cpi->Source &&
4864 !cpi->global_motion_search_done) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004865 YV12_BUFFER_CONFIG *ref_buf;
4866 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004867 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004868 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4870 ref_buf = get_ref_frame_buffer(cpi, frame);
4871 if (ref_buf) {
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004872 aom_clear_system_state();
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004873 if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
David Barker557ce7b2016-11-16 10:22:24 +00004874 cpi->Source, ref_buf,
4875#if CONFIG_AOM_HIGHBITDEPTH
4876 cpi->common.bit_depth,
4877#endif // CONFIG_AOM_HIGHBITDEPTH
4878 params)) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004879 convert_model_to_params(params, &cm->global_motion[frame]);
David Barkercf3d0b02016-11-10 10:14:49 +00004880 if (cm->global_motion[frame].wmtype != IDENTITY) {
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004881 erroradvantage = refine_integerized_param(
4882 &cm->global_motion[frame], cm->global_motion[frame].wmtype,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004883#if CONFIG_AOM_HIGHBITDEPTH
4884 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4885#endif // CONFIG_AOM_HIGHBITDEPTH
4886 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4887 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4888 cpi->Source->y_height, cpi->Source->y_stride, 3);
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004889 if (erroradvantage >
4890 gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004891 set_default_gmparams(&cm->global_motion[frame]);
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004892 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004893 }
4894 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004895 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004896 }
4897 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004898 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004899 }
4900#endif // CONFIG_GLOBAL_MOTION
4901
4902 for (i = 0; i < MAX_SEGMENTS; ++i) {
4903 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004904 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004905 : cm->base_qindex;
4906 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4907 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4908 }
4909
4910 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4911
4912 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004913 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004914
Yaowu Xuf883b422016-08-30 14:01:10 -07004915 av1_initialize_rd_consts(cpi);
4916 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004917 init_encode_frame_mb_context(cpi);
4918
4919 cm->use_prev_frame_mvs =
4920 !cm->error_resilient_mode && cm->width == cm->last_width &&
4921 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004922
4923#if CONFIG_DELTA_Q
4924 // Fix delta q resolution for the moment
4925 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4926#endif
4927
Yaowu Xuc27fc142016-08-22 16:08:15 -07004928#if CONFIG_EXT_REFS
4929 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4930 // show_exisiting_frame=1, nor can it take a frame not used as
4931 // a reference, it is probable that by the time it is being
4932 // referred to, the frame buffer it originally points to may
4933 // already get expired and have been reassigned to the current
4934 // newly coded frame. Hence, we need to check whether this is
4935 // the case, and if yes, we have 2 choices:
4936 // (1) Simply disable the use of previous frame mvs; or
4937 // (2) Have cm->prev_frame point to one reference frame buffer,
4938 // e.g. LAST_FRAME.
4939 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4940 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4941 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4942 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4943 }
4944#endif // CONFIG_EXT_REFS
4945
4946 // Special case: set prev_mi to NULL when the previous mode info
4947 // context cannot be used.
4948 cm->prev_mi =
4949 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4950
4951#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004952 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004953#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004954 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004955#endif
4956#endif
4957
4958 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4959 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004960 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961
4962 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004963 struct aom_usec_timer emr_timer;
4964 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004965
4966#if CONFIG_FP_MB_STATS
4967 if (cpi->use_fp_mb_stats) {
4968 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4969 &cpi->twopass.this_frame_mb_stats);
4970 }
4971#endif
4972
4973 // If allowed, encoding tiles in parallel with one thread handling one tile.
4974 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4975 // 1 tile rows, as it uses the single above_context et al arrays from
4976 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004977 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4978 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004979 else
4980 encode_tiles(cpi);
4981
Yaowu Xuf883b422016-08-30 14:01:10 -07004982 aom_usec_timer_mark(&emr_timer);
4983 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004984 }
4985
4986#if 0
4987 // Keep record of the total distortion this time around for future use
4988 cpi->last_frame_distortion = cpi->frame_distortion;
4989#endif
4990}
4991
Yaowu Xuf883b422016-08-30 14:01:10 -07004992void av1_encode_frame(AV1_COMP *cpi) {
4993 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004994
4995 // In the longer term the encoder should be generalized to match the
4996 // decoder such that we allow compound where one of the 3 buffers has a
4997 // different sign bias and that buffer is then the fixed ref. However, this
4998 // requires further work in the rd loop. For now the only supported encoder
4999 // side behavior is where the ALT ref buffer has opposite sign bias to
5000 // the other two.
5001 if (!frame_is_intra_only(cm)) {
5002 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5003 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
5004 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5005 cm->ref_frame_sign_bias[LAST_FRAME])) {
5006 cpi->allow_comp_inter_inter = 0;
5007 } else {
5008 cpi->allow_comp_inter_inter = 1;
5009
5010#if CONFIG_EXT_REFS
5011 cm->comp_fwd_ref[0] = LAST_FRAME;
5012 cm->comp_fwd_ref[1] = LAST2_FRAME;
5013 cm->comp_fwd_ref[2] = LAST3_FRAME;
5014 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
5015 cm->comp_bwd_ref[0] = BWDREF_FRAME;
5016 cm->comp_bwd_ref[1] = ALTREF_FRAME;
5017#else
5018 cm->comp_fixed_ref = ALTREF_FRAME;
5019 cm->comp_var_ref[0] = LAST_FRAME;
5020 cm->comp_var_ref[1] = GOLDEN_FRAME;
5021#endif // CONFIG_EXT_REFS
5022 }
5023 } else {
5024 cpi->allow_comp_inter_inter = 0;
5025 }
5026
5027 if (cpi->sf.frame_parameter_update) {
5028 int i;
5029 RD_OPT *const rd_opt = &cpi->rd;
5030 FRAME_COUNTS *counts = cpi->td.counts;
5031 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5032
5033 // This code does a single RD pass over the whole frame assuming
5034 // either compound, single or hybrid prediction as per whatever has
5035 // worked best for that type of frame in the past.
5036 // It also predicts whether another coding mode would have worked
5037 // better than this coding mode. If that is the case, it remembers
5038 // that for subsequent frames.
5039 // It does the same analysis for transform size selection also.
5040 //
5041 // TODO(zoeliu): To investigate whether a frame_type other than
5042 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
5043 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
5044 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
5045 const int is_alt_ref = frame_type == ALTREF_FRAME;
5046
5047 /* prediction (compound, single or hybrid) mode selection */
5048 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5049 cm->reference_mode = SINGLE_REFERENCE;
5050 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
5051 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
5052 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
5053 cm->reference_mode = COMPOUND_REFERENCE;
5054 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
5055 cm->reference_mode = SINGLE_REFERENCE;
5056 else
5057 cm->reference_mode = REFERENCE_MODE_SELECT;
5058
5059#if CONFIG_DUAL_FILTER
5060 cm->interp_filter = SWITCHABLE;
5061#endif
5062
5063 encode_frame_internal(cpi);
5064
5065 for (i = 0; i < REFERENCE_MODES; ++i)
5066 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
5067
5068 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5069 int single_count_zero = 0;
5070 int comp_count_zero = 0;
5071
5072 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5073 single_count_zero += counts->comp_inter[i][0];
5074 comp_count_zero += counts->comp_inter[i][1];
5075 }
5076
5077 if (comp_count_zero == 0) {
5078 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005079 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005080 } else if (single_count_zero == 0) {
5081 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005082 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005083 }
5084 }
5085
Jingning Han9777afc2016-10-20 15:17:43 -07005086#if CONFIG_VAR_TX
5087 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005088 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Jingning Han9777afc2016-10-20 15:17:43 -07005089#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005090 if (cm->tx_mode == TX_MODE_SELECT) {
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005091#if CONFIG_TX64X64
5092 int count4x4 = 0;
5093 int count8x8_8x8p = 0, count8x8_lp = 0;
5094 int count16x16_16x16p = 0, count16x16_lp = 0;
5095 int count32x32_32x32p = 0, count32x32_lp = 0;
5096 int count64x64_64x64p = 0;
5097 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5098 // counts->tx_size[max_depth][context_idx][this_depth_level]
5099 count4x4 += counts->tx_size[0][i][0];
5100 count4x4 += counts->tx_size[1][i][0];
5101 count4x4 += counts->tx_size[2][i][0];
5102 count4x4 += counts->tx_size[3][i][0];
5103
5104 count8x8_8x8p += counts->tx_size[0][i][1];
5105 count8x8_lp += counts->tx_size[1][i][1];
5106 count8x8_lp += counts->tx_size[2][i][1];
5107 count8x8_lp += counts->tx_size[3][i][1];
5108
5109 count16x16_16x16p += counts->tx_size[1][i][2];
5110 count16x16_lp += counts->tx_size[2][i][2];
5111 count16x16_lp += counts->tx_size[3][i][2];
5112
5113 count32x32_32x32p += counts->tx_size[2][i][3];
5114 count32x32_lp += counts->tx_size[3][i][3];
5115
5116 count64x64_64x64p += counts->tx_size[3][i][4];
5117 }
5118#if CONFIG_EXT_TX && CONFIG_RECT_TX
5119 count4x4 += counts->tx_size_implied[0][TX_4X4];
5120 count4x4 += counts->tx_size_implied[1][TX_4X4];
5121 count4x4 += counts->tx_size_implied[2][TX_4X4];
5122 count4x4 += counts->tx_size_implied[3][TX_4X4];
5123 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5124 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5125 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5126 count8x8_lp += counts->tx_size_implied[4][TX_8X8];
5127 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5128 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5129 count16x16_lp += counts->tx_size_implied[4][TX_16X16];
5130 count32x32_32x32p += counts->tx_size_implied[3][TX_32X32];
5131 count32x32_lp += counts->tx_size_implied[4][TX_32X32];
Debargha Mukherjee5a488a62016-11-22 22:24:10 -08005132 count64x64_64x64p += counts->tx_size_implied[4][TX_64X64];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005133#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5134 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5135 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5136#if CONFIG_SUPERTX
5137 cm->counts.supertx_size[TX_16X16] == 0 &&
5138 cm->counts.supertx_size[TX_32X32] == 0 &&
5139 cm->counts.supertx_size[TX_64X64] == 0 &&
5140#endif
5141 count64x64_64x64p == 0) {
5142 cm->tx_mode = ALLOW_8X8;
5143 reset_skip_tx_size(cm, TX_8X8);
5144 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5145 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5146 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5147#if CONFIG_SUPERTX
5148 cm->counts.supertx_size[TX_8X8] == 0 &&
5149 cm->counts.supertx_size[TX_16X16] == 0 &&
5150 cm->counts.supertx_size[TX_32X32] == 0 &&
5151 cm->counts.supertx_size[TX_64X64] == 0 &&
5152#endif
5153 count64x64_64x64p == 0) {
5154 cm->tx_mode = ONLY_4X4;
5155 reset_skip_tx_size(cm, TX_4X4);
5156 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5157 count32x32_lp == 0) {
5158 cm->tx_mode = ALLOW_64X64;
5159 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5160#if CONFIG_SUPERTX
5161 cm->counts.supertx_size[TX_64X64] == 0 &&
5162#endif
5163 count64x64_64x64p == 0) {
5164 cm->tx_mode = ALLOW_32X32;
5165 reset_skip_tx_size(cm, TX_32X32);
5166 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5167 count32x32_32x32p == 0 &&
5168#if CONFIG_SUPERTX
5169 cm->counts.supertx_size[TX_32X32] == 0 &&
5170 cm->counts.supertx_size[TX_64X64] == 0 &&
5171#endif
5172 count64x64_64x64p == 0) {
5173 cm->tx_mode = ALLOW_16X16;
5174 reset_skip_tx_size(cm, TX_16X16);
5175 }
5176
5177#else // CONFIG_TX64X64
5178
Yaowu Xuc27fc142016-08-22 16:08:15 -07005179 int count4x4 = 0;
5180 int count8x8_lp = 0, count8x8_8x8p = 0;
5181 int count16x16_16x16p = 0, count16x16_lp = 0;
5182 int count32x32 = 0;
5183 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005184 // counts->tx_size[max_depth][context_idx][this_depth_level]
5185 count4x4 += counts->tx_size[0][i][0];
5186 count4x4 += counts->tx_size[1][i][0];
5187 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005188
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005189 count8x8_8x8p += counts->tx_size[0][i][1];
Jingning Han2adcfb12016-10-27 11:19:53 -07005190 count8x8_lp += counts->tx_size[1][i][1];
5191 count8x8_lp += counts->tx_size[2][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005192
Jingning Han2adcfb12016-10-27 11:19:53 -07005193 count16x16_16x16p += counts->tx_size[1][i][2];
5194 count16x16_lp += counts->tx_size[2][i][2];
5195 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005196 }
5197#if CONFIG_EXT_TX && CONFIG_RECT_TX
5198 count4x4 += counts->tx_size_implied[0][TX_4X4];
5199 count4x4 += counts->tx_size_implied[1][TX_4X4];
5200 count4x4 += counts->tx_size_implied[2][TX_4X4];
5201 count4x4 += counts->tx_size_implied[3][TX_4X4];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005202 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005203 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5204 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5206 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5207 count32x32 += counts->tx_size_implied[3][TX_32X32];
5208#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5209 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5210#if CONFIG_SUPERTX
5211 cm->counts.supertx_size[TX_16X16] == 0 &&
5212 cm->counts.supertx_size[TX_32X32] == 0 &&
5213#endif // CONFIG_SUPERTX
5214 count32x32 == 0) {
5215 cm->tx_mode = ALLOW_8X8;
5216 reset_skip_tx_size(cm, TX_8X8);
5217 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5218 count8x8_lp == 0 && count16x16_lp == 0 &&
5219#if CONFIG_SUPERTX
5220 cm->counts.supertx_size[TX_8X8] == 0 &&
5221 cm->counts.supertx_size[TX_16X16] == 0 &&
5222 cm->counts.supertx_size[TX_32X32] == 0 &&
5223#endif // CONFIG_SUPERTX
5224 count32x32 == 0) {
5225 cm->tx_mode = ONLY_4X4;
5226 reset_skip_tx_size(cm, TX_4X4);
5227 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5228 cm->tx_mode = ALLOW_32X32;
5229 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5230#if CONFIG_SUPERTX
5231 cm->counts.supertx_size[TX_32X32] == 0 &&
5232#endif // CONFIG_SUPERTX
5233 count4x4 == 0) {
5234 cm->tx_mode = ALLOW_16X16;
5235 reset_skip_tx_size(cm, TX_16X16);
5236 }
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005237#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07005238 }
5239#endif
5240 } else {
5241 encode_frame_internal(cpi);
5242 }
5243}
5244
5245static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5246 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
5247 const int intraonly) {
5248 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5249 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5250 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
5251
5252 if (bsize < BLOCK_8X8) {
5253 int idx, idy;
5254 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5255 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5256 for (idy = 0; idy < 2; idy += num_4x4_h)
5257 for (idx = 0; idx < 2; idx += num_4x4_w) {
5258 const int bidx = idy * 2 + idx;
5259 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5260 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005261 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5262 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263 ++counts->kf_y_mode[a][l][bmode];
5264 } else {
5265 ++counts->y_mode[0][bmode];
5266 }
5267 }
5268 } else {
5269 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005270 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5271 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005272 ++counts->kf_y_mode[above][left][y_mode];
5273 } else {
5274 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5275 }
5276 }
5277
5278 ++counts->uv_mode[y_mode][uv_mode];
5279}
5280
5281#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005282static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005283 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005284 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005285 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5286 const int tx_row = blk_row >> 1;
5287 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005288 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5289 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005290 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005291 xd->left_txfm_context + tx_row,
5292 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005293 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5294
Yaowu Xuc27fc142016-08-22 16:08:15 -07005295 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5296
5297 if (tx_size == plane_tx_size) {
5298 ++counts->txfm_partition[ctx][0];
5299 mbmi->tx_size = tx_size;
5300 txfm_partition_update(xd->above_txfm_context + tx_col,
5301 xd->left_txfm_context + tx_row, tx_size);
5302 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005303 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5304 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005305 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005306
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005308 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005309
5310 if (tx_size == TX_8X8) {
5311 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5312 mbmi->tx_size = TX_4X4;
5313 txfm_partition_update(xd->above_txfm_context + tx_col,
5314 xd->left_txfm_context + tx_row, TX_4X4);
5315 return;
5316 }
5317
5318 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005319 int offsetr = (i >> 1) * bs;
5320 int offsetc = (i & 0x01) * bs;
5321 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5322 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005323 }
5324 }
5325}
5326
Jingning Han9777afc2016-10-20 15:17:43 -07005327static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5328 BLOCK_SIZE plane_bsize, int mi_row,
5329 int mi_col, FRAME_COUNTS *td_counts) {
5330 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005331 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5332 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005333 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005334 const int bh = tx_size_high_unit[max_tx_size];
5335 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005336 int idx, idy;
5337
5338 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5339 xd->left_txfm_context =
5340 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5341
5342 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005343 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005344 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5345 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005346}
5347
5348static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5349 int blk_col) {
5350 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5351 const int tx_row = blk_row >> 1;
5352 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005353 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5354 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5356
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5358
5359 if (tx_size == plane_tx_size) {
5360 mbmi->tx_size = tx_size;
5361 txfm_partition_update(xd->above_txfm_context + tx_col,
5362 xd->left_txfm_context + tx_row, tx_size);
5363
5364 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005365 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5366 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005367 int i;
5368
5369 if (tx_size == TX_8X8) {
5370 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5371 mbmi->tx_size = TX_4X4;
5372 txfm_partition_update(xd->above_txfm_context + tx_col,
5373 xd->left_txfm_context + tx_row, TX_4X4);
5374 return;
5375 }
5376
5377 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005378 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005379 int offsetr = (i >> 1) * bsl;
5380 int offsetc = (i & 0x01) * bsl;
5381 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005382 }
5383 }
5384}
5385
Urvang Joshi52648442016-10-13 17:27:51 -07005386static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5387 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5388 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5390 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005391 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005392 const int bh = tx_size_high_unit[max_tx_size];
5393 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394 int idx, idy;
5395
5396 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5397 xd->left_txfm_context =
5398 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5399
5400 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005401 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005402 set_txfm_context(xd, max_tx_size, idy, idx);
5403}
5404#endif
5405
Urvang Joshi52648442016-10-13 17:27:51 -07005406static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5407 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5408 int mi_col, BLOCK_SIZE bsize,
5409 PICK_MODE_CONTEXT *ctx, int *rate) {
5410 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005411 MACROBLOCK *const x = &td->mb;
5412 MACROBLOCKD *const xd = &x->e_mbd;
5413 MODE_INFO **mi_8x8 = xd->mi;
5414 MODE_INFO *mi = mi_8x8[0];
5415 MB_MODE_INFO *mbmi = &mi->mbmi;
5416 const int seg_skip =
5417 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5418 const int mis = cm->mi_stride;
5419 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5420 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005421 const int is_inter = is_inter_block(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005422
Yaowu Xuc27fc142016-08-22 16:08:15 -07005423 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5424
Yushin Cho77bba8d2016-11-04 16:36:56 -07005425#if CONFIG_PVQ
5426 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005427 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005428#endif
5429
Jingning Han94ea1aa2016-11-08 12:10:46 -08005430 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005431 int plane;
5432 mbmi->skip = 1;
5433 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Angie Chiangff6d8902016-10-21 11:02:09 -07005434 av1_encode_intra_block_plane((AV1_COMMON *)cm, x,
5435 AOMMAX(bsize, BLOCK_8X8), plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005436 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005437 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5438 frame_is_intra_only(cm));
5439
hui su5db97432016-10-14 16:10:14 -07005440 // TODO(huisu): move this into sum_intra_stats().
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005441 if (!dry_run && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005443 (void)counts;
5444#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005445 if (mbmi->mode == DC_PRED
5446#if CONFIG_PALETTE
5447 && mbmi->palette_mode_info.palette_size[0] == 0
5448#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005449 ) {
5450 const int use_filter_intra_mode =
5451 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5452 ++counts->filter_intra[0][use_filter_intra_mode];
5453 }
Urvang Joshib100db72016-10-12 16:28:56 -07005454 if (mbmi->uv_mode == DC_PRED
5455#if CONFIG_PALETTE
5456 && mbmi->palette_mode_info.palette_size[1] == 0
5457#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005458 ) {
5459 const int use_filter_intra_mode =
5460 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5461 ++counts->filter_intra[1][use_filter_intra_mode];
5462 }
5463#endif // CONFIG_FILTER_INTRA
5464#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5466 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005467 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005468 p_angle =
5469 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005470 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5472 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005473#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005474 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475
Urvang Joshib100db72016-10-12 16:28:56 -07005476#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005477 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005478 for (plane = 0; plane <= 1; ++plane) {
5479 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5480 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5481 xd->plane[plane].color_index_map[0];
5482 // TODO(huisu): this increases the use of token buffer. Needs stretch
5483 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005484 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005485 }
5486 }
5487 }
Urvang Joshib100db72016-10-12 16:28:56 -07005488#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005489#if CONFIG_VAR_TX
5490 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5491#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005492 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493 } else {
5494 int ref;
5495 const int is_compound = has_second_ref(mbmi);
5496
5497 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5498 for (ref = 0; ref < 1 + is_compound; ++ref) {
5499 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5500 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005501 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5502 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503 }
Yue Chen69f18e12016-09-08 14:48:15 -07005504#if CONFIG_WARPED_MOTION
5505 if (mbmi->motion_mode == WARPED_CAUSAL) {
5506 int i;
5507#if CONFIG_AOM_HIGHBITDEPTH
5508 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
5509#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005510
Yue Chen69f18e12016-09-08 14:48:15 -07005511 for (i = 0; i < 3; ++i) {
5512 const struct macroblockd_plane *pd = &xd->plane[i];
5513
5514 av1_warp_plane(&mbmi->wm_params[0],
5515#if CONFIG_AOM_HIGHBITDEPTH
5516 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5517#endif // CONFIG_AOM_HIGHBITDEPTH
5518 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
5519 pd->pre[0].stride, pd->dst.buf,
5520 ((mi_col * MI_SIZE) >> pd->subsampling_x),
5521 ((mi_row * MI_SIZE) >> pd->subsampling_y),
5522 xd->n8_w * (8 >> pd->subsampling_x),
5523 xd->n8_h * (8 >> pd->subsampling_y), pd->dst.stride,
5524 pd->subsampling_x, pd->subsampling_y, 16, 16, 0);
5525 }
5526 } else {
5527#endif // CONFIG_WARPED_MOTION
5528 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
5529 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5530 AOMMAX(bsize, BLOCK_8X8));
5531
5532 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5533 AOMMAX(bsize, BLOCK_8X8));
5534#if CONFIG_WARPED_MOTION
5535 }
5536#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005537
Yue Chencb60b182016-10-13 15:18:22 -07005538#if CONFIG_MOTION_VAR
5539 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005540 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005541 }
Yue Chencb60b182016-10-13 15:18:22 -07005542#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543
Angie Chiangff6d8902016-10-21 11:02:09 -07005544 av1_encode_sb((AV1_COMMON *)cm, x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005546 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Hanfe45b212016-11-22 10:30:23 -08005547 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5548 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549#else
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005550 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551#endif
5552 }
5553
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005554 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005555#if CONFIG_VAR_TX
5556 TX_SIZE tx_size =
5557 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5558#else
5559 TX_SIZE tx_size = mbmi->tx_size;
5560#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005561 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
Jingning Han94ea1aa2016-11-08 12:10:46 -08005562 !(is_inter && (mbmi->skip || seg_skip))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005563 const int tx_size_ctx = get_tx_size_context(xd);
5564 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5565 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005566 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005567 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005569 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5571#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -08005572 if (is_inter) {
5573 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5574 } else {
5575 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5576 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Yue Chena1e48dc2016-08-29 17:29:33 -07005577 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005578#else
Jingning Han4e1737a2016-10-25 16:05:02 -07005579 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005580#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005582 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005583 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005584 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005585 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005586 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005587 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005588 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005589 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005590 }
5591#if CONFIG_EXT_TX && CONFIG_RECT_TX
5592 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
Jingning Hane67b38a2016-11-04 10:30:00 -07005593 [txsize_sqr_up_map[tx_size]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005594#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5595 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005596 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005597 }
5598
Urvang Joshi454280d2016-10-14 16:51:44 -07005599 for (j = 0; j < mi_height; j++)
5600 for (i = 0; i < mi_width; i++)
5601 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005602 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005603
5604#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005605 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5606 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005607#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005608 }
Jingning Han9777afc2016-10-20 15:17:43 -07005609
Jingning Hane67b38a2016-11-04 10:30:00 -07005610 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005611 ++td->counts
5612 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613#if CONFIG_EXT_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005614 if (get_ext_tx_types(tx_size, bsize, is_inter) > 1 && cm->base_qindex > 0 &&
5615 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005616 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005617 int eset = get_ext_tx_set(tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005619 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005620 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621 [mbmi->tx_type];
5622 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005623 ++td->counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624 }
5625 }
5626 }
5627#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005628 if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005629 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005630 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005631 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005632 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005633 ++td->counts->intra_ext_tx[tx_size]
clang-format67948d32016-09-07 22:40:40 -07005634 [intra_mode_to_tx_type_context[mbmi->mode]]
5635 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 }
5637 }
5638#endif // CONFIG_EXT_TX
5639 }
5640
5641#if CONFIG_VAR_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005642 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 && is_inter &&
5643 !(mbmi->skip || seg_skip)) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005644 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005645 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005646 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005647 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005648 if (is_inter)
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005649 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005650 else
Jingning Hane67b38a2016-11-04 10:30:00 -07005651 tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005652 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005653 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005654 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005655#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005656}
5657
5658#if CONFIG_SUPERTX
5659static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5660 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5661#if CONFIG_EXT_INTER
5662 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5663#endif // CONFIG_EXT_INTER
5664 return 0;
5665}
5666
Urvang Joshi52648442016-10-13 17:27:51 -07005667static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5668 int mi_row, int mi_col, BLOCK_SIZE bsize,
5669 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005670 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005671
5672 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5673 const PARTITION_TYPE partition = pc_tree->partitioning;
5674 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5675#if CONFIG_EXT_PARTITION_TYPES
5676 int i;
5677#endif
5678
5679 assert(bsize >= BLOCK_8X8);
5680
5681 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5682
5683 switch (partition) {
5684 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5685 case PARTITION_VERT:
5686 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5687 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5688 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5689 }
5690 break;
5691 case PARTITION_HORZ:
5692 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5693 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5694 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5695 }
5696 break;
5697 case PARTITION_SPLIT:
5698 if (bsize == BLOCK_8X8) {
5699 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5700 } else {
5701 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5702 pc_tree->split[0]))
5703 return 1;
5704 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5705 pc_tree->split[1]))
5706 return 1;
5707 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5708 pc_tree->split[2]))
5709 return 1;
5710 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5711 pc_tree->split[3]))
5712 return 1;
5713 }
5714 break;
5715#if CONFIG_EXT_PARTITION_TYPES
5716 case PARTITION_HORZ_A:
5717 for (i = 0; i < 3; i++) {
5718 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5719 }
5720 break;
5721 case PARTITION_HORZ_B:
5722 for (i = 0; i < 3; i++) {
5723 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5724 }
5725 break;
5726 case PARTITION_VERT_A:
5727 for (i = 0; i < 3; i++) {
5728 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5729 }
5730 break;
5731 case PARTITION_VERT_B:
5732 for (i = 0; i < 3; i++) {
5733 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5734 }
5735 break;
5736#endif // CONFIG_EXT_PARTITION_TYPES
5737 default: assert(0);
5738 }
5739 return 0;
5740}
5741
5742static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5743 return ctx->mic.mbmi.tx_size == supertx_size;
5744}
5745
5746static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5747 PC_TREE *pc_tree) {
5748 PARTITION_TYPE partition;
5749 BLOCK_SIZE subsize;
5750
5751 partition = pc_tree->partitioning;
5752 subsize = get_subsize(bsize, partition);
5753 switch (partition) {
5754 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5755 case PARTITION_VERT:
5756 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5757 case PARTITION_HORZ:
5758 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5759 case PARTITION_SPLIT:
5760 if (bsize == BLOCK_8X8)
5761 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5762 else
5763 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5764#if CONFIG_EXT_PARTITION_TYPES
5765 case PARTITION_HORZ_A:
5766 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5767 case PARTITION_HORZ_B:
5768 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5769 case PARTITION_VERT_A:
5770 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5771 case PARTITION_VERT_B:
5772 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5773#endif // CONFIG_EXT_PARTITION_TYPES
5774 default: assert(0); return 0;
5775 }
5776}
5777
Urvang Joshi52648442016-10-13 17:27:51 -07005778static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779#if CONFIG_EXT_INTER
5780 int mi_row_ori, int mi_col_ori,
5781#endif // CONFIG_EXT_INTER
5782 int mi_row_pred, int mi_col_pred,
5783 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5784 // Used in supertx
5785 // (mi_row_ori, mi_col_ori): location for mv
5786 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005787 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 MACROBLOCK *const x = &td->mb;
5789 MACROBLOCKD *const xd = &x->e_mbd;
5790 MODE_INFO *mi_8x8 = xd->mi[0];
5791 MODE_INFO *mi = mi_8x8;
5792 MB_MODE_INFO *mbmi = &mi->mbmi;
5793 int ref;
5794 const int is_compound = has_second_ref(mbmi);
5795
5796 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5797
5798 for (ref = 0; ref < 1 + is_compound; ++ref) {
5799 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005800 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5801 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005802 }
5803
5804 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005805 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005806#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005807 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005808#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005809 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005810 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005811 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005812#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005813 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005814#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005815 mi_row_pred, mi_col_pred,
5816 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005817}
5818
Urvang Joshi52648442016-10-13 17:27:51 -07005819static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005820 const TileInfo *const tile, int block,
5821 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5822 int mi_col_pred, int mi_row_top, int mi_col_top,
5823 uint8_t *dst_buf[3], int dst_stride[3],
5824 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005825 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005826 // Used in supertx
5827 // (mi_row_ori, mi_col_ori): location for mv
5828 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5829 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5830 // block: sub location of sub8x8 blocks
5831 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5832 // bextend: 1: region to predict is an extension of ori; 0: not
5833
5834 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005835 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836 MACROBLOCKD *const xd = &x->e_mbd;
5837 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5838 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5839 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5840 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5841
5842 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5843 mi_row_pred >= mi_row_top + mi_height_top ||
5844 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5845 mi_col_pred >= cm->mi_cols)
5846 return;
5847
5848 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5849 mi_col_ori, bsize_pred);
5850 xd->plane[0].dst.stride = dst_stride[0];
5851 xd->plane[1].dst.stride = dst_stride[1];
5852 xd->plane[2].dst.stride = dst_stride[2];
5853 xd->plane[0].dst.buf = dst_buf[0] +
5854 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5855 (c >> xd->plane[0].subsampling_x);
5856 xd->plane[1].dst.buf = dst_buf[1] +
5857 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5858 (c >> xd->plane[1].subsampling_x);
5859 xd->plane[2].dst.buf = dst_buf[2] +
5860 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5861 (c >> xd->plane[2].subsampling_x);
5862
5863 predict_superblock(cpi, td,
5864#if CONFIG_EXT_INTER
5865 mi_row_ori, mi_col_ori,
5866#endif // CONFIG_EXT_INTER
5867 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5868
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005869 if (!dry_run && !bextend) {
5870#if CONFIG_SUPERTX
5871 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
5872#else
5873 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred);
5874#endif
5875 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876}
5877
Urvang Joshi52648442016-10-13 17:27:51 -07005878static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005879 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5880 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005881 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005882 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5883 // dir: 0-lower, 1-upper, 2-left, 3-right
5884 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5885 MACROBLOCKD *xd = &td->mb.e_mbd;
5886 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5887 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5888 int xss = xd->plane[1].subsampling_x;
5889 int yss = xd->plane[1].subsampling_y;
5890 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5891
5892 BLOCK_SIZE extend_bsize;
5893 int unit, mi_row_pred, mi_col_pred;
5894
5895 if (dir == 0 || dir == 1) { // lower and upper
5896 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5897 ? BLOCK_8X8
5898 : BLOCK_16X8;
5899 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5900 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5901 mi_col_pred = mi_col;
5902
5903 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5904 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005905 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005906
5907 if (mi_width > unit) {
5908 int i;
5909 for (i = 0; i < mi_width / unit - 1; i++) {
5910 mi_col_pred += unit;
5911 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5912 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005913 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5914 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005915 }
5916 }
5917 } else if (dir == 2 || dir == 3) { // left and right
5918 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5919 ? BLOCK_8X8
5920 : BLOCK_8X16;
5921 unit = num_8x8_blocks_high_lookup[extend_bsize];
5922 mi_row_pred = mi_row;
5923 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5924
5925 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5926 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005927 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005928
5929 if (mi_height > unit) {
5930 int i;
5931 for (i = 0; i < mi_height / unit - 1; i++) {
5932 mi_row_pred += unit;
5933 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5934 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005935 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5936 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937 }
5938 }
5939 } else {
5940 extend_bsize = BLOCK_8X8;
5941 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5942 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5943
5944 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5945 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005946 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005947 }
5948}
5949
Urvang Joshi52648442016-10-13 17:27:51 -07005950static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005951 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5952 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005953 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954 uint8_t *dst_buf[3], int dst_stride[3]) {
5955 assert(block >= 0 && block < 4);
5956 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005957 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005958 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005959 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005960 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005961 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005962 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005963 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005964 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005965 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005966 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005967 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005968 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005969 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005970 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005971 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005972}
5973
5974// This function generates prediction for multiple blocks, between which
5975// discontinuity around boundary is reduced by smoothing masks. The basic
5976// smoothing mask is a soft step function along horz/vert direction. In more
5977// complicated case when a block is split into 4 subblocks, the basic mask is
5978// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5979// then applied to the 2 masked prediction mentioned above in vertical direction
5980// If the block is split into more than one level, at every stage, masked
5981// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005982static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005983 const TileInfo *const tile, int mi_row,
5984 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005985 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005986 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5987 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005988 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005989 MACROBLOCK *const x = &td->mb;
5990 MACROBLOCKD *const xd = &x->e_mbd;
5991
5992 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5993 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5994 const PARTITION_TYPE partition = pc_tree->partitioning;
5995 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5996#if CONFIG_EXT_PARTITION_TYPES
5997 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5998#endif
5999
6000 int i;
6001 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
6002 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6003 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6004 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6005 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6006 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6007 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6008
6009 assert(bsize >= BLOCK_8X8);
6010
6011 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
6012
Yaowu Xuf883b422016-08-30 14:01:10 -07006013#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006014 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6015 int len = sizeof(uint16_t);
6016 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6017 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
6018 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
6019 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6020 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
6021 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
6022 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
6023 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
6024 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
6025 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006026#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006027 dst_buf1[0] = tmp_buf1;
6028 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
6029 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
6030 dst_buf2[0] = tmp_buf2;
6031 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
6032 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
6033 dst_buf3[0] = tmp_buf3;
6034 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
6035 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006036#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006037 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006038#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006039
Urvang Joshi52648442016-10-13 17:27:51 -07006040 if (!dry_run && bsize < top_bsize) {
6041 // Explicitly cast away const.
6042 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6043 frame_counts->partition[ctx][partition]++;
6044 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006045
6046 for (i = 0; i < MAX_MB_PLANE; i++) {
6047 xd->plane[i].dst.buf = dst_buf[i];
6048 xd->plane[i].dst.stride = dst_stride[i];
6049 }
6050
6051 switch (partition) {
6052 case PARTITION_NONE:
6053 assert(bsize < top_bsize);
6054 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6055 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006056 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006058 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006059 break;
6060 case PARTITION_HORZ:
6061 if (bsize == BLOCK_8X8) {
6062 // Fisrt half
6063 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6064 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006065 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006066 if (bsize < top_bsize)
6067 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006068 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006069
6070 // Second half
6071 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6072 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006073 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006074 if (bsize < top_bsize)
6075 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006076 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006077
6078 // Smooth
6079 xd->plane[0].dst.buf = dst_buf[0];
6080 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006081 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006082 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6083 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6084 0);
6085 } else {
6086 // First half
6087 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6088 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006089 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090 if (bsize < top_bsize)
6091 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006092 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006093 else
6094 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006095 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006096
6097 if (mi_row + hbs < cm->mi_rows) {
6098 // Second half
6099 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6100 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006101 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006102 if (bsize < top_bsize)
6103 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006104 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006105 dst_stride1);
6106 else
6107 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006108 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006109 dst_stride1, 1);
6110
6111 // Smooth
6112 for (i = 0; i < MAX_MB_PLANE; i++) {
6113 xd->plane[i].dst.buf = dst_buf[i];
6114 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006115 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006116 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6117 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6118 PARTITION_HORZ, i);
6119 }
6120 }
6121 }
6122 break;
6123 case PARTITION_VERT:
6124 if (bsize == BLOCK_8X8) {
6125 // First half
6126 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6127 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006128 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006129 if (bsize < top_bsize)
6130 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006131 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006132
6133 // Second half
6134 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6135 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006136 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006137 if (bsize < top_bsize)
6138 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006139 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006140
6141 // Smooth
6142 xd->plane[0].dst.buf = dst_buf[0];
6143 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006144 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6146 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6147 0);
6148 } else {
6149 // bsize: not important, not useful
6150 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6151 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006152 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153 if (bsize < top_bsize)
6154 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006155 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006156 else
6157 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006158 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159
6160 if (mi_col + hbs < cm->mi_cols) {
6161 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6162 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006163 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006164 if (bsize < top_bsize)
6165 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006166 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6167 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 else
6169 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006170 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6171 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006172
6173 for (i = 0; i < MAX_MB_PLANE; i++) {
6174 xd->plane[i].dst.buf = dst_buf[i];
6175 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006176 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006177 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6178 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6179 PARTITION_VERT, i);
6180 }
6181 }
6182 }
6183 break;
6184 case PARTITION_SPLIT:
6185 if (bsize == BLOCK_8X8) {
6186 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6187 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006188 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006189 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6190 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006191 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6193 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006194 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006195 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6196 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006197 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198
6199 if (bsize < top_bsize) {
6200 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006201 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006203 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006204 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006205 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006206 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006207 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006208 }
6209 } else {
6210 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006211 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6212 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006213 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6214 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006215 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6216 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006217 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6218 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006219 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6220 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006221 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6222 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006223 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006224 top_bsize, dst_buf3, dst_stride3,
6225 pc_tree->split[3]);
6226 }
6227 for (i = 0; i < MAX_MB_PLANE; i++) {
6228 if (bsize == BLOCK_8X8 && i != 0)
6229 continue; // Skip <4x4 chroma smoothing
6230 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006231 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006232 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6233 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6234 PARTITION_VERT, i);
6235 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006236 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006237 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6238 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6239 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006240 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006241 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6242 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6243 PARTITION_HORZ, i);
6244 }
6245 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006246 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006247 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6248 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6249 PARTITION_HORZ, i);
6250 }
6251 }
6252 break;
6253#if CONFIG_EXT_PARTITION_TYPES
6254 case PARTITION_HORZ_A:
6255 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6256 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006257 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006258 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006259 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006260
6261 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6262 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006263 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006265 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006266
6267 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6268 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006269 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006270 if (bsize < top_bsize)
6271 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006272 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273 else
6274 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006275 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006276
6277 for (i = 0; i < MAX_MB_PLANE; i++) {
6278 xd->plane[i].dst.buf = dst_buf[i];
6279 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006280 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006281 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6282 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6283 i);
6284 }
6285 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006286 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006287 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6288 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6289 i);
6290 }
6291
6292 break;
6293 case PARTITION_VERT_A:
6294
6295 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6296 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006297 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006299 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006300
6301 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6302 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006303 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006304 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006305 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006306
6307 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6308 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006309 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006310 if (bsize < top_bsize)
6311 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006312 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313 else
6314 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006315 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316
6317 for (i = 0; i < MAX_MB_PLANE; i++) {
6318 xd->plane[i].dst.buf = dst_buf[i];
6319 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006320 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006321 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6322 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6323 i);
6324 }
6325 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006326 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006327 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6328 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6329 i);
6330 }
6331 break;
6332 case PARTITION_HORZ_B:
6333
6334 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6335 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006336 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006337 if (bsize < top_bsize)
6338 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006339 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006340 else
6341 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006342 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006343
6344 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6345 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006346 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006347 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006348 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006349
6350 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6351 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006352 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006353 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006354 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006355 dst_stride2);
6356
6357 for (i = 0; i < MAX_MB_PLANE; i++) {
6358 xd->plane[i].dst.buf = dst_buf1[i];
6359 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006360 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006361 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6362 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6363 PARTITION_VERT, i);
6364 }
6365 for (i = 0; i < MAX_MB_PLANE; i++) {
6366 xd->plane[i].dst.buf = dst_buf[i];
6367 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006368 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006369 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6370 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6371 i);
6372 }
6373 break;
6374 case PARTITION_VERT_B:
6375
6376 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6377 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006378 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379 if (bsize < top_bsize)
6380 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006381 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006382 else
6383 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006384 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006385
6386 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6387 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006388 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006389 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006390 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006391
6392 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6393 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006394 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006395 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006396 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006397 dst_stride2);
6398
6399 for (i = 0; i < MAX_MB_PLANE; i++) {
6400 xd->plane[i].dst.buf = dst_buf1[i];
6401 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006402 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006403 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6404 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6405 PARTITION_HORZ, i);
6406 }
6407 for (i = 0; i < MAX_MB_PLANE; i++) {
6408 xd->plane[i].dst.buf = dst_buf[i];
6409 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006410 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006411 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6412 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6413 i);
6414 }
6415 break;
6416#endif // CONFIG_EXT_PARTITION_TYPES
6417 default: assert(0);
6418 }
6419
6420#if CONFIG_EXT_PARTITION_TYPES
6421 if (bsize < top_bsize)
6422 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6423#else
6424 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6425 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6426#endif // CONFIG_EXT_PARTITION_TYPES
6427}
6428
Urvang Joshi52648442016-10-13 17:27:51 -07006429static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006430 const TileInfo *const tile, int mi_row, int mi_col,
6431 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6432 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006433 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006434 MACROBLOCK *const x = &td->mb;
6435 MACROBLOCKD *const xd = &x->e_mbd;
6436 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6437 base_rate = *tmp_rate;
6438 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6439 uint8_t *dst_buf[3];
6440 int dst_stride[3];
6441 TX_SIZE tx_size;
6442 MB_MODE_INFO *mbmi;
6443 TX_TYPE tx_type, best_tx_nostx;
6444#if CONFIG_EXT_TX
6445 int ext_tx_set;
6446#endif // CONFIG_EXT_TX
6447 int tmp_rate_tx = 0, skip_tx = 0;
6448 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6449
6450 set_skip_context(xd, mi_row, mi_col);
6451 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006452 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006453 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006454 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6455 dst_buf[plane] = xd->plane[plane].dst.buf;
6456 dst_stride[plane] = xd->plane[plane].dst.stride;
6457 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006458 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006459 bsize, dst_buf, dst_stride, pc_tree);
6460
6461 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6462 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6463
6464 mbmi = &xd->mi[0]->mbmi;
6465 best_tx_nostx = mbmi->tx_type;
6466
6467 *best_tx = DCT_DCT;
6468
6469 // chroma
6470 skippable_uv = 1;
6471 rate_uv = 0;
6472 dist_uv = 0;
6473 sse_uv = 0;
6474 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6475#if CONFIG_VAR_TX
6476 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6477 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6478 const struct macroblockd_plane *const pd = &xd->plane[plane];
6479 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006480 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006481 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006482
6483 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006484 tx_size =
6485 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006486 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006487 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6488
Yaowu Xuf883b422016-08-30 14:01:10 -07006489 av1_subtract_plane(x, bsize, plane);
6490 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006491 get_plane_block_size(bsize, pd), coeff_ctx,
6492 &this_rd_stats);
6493
6494 this_rate = this_rd_stats.rate;
6495 this_dist = this_rd_stats.dist;
6496 pnsse = this_rd_stats.sse;
6497 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006498#else
6499 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006500 tx_size =
6501 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006502 av1_subtract_plane(x, bsize, plane);
6503 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6504 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006505#endif // CONFIG_VAR_TX
6506
6507 rate_uv += this_rate;
6508 dist_uv += this_dist;
6509 sse_uv += pnsse;
6510 skippable_uv &= pnskip;
6511 }
6512
6513 // luma
6514 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006515 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006516#if CONFIG_EXT_TX
6517 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6518#endif // CONFIG_EXT_TX
6519 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6520#if CONFIG_VAR_TX
6521 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6522 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6523 const struct macroblockd_plane *const pd = &xd->plane[0];
6524 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006525 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006526#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006527
Yaowu Xuc27fc142016-08-22 16:08:15 -07006528#if CONFIG_EXT_TX
6529 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6530#else
6531 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6532#endif // CONFIG_EXT_TX
6533 mbmi->tx_type = tx_type;
6534
6535#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006536 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006537
Yaowu Xuf883b422016-08-30 14:01:10 -07006538 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006539 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006540 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6541 &this_rd_stats);
6542
6543 this_rate = this_rd_stats.rate;
6544 this_dist = this_rd_stats.dist;
6545 pnsse = this_rd_stats.sse;
6546 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006547#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006548 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6549 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006550#endif // CONFIG_VAR_TX
6551
6552#if CONFIG_EXT_TX
6553 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6554 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6555 if (ext_tx_set > 0)
6556 this_rate +=
6557 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6558 }
6559#else
6560 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6561 this_rate != INT_MAX) {
6562 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6563 }
6564#endif // CONFIG_EXT_TX
6565 *tmp_rate = rate_uv + this_rate;
6566 *tmp_dist = dist_uv + this_dist;
6567 sse = sse_uv + pnsse;
6568 skippable = skippable_uv && pnskip;
6569 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006570 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006571 x->skip = 1;
6572 } else {
6573 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6574 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006575 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006576 x->skip = 0;
6577 } else {
6578 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006579 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006580 x->skip = 1;
6581 }
6582 }
6583 *tmp_rate += base_rate;
6584 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6585 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6586 *best_tx = tx_type;
6587 bestrd_tx = rd_tx;
6588 tmp_rate_tx = *tmp_rate;
6589 tmp_dist_tx = *tmp_dist;
6590 skip_tx = x->skip;
6591 }
6592 }
6593 *tmp_rate = tmp_rate_tx;
6594 *tmp_dist = tmp_dist_tx;
6595 x->skip = skip_tx;
6596#if CONFIG_VAR_TX
6597 for (plane = 0; plane < 1; ++plane)
6598 memset(x->blk_skip[plane], x->skip,
6599 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6600#endif // CONFIG_VAR_TX
6601 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6602}
6603#endif // CONFIG_SUPERTX