blob: 87e7d51b08c4f7fbb34b56fa124566e704ed1745 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./av1_rtcd.h"
17#include "./aom_dsp_rtcd.h"
18#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "aom_ports/system_state.h"
24
25#include "av1/common/common.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconintra.h"
33#include "av1/common/reconinter.h"
34#include "av1/common/seg_common.h"
35#include "av1/common/tile_common.h"
36
37#include "av1/encoder/aq_complexity.h"
38#include "av1/encoder/aq_cyclicrefresh.h"
39#include "av1/encoder/aq_variance.h"
40#if CONFIG_SUPERTX
41#include "av1/encoder/cost.h"
42#endif
43#if CONFIG_GLOBAL_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -070044#include "av1/common/warped_motion.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070045#include "av1/encoder/global_motion.h"
46#endif
47#include "av1/encoder/encodeframe.h"
48#include "av1/encoder/encodemb.h"
49#include "av1/encoder/encodemv.h"
50#include "av1/encoder/ethread.h"
51#include "av1/encoder/extend.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/rdopt.h"
54#include "av1/encoder/segmentation.h"
55#include "av1/encoder/tokenize.h"
56
Yaowu Xuf883b422016-08-30 14:01:10 -070057#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070058#define IF_HBD(...) __VA_ARGS__
59#else
60#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070061#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070062
Yaowu Xuf883b422016-08-30 14:01:10 -070063static void encode_superblock(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
Yaowu Xuc27fc142016-08-22 16:08:15 -070064 int output_enabled, int mi_row, int mi_col,
65 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx);
66
67#if CONFIG_SUPERTX
68static int check_intra_b(PICK_MODE_CONTEXT *ctx);
69
Yaowu Xuf883b422016-08-30 14:01:10 -070070static int check_intra_sb(AV1_COMP *cpi, const TileInfo *const tile, int mi_row,
71 int mi_col, BLOCK_SIZE bsize, PC_TREE *pc_tree);
72static void predict_superblock(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070073#if CONFIG_EXT_INTER
74 int mi_row_ori, int mi_col_ori,
75#endif // CONFIG_EXT_INTER
76 int mi_row_pred, int mi_col_pred,
77 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
78static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
79 PC_TREE *pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -070080static void predict_sb_complex(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070081 const TileInfo *const tile, int mi_row,
82 int mi_col, int mi_row_ori, int mi_col_ori,
83 int output_enabled, BLOCK_SIZE bsize,
84 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
85 int dst_stride[3], PC_TREE *pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -070086static void update_state_sb_supertx(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070087 const TileInfo *const tile, int mi_row,
88 int mi_col, BLOCK_SIZE bsize,
89 int output_enabled, PC_TREE *pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -070090static void rd_supertx_sb(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 const TileInfo *const tile, int mi_row, int mi_col,
92 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
93 TX_TYPE *best_tx, PC_TREE *pc_tree);
94#endif // CONFIG_SUPERTX
95
96// This is used as a reference when computing the source variance for the
97// purposes of activity masking.
98// Eventually this should be replaced by custom no-reference routines,
99// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700100static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700101 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
102 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
103 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
106#if CONFIG_EXT_PARTITION
107 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
108 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
109 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 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#endif // CONFIG_EXT_PARTITION
113};
114
Yaowu Xuf883b422016-08-30 14:01:10 -0700115#if CONFIG_AOM_HIGHBITDEPTH
116static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
118 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
119 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
120 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
121 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
122#if CONFIG_EXT_PARTITION
123 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
124 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
125 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 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#endif // CONFIG_EXT_PARTITION
129};
130
Yaowu Xuf883b422016-08-30 14:01:10 -0700131static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
133 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
134 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
135 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
136 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
137 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
138 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
139 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
140#if CONFIG_EXT_PARTITION
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 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
147 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
148 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
149#endif // CONFIG_EXT_PARTITION
150};
151
Yaowu Xuf883b422016-08-30 14:01:10 -0700152static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700153 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
154 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
155 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
156 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
157 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
158 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
159 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
160 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
161 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
162 128 * 16,
163#if CONFIG_EXT_PARTITION
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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
169 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
170 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
171 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
172 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
173 128 * 16
174#endif // CONFIG_EXT_PARTITION
175};
Yaowu Xuf883b422016-08-30 14:01:10 -0700176#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177
Yaowu Xuf883b422016-08-30 14:01:10 -0700178unsigned int av1_get_sby_perpixel_variance(AV1_COMP *cpi,
179 const struct buf_2d *ref,
180 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181 unsigned int sse;
182 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700183 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700184 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
185}
186
Yaowu Xuf883b422016-08-30 14:01:10 -0700187#if CONFIG_AOM_HIGHBITDEPTH
188unsigned int av1_high_get_sby_perpixel_variance(AV1_COMP *cpi,
189 const struct buf_2d *ref,
190 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700191 unsigned int var, sse;
192 switch (bd) {
193 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700194 var =
195 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
196 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197 break;
198 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700199 var =
200 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
201 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700202 break;
203 case 8:
204 default:
205 var =
206 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700207 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700208 break;
209 }
210 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
211}
Yaowu Xuf883b422016-08-30 14:01:10 -0700212#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700213
Yaowu Xuf883b422016-08-30 14:01:10 -0700214static unsigned int get_sby_perpixel_diff_variance(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700215 const struct buf_2d *ref,
216 int mi_row, int mi_col,
217 BLOCK_SIZE bs) {
218 unsigned int sse, var;
219 uint8_t *last_y;
220 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
221
222 assert(last != NULL);
223 last_y =
224 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
225 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
226 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
227}
228
Yaowu Xuf883b422016-08-30 14:01:10 -0700229static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
230 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700231 unsigned int var = get_sby_perpixel_diff_variance(
232 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
233 if (var < 8)
234 return BLOCK_64X64;
235 else if (var < 128)
236 return BLOCK_32X32;
237 else if (var < 2048)
238 return BLOCK_16X16;
239 else
240 return BLOCK_8X8;
241}
242
243// Lighter version of set_offsets that only sets the mode info
244// pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700245static void set_mode_info_offsets(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700246 MACROBLOCKD *const xd, int mi_row,
247 int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700248 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700249 const int idx_str = xd->mi_stride * mi_row + mi_col;
250 xd->mi = cm->mi_grid_visible + idx_str;
251 xd->mi[0] = cm->mi + idx_str;
252 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
253}
254
Yaowu Xuf883b422016-08-30 14:01:10 -0700255static void set_offsets_without_segment_id(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256 const TileInfo *const tile,
257 MACROBLOCK *const x, int mi_row,
258 int mi_col, BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700259 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700260 MACROBLOCKD *const xd = &x->e_mbd;
261 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
262 const int mi_height = num_8x8_blocks_high_lookup[bsize];
263
264 set_skip_context(xd, mi_row, mi_col);
265
266 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
267
268#if CONFIG_VAR_TX
269 xd->above_txfm_context = cm->above_txfm_context + mi_col;
270 xd->left_txfm_context =
271 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
272 xd->max_tx_size = max_txsize_lookup[bsize];
273#endif
274
275 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700276 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700277
278 // Set up limit values for MV components.
279 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700280 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
281 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
282 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
283 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700284
285 // Set up distance of MB to edge of frame in 1/8th pel units.
286 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
287 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
288 cm->mi_cols);
289
290 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700291 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292
293 // R/D setup.
294 x->rddiv = cpi->rd.RDDIV;
295 x->rdmult = cpi->rd.RDMULT;
296
Yaowu Xuf883b422016-08-30 14:01:10 -0700297 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298 xd->tile = *tile;
299}
300
Yaowu Xuf883b422016-08-30 14:01:10 -0700301static void set_offsets(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700302 MACROBLOCK *const x, int mi_row, int mi_col,
303 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700304 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700305 MACROBLOCKD *const xd = &x->e_mbd;
306 MB_MODE_INFO *mbmi;
307 const struct segmentation *const seg = &cm->seg;
308
309 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
310
311 mbmi = &xd->mi[0]->mbmi;
312
313 // Setup segment ID.
314 if (seg->enabled) {
315 if (!cpi->vaq_refresh) {
316 const uint8_t *const map =
317 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
318 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
319 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700320 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700321
322 x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
323 } else {
324 mbmi->segment_id = 0;
325 x->encode_breakout = cpi->encode_breakout;
326 }
327
328#if CONFIG_SUPERTX
329 mbmi->segment_id_supertx = MAX_SEGMENTS;
330#endif // CONFIG_SUPERTX
331}
332
333#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700334static void set_offsets_supertx(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700335 const TileInfo *const tile, int mi_row,
336 int mi_col, BLOCK_SIZE bsize) {
337 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -0700338 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700339 MACROBLOCKD *const xd = &x->e_mbd;
340 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
341 const int mi_height = num_8x8_blocks_high_lookup[bsize];
342
343 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
344
345 // Set up distance of MB to edge of frame in 1/8th pel units.
346 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
347 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
348 cm->mi_cols);
349}
350
Yaowu Xuf883b422016-08-30 14:01:10 -0700351static void set_offsets_extend(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700352 const TileInfo *const tile, int mi_row_pred,
353 int mi_col_pred, int mi_row_ori, int mi_col_ori,
354 BLOCK_SIZE bsize_pred) {
355 // Used in supertx
356 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
357 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
358 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -0700359 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700360 MACROBLOCKD *const xd = &x->e_mbd;
361 const int mi_width = num_8x8_blocks_wide_lookup[bsize_pred];
362 const int mi_height = num_8x8_blocks_high_lookup[bsize_pred];
363
364 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
365
366 // Set up limit values for MV components.
367 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700368 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
369 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
370 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
371 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700372
373 // Set up distance of MB to edge of frame in 1/8th pel units.
374 assert(!(mi_col_pred & (mi_width - 1)) && !(mi_row_pred & (mi_height - 1)));
375 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
376 cm->mi_rows, cm->mi_cols);
377 xd->up_available = (mi_row_ori > tile->mi_row_start);
378 xd->left_available = (mi_col_ori > tile->mi_col_start);
379
380 // R/D setup.
381 x->rddiv = cpi->rd.RDDIV;
382 x->rdmult = cpi->rd.RDMULT;
383}
384
Yaowu Xuf883b422016-08-30 14:01:10 -0700385static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700386 MACROBLOCK *const x, const int mi_row,
387 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700388 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700389 const struct segmentation *seg = &cm->seg;
390 const int miw =
Yaowu Xuf883b422016-08-30 14:01:10 -0700391 AOMMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700392 const int mih =
Yaowu Xuf883b422016-08-30 14:01:10 -0700393 AOMMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700394 const int mi_offset = mi_row * cm->mi_stride + mi_col;
395 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
396 int r, c;
397 int seg_id_supertx = MAX_SEGMENTS;
398
399 if (!seg->enabled) {
400 seg_id_supertx = 0;
401 x->encode_breakout = cpi->encode_breakout;
402 } else {
403 // Find the minimum segment_id
404 for (r = 0; r < mih; r++)
405 for (c = 0; c < miw; c++)
406 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700407 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
409
410 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700411 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700412 x->encode_breakout = cpi->segment_encode_breakout[seg_id_supertx];
413 }
414
415 // Assign the the segment_id back to segment_id_supertx
416 for (r = 0; r < mih; r++)
417 for (c = 0; c < miw; c++)
418 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
419}
420#endif // CONFIG_SUPERTX
421
Yaowu Xuf883b422016-08-30 14:01:10 -0700422static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700423 MACROBLOCKD *const xd, int mi_row, int mi_col,
424 BLOCK_SIZE bsize) {
425 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
426 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
427 xd->mi[0]->mbmi.sb_type = bsize;
428 }
429}
430
Yaowu Xuf883b422016-08-30 14:01:10 -0700431static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700432 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
433 int mi_col, const int64_t *const threshold,
434 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700435 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700436 const int hbw = num_8x8_blocks_wide_lookup[vt->bsize] / 2;
437 const int hbh = num_8x8_blocks_high_lookup[vt->bsize] / 2;
438 const int has_cols = mi_col + hbw < cm->mi_cols;
439 const int has_rows = mi_row + hbh < cm->mi_rows;
440
441 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
442
443 assert(vt->bsize >= BLOCK_8X8);
444
445 assert(hbh == hbw);
446
447 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
448 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
449 return;
450 }
451
452 if (vt->force_split || (!has_cols && !has_rows)) goto split;
453
454 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
455 // variance is below threshold, otherwise split will be selected.
456 // No check for vert/horiz split as too few samples for variance.
457 if (vt->bsize == bsize_min[0]) {
458 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
459 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
460 return;
461 } else {
462 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
463 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
464 if (vt->bsize > BLOCK_8X8) {
465 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
466 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
467 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
468 }
469 return;
470 }
471 } else if (vt->bsize > bsize_min[0]) {
472 // For key frame: take split for bsize above 32X32 or very high variance.
473 if (cm->frame_type == KEY_FRAME &&
474 (vt->bsize > BLOCK_32X32 ||
475 vt->variances.none.variance > (threshold[0] << 4))) {
476 goto split;
477 }
478 // If variance is low, take the bsize (no split).
479 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
480 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
481 return;
482 }
483
484 // Check vertical split.
485 if (has_rows) {
486 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
487 if (vt->variances.vert[0].variance < threshold[0] &&
488 vt->variances.vert[1].variance < threshold[0] &&
489 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
490 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
491 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
492 return;
493 }
494 }
495 // Check horizontal split.
496 if (has_cols) {
497 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
498 if (vt->variances.horz[0].variance < threshold[0] &&
499 vt->variances.horz[1].variance < threshold[0] &&
500 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
501 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
502 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
503 return;
504 }
505 }
506 }
507
508split : {
509 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
510 bsize_min + 1);
511 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
512 threshold + 1, bsize_min + 1);
513 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
514 threshold + 1, bsize_min + 1);
515 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
516 threshold + 1, bsize_min + 1);
517 return;
518}
519}
520
521// Set the variance split thresholds for following the block sizes:
522// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
523// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
524// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700525static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
526 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700527 const int is_key_frame = (cm->frame_type == KEY_FRAME);
528 const int threshold_multiplier = is_key_frame ? 20 : 1;
529 const int64_t threshold_base =
530 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
531 if (is_key_frame) {
532 thresholds[1] = threshold_base;
533 thresholds[2] = threshold_base >> 2;
534 thresholds[3] = threshold_base >> 2;
535 thresholds[4] = threshold_base << 2;
536 } else {
537 thresholds[2] = threshold_base;
538 if (cm->width <= 352 && cm->height <= 288) {
539 thresholds[1] = threshold_base >> 2;
540 thresholds[3] = threshold_base << 3;
541 } else {
542 thresholds[1] = threshold_base;
543 thresholds[2] = (5 * threshold_base) >> 2;
544 if (cm->width >= 1920 && cm->height >= 1080)
545 thresholds[2] = (7 * threshold_base) >> 2;
546 thresholds[3] = threshold_base << cpi->oxcf.speed;
547 }
548 }
549 thresholds[0] = INT64_MIN;
550}
551
Yaowu Xuf883b422016-08-30 14:01:10 -0700552void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
553 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700554 SPEED_FEATURES *const sf = &cpi->sf;
555 const int is_key_frame = (cm->frame_type == KEY_FRAME);
556 if (sf->partition_search_type != VAR_BASED_PARTITION &&
557 sf->partition_search_type != REFERENCE_PARTITION) {
558 return;
559 } else {
560 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
561 // The thresholds below are not changed locally.
562 if (is_key_frame) {
563 cpi->vbp_threshold_sad = 0;
564 cpi->vbp_bsize_min = BLOCK_8X8;
565 } else {
566 if (cm->width <= 352 && cm->height <= 288)
567 cpi->vbp_threshold_sad = 100;
568 else
569 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
570 ? (cpi->y_dequant[q][1] << 1)
571 : 1000;
572 cpi->vbp_bsize_min = BLOCK_16X16;
573 }
574 cpi->vbp_threshold_minmax = 15 + (q >> 3);
575 }
576}
577
578// Compute the minmax over the 8x8 subblocks.
579static int compute_minmax_8x8(const uint8_t *src, int src_stride,
580 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700581#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700582 int highbd,
583#endif
584 int pixels_wide, int pixels_high) {
585 int k;
586 int minmax_max = 0;
587 int minmax_min = 255;
588 // Loop over the 4 8x8 subblocks.
589 for (k = 0; k < 4; k++) {
590 const int x8_idx = ((k & 1) << 3);
591 const int y8_idx = ((k >> 1) << 3);
592 int min = 0;
593 int max = 0;
594 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
595 const int src_offset = y8_idx * src_stride + x8_idx;
596 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700597#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700598 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700599 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 ref_stride, &min, &max);
601 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700602 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603 ref_stride, &min, &max);
604 }
605#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700606 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700607 &min, &max);
608#endif
609 if ((max - min) > minmax_max) minmax_max = (max - min);
610 if ((max - min) < minmax_min) minmax_min = (max - min);
611 }
612 }
613 return (minmax_max - minmax_min);
614}
615
Yaowu Xuf883b422016-08-30 14:01:10 -0700616#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700617static INLINE int avg_4x4(const uint8_t *const src, const int stride,
618 const int highbd) {
619 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700620 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700622 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700623 }
624}
625#else
626static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700627 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628}
629#endif
630
Yaowu Xuf883b422016-08-30 14:01:10 -0700631#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700632static INLINE int avg_8x8(const uint8_t *const src, const int stride,
633 const int highbd) {
634 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700635 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700637 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 }
639}
640#else
641static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700642 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643}
644#endif
645
646static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700647#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648 const int highbd,
649#endif
650 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
651 const int width, const int height,
652 const uint8_t *const src, const int src_stride,
653 const uint8_t *const ref, const int ref_stride) {
654 assert(bsize >= leaf_size);
655
656 vt->bsize = bsize;
657
658 vt->force_split = 0;
659
660 vt->src = src;
661 vt->src_stride = src_stride;
662 vt->ref = ref;
663 vt->ref_stride = ref_stride;
664
665 vt->width = width;
666 vt->height = height;
667
Yaowu Xuf883b422016-08-30 14:01:10 -0700668#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700669 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700670#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700671
672 if (bsize > leaf_size) {
673 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
674 const int px = num_4x4_blocks_wide_lookup[subsize] * 4;
675
676 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700677#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700679#endif // CONFIG_AOM_HIGHBITDEPTH
680 subsize, leaf_size, AOMMIN(px, width),
681 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700682 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700683#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700685#endif // CONFIG_AOM_HIGHBITDEPTH
686 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 src + px, src_stride, ref + px, ref_stride);
688 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700689#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700691#endif // CONFIG_AOM_HIGHBITDEPTH
692 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700693 src + px * src_stride, src_stride, ref + px * ref_stride,
694 ref_stride);
695 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700696#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700697 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700698#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699 subsize, leaf_size, width - px, height - px,
700 src + px * src_stride + px, src_stride,
701 ref + px * ref_stride + px, ref_stride);
702 }
703}
704
705// Fill the variance tree based on averaging pixel values (sub-sampling), at
706// the leaf node size.
707static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
708 if (vt->bsize > leaf_size) {
709 fill_variance_tree(vt->split[0], leaf_size);
710 fill_variance_tree(vt->split[1], leaf_size);
711 fill_variance_tree(vt->split[2], leaf_size);
712 fill_variance_tree(vt->split[3], leaf_size);
713 fill_variance_node(vt);
714 } else if (vt->width <= 0 || vt->height <= 0) {
715 fill_variance(0, 0, 0, &vt->variances.none);
716 } else {
717 unsigned int sse = 0;
718 int sum = 0;
719 int src_avg;
720 int ref_avg;
721 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
722 if (leaf_size == BLOCK_4X4) {
723 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
724 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
725 } else {
726 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
727 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
728 }
729 sum = src_avg - ref_avg;
730 sse = sum * sum;
731 fill_variance(sse, sum, 0, &vt->variances.none);
732 }
733}
734
735static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
736 if (vt->bsize >= BLOCK_8X8) {
737 if (vt->bsize == BLOCK_16X16) {
738 if (vt->variances.none.variance <= threshold)
739 return;
740 else
741 vt->force_split = 0;
742 }
743
744 refine_variance_tree(vt->split[0], threshold);
745 refine_variance_tree(vt->split[1], threshold);
746 refine_variance_tree(vt->split[2], threshold);
747 refine_variance_tree(vt->split[3], threshold);
748
749 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
750 } else if (vt->width <= 0 || vt->height <= 0) {
751 fill_variance(0, 0, 0, &vt->variances.none);
752 } else {
753 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
754 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
755 const int sum = src_avg - ref_avg;
756 const unsigned int sse = sum * sum;
757 assert(vt->bsize == BLOCK_4X4);
758 fill_variance(sse, sum, 0, &vt->variances.none);
759 }
760}
761
762static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
763 if (vt->bsize == BLOCK_32X32) {
764 vt->force_split = vt->variances.none.variance > threshold;
765 } else {
766 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
767 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
768 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
769 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
770 }
771 return vt->force_split;
772}
773
Yaowu Xuf883b422016-08-30 14:01:10 -0700774static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775 const int segment_id, const int64_t *const thresholds) {
776 if (vt->bsize == BLOCK_16X16) {
777 vt->force_split = vt->variances.none.variance > thresholds[0];
778 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
779 !cyclic_refresh_segment_id_boosted(segment_id)) {
780 // We have some nominal amount of 16x16 variance (based on average),
781 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
782 // force split to 8x8 block for this 16x16 block.
783 int minmax =
784 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700785#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700786 vt->highbd,
787#endif
788 vt->width, vt->height);
789 vt->force_split = minmax > cpi->vbp_threshold_minmax;
790 }
791 } else {
792 vt->force_split |=
793 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
794 vt->force_split |=
795 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
796 vt->force_split |=
797 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
798 vt->force_split |=
799 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
800
801 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
802 vt->force_split = vt->variances.none.variance > thresholds[0];
803 }
804 }
805
806 return vt->force_split;
807}
808
809// This function chooses partitioning based on the variance between source and
810// reconstructed last (or golden), where variance is computed for down-sampled
811// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700812static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813 const TileInfo *const tile, MACROBLOCK *const x,
814 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700815 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816 MACROBLOCKD *const xd = &x->e_mbd;
817 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
818 int i;
819 const uint8_t *src;
820 const uint8_t *ref;
821 int src_stride;
822 int ref_stride;
823 int pixels_wide = 8 * num_8x8_blocks_wide_lookup[cm->sb_size];
824 int pixels_high = 8 * num_8x8_blocks_high_lookup[cm->sb_size];
825 int64_t thresholds[5] = {
826 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
827 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
828 };
829 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
830 cpi->vbp_bsize_min, BLOCK_8X8 };
831 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
832 const int64_t *const thre = thresholds + start_level;
833 const BLOCK_SIZE *const bmin = bsize_min + start_level;
834
835 const int is_key_frame = (cm->frame_type == KEY_FRAME);
836 const int low_res = (cm->width <= 352 && cm->height <= 288);
837
838 int segment_id = CR_SEGMENT_ID_BASE;
839
840 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
841 const uint8_t *const map =
842 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
843 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
844
845 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700846 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700847 assert(q == xd->qindex[segment_id]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700848 set_vbp_thresholds(cpi, thresholds, q);
849 }
850 }
851
852 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
853
854 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
855 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
856
857 src = x->plane[0].src.buf;
858 src_stride = x->plane[0].src.stride;
859
860 if (!is_key_frame) {
861 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
862 unsigned int uv_sad;
863 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
864 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
865 unsigned int y_sad, y_sad_g;
866
867 const int hbs = cm->mib_size / 2;
868 const int split_vert = mi_col + hbs >= cm->mi_cols;
869 const int split_horz = mi_row + hbs >= cm->mi_rows;
870 BLOCK_SIZE bsize;
871
872 if (split_vert && split_horz)
873 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
874 else if (split_vert)
875 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
876 else if (split_horz)
877 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
878 else
879 bsize = cm->sb_size;
880
881 assert(yv12 != NULL);
882
883 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700884 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
885 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 y_sad_g = cpi->fn_ptr[bsize].sdf(
887 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
888 xd->plane[0].pre[0].stride);
889 } else {
890 y_sad_g = UINT_MAX;
891 }
892
Yaowu Xuf883b422016-08-30 14:01:10 -0700893 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
894 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895 mbmi->ref_frame[0] = LAST_FRAME;
896 mbmi->ref_frame[1] = NONE;
897 mbmi->sb_type = cm->sb_size;
898 mbmi->mv[0].as_int = 0;
899#if CONFIG_DUAL_FILTER
900 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
901#else
902 mbmi->interp_filter = BILINEAR;
903#endif
904
Yaowu Xuf883b422016-08-30 14:01:10 -0700905 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700906
907 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700908 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
909 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700910 mbmi->ref_frame[0] = GOLDEN_FRAME;
911 mbmi->mv[0].as_int = 0;
912 y_sad = y_sad_g;
913 } else {
914 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
915 }
916
Yaowu Xuf883b422016-08-30 14:01:10 -0700917 av1_build_inter_predictors_sb(xd, mi_row, mi_col, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918
919 for (i = 1; i < MAX_MB_PLANE; ++i) {
920 struct macroblock_plane *p = &x->plane[i];
921 struct macroblockd_plane *pd = &xd->plane[i];
922 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
923
924 if (bs == BLOCK_INVALID)
925 uv_sad = UINT_MAX;
926 else
927 uv_sad = cpi->fn_ptr[bs].sdf(p->src.buf, p->src.stride, pd->dst.buf,
928 pd->dst.stride);
929
930 x->color_sensitivity[i - 1] = uv_sad > (y_sad >> 2);
931 }
932
933 ref = xd->plane[0].dst.buf;
934 ref_stride = xd->plane[0].dst.stride;
935
936 // If the y_sad is very small, take the largest partition and exit.
937 // Don't check on boosted segment for now, as largest is suppressed there.
938 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
939 if (!split_vert && !split_horz) {
940 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
941 return;
942 }
943 }
944 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700945 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700947#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
949 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700950 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
951 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700953 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700954 }
955 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700956#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700957 }
958
959 init_variance_tree(
960 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700961#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700963#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700964 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
965 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
966
967 // Fill in the entire tree of variances and compute splits.
968 if (is_key_frame) {
969 fill_variance_tree(vt, BLOCK_4X4);
970 check_split_key_frame(vt, thre[1]);
971 } else {
972 fill_variance_tree(vt, BLOCK_8X8);
973 check_split(cpi, vt, segment_id, thre);
974 if (low_res) {
975 refine_variance_tree(vt, thre[1] << 1);
976 }
977 }
978
979 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
980 mi_row + cm->mib_size > cm->mi_rows;
981
982 // Now go through the entire structure, splitting every block size until
983 // we get to one that's got a variance lower than our threshold.
984 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
985}
986
987#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700988static void reset_intmv_filter_type(AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700989 MB_MODE_INFO *mbmi) {
990 int dir;
991 for (dir = 0; dir < 2; ++dir) {
992 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
993 (mbmi->ref_frame[1] == NONE ||
994 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
995 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
996 ? EIGHTTAP_REGULAR
997 : cm->interp_filter;
998 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
999 }
1000}
1001
1002static void update_filter_type_count(FRAME_COUNTS *counts,
1003 const MACROBLOCKD *xd,
1004 const MB_MODE_INFO *mbmi) {
1005 int dir;
1006 for (dir = 0; dir < 2; ++dir) {
1007 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
1008 (mbmi->ref_frame[1] > INTRA_FRAME &&
1009 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001010 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001011 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1012 }
1013 }
1014}
1015#endif
1016#if CONFIG_GLOBAL_MOTION
1017static void update_global_motion_used(PREDICTION_MODE mode,
Yaowu Xuf883b422016-08-30 14:01:10 -07001018 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019 if (mode == ZEROMV) {
1020 ++cpi->global_motion_used[mbmi->ref_frame[0]];
1021 if (has_second_ref(mbmi)) ++cpi->global_motion_used[mbmi->ref_frame[1]];
1022 }
1023}
1024#endif // CONFIG_GLOBAL_MOTION
1025
Yaowu Xuf883b422016-08-30 14:01:10 -07001026static void update_state(AV1_COMP *cpi, ThreadData *td, PICK_MODE_CONTEXT *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001027 int mi_row, int mi_col, BLOCK_SIZE bsize,
1028 int output_enabled) {
1029 int i, x_idx, y;
Yaowu Xuf883b422016-08-30 14:01:10 -07001030 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001031 RD_COUNTS *const rdc = &td->rd_counts;
1032 MACROBLOCK *const x = &td->mb;
1033 MACROBLOCKD *const xd = &x->e_mbd;
1034 struct macroblock_plane *const p = x->plane;
1035 struct macroblockd_plane *const pd = xd->plane;
1036 MODE_INFO *mi = &ctx->mic;
1037 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1038 MODE_INFO *mi_addr = xd->mi[0];
1039 const struct segmentation *const seg = &cm->seg;
1040 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
1041 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001042 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1043 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001044 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1045 int w, h;
1046
1047 const int mis = cm->mi_stride;
1048 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1049 const int mi_height = num_8x8_blocks_high_lookup[bsize];
1050 int max_plane;
1051
1052#if CONFIG_REF_MV
1053 int8_t rf_type;
1054#endif
1055
1056#if !CONFIG_SUPERTX
1057 assert(mi->mbmi.sb_type == bsize);
1058#endif
1059
1060 *mi_addr = *mi;
1061 *x->mbmi_ext = ctx->mbmi_ext;
1062
1063#if CONFIG_DUAL_FILTER
1064 reset_intmv_filter_type(cm, xd, mbmi);
1065#endif
1066
1067#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001068 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001069 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1070 mbmi->mode == NEWMV) {
1071 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1072 int_mv this_mv =
1073 (i == 0)
1074 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1075 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1076 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1077 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1078 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001079 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001080 }
1081 }
1082#endif
1083
1084 // If segmentation in use
1085 if (seg->enabled) {
1086 // For in frame complexity AQ copy the segment id from the segment map.
1087 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1088 const uint8_t *const map =
1089 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1090 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1091 }
1092 // Else for cyclic refresh mode update the segment map, set the segment id
1093 // and then update the quantizer.
1094 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001095 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1096 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001097 }
1098 }
1099
1100 max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
1101 for (i = 0; i < max_plane; ++i) {
1102 p[i].coeff = ctx->coeff[i][1];
1103 p[i].qcoeff = ctx->qcoeff[i][1];
1104 pd[i].dqcoeff = ctx->dqcoeff[i][1];
1105 p[i].eobs = ctx->eobs[i][1];
1106 }
1107
1108 for (i = max_plane; i < MAX_MB_PLANE; ++i) {
1109 p[i].coeff = ctx->coeff[i][2];
1110 p[i].qcoeff = ctx->qcoeff[i][2];
1111 pd[i].dqcoeff = ctx->dqcoeff[i][2];
1112 p[i].eobs = ctx->eobs[i][2];
1113 }
1114
1115 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
1116
1117 // Restore the coding context of the MB to that that was in place
1118 // when the mode was picked for it
1119 for (y = 0; y < mi_height; y++)
1120 for (x_idx = 0; x_idx < mi_width; x_idx++)
1121 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1122 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1123 xd->mi[x_idx + y * mis] = mi_addr;
1124 }
1125
1126 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001127 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128
1129 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1130 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1131 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1132 }
1133
1134 x->skip = ctx->skip;
1135
1136#if CONFIG_VAR_TX
1137 for (i = 0; i < 1; ++i)
1138 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1139 sizeof(uint8_t) * ctx->num_4x4_blk);
1140#endif
1141
1142 if (!output_enabled) return;
1143
1144#if CONFIG_INTERNAL_STATS
1145 if (frame_is_intra_only(cm)) {
1146 static const int kf_mode_index[] = {
1147 THR_DC /*DC_PRED*/, THR_V_PRED /*V_PRED*/,
1148 THR_H_PRED /*H_PRED*/, THR_D45_PRED /*D45_PRED*/,
1149 THR_D135_PRED /*D135_PRED*/, THR_D117_PRED /*D117_PRED*/,
1150 THR_D153_PRED /*D153_PRED*/, THR_D207_PRED /*D207_PRED*/,
1151 THR_D63_PRED /*D63_PRED*/, THR_TM /*TM_PRED*/,
1152 };
1153 ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]];
1154 } else {
1155 // Note how often each mode chosen as best
1156 ++cpi->mode_chosen_counts[ctx->best_mode_index];
1157 }
1158#endif
1159 if (!frame_is_intra_only(cm)) {
1160 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001161 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162#if CONFIG_GLOBAL_MOTION
1163 if (bsize >= BLOCK_8X8) {
1164 update_global_motion_used(mbmi->mode, mbmi, cpi);
1165 } else {
1166 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1167 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1168 int idx, idy;
1169 for (idy = 0; idy < 2; idy += num_4x4_h) {
1170 for (idx = 0; idx < 2; idx += num_4x4_w) {
1171 const int j = idy * 2 + idx;
1172 update_global_motion_used(mi->bmi[j].as_mode, mbmi, cpi);
1173 }
1174 }
1175 }
1176#endif // CONFIG_GLOBAL_MOTION
1177 if (cm->interp_filter == SWITCHABLE
1178#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001179 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180#endif
1181 ) {
1182#if CONFIG_DUAL_FILTER
1183 update_filter_type_count(td->counts, xd, mbmi);
1184#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001185 const int ctx = av1_get_pred_context_switchable_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 ++td->counts->switchable_interp[ctx][mbmi->interp_filter];
1187#endif
1188 }
1189 }
1190
1191 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1192 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1193 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1194 }
1195
1196 for (h = 0; h < y_mis; ++h) {
1197 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1198 for (w = 0; w < x_mis; ++w) {
1199 MV_REF *const mv = frame_mv + w;
1200 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1201 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1202 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1203 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1204 }
1205 }
1206}
1207
1208#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001209static void update_state_supertx(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1211 BLOCK_SIZE bsize, int output_enabled) {
1212 int y, x_idx;
1213#if CONFIG_VAR_TX || CONFIG_REF_MV
1214 int i;
1215#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001216 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217 RD_COUNTS *const rdc = &td->rd_counts;
1218 MACROBLOCK *const x = &td->mb;
1219 MACROBLOCKD *const xd = &x->e_mbd;
1220 MODE_INFO *mi = &ctx->mic;
1221 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1222 MODE_INFO *mi_addr = xd->mi[0];
1223 const struct segmentation *const seg = &cm->seg;
1224 const int mis = cm->mi_stride;
1225 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1226 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001227 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1228 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1230 int w, h;
1231
1232#if CONFIG_REF_MV
1233 int8_t rf_type;
1234#endif
1235
1236 *mi_addr = *mi;
1237 *x->mbmi_ext = ctx->mbmi_ext;
1238 assert(is_inter_block(mbmi));
1239 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1240
1241#if CONFIG_DUAL_FILTER
1242 reset_intmv_filter_type(cm, xd, mbmi);
1243#endif
1244
1245#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001246 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001247 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1248 mbmi->mode == NEWMV) {
1249 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1250 int_mv this_mv =
1251 (i == 0)
1252 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1253 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1254 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1255 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1256 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1257 mbmi->pred_mv[i] = this_mv;
1258 }
1259 }
1260#endif
1261
1262 // If segmentation in use
1263 if (seg->enabled) {
1264 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001265 const int energy =
1266 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1267 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001268 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1269 // For cyclic refresh mode, now update the segment map
1270 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001271 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1272 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001273 } else {
1274 // Otherwise just set the segment id based on the current segment map
1275 const uint8_t *const map =
1276 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1277 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1278 }
1279 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1280 }
1281
1282 // Restore the coding context of the MB to that that was in place
1283 // when the mode was picked for it
1284 for (y = 0; y < mi_height; y++)
1285 for (x_idx = 0; x_idx < mi_width; x_idx++)
1286 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1287 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1288 xd->mi[x_idx + y * mis] = mi_addr;
1289 }
1290
1291 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1292 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1293 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1294 }
1295
1296 x->skip = ctx->skip;
1297
1298#if CONFIG_VAR_TX
1299 for (i = 0; i < 1; ++i)
1300 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1301 sizeof(uint8_t) * ctx->num_4x4_blk);
1302#endif // CONFIG_VAR_TX
1303
1304#if CONFIG_VAR_TX
1305 {
1306 const TX_SIZE mtx = mbmi->tx_size;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001307 const int num_4x4_blocks_wide = num_4x4_blocks_wide_txsize_lookup[mtx] >> 1;
1308 const int num_4x4_blocks_high = num_4x4_blocks_high_txsize_lookup[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001310 mbmi->inter_tx_size[0][0] = mtx;
1311 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1312 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1313 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001314 }
1315#endif // CONFIG_VAR_TX
1316 // Turn motion variation off for supertx
1317 mbmi->motion_variation = SIMPLE_TRANSLATION;
1318
1319 if (!output_enabled) return;
1320
1321 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001322 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001323
1324 if (cm->interp_filter == SWITCHABLE
1325#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001326 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001327#endif
1328 ) {
1329#if CONFIG_DUAL_FILTER
1330 update_filter_type_count(td->counts, xd, mbmi);
1331#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001332 const int ctx = av1_get_pred_context_switchable_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001333 ++td->counts->switchable_interp[ctx][mbmi->interp_filter];
1334#endif
1335 }
1336
1337 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1338 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1339 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1340 }
1341
1342 for (h = 0; h < y_mis; ++h) {
1343 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1344 for (w = 0; w < x_mis; ++w) {
1345 MV_REF *const mv = frame_mv + w;
1346 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1347 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1348 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1349 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1350 }
1351 }
1352}
1353
Yaowu Xuf883b422016-08-30 14:01:10 -07001354static void update_state_sb_supertx(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001355 const TileInfo *const tile, int mi_row,
1356 int mi_col, BLOCK_SIZE bsize,
1357 int output_enabled, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001358 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001359 MACROBLOCK *const x = &td->mb;
1360 MACROBLOCKD *const xd = &x->e_mbd;
1361 struct macroblock_plane *const p = x->plane;
1362 struct macroblockd_plane *const pd = xd->plane;
1363 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1364 PARTITION_TYPE partition = pc_tree->partitioning;
1365 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1366 int i;
1367#if CONFIG_EXT_PARTITION_TYPES
1368 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1369#endif
1370 PICK_MODE_CONTEXT *pmc = NULL;
1371
1372 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1373
1374 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001375 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001376
1377 switch (partition) {
1378 case PARTITION_NONE:
1379 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1380 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
1381 output_enabled);
1382 break;
1383 case PARTITION_VERT:
1384 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1385 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
1386 subsize, output_enabled);
1387 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1388 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1389 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
1390 mi_col + hbs, subsize, output_enabled);
1391 }
1392 pmc = &pc_tree->vertical_supertx;
1393 break;
1394 case PARTITION_HORZ:
1395 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1396 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
1397 subsize, output_enabled);
1398 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1399 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1400 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
1401 mi_col, subsize, output_enabled);
1402 }
1403 pmc = &pc_tree->horizontal_supertx;
1404 break;
1405 case PARTITION_SPLIT:
1406 if (bsize == BLOCK_8X8) {
1407 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1408 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
1409 subsize, output_enabled);
1410 } else {
1411 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1412 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize,
1413 output_enabled, pc_tree->split[0]);
1414 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1415 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
1416 output_enabled, pc_tree->split[1]);
1417 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1418 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
1419 output_enabled, pc_tree->split[2]);
1420 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1421 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
1422 subsize, output_enabled, pc_tree->split[3]);
1423 }
1424 pmc = &pc_tree->split_supertx;
1425 break;
1426#if CONFIG_EXT_PARTITION_TYPES
1427 case PARTITION_HORZ_A:
1428 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1429 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
1430 bsize2, output_enabled);
1431 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1432 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
1433 mi_col + hbs, bsize2, output_enabled);
1434 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1435 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
1436 mi_col, subsize, output_enabled);
1437 pmc = &pc_tree->horizontala_supertx;
1438 break;
1439 case PARTITION_HORZ_B:
1440 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1441 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
1442 subsize, output_enabled);
1443 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1444 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
1445 mi_col, bsize2, output_enabled);
1446 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1447 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
1448 mi_col + hbs, bsize2, output_enabled);
1449 pmc = &pc_tree->horizontalb_supertx;
1450 break;
1451 case PARTITION_VERT_A:
1452 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1453 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
1454 bsize2, output_enabled);
1455 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1456 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
1457 mi_col, bsize2, output_enabled);
1458 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1459 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
1460 mi_col + hbs, subsize, output_enabled);
1461 pmc = &pc_tree->verticala_supertx;
1462 break;
1463 case PARTITION_VERT_B:
1464 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1465 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
1466 subsize, output_enabled);
1467 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1468 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
1469 mi_col + hbs, bsize2, output_enabled);
1470 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1471 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
1472 mi_col + hbs, bsize2, output_enabled);
1473 pmc = &pc_tree->verticalb_supertx;
1474 break;
1475#endif // CONFIG_EXT_PARTITION_TYPES
1476 default: assert(0);
1477 }
1478
1479 for (i = 0; i < MAX_MB_PLANE; ++i) {
1480 if (pmc != NULL) {
1481 p[i].coeff = pmc->coeff[i][1];
1482 p[i].qcoeff = pmc->qcoeff[i][1];
1483 pd[i].dqcoeff = pmc->dqcoeff[i][1];
1484 p[i].eobs = pmc->eobs[i][1];
1485 } else {
1486 // These should never be used
1487 p[i].coeff = NULL;
1488 p[i].qcoeff = NULL;
1489 pd[i].dqcoeff = NULL;
1490 p[i].eobs = NULL;
1491 }
1492 }
1493}
1494
1495static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1496 int best_tx, TX_SIZE supertx_size) {
1497 MACROBLOCK *const x = &td->mb;
1498#if CONFIG_VAR_TX
1499 int i;
1500
1501 for (i = 0; i < 1; ++i)
1502 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1503 sizeof(uint8_t) * ctx->num_4x4_blk);
1504#endif // CONFIG_VAR_TX
1505 ctx->mic.mbmi.tx_size = supertx_size;
1506 ctx->skip = x->skip;
1507 ctx->mic.mbmi.tx_type = best_tx;
1508}
1509
Yaowu Xuf883b422016-08-30 14:01:10 -07001510static void update_supertx_param_sb(AV1_COMP *cpi, ThreadData *td, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001511 int mi_col, BLOCK_SIZE bsize, int best_tx,
1512 TX_SIZE supertx_size, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001513 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001514 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1515 PARTITION_TYPE partition = pc_tree->partitioning;
1516 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1517#if CONFIG_EXT_PARTITION_TYPES
1518 int i;
1519#endif
1520
1521 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1522
1523 switch (partition) {
1524 case PARTITION_NONE:
1525 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1526 break;
1527 case PARTITION_VERT:
1528 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
1529 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8)
1530 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1531 break;
1532 case PARTITION_HORZ:
1533 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
1534 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8)
1535 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1536 supertx_size);
1537 break;
1538 case PARTITION_SPLIT:
1539 if (bsize == BLOCK_8X8) {
1540 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1541 } else {
1542 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1543 supertx_size, pc_tree->split[0]);
1544 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1545 supertx_size, pc_tree->split[1]);
1546 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1547 supertx_size, pc_tree->split[2]);
1548 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1549 best_tx, supertx_size, pc_tree->split[3]);
1550 }
1551 break;
1552#if CONFIG_EXT_PARTITION_TYPES
1553 case PARTITION_HORZ_A:
1554 for (i = 0; i < 3; i++)
1555 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1556 supertx_size);
1557 break;
1558 case PARTITION_HORZ_B:
1559 for (i = 0; i < 3; i++)
1560 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1561 supertx_size);
1562 break;
1563 case PARTITION_VERT_A:
1564 for (i = 0; i < 3; i++)
1565 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1566 break;
1567 case PARTITION_VERT_B:
1568 for (i = 0; i < 3; i++)
1569 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1570 break;
1571#endif // CONFIG_EXT_PARTITION_TYPES
1572 default: assert(0);
1573 }
1574}
1575#endif // CONFIG_SUPERTX
1576
Yaowu Xuf883b422016-08-30 14:01:10 -07001577void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1578 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001579 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1580 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1581 src->uv_crop_width };
1582 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1583 src->uv_crop_height };
1584 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1585 int i;
1586
1587 // Set current frame pointer.
1588 x->e_mbd.cur_buf = src;
1589
1590 for (i = 0; i < MAX_MB_PLANE; i++)
1591 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1592 strides[i], mi_row, mi_col, NULL,
1593 x->e_mbd.plane[i].subsampling_x,
1594 x->e_mbd.plane[i].subsampling_y);
1595}
1596
Yaowu Xuf883b422016-08-30 14:01:10 -07001597static int set_segment_rdmult(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001598 int8_t segment_id) {
1599 int segment_qindex;
Yaowu Xuf883b422016-08-30 14:01:10 -07001600 AV1_COMMON *const cm = &cpi->common;
1601 av1_init_plane_quantizers(cpi, x, segment_id);
1602 aom_clear_system_state();
1603 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Debargha Mukherjee3c42c092016-09-29 09:17:36 -07001604 assert(segment_qindex == x->e_mbd.qindex[segment_id]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001605 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001606}
1607
Yaowu Xuf883b422016-08-30 14:01:10 -07001608static void rd_pick_sb_modes(AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001609 MACROBLOCK *const x, int mi_row, int mi_col,
1610 RD_COST *rd_cost,
1611#if CONFIG_SUPERTX
1612 int *totalrate_nocoef,
1613#endif
1614#if CONFIG_EXT_PARTITION_TYPES
1615 PARTITION_TYPE partition,
1616#endif
1617 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1618 int64_t best_rd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001619 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620 TileInfo *const tile_info = &tile_data->tile_info;
1621 MACROBLOCKD *const xd = &x->e_mbd;
1622 MB_MODE_INFO *mbmi;
1623 struct macroblock_plane *const p = x->plane;
1624 struct macroblockd_plane *const pd = xd->plane;
1625 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1626 int i, orig_rdmult;
1627
Yaowu Xuf883b422016-08-30 14:01:10 -07001628 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001629
1630 // Use the lower precision, but faster, 32x32 fdct for mode selection.
1631 x->use_lp32x32fdct = 1;
1632
1633 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1634 mbmi = &xd->mi[0]->mbmi;
1635 mbmi->sb_type = bsize;
1636#if CONFIG_SUPERTX
1637 // We set tx_size here as skip blocks would otherwise not set it.
1638 // tx_size needs to be set at this point as supertx_enable in
1639 // write_modes_sb is computed based on this, and if the garbage in memory
1640 // just happens to be the supertx_size, then the packer will code this
1641 // block as a supertx block, even if rdopt did not pick it as such.
1642 mbmi->tx_size = max_txsize_lookup[bsize];
1643#endif
1644#if CONFIG_EXT_PARTITION_TYPES
1645 mbmi->partition = partition;
1646#endif
1647
1648 for (i = 0; i < MAX_MB_PLANE; ++i) {
1649 p[i].coeff = ctx->coeff[i][0];
1650 p[i].qcoeff = ctx->qcoeff[i][0];
1651 pd[i].dqcoeff = ctx->dqcoeff[i][0];
1652 p[i].eobs = ctx->eobs[i][0];
1653 }
1654
1655 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
1656
1657 ctx->is_coded = 0;
1658 ctx->skippable = 0;
1659 ctx->pred_pixel_ready = 0;
1660
1661 // Set to zero to make sure we do not use the previous encoded frame stats
1662 mbmi->skip = 0;
1663
Yaowu Xuf883b422016-08-30 14:01:10 -07001664#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001665 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001666 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001667 cpi, &x->plane[0].src, bsize, xd->bd);
1668 } else {
1669 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001670 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001671 }
1672#else
1673 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001674 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1675#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001676
1677 // Save rdmult before it might be changed, so it can be restored later.
1678 orig_rdmult = x->rdmult;
1679
1680 if (aq_mode == VARIANCE_AQ) {
1681 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001682 const int energy =
1683 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1684 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001685 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001686 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001687 x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
1688 }
1689 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1690 } else if (aq_mode == COMPLEXITY_AQ) {
1691 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1692 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1693 // If segment is boosted, use rdmult for that segment.
1694 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001695 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001696 }
1697
1698 // Find best coding mode & reconstruct the MB so it is available
1699 // as a predictor for MBs that follow in the SB
1700 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001701 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702#if CONFIG_SUPERTX
1703 *totalrate_nocoef = 0;
1704#endif // CONFIG_SUPERTX
1705 } else {
1706 if (bsize >= BLOCK_8X8) {
1707 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001708 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1709 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001710#if CONFIG_SUPERTX
1711 *totalrate_nocoef = rd_cost->rate;
1712#endif // CONFIG_SUPERTX
1713 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001714 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001716 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001717#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001718 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001719#if CONFIG_SUPERTX
1720 assert(*totalrate_nocoef >= 0);
1721#endif // CONFIG_SUPERTX
1722 }
1723 } else {
1724 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1725 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1726 rd_cost->rate = INT_MAX;
1727 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001728 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1729 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001730#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001731 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001733 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001734#if CONFIG_SUPERTX
1735 assert(*totalrate_nocoef >= 0);
1736#endif // CONFIG_SUPERTX
1737 }
1738 }
1739 }
1740
1741 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1742 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1743 (bsize >= BLOCK_16X16) &&
1744 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1745 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001746 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001747 }
1748
1749 x->rdmult = orig_rdmult;
1750
1751 // TODO(jingning) The rate-distortion optimization flow needs to be
1752 // refactored to provide proper exit/return handle.
1753 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1754
1755 ctx->rate = rd_cost->rate;
1756 ctx->dist = rd_cost->dist;
1757}
1758
1759#if CONFIG_REF_MV
1760static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1761#if CONFIG_EXT_INTER
1762 int is_compound,
1763#endif // CONFIG_EXT_INTER
1764 int16_t mode_context) {
1765 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1766#if CONFIG_EXT_INTER
1767 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1768 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1769#else
1770 if (mode == NEWMV) {
1771#endif // CONFIG_EXT_INTER
1772 ++counts->newmv_mode[mode_ctx][0];
1773 return;
1774 } else {
1775 ++counts->newmv_mode[mode_ctx][1];
1776
1777 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1778 return;
1779 }
1780
1781 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1782 if (mode == ZEROMV) {
1783 ++counts->zeromv_mode[mode_ctx][0];
1784 return;
1785 } else {
1786 ++counts->zeromv_mode[mode_ctx][1];
1787 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1788
1789 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1790 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1791 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1792
1793 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1794 }
1795 }
1796}
1797#endif
1798
Yaowu Xuf883b422016-08-30 14:01:10 -07001799static void update_stats(AV1_COMMON *cm, ThreadData *td
Yaowu Xuc27fc142016-08-22 16:08:15 -07001800#if CONFIG_SUPERTX
1801 ,
1802 int supertx_enabled
1803#endif
1804 ) {
1805 const MACROBLOCK *x = &td->mb;
1806 const MACROBLOCKD *const xd = &x->e_mbd;
1807 const MODE_INFO *const mi = xd->mi[0];
1808 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1809 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1810 const BLOCK_SIZE bsize = mbmi->sb_type;
1811
1812 if (!frame_is_intra_only(cm)) {
1813 FRAME_COUNTS *const counts = td->counts;
1814 const int inter_block = is_inter_block(mbmi);
1815 const int seg_ref_active =
1816 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1817 if (!seg_ref_active) {
1818#if CONFIG_SUPERTX
1819 if (!supertx_enabled)
1820#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001821 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001822 // If the segment reference feature is enabled we have only a single
1823 // reference frame allowed for the segment so exclude it from
1824 // the reference frame counts used to work out probabilities.
1825 if (inter_block) {
1826 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1827#if CONFIG_EXT_REFS
1828 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1829#endif // CONFIG_EXT_REFS
1830
1831 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07001832 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1833 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001834
1835 if (has_second_ref(mbmi)) {
1836#if CONFIG_EXT_REFS
1837 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1838
Yaowu Xuf883b422016-08-30 14:01:10 -07001839 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001840 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07001841 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1842 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001843 } else {
clang-format67948d32016-09-07 22:40:40 -07001844 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1845 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001846 }
1847
clang-format67948d32016-09-07 22:40:40 -07001848 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1849 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001850#else
clang-format67948d32016-09-07 22:40:40 -07001851 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1852 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001853#endif // CONFIG_EXT_REFS
1854 } else {
1855#if CONFIG_EXT_REFS
1856 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
1857
Yaowu Xuf883b422016-08-30 14:01:10 -07001858 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07001860 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1861 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862 } else {
1863 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001864 counts->single_ref[av1_get_pred_context_single_ref_p3(xd)][2]
1865 [bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001867 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1868 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001869 } else {
clang-format67948d32016-09-07 22:40:40 -07001870 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1871 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001872 }
1873 }
1874#else
clang-format67948d32016-09-07 22:40:40 -07001875 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1876 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07001878 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1879 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880 }
1881#endif // CONFIG_EXT_REFS
1882 }
1883
1884#if CONFIG_EXT_INTER
1885 if (cm->reference_mode != COMPOUND_REFERENCE &&
1886#if CONFIG_SUPERTX
1887 !supertx_enabled &&
1888#endif
1889 is_interintra_allowed(mbmi)) {
1890 const int bsize_group = size_group_lookup[bsize];
1891 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1892 counts->interintra[bsize_group][1]++;
1893 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1894 if (is_interintra_wedge_used(bsize))
1895 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1896 } else {
1897 counts->interintra[bsize_group][0]++;
1898 }
1899 }
1900#endif // CONFIG_EXT_INTER
1901
1902#if CONFIG_OBMC || CONFIG_WARPED_MOTION
1903#if CONFIG_SUPERTX
1904 if (!supertx_enabled)
1905#endif // CONFIG_SUPERTX
1906#if CONFIG_EXT_INTER
1907 if (mbmi->ref_frame[1] != INTRA_FRAME)
1908#endif // CONFIG_EXT_INTER
1909 if (is_motvar_allowed(mbmi))
1910 counts->motvar[mbmi->sb_type][mbmi->motion_variation]++;
1911#endif // CONFIG_OBMC || CONFIG_WARPED_MOTION
1912
1913#if CONFIG_EXT_INTER
1914 if (cm->reference_mode != SINGLE_REFERENCE &&
1915 is_inter_compound_mode(mbmi->mode) &&
1916#if CONFIG_OBMC || CONFIG_WARPED_MOTION
1917 !(is_motvar_allowed(mbmi) &&
1918 mbmi->motion_variation != SIMPLE_TRANSLATION) &&
1919#endif // CONFIG_OBMC || CONFIG_WARPED_MOTION
1920 is_interinter_wedge_used(bsize)) {
1921 counts->wedge_interinter[bsize][mbmi->use_wedge_interinter]++;
1922 }
1923#endif // CONFIG_EXT_INTER
1924 }
1925 }
1926
1927 if (inter_block &&
1928 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1929 int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
1930 if (bsize >= BLOCK_8X8) {
1931 const PREDICTION_MODE mode = mbmi->mode;
1932#if CONFIG_REF_MV
1933#if CONFIG_EXT_INTER
1934 if (has_second_ref(mbmi)) {
1935 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1936 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
1937 } else {
1938#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001939 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
1940 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001941 update_inter_mode_stats(counts, mode,
1942#if CONFIG_EXT_INTER
1943 has_second_ref(mbmi),
1944#endif // CONFIG_EXT_INTER
1945 mode_ctx);
1946
1947 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001948 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949 int idx;
1950
1951 for (idx = 0; idx < 2; ++idx) {
1952 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1953 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07001954 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001955 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
1956
1957 if (mbmi->ref_mv_idx == idx) break;
1958 }
1959 }
1960 }
1961
1962 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001963 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001964 int idx;
1965
1966 for (idx = 1; idx < 3; ++idx) {
1967 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1968 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07001969 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001970 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
1971
1972 if (mbmi->ref_mv_idx == idx - 1) break;
1973 }
1974 }
1975 }
1976#if CONFIG_EXT_INTER
1977 }
1978#endif // CONFIG_EXT_INTER
1979#else
1980#if CONFIG_EXT_INTER
1981 if (is_inter_compound_mode(mode))
1982 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
1983 else
1984#endif // CONFIG_EXT_INTER
1985 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
1986#endif
1987 } else {
1988 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1989 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1990 int idx, idy;
1991 for (idy = 0; idy < 2; idy += num_4x4_h) {
1992 for (idx = 0; idx < 2; idx += num_4x4_w) {
1993 const int j = idy * 2 + idx;
1994 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
1995#if CONFIG_REF_MV
1996#if CONFIG_EXT_INTER
1997 if (has_second_ref(mbmi)) {
1998 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07001999 ++counts->inter_compound_mode[mode_ctx]
2000 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001 } else {
2002#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002003 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2004 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002005 update_inter_mode_stats(counts, b_mode,
2006#if CONFIG_EXT_INTER
2007 has_second_ref(mbmi),
2008#endif // CONFIG_EXT_INTER
2009 mode_ctx);
2010#if CONFIG_EXT_INTER
2011 }
2012#endif // CONFIG_EXT_INTER
2013#else
2014#if CONFIG_EXT_INTER
2015 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002016 ++counts->inter_compound_mode[mode_ctx]
2017 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002018 else
2019#endif // CONFIG_EXT_INTER
2020 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2021#endif
2022 }
2023 }
2024 }
2025 }
2026 }
2027}
2028
2029typedef struct {
2030 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2031 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2032 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2033 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2034#if CONFIG_VAR_TX
2035 TXFM_CONTEXT *p_ta;
2036 TXFM_CONTEXT *p_tl;
2037 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2038 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2039#endif
2040} RD_SEARCH_MACROBLOCK_CONTEXT;
2041
2042static void restore_context(MACROBLOCK *x,
2043 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
2044 int mi_col, BLOCK_SIZE bsize) {
2045 MACROBLOCKD *xd = &x->e_mbd;
2046 int p;
2047 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2048 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2049 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2050 int mi_height = num_8x8_blocks_high_lookup[bsize];
2051 for (p = 0; p < MAX_MB_PLANE; p++) {
2052 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2053 ctx->a + num_4x4_blocks_wide * p,
2054 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2055 xd->plane[p].subsampling_x);
2056 memcpy(xd->left_context[p] +
2057 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2058 ctx->l + num_4x4_blocks_high * p,
2059 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2060 xd->plane[p].subsampling_y);
2061 }
2062 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2063 sizeof(*xd->above_seg_context) * mi_width);
2064 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2065 sizeof(xd->left_seg_context[0]) * mi_height);
2066#if CONFIG_VAR_TX
2067 xd->above_txfm_context = ctx->p_ta;
2068 xd->left_txfm_context = ctx->p_tl;
2069 memcpy(xd->above_txfm_context, ctx->ta,
2070 sizeof(*xd->above_txfm_context) * mi_width);
2071 memcpy(xd->left_txfm_context, ctx->tl,
2072 sizeof(*xd->left_txfm_context) * mi_height);
2073#endif
2074}
2075
2076static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
2077 int mi_row, int mi_col, BLOCK_SIZE bsize) {
2078 const MACROBLOCKD *xd = &x->e_mbd;
2079 int p;
2080 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2081 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2082 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2083 int mi_height = num_8x8_blocks_high_lookup[bsize];
2084
2085 // buffer the above/left context information of the block in search.
2086 for (p = 0; p < MAX_MB_PLANE; ++p) {
2087 memcpy(ctx->a + num_4x4_blocks_wide * p,
2088 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2089 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2090 xd->plane[p].subsampling_x);
2091 memcpy(ctx->l + num_4x4_blocks_high * p,
2092 xd->left_context[p] +
2093 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2094 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2095 xd->plane[p].subsampling_y);
2096 }
2097 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2098 sizeof(*xd->above_seg_context) * mi_width);
2099 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2100 sizeof(xd->left_seg_context[0]) * mi_height);
2101#if CONFIG_VAR_TX
2102 memcpy(ctx->ta, xd->above_txfm_context,
2103 sizeof(*xd->above_txfm_context) * mi_width);
2104 memcpy(ctx->tl, xd->left_txfm_context,
2105 sizeof(*xd->left_txfm_context) * mi_height);
2106 ctx->p_ta = xd->above_txfm_context;
2107 ctx->p_tl = xd->left_txfm_context;
2108#endif
2109}
2110
Yaowu Xuf883b422016-08-30 14:01:10 -07002111static void encode_b(AV1_COMP *cpi, const TileInfo *const tile, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002112 TOKENEXTRA **tp, int mi_row, int mi_col,
2113 int output_enabled, BLOCK_SIZE bsize,
2114#if CONFIG_EXT_PARTITION_TYPES
2115 PARTITION_TYPE partition,
2116#endif
2117 PICK_MODE_CONTEXT *ctx) {
2118 MACROBLOCK *const x = &td->mb;
2119 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2120#if CONFIG_EXT_PARTITION_TYPES
2121 x->e_mbd.mi[0]->mbmi.partition = partition;
2122#endif
2123 update_state(cpi, td, ctx, mi_row, mi_col, bsize, output_enabled);
2124 encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx);
2125
2126 if (output_enabled) {
2127#if CONFIG_SUPERTX
2128 update_stats(&cpi->common, td, 0);
2129#else
2130 update_stats(&cpi->common, td);
2131#endif
2132 }
2133}
2134
Yaowu Xuf883b422016-08-30 14:01:10 -07002135static void encode_sb(AV1_COMP *cpi, ThreadData *td, const TileInfo *const tile,
2136 TOKENEXTRA **tp, int mi_row, int mi_col,
2137 int output_enabled, BLOCK_SIZE bsize, PC_TREE *pc_tree) {
2138 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002139 MACROBLOCK *const x = &td->mb;
2140 MACROBLOCKD *const xd = &x->e_mbd;
2141
2142 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
2143 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
2144 const PARTITION_TYPE partition = pc_tree->partitioning;
2145 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2146#if CONFIG_EXT_PARTITION_TYPES
2147 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2148#endif
2149
2150 assert(bsize >= BLOCK_8X8);
2151
2152 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2153
2154 if (output_enabled) td->counts->partition[ctx][partition]++;
2155
2156#if CONFIG_SUPERTX
2157 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2158 partition != PARTITION_NONE && !xd->lossless[0]) {
2159 int supertx_enabled;
2160 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2161 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2162 if (supertx_enabled) {
2163 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2164 const int mi_height = num_8x8_blocks_high_lookup[bsize];
2165 int x_idx, y_idx, i;
2166 uint8_t *dst_buf[3];
2167 int dst_stride[3];
2168 set_skip_context(xd, mi_row, mi_col);
2169 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
2170 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize,
2171 output_enabled, pc_tree);
2172
Yaowu Xuf883b422016-08-30 14:01:10 -07002173 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002174 for (i = 0; i < MAX_MB_PLANE; i++) {
2175 dst_buf[i] = xd->plane[i].dst.buf;
2176 dst_stride[i] = xd->plane[i].dst.stride;
2177 }
2178 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col,
2179 output_enabled, bsize, bsize, dst_buf, dst_stride,
2180 pc_tree);
2181
2182 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2183 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2184
2185 if (!x->skip) {
2186 x->skip_optimize = 0;
2187 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2188
Yaowu Xuf883b422016-08-30 14:01:10 -07002189 av1_encode_sb_supertx(x, bsize);
2190 av1_tokenize_sb_supertx(cpi, td, tp, !output_enabled, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002191 } else {
2192 xd->mi[0]->mbmi.skip = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002193 if (output_enabled) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002194 reset_skip_context(xd, bsize);
2195 }
2196 if (output_enabled) {
2197 for (y_idx = 0; y_idx < mi_height; y_idx++)
2198 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2199 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2200 x_idx &&
2201 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2202 y_idx) {
2203 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2204 xd->mi[0]->mbmi.skip;
2205 }
2206 }
2207 td->counts->supertx[partition_supertx_context_lookup[partition]]
2208 [supertx_size][1]++;
2209 td->counts->supertx_size[supertx_size]++;
2210#if CONFIG_EXT_TX
2211 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2212 !xd->mi[0]->mbmi.skip) {
2213 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2214 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002215 ++td->counts->inter_ext_tx[eset][supertx_size]
2216 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217 }
2218 }
2219#else
2220 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2221 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2222 }
2223#endif // CONFIG_EXT_TX
2224 }
2225#if CONFIG_EXT_PARTITION_TYPES
2226 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2227 partition);
2228#else
2229 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2230 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2231#endif
2232#if CONFIG_VAR_TX
2233 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd);
2234#endif // CONFIG_VAR_TX
2235 return;
2236 } else {
2237 if (output_enabled) {
2238 td->counts->supertx[partition_supertx_context_lookup[partition]]
2239 [supertx_size][0]++;
2240 }
2241 }
2242 }
2243#endif // CONFIG_SUPERTX
2244
2245 switch (partition) {
2246 case PARTITION_NONE:
2247 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2248#if CONFIG_EXT_PARTITION_TYPES
2249 partition,
2250#endif
2251 &pc_tree->none);
2252 break;
2253 case PARTITION_VERT:
2254 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2255#if CONFIG_EXT_PARTITION_TYPES
2256 partition,
2257#endif
2258 &pc_tree->vertical[0]);
2259 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
2260 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled,
2261 subsize,
2262#if CONFIG_EXT_PARTITION_TYPES
2263 partition,
2264#endif
2265 &pc_tree->vertical[1]);
2266 }
2267 break;
2268 case PARTITION_HORZ:
2269 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2270#if CONFIG_EXT_PARTITION_TYPES
2271 partition,
2272#endif
2273 &pc_tree->horizontal[0]);
2274 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
2275 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled,
2276 subsize,
2277#if CONFIG_EXT_PARTITION_TYPES
2278 partition,
2279#endif
2280 &pc_tree->horizontal[1]);
2281 }
2282 break;
2283 case PARTITION_SPLIT:
2284 if (bsize == BLOCK_8X8) {
2285 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2286#if CONFIG_EXT_PARTITION_TYPES
2287 partition,
2288#endif
2289 pc_tree->leaf_split[0]);
2290 } else {
2291 encode_sb(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
2292 pc_tree->split[0]);
2293 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled,
2294 subsize, pc_tree->split[1]);
2295 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled,
2296 subsize, pc_tree->split[2]);
2297 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
2298 subsize, pc_tree->split[3]);
2299 }
2300 break;
2301#if CONFIG_EXT_PARTITION_TYPES
2302 case PARTITION_HORZ_A:
2303 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, bsize2,
2304 partition, &pc_tree->horizontala[0]);
2305 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, bsize2,
2306 partition, &pc_tree->horizontala[1]);
2307 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, subsize,
2308 partition, &pc_tree->horizontala[2]);
2309 break;
2310 case PARTITION_HORZ_B:
2311 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2312 partition, &pc_tree->horizontalb[0]);
2313 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, bsize2,
2314 partition, &pc_tree->horizontalb[1]);
2315 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, output_enabled,
2316 bsize2, partition, &pc_tree->horizontalb[2]);
2317 break;
2318 case PARTITION_VERT_A:
2319 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, bsize2,
2320 partition, &pc_tree->verticala[0]);
2321 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, bsize2,
2322 partition, &pc_tree->verticala[1]);
2323 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, subsize,
2324 partition, &pc_tree->verticala[2]);
2325
2326 break;
2327 case PARTITION_VERT_B:
2328 encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
2329 partition, &pc_tree->verticalb[0]);
2330 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, bsize2,
2331 partition, &pc_tree->verticalb[1]);
2332 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, output_enabled,
2333 bsize2, partition, &pc_tree->verticalb[2]);
2334 break;
2335#endif // CONFIG_EXT_PARTITION_TYPES
2336 default: assert(0 && "Invalid partition type."); break;
2337 }
2338
2339#if CONFIG_EXT_PARTITION_TYPES
2340 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2341#else
2342 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2343 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2344#endif // CONFIG_EXT_PARTITION_TYPES
2345}
2346
2347// Check to see if the given partition size is allowed for a specified number
2348// of mi block rows and columns remaining in the image.
2349// If not then return the largest allowed partition size
2350static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2351 int cols_left, int *bh, int *bw) {
2352 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002353 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002354 } else {
2355 for (; bsize > 0; bsize -= 3) {
2356 *bh = num_8x8_blocks_high_lookup[bsize];
2357 *bw = num_8x8_blocks_wide_lookup[bsize];
2358 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2359 break;
2360 }
2361 }
2362 }
2363 return bsize;
2364}
2365
Yaowu Xuf883b422016-08-30 14:01:10 -07002366static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002367 int bh_in, int bw_in,
2368 int mi_rows_remaining,
2369 int mi_cols_remaining, BLOCK_SIZE bsize,
2370 MODE_INFO **mib) {
2371 int bh = bh_in;
2372 int r, c;
2373 for (r = 0; r < cm->mib_size; r += bh) {
2374 int bw = bw_in;
2375 for (c = 0; c < cm->mib_size; c += bw) {
2376 const int index = r * cm->mi_stride + c;
2377 mib[index] = mi + index;
2378 mib[index]->mbmi.sb_type = find_partition_size(
2379 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2380 }
2381 }
2382}
2383
2384// This function attempts to set all mode info entries in a given superblock
2385// to the same block partition size.
2386// However, at the bottom and right borders of the image the requested size
2387// may not be allowed in which case this code attempts to choose the largest
2388// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002389static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002390 MODE_INFO **mib, int mi_row, int mi_col,
2391 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002392 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002393 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2394 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2395 int block_row, block_col;
2396 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2397 int bh = num_8x8_blocks_high_lookup[bsize];
2398 int bw = num_8x8_blocks_wide_lookup[bsize];
2399
2400 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2401
2402 // Apply the requested partition size to the SB if it is all "in image"
2403 if ((mi_cols_remaining >= cm->mib_size) &&
2404 (mi_rows_remaining >= cm->mib_size)) {
2405 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2406 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2407 int index = block_row * cm->mi_stride + block_col;
2408 mib[index] = mi_upper_left + index;
2409 mib[index]->mbmi.sb_type = bsize;
2410 }
2411 }
2412 } else {
2413 // Else this is a partial SB.
2414 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2415 mi_cols_remaining, bsize, mib);
2416 }
2417}
2418
Yaowu Xuf883b422016-08-30 14:01:10 -07002419static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002420 TileDataEnc *tile_data, MODE_INFO **mib,
2421 TOKENEXTRA **tp, int mi_row, int mi_col,
2422 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2423#if CONFIG_SUPERTX
2424 int *rate_nocoef,
2425#endif
2426 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002427 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002428 TileInfo *const tile_info = &tile_data->tile_info;
2429 MACROBLOCK *const x = &td->mb;
2430 MACROBLOCKD *const xd = &x->e_mbd;
2431 const int bs = num_8x8_blocks_wide_lookup[bsize];
2432 const int hbs = bs / 2;
2433 int i;
2434 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2435 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2436 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2437 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2438 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2439 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2440 int splits_below = 0;
2441 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2442 int do_partition_search = 1;
2443 PICK_MODE_CONTEXT *ctx = &pc_tree->none;
2444#if CONFIG_SUPERTX
2445 int last_part_rate_nocoef = INT_MAX;
2446 int none_rate_nocoef = INT_MAX;
2447 int chosen_rate_nocoef = INT_MAX;
2448#endif
2449
2450 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2451
2452 assert(num_4x4_blocks_wide_lookup[bsize] ==
2453 num_4x4_blocks_high_lookup[bsize]);
2454
Yaowu Xuf883b422016-08-30 14:01:10 -07002455 av1_rd_cost_reset(&last_part_rdc);
2456 av1_rd_cost_reset(&none_rdc);
2457 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002458
2459 pc_tree->partitioning = partition;
2460
2461#if CONFIG_VAR_TX
2462 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2463 xd->left_txfm_context =
2464 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2465#endif
2466
2467 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2468
2469 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2470 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002471 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002472 }
2473
2474 if (do_partition_search &&
2475 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2476 cpi->sf.adjust_partitioning_from_last_frame) {
2477 // Check if any of the sub blocks are further split.
2478 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2479 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2480 splits_below = 1;
2481 for (i = 0; i < 4; i++) {
2482 int jj = i >> 1, ii = i & 0x01;
2483 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2484 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2485 splits_below = 0;
2486 }
2487 }
2488 }
2489
2490 // If partition is not none try none unless each of the 4 splits are split
2491 // even further..
2492 if (partition != PARTITION_NONE && !splits_below &&
2493 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2494 pc_tree->partitioning = PARTITION_NONE;
2495 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2496#if CONFIG_SUPERTX
2497 &none_rate_nocoef,
2498#endif
2499#if CONFIG_EXT_PARTITION_TYPES
2500 PARTITION_NONE,
2501#endif
2502 bsize, ctx, INT64_MAX);
2503
2504 if (none_rdc.rate < INT_MAX) {
2505 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2506 none_rdc.rdcost =
2507 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2508#if CONFIG_SUPERTX
2509 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2510#endif
2511 }
2512
2513 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2514
2515 mib[0]->mbmi.sb_type = bs_type;
2516 pc_tree->partitioning = partition;
2517 }
2518 }
2519
2520 switch (partition) {
2521 case PARTITION_NONE:
2522 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2523#if CONFIG_SUPERTX
2524 &last_part_rate_nocoef,
2525#endif
2526#if CONFIG_EXT_PARTITION_TYPES
2527 PARTITION_NONE,
2528#endif
2529 bsize, ctx, INT64_MAX);
2530 break;
2531 case PARTITION_HORZ:
2532 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2533#if CONFIG_SUPERTX
2534 &last_part_rate_nocoef,
2535#endif
2536#if CONFIG_EXT_PARTITION_TYPES
2537 PARTITION_HORZ,
2538#endif
2539 subsize, &pc_tree->horizontal[0], INT64_MAX);
2540 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2541 mi_row + hbs < cm->mi_rows) {
2542 RD_COST tmp_rdc;
2543#if CONFIG_SUPERTX
2544 int rt_nocoef = 0;
2545#endif
2546 PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002547 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
2549 encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
2550 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2551#if CONFIG_SUPERTX
2552 &rt_nocoef,
2553#endif
2554#if CONFIG_EXT_PARTITION_TYPES
2555 PARTITION_HORZ,
2556#endif
2557 subsize, &pc_tree->horizontal[1], INT64_MAX);
2558 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002559 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002560#if CONFIG_SUPERTX
2561 last_part_rate_nocoef = INT_MAX;
2562#endif
2563 break;
2564 }
2565 last_part_rdc.rate += tmp_rdc.rate;
2566 last_part_rdc.dist += tmp_rdc.dist;
2567 last_part_rdc.rdcost += tmp_rdc.rdcost;
2568#if CONFIG_SUPERTX
2569 last_part_rate_nocoef += rt_nocoef;
2570#endif
2571 }
2572 break;
2573 case PARTITION_VERT:
2574 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2575#if CONFIG_SUPERTX
2576 &last_part_rate_nocoef,
2577#endif
2578#if CONFIG_EXT_PARTITION_TYPES
2579 PARTITION_VERT,
2580#endif
2581 subsize, &pc_tree->vertical[0], INT64_MAX);
2582 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2583 mi_col + hbs < cm->mi_cols) {
2584 RD_COST tmp_rdc;
2585#if CONFIG_SUPERTX
2586 int rt_nocoef = 0;
2587#endif
2588 PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002589 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590 update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
2591 encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
2592 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2593#if CONFIG_SUPERTX
2594 &rt_nocoef,
2595#endif
2596#if CONFIG_EXT_PARTITION_TYPES
2597 PARTITION_VERT,
2598#endif
2599 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2600 INT64_MAX);
2601 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002602 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603#if CONFIG_SUPERTX
2604 last_part_rate_nocoef = INT_MAX;
2605#endif
2606 break;
2607 }
2608 last_part_rdc.rate += tmp_rdc.rate;
2609 last_part_rdc.dist += tmp_rdc.dist;
2610 last_part_rdc.rdcost += tmp_rdc.rdcost;
2611#if CONFIG_SUPERTX
2612 last_part_rate_nocoef += rt_nocoef;
2613#endif
2614 }
2615 break;
2616 case PARTITION_SPLIT:
2617 if (bsize == BLOCK_8X8) {
2618 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2619#if CONFIG_SUPERTX
2620 &last_part_rate_nocoef,
2621#endif
2622#if CONFIG_EXT_PARTITION_TYPES
2623 PARTITION_SPLIT,
2624#endif
2625 subsize, pc_tree->leaf_split[0], INT64_MAX);
2626 break;
2627 }
2628 last_part_rdc.rate = 0;
2629 last_part_rdc.dist = 0;
2630 last_part_rdc.rdcost = 0;
2631#if CONFIG_SUPERTX
2632 last_part_rate_nocoef = 0;
2633#endif
2634 for (i = 0; i < 4; i++) {
2635 int x_idx = (i & 1) * hbs;
2636 int y_idx = (i >> 1) * hbs;
2637 int jj = i >> 1, ii = i & 0x01;
2638 RD_COST tmp_rdc;
2639#if CONFIG_SUPERTX
2640 int rt_nocoef;
2641#endif
2642 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2643 continue;
2644
Yaowu Xuf883b422016-08-30 14:01:10 -07002645 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646 rd_use_partition(cpi, td, tile_data,
2647 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2648 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2649 &tmp_rdc.dist,
2650#if CONFIG_SUPERTX
2651 &rt_nocoef,
2652#endif
2653 i != 3, pc_tree->split[i]);
2654 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002655 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002656#if CONFIG_SUPERTX
2657 last_part_rate_nocoef = INT_MAX;
2658#endif
2659 break;
2660 }
2661 last_part_rdc.rate += tmp_rdc.rate;
2662 last_part_rdc.dist += tmp_rdc.dist;
2663#if CONFIG_SUPERTX
2664 last_part_rate_nocoef += rt_nocoef;
2665#endif
2666 }
2667 break;
2668#if CONFIG_EXT_PARTITION_TYPES
2669 case PARTITION_VERT_A:
2670 case PARTITION_VERT_B:
2671 case PARTITION_HORZ_A:
2672 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2673#endif // CONFIG_EXT_PARTITION_TYPES
2674 default: assert(0); break;
2675 }
2676
2677 if (last_part_rdc.rate < INT_MAX) {
2678 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2679 last_part_rdc.rdcost =
2680 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2681#if CONFIG_SUPERTX
2682 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2683#endif
2684 }
2685
2686 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2687 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2688 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2689 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2690 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2691 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2692 chosen_rdc.rate = 0;
2693 chosen_rdc.dist = 0;
2694#if CONFIG_SUPERTX
2695 chosen_rate_nocoef = 0;
2696#endif
2697
2698 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2699
2700 pc_tree->partitioning = PARTITION_SPLIT;
2701
2702 // Split partition.
2703 for (i = 0; i < 4; i++) {
2704 int x_idx = (i & 1) * hbs;
2705 int y_idx = (i >> 1) * hbs;
2706 RD_COST tmp_rdc;
2707#if CONFIG_SUPERTX
2708 int rt_nocoef = 0;
2709#endif
2710 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2711
2712 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2713 continue;
2714
2715 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2716 pc_tree->split[i]->partitioning = PARTITION_NONE;
2717 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2718 &tmp_rdc,
2719#if CONFIG_SUPERTX
2720 &rt_nocoef,
2721#endif
2722#if CONFIG_EXT_PARTITION_TYPES
2723 PARTITION_SPLIT,
2724#endif
2725 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2726
2727 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2728
2729 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002730 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002731#if CONFIG_SUPERTX
2732 chosen_rate_nocoef = INT_MAX;
2733#endif
2734 break;
2735 }
2736
2737 chosen_rdc.rate += tmp_rdc.rate;
2738 chosen_rdc.dist += tmp_rdc.dist;
2739#if CONFIG_SUPERTX
2740 chosen_rate_nocoef += rt_nocoef;
2741#endif
2742
2743 if (i != 3)
2744 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx, 0,
2745 split_subsize, pc_tree->split[i]);
2746
2747 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2748#if CONFIG_SUPERTX
2749 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2750#endif
2751 }
2752 if (chosen_rdc.rate < INT_MAX) {
2753 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2754 chosen_rdc.rdcost =
2755 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2756#if CONFIG_SUPERTX
2757 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2758#endif
2759 }
2760 }
2761
2762 // If last_part is better set the partitioning to that.
2763 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2764 mib[0]->mbmi.sb_type = bsize;
2765 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2766 chosen_rdc = last_part_rdc;
2767#if CONFIG_SUPERTX
2768 chosen_rate_nocoef = last_part_rate_nocoef;
2769#endif
2770 }
2771 // If none was better set the partitioning to that.
2772 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2773 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2774 chosen_rdc = none_rdc;
2775#if CONFIG_SUPERTX
2776 chosen_rate_nocoef = none_rate_nocoef;
2777#endif
2778 }
2779
2780 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2781
2782 // We must have chosen a partitioning and encoding or we'll fail later on.
2783 // No other opportunities for success.
2784 if (bsize == cm->sb_size)
2785 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2786
2787 if (do_recon) {
2788 int output_enabled = (bsize == cm->sb_size);
2789 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
2790 pc_tree);
2791 }
2792
2793 *rate = chosen_rdc.rate;
2794 *dist = chosen_rdc.dist;
2795#if CONFIG_SUPERTX
2796 *rate_nocoef = chosen_rate_nocoef;
2797#endif
2798}
2799
2800/* clang-format off */
2801static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2802 BLOCK_4X4, // 4x4
2803 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2804 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2805 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2806 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2807#if CONFIG_EXT_PARTITION
2808 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2809#endif // CONFIG_EXT_PARTITION
2810};
2811
2812static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2813 BLOCK_8X8, // 4x4
2814 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2815 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2816 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2817 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2818#if CONFIG_EXT_PARTITION
2819 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2820#endif // CONFIG_EXT_PARTITION
2821};
2822
2823// Next square block size less or equal than current block size.
2824static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2825 BLOCK_4X4, // 4x4
2826 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2827 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2828 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2829 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2830#if CONFIG_EXT_PARTITION
2831 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
2832#endif // CONFIG_EXT_PARTITION
2833};
2834/* clang-format on */
2835
2836// Look at all the mode_info entries for blocks that are part of this
2837// partition and find the min and max values for sb_type.
2838// At the moment this is designed to work on a superblock but could be
2839// adjusted to use a size parameter.
2840//
2841// The min and max are assumed to have been initialized prior to calling this
2842// function so repeat calls can accumulate a min and max of more than one
2843// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002844static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845 MACROBLOCKD *xd, MODE_INFO **mib,
2846 BLOCK_SIZE *min_block_size,
2847 BLOCK_SIZE *max_block_size) {
2848 int i, j;
2849 int index = 0;
2850
2851 // Check the sb_type for each block that belongs to this region.
2852 for (i = 0; i < cm->mib_size; ++i) {
2853 for (j = 0; j < cm->mib_size; ++j) {
2854 MODE_INFO *mi = mib[index + j];
2855 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002856 *min_block_size = AOMMIN(*min_block_size, sb_type);
2857 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002858 }
2859 index += xd->mi_stride;
2860 }
2861}
2862
2863// Look at neighboring blocks and set a min and max partition size based on
2864// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002865static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002866 MACROBLOCKD *const xd, int mi_row,
2867 int mi_col, BLOCK_SIZE *min_block_size,
2868 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002869 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002870 MODE_INFO **mi = xd->mi;
2871 const int left_in_image = xd->left_available && mi[-1];
2872 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
2873 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2874 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2875 int bh, bw;
2876 BLOCK_SIZE min_size = BLOCK_4X4;
2877 BLOCK_SIZE max_size = BLOCK_LARGEST;
2878
2879 // Trap case where we do not have a prediction.
2880 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2881 // Default "min to max" and "max to min"
2882 min_size = BLOCK_LARGEST;
2883 max_size = BLOCK_4X4;
2884
2885 // NOTE: each call to get_sb_partition_size_range() uses the previous
2886 // passed in values for min and max as a starting point.
2887 // Find the min and max partition used in previous frame at this location
2888 if (cm->frame_type != KEY_FRAME) {
2889 MODE_INFO **prev_mi =
2890 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
2891 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
2892 }
2893 // Find the min and max partition sizes used in the left superblock
2894 if (left_in_image) {
2895 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
2896 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
2897 }
2898 // Find the min and max partition sizes used in the above suprblock.
2899 if (above_in_image) {
2900 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
2901 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
2902 }
2903
2904 // Adjust observed min and max for "relaxed" auto partition case.
2905 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2906 min_size = min_partition_size[min_size];
2907 max_size = max_partition_size[max_size];
2908 }
2909 }
2910
2911 // Check border cases where max and min from neighbors may not be legal.
2912 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
2913 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07002914 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002915
2916 // Test for blocks at the edge of the active image.
2917 // This may be the actual edge of the image or where there are formatting
2918 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07002919 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002920 min_size = BLOCK_4X4;
2921 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002922 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002923 }
2924
2925 // When use_square_partition_only is true, make sure at least one square
2926 // partition is allowed by selecting the next smaller square size as
2927 // *min_block_size.
2928 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002929 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002930 }
2931
Yaowu Xuf883b422016-08-30 14:01:10 -07002932 *min_block_size = AOMMIN(min_size, cm->sb_size);
2933 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002934}
2935
2936// TODO(jingning) refactor functions setting partition search range
Yaowu Xuf883b422016-08-30 14:01:10 -07002937static void set_partition_range(AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002938 int mi_col, BLOCK_SIZE bsize,
2939 BLOCK_SIZE *min_bs, BLOCK_SIZE *max_bs) {
2940 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2941 int mi_height = num_8x8_blocks_high_lookup[bsize];
2942 int idx, idy;
2943
2944 MODE_INFO *mi;
2945 const int idx_str = cm->mi_stride * mi_row + mi_col;
2946 MODE_INFO **prev_mi = &cm->prev_mi_grid_visible[idx_str];
2947 BLOCK_SIZE bs, min_size, max_size;
2948
2949 min_size = BLOCK_LARGEST;
2950 max_size = BLOCK_4X4;
2951
2952 if (prev_mi) {
2953 for (idy = 0; idy < mi_height; ++idy) {
2954 for (idx = 0; idx < mi_width; ++idx) {
2955 mi = prev_mi[idy * cm->mi_stride + idx];
2956 bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002957 min_size = AOMMIN(min_size, bs);
2958 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002959 }
2960 }
2961 }
2962
2963 if (xd->left_available) {
2964 for (idy = 0; idy < mi_height; ++idy) {
2965 mi = xd->mi[idy * cm->mi_stride - 1];
2966 bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002967 min_size = AOMMIN(min_size, bs);
2968 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002969 }
2970 }
2971
2972 if (xd->up_available) {
2973 for (idx = 0; idx < mi_width; ++idx) {
2974 mi = xd->mi[idx - cm->mi_stride];
2975 bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002976 min_size = AOMMIN(min_size, bs);
2977 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002978 }
2979 }
2980
2981 if (min_size == max_size) {
2982 min_size = min_partition_size[min_size];
2983 max_size = max_partition_size[max_size];
2984 }
2985
Yaowu Xuf883b422016-08-30 14:01:10 -07002986 *min_bs = AOMMIN(min_size, cm->sb_size);
2987 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002988}
2989
2990static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2991 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
2992}
2993
2994static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2995 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
2996}
2997
2998#if CONFIG_FP_MB_STATS
2999const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3000 0,
3001 10,
3002 10,
3003 30,
3004 40,
3005 40,
3006 60,
3007 80,
3008 80,
3009 90,
3010 100,
3011 100,
3012 120,
3013#if CONFIG_EXT_PARTITION
3014 // TODO(debargha): What are the correct numbers here?
3015 130,
3016 130,
3017 150
3018#endif // CONFIG_EXT_PARTITION
3019};
3020const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3021 0,
3022 3,
3023 3,
3024 7,
3025 15,
3026 15,
3027 30,
3028 40,
3029 40,
3030 60,
3031 80,
3032 80,
3033 120,
3034#if CONFIG_EXT_PARTITION
3035 // TODO(debargha): What are the correct numbers here?
3036 160,
3037 160,
3038 240
3039#endif // CONFIG_EXT_PARTITION
3040};
3041const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3042 1,
3043 1,
3044 1,
3045 1,
3046 1,
3047 1,
3048 1,
3049 1,
3050 1,
3051 1,
3052 4,
3053 4,
3054 6
3055#if CONFIG_EXT_PARTITION
3056 // TODO(debargha): What are the correct numbers here?
3057 8,
3058 8,
3059 10
3060#endif // CONFIG_EXT_PARTITION
3061};
3062
3063typedef enum {
3064 MV_ZERO = 0,
3065 MV_LEFT = 1,
3066 MV_UP = 2,
3067 MV_RIGHT = 3,
3068 MV_DOWN = 4,
3069 MV_INVALID
3070} MOTION_DIRECTION;
3071
3072static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3073 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3074 return MV_ZERO;
3075 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3076 return MV_LEFT;
3077 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3078 return MV_RIGHT;
3079 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3080 return MV_UP;
3081 } else {
3082 return MV_DOWN;
3083 }
3084}
3085
3086static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3087 MOTION_DIRECTION that_mv) {
3088 if (this_mv == that_mv) {
3089 return 0;
3090 } else {
3091 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3092 }
3093}
3094#endif
3095
3096#if CONFIG_EXT_PARTITION_TYPES
3097static void rd_test_partition3(
Yaowu Xuf883b422016-08-30 14:01:10 -07003098 AV1_COMP *cpi, ThreadData *td, TileDataEnc *tile_data, TOKENEXTRA **tp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003099 PC_TREE *pc_tree, RD_COST *best_rdc, PICK_MODE_CONTEXT ctxs[3],
3100 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col, BLOCK_SIZE bsize,
3101 PARTITION_TYPE partition,
3102#if CONFIG_SUPERTX
3103 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3104#endif
3105 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3106 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3107 MACROBLOCK *const x = &td->mb;
3108 MACROBLOCKD *const xd = &x->e_mbd;
3109 RD_COST this_rdc, sum_rdc;
3110#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07003111 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003112 TileInfo *const tile_info = &tile_data->tile_info;
3113 int this_rate_nocoef, sum_rate_nocoef;
3114 int abort_flag;
3115 const int supertx_allowed = !frame_is_intra_only(cm) &&
3116 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3117 !xd->lossless[0];
3118#endif
3119 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3120
3121 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3122#if CONFIG_SUPERTX
3123 &sum_rate_nocoef,
3124#endif
3125#if CONFIG_EXT_PARTITION_TYPES
3126 partition,
3127#endif
3128 subsize0, &ctxs[0], best_rdc->rdcost);
3129#if CONFIG_SUPERTX
3130 abort_flag = sum_rdc.rdcost >= best_rd;
3131#endif
3132
3133#if CONFIG_SUPERTX
3134 if (sum_rdc.rdcost < INT64_MAX) {
3135#else
3136 if (sum_rdc.rdcost < best_rdc->rdcost) {
3137#endif
3138 PICK_MODE_CONTEXT *ctx = &ctxs[0];
3139 update_state(cpi, td, ctx, mi_row0, mi_col0, subsize0, 0);
3140 encode_superblock(cpi, td, tp, 0, mi_row0, mi_col0, subsize0, ctx);
3141
3142 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3143
3144#if CONFIG_SUPERTX
3145 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3146 &this_rate_nocoef,
3147#if CONFIG_EXT_PARTITION_TYPES
3148 partition,
3149#endif
3150 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3151#else
3152 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3153#if CONFIG_EXT_PARTITION_TYPES
3154 partition,
3155#endif
3156 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3157#endif // CONFIG_SUPERTX
3158
3159 if (this_rdc.rate == INT_MAX) {
3160 sum_rdc.rdcost = INT64_MAX;
3161#if CONFIG_SUPERTX
3162 sum_rate_nocoef = INT_MAX;
3163#endif
3164 } else {
3165 sum_rdc.rate += this_rdc.rate;
3166 sum_rdc.dist += this_rdc.dist;
3167 sum_rdc.rdcost += this_rdc.rdcost;
3168#if CONFIG_SUPERTX
3169 sum_rate_nocoef += this_rate_nocoef;
3170#endif
3171 }
3172
3173#if CONFIG_SUPERTX
3174 if (sum_rdc.rdcost < INT64_MAX) {
3175#else
3176 if (sum_rdc.rdcost < best_rdc->rdcost) {
3177#endif
3178 PICK_MODE_CONTEXT *ctx = &ctxs[1];
3179 update_state(cpi, td, ctx, mi_row1, mi_col1, subsize1, 0);
3180 encode_superblock(cpi, td, tp, 0, mi_row1, mi_col1, subsize1, ctx);
3181
3182 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3183
3184#if CONFIG_SUPERTX
3185 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3186 &this_rate_nocoef,
3187#if CONFIG_EXT_PARTITION_TYPES
3188 partition,
3189#endif
3190 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3191#else
3192 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3193#if CONFIG_EXT_PARTITION_TYPES
3194 partition,
3195#endif
3196 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3197#endif // CONFIG_SUPERTX
3198
3199 if (this_rdc.rate == INT_MAX) {
3200 sum_rdc.rdcost = INT64_MAX;
3201#if CONFIG_SUPERTX
3202 sum_rate_nocoef = INT_MAX;
3203#endif
3204 } else {
3205 sum_rdc.rate += this_rdc.rate;
3206 sum_rdc.dist += this_rdc.dist;
3207 sum_rdc.rdcost += this_rdc.rdcost;
3208#if CONFIG_SUPERTX
3209 sum_rate_nocoef += this_rate_nocoef;
3210#endif
3211 }
3212
3213#if CONFIG_SUPERTX
3214 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3215 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3216 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3217 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003218 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003219 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3220 [supertx_size],
3221 0);
3222 sum_rdc.rdcost =
3223 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3224
3225 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3226 TX_TYPE best_tx = DCT_DCT;
3227 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3228
3229 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3230
3231 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3232 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3233
Yaowu Xuf883b422016-08-30 14:01:10 -07003234 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003235 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3236 [supertx_size],
3237 1);
3238 tmp_rdc.rdcost =
3239 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3240 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3241 sum_rdc = tmp_rdc;
3242 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3243 supertx_size, pc_tree);
3244 }
3245 }
3246
3247 pc_tree->partitioning = best_partition;
3248 }
3249#endif // CONFIG_SUPERTX
3250
3251 if (sum_rdc.rdcost < best_rdc->rdcost) {
3252 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3253 sum_rdc.rate += cpi->partition_cost[pl][partition];
3254 sum_rdc.rdcost =
3255 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3256#if CONFIG_SUPERTX
3257 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3258#endif
3259 if (sum_rdc.rdcost < best_rdc->rdcost) {
3260#if CONFIG_SUPERTX
3261 *best_rate_nocoef = sum_rate_nocoef;
3262 assert(*best_rate_nocoef >= 0);
3263#endif
3264 *best_rdc = sum_rdc;
3265 pc_tree->partitioning = partition;
3266 }
3267 }
3268 }
3269 }
3270}
3271#endif // CONFIG_EXT_PARTITION_TYPES
3272
3273// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3274// unlikely to be selected depending on previous rate-distortion optimization
3275// results, for encoding speed-up.
Yaowu Xuf883b422016-08-30 14:01:10 -07003276static void rd_pick_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003277 TileDataEnc *tile_data, TOKENEXTRA **tp,
3278 int mi_row, int mi_col, BLOCK_SIZE bsize,
3279 RD_COST *rd_cost,
3280#if CONFIG_SUPERTX
3281 int *rate_nocoef,
3282#endif
3283 int64_t best_rd, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003284 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003285 TileInfo *const tile_info = &tile_data->tile_info;
3286 MACROBLOCK *const x = &td->mb;
3287 MACROBLOCKD *const xd = &x->e_mbd;
3288 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
3289 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
3290 TOKENEXTRA *tp_orig = *tp;
3291 PICK_MODE_CONTEXT *ctx = &pc_tree->none;
3292 int i;
3293 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3294 int *partition_cost = cpi->partition_cost[pl];
3295 int tmp_partition_cost[PARTITION_TYPES];
3296 BLOCK_SIZE subsize;
3297 RD_COST this_rdc, sum_rdc, best_rdc;
3298#if CONFIG_SUPERTX
3299 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3300 int abort_flag;
3301 const int supertx_allowed = !frame_is_intra_only(cm) &&
3302 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3303 !xd->lossless[0];
3304#endif // CONFIG_SUPERTX
3305 int do_split = bsize >= BLOCK_8X8;
3306 int do_rect = 1;
3307#if CONFIG_EXT_PARTITION_TYPES
3308 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3309#endif
3310
3311 // Override skipping rectangular partition operations for edge blocks
3312 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3313 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3314 const int xss = x->e_mbd.plane[1].subsampling_x;
3315 const int yss = x->e_mbd.plane[1].subsampling_y;
3316
3317 BLOCK_SIZE min_size = x->min_partition_size;
3318 BLOCK_SIZE max_size = x->max_partition_size;
3319
3320#if CONFIG_FP_MB_STATS
3321 unsigned int src_diff_var = UINT_MAX;
3322 int none_complexity = 0;
3323#endif
3324
3325 int partition_none_allowed = !force_horz_split && !force_vert_split;
3326 int partition_horz_allowed =
3327 !force_vert_split && yss <= xss && bsize >= BLOCK_8X8;
3328 int partition_vert_allowed =
3329 !force_horz_split && xss <= yss && bsize >= BLOCK_8X8;
3330 (void)*tp_orig;
3331
3332 if (force_horz_split || force_vert_split) {
3333 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3334
3335 if (!force_vert_split) { // force_horz_split only
3336 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3337 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003338 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003339 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003340 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003341 } else if (!force_horz_split) { // force_vert_split only
3342 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3343 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003344 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003345 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003346 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003347 } else { // force_ horz_split && force_vert_split horz_split
3348 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3349 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3350 tmp_partition_cost[PARTITION_SPLIT] = 0;
3351 }
3352
3353 partition_cost = tmp_partition_cost;
3354 }
3355
3356#if CONFIG_VAR_TX
3357#ifndef NDEBUG
3358 // Nothing should rely on the default value of this array (which is just
3359 // leftover from encoding the previous block. Setting it to magic number
3360 // when debugging.
3361 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3362#endif // NDEBUG
3363#endif // CONFIG_VAR_TX
3364
3365 assert(num_8x8_blocks_wide_lookup[bsize] ==
3366 num_8x8_blocks_high_lookup[bsize]);
3367
Yaowu Xuf883b422016-08-30 14:01:10 -07003368 av1_rd_cost_init(&this_rdc);
3369 av1_rd_cost_init(&sum_rdc);
3370 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003371 best_rdc.rdcost = best_rd;
3372
3373 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3374
3375 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003376 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003377
3378 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
3379 int cb_partition_search_ctrl =
3380 ((pc_tree->index == 0 || pc_tree->index == 3) +
3381 get_chessboard_index(cm->current_video_frame)) &
3382 0x1;
3383
3384 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3385 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3386 }
3387
3388 // Determine partition types in search according to the speed features.
3389 // The threshold set here has to be of square block size.
3390 if (cpi->sf.auto_min_max_partition_size) {
3391 partition_none_allowed &= (bsize <= max_size && bsize >= min_size);
3392 partition_horz_allowed &=
3393 ((bsize <= max_size && bsize > min_size) || force_horz_split);
3394 partition_vert_allowed &=
3395 ((bsize <= max_size && bsize > min_size) || force_vert_split);
3396 do_split &= bsize > min_size;
3397 }
3398 if (cpi->sf.use_square_partition_only) {
3399 partition_horz_allowed &= force_horz_split;
3400 partition_vert_allowed &= force_vert_split;
3401 }
3402
3403#if CONFIG_VAR_TX
3404 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3405 xd->left_txfm_context =
3406 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3407#endif
3408
3409 save_context(x, &x_ctx, mi_row, mi_col, bsize);
3410
3411#if CONFIG_FP_MB_STATS
3412 if (cpi->use_fp_mb_stats) {
3413 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3414 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3415 mi_col, bsize);
3416 }
3417#endif
3418
3419#if CONFIG_FP_MB_STATS
3420 // Decide whether we shall split directly and skip searching NONE by using
3421 // the first pass block statistics
3422 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_split &&
3423 partition_none_allowed && src_diff_var > 4 &&
3424 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3425 int mb_row = mi_row >> 1;
3426 int mb_col = mi_col >> 1;
3427 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003428 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003429 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003430 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 int r, c;
3432
3433 // compute a complexity measure, basically measure inconsistency of motion
3434 // vectors obtained from the first pass in the current block
3435 for (r = mb_row; r < mb_row_end; r++) {
3436 for (c = mb_col; c < mb_col_end; c++) {
3437 const int mb_index = r * cm->mb_cols + c;
3438
3439 MOTION_DIRECTION this_mv;
3440 MOTION_DIRECTION right_mv;
3441 MOTION_DIRECTION bottom_mv;
3442
3443 this_mv =
3444 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3445
3446 // to its right
3447 if (c != mb_col_end - 1) {
3448 right_mv = get_motion_direction_fp(
3449 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3450 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3451 }
3452
3453 // to its bottom
3454 if (r != mb_row_end - 1) {
3455 bottom_mv = get_motion_direction_fp(
3456 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3457 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3458 }
3459
3460 // do not count its left and top neighbors to avoid double counting
3461 }
3462 }
3463
3464 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3465 partition_none_allowed = 0;
3466 }
3467 }
3468#endif
3469
3470 // PARTITION_NONE
3471 if (partition_none_allowed) {
3472 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3473#if CONFIG_SUPERTX
3474 &this_rate_nocoef,
3475#endif
3476#if CONFIG_EXT_PARTITION_TYPES
3477 PARTITION_NONE,
3478#endif
3479 bsize, ctx, best_rdc.rdcost);
3480 if (this_rdc.rate != INT_MAX) {
3481 if (bsize >= BLOCK_8X8) {
3482 this_rdc.rate += partition_cost[PARTITION_NONE];
3483 this_rdc.rdcost =
3484 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3485#if CONFIG_SUPERTX
3486 this_rate_nocoef += partition_cost[PARTITION_NONE];
3487#endif
3488 }
3489
3490 if (this_rdc.rdcost < best_rdc.rdcost) {
3491 int64_t dist_breakout_thr = cpi->sf.partition_search_breakout_dist_thr;
3492 int rate_breakout_thr = cpi->sf.partition_search_breakout_rate_thr;
3493
3494 best_rdc = this_rdc;
3495#if CONFIG_SUPERTX
3496 best_rate_nocoef = this_rate_nocoef;
3497 assert(best_rate_nocoef >= 0);
3498#endif
3499 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
3500
3501 // Adjust dist breakout threshold according to the partition size.
3502 dist_breakout_thr >>=
3503 (2 * (MAX_SB_SIZE_LOG2 - 2)) -
3504 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
3505
3506 rate_breakout_thr *= num_pels_log2_lookup[bsize];
3507
3508 // If all y, u, v transform blocks in this partition are skippable, and
3509 // the dist & rate are within the thresholds, the partition search is
3510 // terminated for current branch of the partition search tree.
3511 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3512 // early termination at that speed.
3513 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
3514 (ctx->skippable && best_rdc.dist < dist_breakout_thr &&
3515 best_rdc.rate < rate_breakout_thr)) {
3516 do_split = 0;
3517 do_rect = 0;
3518 }
3519
3520#if CONFIG_FP_MB_STATS
3521 // Check if every 16x16 first pass block statistics has zero
3522 // motion and the corresponding first pass residue is small enough.
3523 // If that is the case, check the difference variance between the
3524 // current frame and the last frame. If the variance is small enough,
3525 // stop further splitting in RD optimization
3526 if (cpi->use_fp_mb_stats && do_split != 0 &&
3527 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3528 int mb_row = mi_row >> 1;
3529 int mb_col = mi_col >> 1;
3530 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003531 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003533 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003534 int r, c;
3535
3536 int skip = 1;
3537 for (r = mb_row; r < mb_row_end; r++) {
3538 for (c = mb_col; c < mb_col_end; c++) {
3539 const int mb_index = r * cm->mb_cols + c;
3540 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3541 FPMB_MOTION_ZERO_MASK) ||
3542 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3543 FPMB_ERROR_SMALL_MASK)) {
3544 skip = 0;
3545 break;
3546 }
3547 }
3548 if (skip == 0) {
3549 break;
3550 }
3551 }
3552 if (skip) {
3553 if (src_diff_var == UINT_MAX) {
3554 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3555 src_diff_var = get_sby_perpixel_diff_variance(
3556 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3557 }
3558 if (src_diff_var < 8) {
3559 do_split = 0;
3560 do_rect = 0;
3561 }
3562 }
3563 }
3564#endif
3565 }
3566 }
3567
3568 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3569 }
3570
3571 // store estimated motion vector
3572 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx);
3573
3574 // PARTITION_SPLIT
3575 // TODO(jingning): use the motion vectors given by the above search as
3576 // the starting point of motion search in the following partition type check.
3577 if (do_split) {
3578 subsize = get_subsize(bsize, PARTITION_SPLIT);
3579 if (bsize == BLOCK_8X8) {
3580 i = 4;
3581#if CONFIG_DUAL_FILTER
3582 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3583 pc_tree->leaf_split[0]->pred_interp_filter =
3584 ctx->mic.mbmi.interp_filter[0];
3585#else
3586 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3587 pc_tree->leaf_split[0]->pred_interp_filter =
3588 ctx->mic.mbmi.interp_filter;
3589#endif
3590#if CONFIG_SUPERTX
3591 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3592 &sum_rate_nocoef,
3593#if CONFIG_EXT_PARTITION_TYPES
3594 PARTITION_SPLIT,
3595#endif
3596 subsize, pc_tree->leaf_split[0], INT64_MAX);
3597#else
3598 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3599#if CONFIG_EXT_PARTITION_TYPES
3600 PARTITION_SPLIT,
3601#endif
3602 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3603#endif // CONFIG_SUPERTX
3604 if (sum_rdc.rate == INT_MAX) {
3605 sum_rdc.rdcost = INT64_MAX;
3606#if CONFIG_SUPERTX
3607 sum_rate_nocoef = INT_MAX;
3608#endif
3609 }
3610#if CONFIG_SUPERTX
3611 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3612 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3613 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3614
3615 pc_tree->partitioning = PARTITION_SPLIT;
3616
clang-format67948d32016-09-07 22:40:40 -07003617 sum_rdc.rate +=
3618 av1_cost_bit(cm->fc->supertx_prob
3619 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3620 [supertx_size],
3621 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622 sum_rdc.rdcost =
3623 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3624
3625 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3626 TX_TYPE best_tx = DCT_DCT;
3627 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3628
3629 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3630
3631 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3632 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3633
Yaowu Xuf883b422016-08-30 14:01:10 -07003634 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003635 cm->fc->supertx_prob
3636 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3637 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638 1);
3639 tmp_rdc.rdcost =
3640 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3641 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3642 sum_rdc = tmp_rdc;
3643 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3644 supertx_size, pc_tree);
3645 }
3646 }
3647
3648 pc_tree->partitioning = best_partition;
3649 }
3650#endif // CONFIG_SUPERTX
3651 } else {
3652#if CONFIG_SUPERTX
3653 for (i = 0; i < 4 && sum_rdc.rdcost < INT64_MAX; ++i) {
3654#else
3655 for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) {
3656#endif // CONFIG_SUPERTX
3657 const int x_idx = (i & 1) * mi_step;
3658 const int y_idx = (i >> 1) * mi_step;
3659
3660 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3661 continue;
3662
3663 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3664
3665 pc_tree->split[i]->index = i;
3666#if CONFIG_SUPERTX
3667 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3668 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
3669 INT64_MAX - sum_rdc.rdcost, pc_tree->split[i]);
3670#else
3671 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3672 mi_col + x_idx, subsize, &this_rdc,
3673 best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
3674#endif // CONFIG_SUPERTX
3675
3676 if (this_rdc.rate == INT_MAX) {
3677 sum_rdc.rdcost = INT64_MAX;
3678#if CONFIG_SUPERTX
3679 sum_rate_nocoef = INT_MAX;
3680#endif // CONFIG_SUPERTX
3681 break;
3682 } else {
3683 sum_rdc.rate += this_rdc.rate;
3684 sum_rdc.dist += this_rdc.dist;
3685 sum_rdc.rdcost += this_rdc.rdcost;
3686#if CONFIG_SUPERTX
3687 sum_rate_nocoef += this_rate_nocoef;
3688#endif // CONFIG_SUPERTX
3689 }
3690 }
3691#if CONFIG_SUPERTX
3692 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && i == 4) {
3693 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3694 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3695
3696 pc_tree->partitioning = PARTITION_SPLIT;
3697
clang-format67948d32016-09-07 22:40:40 -07003698 sum_rdc.rate +=
3699 av1_cost_bit(cm->fc->supertx_prob
3700 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3701 [supertx_size],
3702 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003703 sum_rdc.rdcost =
3704 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3705
3706 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3707 TX_TYPE best_tx = DCT_DCT;
3708 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3709
3710 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3711
3712 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3713 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3714
Yaowu Xuf883b422016-08-30 14:01:10 -07003715 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003716 cm->fc->supertx_prob
3717 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3718 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 1);
3720 tmp_rdc.rdcost =
3721 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3722 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3723 sum_rdc = tmp_rdc;
3724 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3725 supertx_size, pc_tree);
3726 }
3727 }
3728
3729 pc_tree->partitioning = best_partition;
3730 }
3731#endif // CONFIG_SUPERTX
3732 }
3733
3734 if (sum_rdc.rdcost < best_rdc.rdcost && i == 4) {
3735 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3736 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3737#if CONFIG_SUPERTX
3738 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3739#endif // CONFIG_SUPERTX
3740
3741 if (sum_rdc.rdcost < best_rdc.rdcost) {
3742 best_rdc = sum_rdc;
3743#if CONFIG_SUPERTX
3744 best_rate_nocoef = sum_rate_nocoef;
3745 assert(best_rate_nocoef >= 0);
3746#endif // CONFIG_SUPERTX
3747 pc_tree->partitioning = PARTITION_SPLIT;
3748 }
3749 } else {
3750 // skip rectangular partition test when larger block size
3751 // gives better rd cost
3752 if (cpi->sf.less_rectangular_check) do_rect &= !partition_none_allowed;
3753 }
3754
3755 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3756 } // if (do_split)
3757
3758 // PARTITION_HORZ
3759 if (partition_horz_allowed &&
Yaowu Xuf883b422016-08-30 14:01:10 -07003760 (do_rect || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003761 subsize = get_subsize(bsize, PARTITION_HORZ);
3762 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3763#if CONFIG_DUAL_FILTER
3764 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3765 partition_none_allowed)
3766 pc_tree->horizontal[0].pred_interp_filter =
3767 ctx->mic.mbmi.interp_filter[0];
3768#else
3769 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3770 partition_none_allowed)
3771 pc_tree->horizontal[0].pred_interp_filter = ctx->mic.mbmi.interp_filter;
3772#endif
3773 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3774#if CONFIG_SUPERTX
3775 &sum_rate_nocoef,
3776#endif // CONFIG_SUPERTX
3777#if CONFIG_EXT_PARTITION_TYPES
3778 PARTITION_HORZ,
3779#endif
3780 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3781
3782#if CONFIG_SUPERTX
3783 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3784 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3785 if (sum_rdc.rdcost < INT64_MAX &&
3786#else
3787 if (sum_rdc.rdcost < best_rdc.rdcost &&
3788#endif // CONFIG_SUPERTX
3789 mi_row + mi_step < cm->mi_rows && bsize > BLOCK_8X8) {
3790 PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
3791 update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
3792 encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
3793
3794 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3795
3796#if CONFIG_DUAL_FILTER
3797 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3798 partition_none_allowed)
3799 pc_tree->horizontal[1].pred_interp_filter =
3800 ctx->mic.mbmi.interp_filter[0];
3801#else
3802 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3803 partition_none_allowed)
3804 pc_tree->horizontal[1].pred_interp_filter = ctx->mic.mbmi.interp_filter;
3805#endif
3806#if CONFIG_SUPERTX
3807 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3808 &this_rate_nocoef,
3809#if CONFIG_EXT_PARTITION_TYPES
3810 PARTITION_HORZ,
3811#endif
3812 subsize, &pc_tree->horizontal[1], INT64_MAX);
3813#else
3814 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3815#if CONFIG_EXT_PARTITION_TYPES
3816 PARTITION_HORZ,
3817#endif
3818 subsize, &pc_tree->horizontal[1],
3819 best_rdc.rdcost - sum_rdc.rdcost);
3820#endif // CONFIG_SUPERTX
3821 if (this_rdc.rate == INT_MAX) {
3822 sum_rdc.rdcost = INT64_MAX;
3823#if CONFIG_SUPERTX
3824 sum_rate_nocoef = INT_MAX;
3825#endif // CONFIG_SUPERTX
3826 } else {
3827 sum_rdc.rate += this_rdc.rate;
3828 sum_rdc.dist += this_rdc.dist;
3829 sum_rdc.rdcost += this_rdc.rdcost;
3830#if CONFIG_SUPERTX
3831 sum_rate_nocoef += this_rate_nocoef;
3832#endif // CONFIG_SUPERTX
3833 }
3834 }
3835
3836#if CONFIG_SUPERTX
3837 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3838 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3839 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3840
3841 pc_tree->partitioning = PARTITION_HORZ;
3842
Yaowu Xuf883b422016-08-30 14:01:10 -07003843 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3845 [supertx_size],
3846 0);
3847 sum_rdc.rdcost = 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, &tmp_rdc.rate,
3856 &tmp_rdc.dist, &best_tx, pc_tree);
3857
Yaowu Xuf883b422016-08-30 14:01:10 -07003858 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003859 cm->fc
3860 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3861 [supertx_size],
3862 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 if (sum_rdc.rdcost < best_rdc.rdcost) {
3877 sum_rdc.rate += partition_cost[PARTITION_HORZ];
3878 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3879#if CONFIG_SUPERTX
3880 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
3881#endif // CONFIG_SUPERTX
3882 if (sum_rdc.rdcost < best_rdc.rdcost) {
3883 best_rdc = sum_rdc;
3884#if CONFIG_SUPERTX
3885 best_rate_nocoef = sum_rate_nocoef;
3886 assert(best_rate_nocoef >= 0);
3887#endif // CONFIG_SUPERTX
3888 pc_tree->partitioning = PARTITION_HORZ;
3889 }
3890 }
3891
3892 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3893 }
3894
3895 // PARTITION_VERT
3896 if (partition_vert_allowed &&
Yaowu Xuf883b422016-08-30 14:01:10 -07003897 (do_rect || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898 subsize = get_subsize(bsize, PARTITION_VERT);
3899
3900 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3901
3902#if CONFIG_DUAL_FILTER
3903 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3904 partition_none_allowed)
3905 pc_tree->vertical[0].pred_interp_filter = ctx->mic.mbmi.interp_filter[0];
3906#else
3907 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3908 partition_none_allowed)
3909 pc_tree->vertical[0].pred_interp_filter = ctx->mic.mbmi.interp_filter;
3910#endif
3911 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3912#if CONFIG_SUPERTX
3913 &sum_rate_nocoef,
3914#endif // CONFIG_SUPERTX
3915#if CONFIG_EXT_PARTITION_TYPES
3916 PARTITION_VERT,
3917#endif
3918 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
3919#if CONFIG_SUPERTX
3920 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3921 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3922 if (sum_rdc.rdcost < INT64_MAX &&
3923#else
3924 if (sum_rdc.rdcost < best_rdc.rdcost &&
3925#endif // CONFIG_SUPERTX
3926 mi_col + mi_step < cm->mi_cols && bsize > BLOCK_8X8) {
3927 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 0);
3928 encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize,
3929 &pc_tree->vertical[0]);
3930
3931 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3932
3933#if CONFIG_DUAL_FILTER
3934 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3935 partition_none_allowed)
3936 pc_tree->vertical[1].pred_interp_filter =
3937 ctx->mic.mbmi.interp_filter[0];
3938#else
3939 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3940 partition_none_allowed)
3941 pc_tree->vertical[1].pred_interp_filter = ctx->mic.mbmi.interp_filter;
3942#endif
3943#if CONFIG_SUPERTX
3944 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
3945 &this_rate_nocoef,
3946#if CONFIG_EXT_PARTITION_TYPES
3947 PARTITION_VERT,
3948#endif
3949 subsize, &pc_tree->vertical[1],
3950 INT64_MAX - sum_rdc.rdcost);
3951#else
3952 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
3953#if CONFIG_EXT_PARTITION_TYPES
3954 PARTITION_VERT,
3955#endif
3956 subsize, &pc_tree->vertical[1],
3957 best_rdc.rdcost - sum_rdc.rdcost);
3958#endif // CONFIG_SUPERTX
3959 if (this_rdc.rate == INT_MAX) {
3960 sum_rdc.rdcost = INT64_MAX;
3961#if CONFIG_SUPERTX
3962 sum_rate_nocoef = INT_MAX;
3963#endif // CONFIG_SUPERTX
3964 } else {
3965 sum_rdc.rate += this_rdc.rate;
3966 sum_rdc.dist += this_rdc.dist;
3967 sum_rdc.rdcost += this_rdc.rdcost;
3968#if CONFIG_SUPERTX
3969 sum_rate_nocoef += this_rate_nocoef;
3970#endif // CONFIG_SUPERTX
3971 }
3972 }
3973#if CONFIG_SUPERTX
3974 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3975 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3976 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3977
3978 pc_tree->partitioning = PARTITION_VERT;
3979
Yaowu Xuf883b422016-08-30 14:01:10 -07003980 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003981 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
3982 [supertx_size],
3983 0);
3984 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3985
3986 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3987 TX_TYPE best_tx = DCT_DCT;
3988 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3989
3990 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3991
3992 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
3993 &tmp_rdc.dist, &best_tx, pc_tree);
3994
Yaowu Xuf883b422016-08-30 14:01:10 -07003995 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003996 cm->fc
3997 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
3998 [supertx_size],
3999 1);
4000 tmp_rdc.rdcost =
4001 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4002 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4003 sum_rdc = tmp_rdc;
4004 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4005 supertx_size, pc_tree);
4006 }
4007 }
4008
4009 pc_tree->partitioning = best_partition;
4010 }
4011#endif // CONFIG_SUPERTX
4012
4013 if (sum_rdc.rdcost < best_rdc.rdcost) {
4014 sum_rdc.rate += partition_cost[PARTITION_VERT];
4015 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4016#if CONFIG_SUPERTX
4017 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4018#endif // CONFIG_SUPERTX
4019 if (sum_rdc.rdcost < best_rdc.rdcost) {
4020 best_rdc = sum_rdc;
4021#if CONFIG_SUPERTX
4022 best_rate_nocoef = sum_rate_nocoef;
4023 assert(best_rate_nocoef >= 0);
4024#endif // CONFIG_SUPERTX
4025 pc_tree->partitioning = PARTITION_VERT;
4026 }
4027 }
4028 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4029 }
4030
4031#if CONFIG_EXT_PARTITION_TYPES
4032 // PARTITION_HORZ_A
4033 if (partition_horz_allowed && do_rect && bsize > BLOCK_8X8 &&
4034 partition_none_allowed) {
4035 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4036 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4037 pc_tree->horizontala, ctx, mi_row, mi_col, bsize,
4038 PARTITION_HORZ_A,
4039#if CONFIG_SUPERTX
4040 best_rd, &best_rate_nocoef, &x_ctx,
4041#endif
4042 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4043 mi_row + mi_step, mi_col, subsize);
4044 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4045 }
4046 // PARTITION_HORZ_B
4047 if (partition_horz_allowed && do_rect && bsize > BLOCK_8X8 &&
4048 partition_none_allowed) {
4049 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4050 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4051 pc_tree->horizontalb, ctx, mi_row, mi_col, bsize,
4052 PARTITION_HORZ_B,
4053#if CONFIG_SUPERTX
4054 best_rd, &best_rate_nocoef, &x_ctx,
4055#endif
4056 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4057 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4058 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4059 }
4060 // PARTITION_VERT_A
4061 if (partition_vert_allowed && do_rect && bsize > BLOCK_8X8 &&
4062 partition_none_allowed) {
4063 subsize = get_subsize(bsize, PARTITION_VERT_A);
4064 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4065 pc_tree->verticala, ctx, mi_row, mi_col, bsize,
4066 PARTITION_VERT_A,
4067#if CONFIG_SUPERTX
4068 best_rd, &best_rate_nocoef, &x_ctx,
4069#endif
4070 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4071 mi_row, mi_col + mi_step, subsize);
4072 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4073 }
4074 // PARTITION_VERT_B
4075 if (partition_vert_allowed && do_rect && bsize > BLOCK_8X8 &&
4076 partition_none_allowed) {
4077 subsize = get_subsize(bsize, PARTITION_VERT_B);
4078 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4079 pc_tree->verticalb, ctx, mi_row, mi_col, bsize,
4080 PARTITION_VERT_B,
4081#if CONFIG_SUPERTX
4082 best_rd, &best_rate_nocoef, &x_ctx,
4083#endif
4084 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4085 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4086 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4087 }
4088#endif // CONFIG_EXT_PARTITION_TYPES
4089
4090 // TODO(jbb): This code added so that we avoid static analysis
4091 // warning related to the fact that best_rd isn't used after this
4092 // point. This code should be refactored so that the duplicate
4093 // checks occur in some sub function and thus are used...
4094 (void)best_rd;
4095 *rd_cost = best_rdc;
4096#if CONFIG_SUPERTX
4097 *rate_nocoef = best_rate_nocoef;
4098#endif // CONFIG_SUPERTX
4099
4100 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4101 pc_tree->index != 3) {
4102 int output_enabled = (bsize == cm->sb_size);
4103 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
4104 pc_tree);
4105 }
4106
4107 if (bsize == cm->sb_size) {
4108 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
4109 assert(best_rdc.rate < INT_MAX);
4110 assert(best_rdc.dist < INT64_MAX);
4111 } else {
4112 assert(tp_orig == *tp);
4113 }
4114}
4115
Yaowu Xuf883b422016-08-30 14:01:10 -07004116static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004117 TileDataEnc *tile_data, int mi_row,
4118 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004119 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120 const TileInfo *const tile_info = &tile_data->tile_info;
4121 MACROBLOCK *const x = &td->mb;
4122 MACROBLOCKD *const xd = &x->e_mbd;
4123 SPEED_FEATURES *const sf = &cpi->sf;
4124 int mi_col;
4125#if CONFIG_EXT_PARTITION
4126 const int leaf_nodes = 256;
4127#else
4128 const int leaf_nodes = 64;
4129#endif // CONFIG_EXT_PARTITION
4130
4131 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004132 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004133
4134 // Code each SB in the row
4135 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4136 mi_col += cm->mib_size) {
4137 const struct segmentation *const seg = &cm->seg;
4138 int dummy_rate;
4139 int64_t dummy_dist;
4140 RD_COST dummy_rdc;
4141#if CONFIG_SUPERTX
4142 int dummy_rate_nocoef;
4143#endif // CONFIG_SUPERTX
4144 int i;
4145 int seg_skip = 0;
4146
4147 const int idx_str = cm->mi_stride * mi_row + mi_col;
4148 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4149 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4150
4151 if (sf->adaptive_pred_interp_filter) {
4152 for (i = 0; i < leaf_nodes; ++i)
4153 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4154
4155 for (i = 0; i < leaf_nodes; ++i) {
4156 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4157 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4158 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4159 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4160 }
4161 }
4162
Yaowu Xuf883b422016-08-30 14:01:10 -07004163 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004164 pc_root->index = 0;
4165
4166 if (seg->enabled) {
4167 const uint8_t *const map =
4168 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4169 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4170 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4171 }
4172
4173 x->source_variance = UINT_MAX;
4174 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4175 BLOCK_SIZE bsize;
4176 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4177 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4178 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4179 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4180 &dummy_rate, &dummy_dist,
4181#if CONFIG_SUPERTX
4182 &dummy_rate_nocoef,
4183#endif // CONFIG_SUPERTX
4184 1, pc_root);
4185 } else if (cpi->partition_search_skippable_frame) {
4186 BLOCK_SIZE bsize;
4187 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4188 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4189 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4190 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4191 &dummy_rate, &dummy_dist,
4192#if CONFIG_SUPERTX
4193 &dummy_rate_nocoef,
4194#endif // CONFIG_SUPERTX
4195 1, pc_root);
4196 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4197 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4198 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4199 &dummy_rate, &dummy_dist,
4200#if CONFIG_SUPERTX
4201 &dummy_rate_nocoef,
4202#endif // CONFIG_SUPERTX
4203 1, pc_root);
4204 } else {
4205 // If required set upper and lower partition size limits
4206 if (sf->auto_min_max_partition_size) {
4207 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4208 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4209 &x->min_partition_size, &x->max_partition_size);
4210 }
4211 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4212 &dummy_rdc,
4213#if CONFIG_SUPERTX
4214 &dummy_rate_nocoef,
4215#endif // CONFIG_SUPERTX
4216 INT64_MAX, pc_root);
4217 }
4218 }
4219#if CONFIG_ENTROPY
4220 if (cm->do_subframe_update &&
4221 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4222 if ((mi_row + MI_SIZE) %
4223 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004224 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225 0 &&
4226 mi_row + MI_SIZE < cm->mi_rows &&
4227 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4228 TX_SIZE t;
4229 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4230
4231 for (t = TX_4X4; t <= TX_32X32; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004232 av1_full_to_model_counts(cpi->td.counts->coef[t],
4233 cpi->td.rd_counts.coef_counts[t]);
4234 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004235 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004236 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4237 cm->fc->coef_probs);
4238 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4239 cpi->td.rd_counts.coef_counts);
4240 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4241 cm->counts.eob_branch);
4242 av1_fill_token_costs(x->token_costs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004243#if CONFIG_ANS
Yaowu Xuf883b422016-08-30 14:01:10 -07004244 cm->fc->coef_cdfs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245#endif // CONFIG_ANS
Yaowu Xuf883b422016-08-30 14:01:10 -07004246 cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004247 }
4248 }
4249#endif // CONFIG_ENTROPY
4250}
4251
Yaowu Xuf883b422016-08-30 14:01:10 -07004252static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004253 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004254 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004255 MACROBLOCKD *const xd = &x->e_mbd;
4256
4257 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004258 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004259
Yaowu Xuf883b422016-08-30 14:01:10 -07004260 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004261}
4262
Yaowu Xuf883b422016-08-30 14:01:10 -07004263static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004264 const int ref_flags = cpi->ref_frame_flags;
4265
4266 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4267 return 0;
4268 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004269 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004270#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004271 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4272 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004273#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004274 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004275 }
4276}
4277
4278#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004279static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004280 int mi_row, mi_col;
4281 const int mis = cm->mi_stride;
4282 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4283
4284 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4285 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4286 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4287 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4288 }
4289 }
4290}
4291#endif
4292
Yaowu Xuf883b422016-08-30 14:01:10 -07004293static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004294 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4295#if CONFIG_EXT_REFS
4296 // We will not update the golden frame with an internal overlay frame
4297 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4298 cpi->rc.is_src_frame_ext_arf)
4299#else
4300 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4301#endif
4302 return ALTREF_FRAME;
4303 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4304 return GOLDEN_FRAME;
4305 else
4306 // TODO(zoeliu): To investigate whether a frame_type other than
4307 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4308 return LAST_FRAME;
4309}
4310
Yaowu Xuf883b422016-08-30 14:01:10 -07004311static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004312 if (xd->lossless[0]) return ONLY_4X4;
4313 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
4314 return ALLOW_32X32;
4315 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4316 cpi->sf.tx_size_search_method == USE_TX_8X8)
4317 return TX_MODE_SELECT;
4318 else
4319 return cpi->common.tx_mode;
4320}
4321
Yaowu Xuf883b422016-08-30 14:01:10 -07004322void av1_init_tile_data(AV1_COMP *cpi) {
4323 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004324 const int tile_cols = cm->tile_cols;
4325 const int tile_rows = cm->tile_rows;
4326 int tile_col, tile_row;
4327 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4328 unsigned int tile_tok = 0;
4329
4330 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004331 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4332 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004333 sizeof(*cpi->tile_data)));
4334 cpi->allocated_tiles = tile_cols * tile_rows;
4335
4336 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4337 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4338 TileDataEnc *const tile_data =
4339 &cpi->tile_data[tile_row * tile_cols + tile_col];
4340 int i, j;
4341 for (i = 0; i < BLOCK_SIZES; ++i) {
4342 for (j = 0; j < MAX_MODES; ++j) {
4343 tile_data->thresh_freq_fact[i][j] = 32;
4344 tile_data->mode_map[i][j] = j;
4345 }
4346 }
4347 }
4348 }
4349
4350 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4351 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4352 TileInfo *const tile_info =
4353 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004354 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004355
4356 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4357 pre_tok = cpi->tile_tok[tile_row][tile_col];
4358 tile_tok = allocated_tokens(*tile_info);
4359 }
4360 }
4361}
4362
Yaowu Xuf883b422016-08-30 14:01:10 -07004363void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4364 int tile_col) {
4365 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004366 TileDataEnc *const this_tile =
4367 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4368 const TileInfo *const tile_info = &this_tile->tile_info;
4369 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4370 int mi_row;
4371
Yaowu Xuf883b422016-08-30 14:01:10 -07004372 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004373
4374 // Set up pointers to per thread motion search counters.
4375 td->mb.m_search_count_ptr = &td->rd_counts.m_search_count;
4376 td->mb.ex_search_count_ptr = &td->rd_counts.ex_search_count;
4377
4378 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4379 mi_row += cm->mib_size) {
4380 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4381 }
4382
4383 cpi->tok_count[tile_row][tile_col] =
4384 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4385 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
4386}
4387
Yaowu Xuf883b422016-08-30 14:01:10 -07004388static void encode_tiles(AV1_COMP *cpi) {
4389 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390 int tile_col, tile_row;
4391
Yaowu Xuf883b422016-08-30 14:01:10 -07004392 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004393
4394 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4395 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004396 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004397}
4398
4399#if CONFIG_FP_MB_STATS
4400static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004401 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004402 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4403 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4404
4405 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4406
4407 *this_frame_mb_stats = mb_stats_in;
4408
4409 return 1;
4410}
4411#endif
4412
4413#if CONFIG_GLOBAL_MOTION
4414#define MIN_TRANS_THRESH 8
4415#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004416#define GLOBAL_MOTION_MODEL ROTZOOM
4417static void refine_integerized_param(WarpedMotionParams *wm,
4418#if CONFIG_AOM_HIGHBITDEPTH
4419 int use_hbd, int bd,
4420#endif // CONFIG_AOM_HIGHBITDEPTH
4421 uint8_t *ref, int r_width, int r_height,
4422 int r_stride, uint8_t *dst, int d_width,
4423 int d_height, int d_stride,
4424 int n_refinements) {
4425 int i = 0, p;
4426 int n_params = n_trans_model_params[wm->wmtype];
4427 int16_t *param_mat = (int16_t *)wm->wmmat;
4428 double step_error;
4429 int step;
4430 int16_t *param;
4431 int16_t curr_param;
4432 int16_t best_param;
4433
4434 double best_error =
4435 av1_warp_erroradv(wm,
4436#if CONFIG_AOM_HIGHBITDEPTH
4437 use_hbd, bd,
4438#endif // CONFIG_AOM_HIGHBITDEPTH
4439 ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
4440 d_height, d_stride, 0, 0, 16, 16);
4441 for (p = 0; p < n_params; ++p) {
4442 param = param_mat + p;
4443 step = 1 << (n_refinements + 1);
4444 curr_param = *param;
4445 best_param = curr_param;
4446 for (i = 0; i < n_refinements; i++) {
4447 // look to the left
4448 *param = curr_param - step;
4449 step_error =
4450 av1_warp_erroradv(wm,
4451#if CONFIG_AOM_HIGHBITDEPTH
4452 use_hbd, bd,
4453#endif // CONFIG_AOM_HIGHBITDEPTH
4454 ref, r_width, r_height, r_stride, dst, 0, 0,
4455 d_width, d_height, d_stride, 0, 0, 16, 16);
4456 if (step_error < best_error) {
4457 step >>= 1;
4458 best_error = step_error;
4459 best_param = *param;
4460 curr_param = best_param;
4461 continue;
4462 }
4463
4464 // look to the right
4465 *param = curr_param + step;
4466 step_error =
4467 av1_warp_erroradv(wm,
4468#if CONFIG_AOM_HIGHBITDEPTH
4469 use_hbd, bd,
4470#endif // CONFIG_AOM_HIGHBITDEPTH
4471 ref, r_width, r_height, r_stride, dst, 0, 0,
4472 d_width, d_height, d_stride, 0, 0, 16, 16);
4473 if (step_error < best_error) {
4474 step >>= 1;
4475 best_error = step_error;
4476 best_param = *param;
4477 curr_param = best_param;
4478 continue;
4479 }
4480
4481 // no improvement found-> means we're either already at a minimum or
4482 // step is too wide
4483 step >>= 1;
4484 }
4485
4486 *param = best_param;
4487 }
4488}
4489
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004490static void convert_to_params(const double *params, TransformationType type,
Sarah Parkere5299862016-08-16 14:57:37 -07004491 int16_t *model) {
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004492 int i, diag_value;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004493 int alpha_present = 0;
4494 int n_params = n_trans_model_params[type];
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004495 model[0] = (int16_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4496 model[1] = (int16_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
Sarah Parkere5299862016-08-16 14:57:37 -07004497 model[0] = (int16_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
4498 GM_TRANS_DECODE_FACTOR;
4499 model[1] = (int16_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
4500 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004501
4502 for (i = 2; i < n_params; ++i) {
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004503 diag_value = ((i && 1) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004504 model[i] = (int16_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004505 model[i] =
4506 (int16_t)(clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX) +
4507 diag_value) *
4508 GM_ALPHA_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004509 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004510 }
4511
4512 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004513 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4514 model[0] = 0;
4515 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516 }
4517 }
4518}
4519
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004520static void convert_model_to_params(const double *params,
4521 TransformationType type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004522 Global_Motion_Params *model) {
4523 // TODO(sarahparker) implement for homography
Sarah Parkere5299862016-08-16 14:57:37 -07004524 if (type > HOMOGRAPHY)
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004525 convert_to_params(params, type, (int16_t *)model->motion_params.wmmat);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526 model->gmtype = get_gmtype(model);
4527 model->motion_params.wmtype = gm_to_trans_type(model->gmtype);
4528}
4529#endif // CONFIG_GLOBAL_MOTION
4530
Yaowu Xuf883b422016-08-30 14:01:10 -07004531static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004532 ThreadData *const td = &cpi->td;
4533 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004534 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004535 MACROBLOCKD *const xd = &x->e_mbd;
4536 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4537 int i;
4538
Yaowu Xuf883b422016-08-30 14:01:10 -07004539 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4540 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004541
4542 xd->mi = cm->mi_grid_visible;
4543 xd->mi[0] = cm->mi;
4544
Yaowu Xuf883b422016-08-30 14:01:10 -07004545 av1_zero(*td->counts);
4546 av1_zero(rdc->coef_counts);
4547 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004548 rdc->m_search_count = 0; // Count of motion search hits.
4549 rdc->ex_search_count = 0; // Exhaustive mesh search hits.
4550
4551#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004552 aom_clear_system_state();
4553 av1_zero(cpi->global_motion_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004554 if (cpi->common.frame_type == INTER_FRAME && cpi->Source) {
4555 YV12_BUFFER_CONFIG *ref_buf;
4556 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004557 double erroradvantage = 0;
4558 double params[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004559 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4560 ref_buf = get_ref_frame_buffer(cpi, frame);
4561 if (ref_buf) {
4562 if (compute_global_motion_feature_based(GLOBAL_MOTION_MODEL,
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004563 cpi->Source, ref_buf, params)) {
4564 convert_model_to_params(params, GLOBAL_MOTION_MODEL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004565 &cm->global_motion[frame]);
4566 if (get_gmtype(&cm->global_motion[frame]) > GLOBAL_ZERO) {
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004567 refine_integerized_param(
4568 &cm->global_motion[frame].motion_params,
4569#if CONFIG_AOM_HIGHBITDEPTH
4570 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4571#endif // CONFIG_AOM_HIGHBITDEPTH
4572 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4573 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4574 cpi->Source->y_height, cpi->Source->y_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575 // compute the advantage of using gm parameters over 0 motion
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004576 erroradvantage = av1_warp_erroradv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577 &cm->global_motion[frame].motion_params,
Yaowu Xuf883b422016-08-30 14:01:10 -07004578#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004579 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Yaowu Xuf883b422016-08-30 14:01:10 -07004580#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004581 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4582 ref_buf->y_stride, cpi->Source->y_buffer, 0, 0,
4583 cpi->Source->y_width, cpi->Source->y_height,
4584 cpi->Source->y_stride, 0, 0, 16, 16);
4585 if (erroradvantage > GLOBAL_MOTION_ADVANTAGE_THRESH)
4586 // Not enough advantage in using a global model. Make 0.
4587 memset(&cm->global_motion[frame], 0,
4588 sizeof(cm->global_motion[frame]));
4589 }
4590 }
4591 }
4592 }
4593 }
4594#endif // CONFIG_GLOBAL_MOTION
4595
4596 for (i = 0; i < MAX_SEGMENTS; ++i) {
4597 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004598 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599 : cm->base_qindex;
4600 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4601 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -07004602 xd->qindex[i] = qindex;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004603 }
4604
4605 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4606
4607 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004608 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004609
Yaowu Xuf883b422016-08-30 14:01:10 -07004610 av1_initialize_rd_consts(cpi);
4611 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004612 init_encode_frame_mb_context(cpi);
4613
4614 cm->use_prev_frame_mvs =
4615 !cm->error_resilient_mode && cm->width == cm->last_width &&
4616 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
4617#if CONFIG_EXT_REFS
4618 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4619 // show_exisiting_frame=1, nor can it take a frame not used as
4620 // a reference, it is probable that by the time it is being
4621 // referred to, the frame buffer it originally points to may
4622 // already get expired and have been reassigned to the current
4623 // newly coded frame. Hence, we need to check whether this is
4624 // the case, and if yes, we have 2 choices:
4625 // (1) Simply disable the use of previous frame mvs; or
4626 // (2) Have cm->prev_frame point to one reference frame buffer,
4627 // e.g. LAST_FRAME.
4628 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4629 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4630 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4631 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4632 }
4633#endif // CONFIG_EXT_REFS
4634
4635 // Special case: set prev_mi to NULL when the previous mode info
4636 // context cannot be used.
4637 cm->prev_mi =
4638 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4639
4640#if CONFIG_VAR_TX
4641#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004642 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004643#endif
4644#endif
4645
4646 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4647 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004648 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649
4650 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004651 struct aom_usec_timer emr_timer;
4652 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653
4654#if CONFIG_FP_MB_STATS
4655 if (cpi->use_fp_mb_stats) {
4656 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4657 &cpi->twopass.this_frame_mb_stats);
4658 }
4659#endif
4660
4661 // If allowed, encoding tiles in parallel with one thread handling one tile.
4662 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4663 // 1 tile rows, as it uses the single above_context et al arrays from
4664 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004665 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4666 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004667 else
4668 encode_tiles(cpi);
4669
Yaowu Xuf883b422016-08-30 14:01:10 -07004670 aom_usec_timer_mark(&emr_timer);
4671 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 }
4673
4674#if 0
4675 // Keep record of the total distortion this time around for future use
4676 cpi->last_frame_distortion = cpi->frame_distortion;
4677#endif
4678}
4679
Yaowu Xuf883b422016-08-30 14:01:10 -07004680void av1_encode_frame(AV1_COMP *cpi) {
4681 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004682
4683 // In the longer term the encoder should be generalized to match the
4684 // decoder such that we allow compound where one of the 3 buffers has a
4685 // different sign bias and that buffer is then the fixed ref. However, this
4686 // requires further work in the rd loop. For now the only supported encoder
4687 // side behavior is where the ALT ref buffer has opposite sign bias to
4688 // the other two.
4689 if (!frame_is_intra_only(cm)) {
4690 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4691 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4692 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4693 cm->ref_frame_sign_bias[LAST_FRAME])) {
4694 cpi->allow_comp_inter_inter = 0;
4695 } else {
4696 cpi->allow_comp_inter_inter = 1;
4697
4698#if CONFIG_EXT_REFS
4699 cm->comp_fwd_ref[0] = LAST_FRAME;
4700 cm->comp_fwd_ref[1] = LAST2_FRAME;
4701 cm->comp_fwd_ref[2] = LAST3_FRAME;
4702 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4703 cm->comp_bwd_ref[0] = BWDREF_FRAME;
4704 cm->comp_bwd_ref[1] = ALTREF_FRAME;
4705#else
4706 cm->comp_fixed_ref = ALTREF_FRAME;
4707 cm->comp_var_ref[0] = LAST_FRAME;
4708 cm->comp_var_ref[1] = GOLDEN_FRAME;
4709#endif // CONFIG_EXT_REFS
4710 }
4711 } else {
4712 cpi->allow_comp_inter_inter = 0;
4713 }
4714
4715 if (cpi->sf.frame_parameter_update) {
4716 int i;
4717 RD_OPT *const rd_opt = &cpi->rd;
4718 FRAME_COUNTS *counts = cpi->td.counts;
4719 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4720
4721 // This code does a single RD pass over the whole frame assuming
4722 // either compound, single or hybrid prediction as per whatever has
4723 // worked best for that type of frame in the past.
4724 // It also predicts whether another coding mode would have worked
4725 // better than this coding mode. If that is the case, it remembers
4726 // that for subsequent frames.
4727 // It does the same analysis for transform size selection also.
4728 //
4729 // TODO(zoeliu): To investigate whether a frame_type other than
4730 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4731 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4732 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4733 const int is_alt_ref = frame_type == ALTREF_FRAME;
4734
4735 /* prediction (compound, single or hybrid) mode selection */
4736 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4737 cm->reference_mode = SINGLE_REFERENCE;
4738 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4739 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4740 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4741 cm->reference_mode = COMPOUND_REFERENCE;
4742 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4743 cm->reference_mode = SINGLE_REFERENCE;
4744 else
4745 cm->reference_mode = REFERENCE_MODE_SELECT;
4746
4747#if CONFIG_DUAL_FILTER
4748 cm->interp_filter = SWITCHABLE;
4749#endif
4750
4751 encode_frame_internal(cpi);
4752
4753 for (i = 0; i < REFERENCE_MODES; ++i)
4754 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4755
4756 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4757 int single_count_zero = 0;
4758 int comp_count_zero = 0;
4759
4760 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
4761 single_count_zero += counts->comp_inter[i][0];
4762 comp_count_zero += counts->comp_inter[i][1];
4763 }
4764
4765 if (comp_count_zero == 0) {
4766 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004767 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768 } else if (single_count_zero == 0) {
4769 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004770 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004771 }
4772 }
4773
4774#if !CONFIG_VAR_TX
4775 if (cm->tx_mode == TX_MODE_SELECT) {
4776 int count4x4 = 0;
4777 int count8x8_lp = 0, count8x8_8x8p = 0;
4778 int count16x16_16x16p = 0, count16x16_lp = 0;
4779 int count32x32 = 0;
4780 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
4781 count4x4 += counts->tx_size[0][i][TX_4X4];
4782 count4x4 += counts->tx_size[1][i][TX_4X4];
4783 count4x4 += counts->tx_size[2][i][TX_4X4];
4784
4785 count8x8_lp += counts->tx_size[1][i][TX_8X8];
4786 count8x8_lp += counts->tx_size[2][i][TX_8X8];
4787 count8x8_8x8p += counts->tx_size[0][i][TX_8X8];
4788
4789 count16x16_16x16p += counts->tx_size[1][i][TX_16X16];
4790 count16x16_lp += counts->tx_size[2][i][TX_16X16];
4791 count32x32 += counts->tx_size[2][i][TX_32X32];
4792 }
4793#if CONFIG_EXT_TX && CONFIG_RECT_TX
4794 count4x4 += counts->tx_size_implied[0][TX_4X4];
4795 count4x4 += counts->tx_size_implied[1][TX_4X4];
4796 count4x4 += counts->tx_size_implied[2][TX_4X4];
4797 count4x4 += counts->tx_size_implied[3][TX_4X4];
4798 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
4799 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
4800 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
4801 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
4802 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
4803 count32x32 += counts->tx_size_implied[3][TX_32X32];
4804#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4805 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
4806#if CONFIG_SUPERTX
4807 cm->counts.supertx_size[TX_16X16] == 0 &&
4808 cm->counts.supertx_size[TX_32X32] == 0 &&
4809#endif // CONFIG_SUPERTX
4810 count32x32 == 0) {
4811 cm->tx_mode = ALLOW_8X8;
4812 reset_skip_tx_size(cm, TX_8X8);
4813 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
4814 count8x8_lp == 0 && count16x16_lp == 0 &&
4815#if CONFIG_SUPERTX
4816 cm->counts.supertx_size[TX_8X8] == 0 &&
4817 cm->counts.supertx_size[TX_16X16] == 0 &&
4818 cm->counts.supertx_size[TX_32X32] == 0 &&
4819#endif // CONFIG_SUPERTX
4820 count32x32 == 0) {
4821 cm->tx_mode = ONLY_4X4;
4822 reset_skip_tx_size(cm, TX_4X4);
4823 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
4824 cm->tx_mode = ALLOW_32X32;
4825 } else if (count32x32 == 0 && count8x8_lp == 0 &&
4826#if CONFIG_SUPERTX
4827 cm->counts.supertx_size[TX_32X32] == 0 &&
4828#endif // CONFIG_SUPERTX
4829 count4x4 == 0) {
4830 cm->tx_mode = ALLOW_16X16;
4831 reset_skip_tx_size(cm, TX_16X16);
4832 }
4833 }
4834#endif
4835 } else {
4836 encode_frame_internal(cpi);
4837 }
4838}
4839
4840static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
4841 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
4842 const int intraonly) {
4843 const PREDICTION_MODE y_mode = mi->mbmi.mode;
4844 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
4845 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
4846
4847 if (bsize < BLOCK_8X8) {
4848 int idx, idy;
4849 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
4850 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
4851 for (idy = 0; idy < 2; idy += num_4x4_h)
4852 for (idx = 0; idx < 2; idx += num_4x4_w) {
4853 const int bidx = idy * 2 + idx;
4854 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
4855 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004856 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
4857 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004858 ++counts->kf_y_mode[a][l][bmode];
4859 } else {
4860 ++counts->y_mode[0][bmode];
4861 }
4862 }
4863 } else {
4864 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004865 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
4866 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004867 ++counts->kf_y_mode[above][left][y_mode];
4868 } else {
4869 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
4870 }
4871 }
4872
4873 ++counts->uv_mode[y_mode][uv_mode];
4874}
4875
4876#if CONFIG_VAR_TX
4877static void update_txfm_count(MACROBLOCKD *xd, FRAME_COUNTS *counts,
4878 TX_SIZE tx_size, int blk_row, int blk_col) {
4879 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4880 const int tx_row = blk_row >> 1;
4881 const int tx_col = blk_col >> 1;
4882 int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4883 int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4884 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
4885 xd->left_txfm_context + tx_row, tx_size);
4886 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
4887
4888 if (xd->mb_to_bottom_edge < 0) max_blocks_high += xd->mb_to_bottom_edge >> 5;
4889 if (xd->mb_to_right_edge < 0) max_blocks_wide += xd->mb_to_right_edge >> 5;
4890
4891 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4892
4893 if (tx_size == plane_tx_size) {
4894 ++counts->txfm_partition[ctx][0];
4895 mbmi->tx_size = tx_size;
4896 txfm_partition_update(xd->above_txfm_context + tx_col,
4897 xd->left_txfm_context + tx_row, tx_size);
4898 } else {
4899 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4900 int bh = num_4x4_blocks_high_lookup[bsize];
4901 int i;
4902 ++counts->txfm_partition[ctx][1];
4903
4904 if (tx_size == TX_8X8) {
4905 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
4906 mbmi->tx_size = TX_4X4;
4907 txfm_partition_update(xd->above_txfm_context + tx_col,
4908 xd->left_txfm_context + tx_row, TX_4X4);
4909 return;
4910 }
4911
4912 for (i = 0; i < 4; ++i) {
4913 int offsetr = (i >> 1) * bh / 2;
4914 int offsetc = (i & 0x01) * bh / 2;
4915 update_txfm_count(xd, counts, tx_size - 1, blk_row + offsetr,
4916 blk_col + offsetc);
4917 }
4918 }
4919}
4920
Yaowu Xuf883b422016-08-30 14:01:10 -07004921static void tx_partition_count_update(AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004922 BLOCK_SIZE plane_bsize, int mi_row,
4923 int mi_col, FRAME_COUNTS *td_counts) {
4924 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
4925 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
4926 TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
4927 BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
4928 int bh = num_4x4_blocks_wide_lookup[txb_size];
4929 int idx, idy;
4930
4931 xd->above_txfm_context = cm->above_txfm_context + mi_col;
4932 xd->left_txfm_context =
4933 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
4934
4935 for (idy = 0; idy < mi_height; idy += bh)
4936 for (idx = 0; idx < mi_width; idx += bh)
4937 update_txfm_count(xd, td_counts, max_tx_size, idy, idx);
4938}
4939
4940static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
4941 int blk_col) {
4942 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4943 const int tx_row = blk_row >> 1;
4944 const int tx_col = blk_col >> 1;
4945 int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4946 int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4947 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
4948
4949 if (xd->mb_to_bottom_edge < 0) max_blocks_high += xd->mb_to_bottom_edge >> 5;
4950 if (xd->mb_to_right_edge < 0) max_blocks_wide += xd->mb_to_right_edge >> 5;
4951
4952 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4953
4954 if (tx_size == plane_tx_size) {
4955 mbmi->tx_size = tx_size;
4956 txfm_partition_update(xd->above_txfm_context + tx_col,
4957 xd->left_txfm_context + tx_row, tx_size);
4958
4959 } else {
4960 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4961 int bsl = b_width_log2_lookup[bsize];
4962 int i;
4963
4964 if (tx_size == TX_8X8) {
4965 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
4966 mbmi->tx_size = TX_4X4;
4967 txfm_partition_update(xd->above_txfm_context + tx_col,
4968 xd->left_txfm_context + tx_row, TX_4X4);
4969 return;
4970 }
4971
4972 assert(bsl > 0);
4973 --bsl;
4974 for (i = 0; i < 4; ++i) {
4975 int offsetr = (i >> 1) << bsl;
4976 int offsetc = (i & 0x01) << bsl;
4977 set_txfm_context(xd, tx_size - 1, blk_row + offsetr, blk_col + offsetc);
4978 }
4979 }
4980}
4981
Yaowu Xuf883b422016-08-30 14:01:10 -07004982static void tx_partition_set_contexts(AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004983 BLOCK_SIZE plane_bsize, int mi_row,
4984 int mi_col) {
4985 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
4986 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
4987 TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
4988 BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
4989 int bh = num_4x4_blocks_wide_lookup[txb_size];
4990 int idx, idy;
4991
4992 xd->above_txfm_context = cm->above_txfm_context + mi_col;
4993 xd->left_txfm_context =
4994 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
4995
4996 for (idy = 0; idy < mi_height; idy += bh)
4997 for (idx = 0; idx < mi_width; idx += bh)
4998 set_txfm_context(xd, max_tx_size, idy, idx);
4999}
5000#endif
5001
Yaowu Xuf883b422016-08-30 14:01:10 -07005002static void encode_superblock(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005003 int output_enabled, int mi_row, int mi_col,
5004 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005005 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005006 MACROBLOCK *const x = &td->mb;
5007 MACROBLOCKD *const xd = &x->e_mbd;
5008 MODE_INFO **mi_8x8 = xd->mi;
5009 MODE_INFO *mi = mi_8x8[0];
5010 MB_MODE_INFO *mbmi = &mi->mbmi;
5011 const int seg_skip =
5012 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5013 const int mis = cm->mi_stride;
5014 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5015 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5016
5017 x->skip_optimize = ctx->is_coded;
5018 ctx->is_coded = 1;
5019 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5020
5021 if (!is_inter_block(mbmi)) {
5022 int plane;
5023 mbmi->skip = 1;
5024 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07005025 av1_encode_intra_block_plane(x, AOMMAX(bsize, BLOCK_8X8), plane, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005026 if (output_enabled)
5027 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5028 frame_is_intra_only(cm));
5029
5030#if CONFIG_EXT_INTRA
5031 if (output_enabled && bsize >= BLOCK_8X8) {
5032 FRAME_COUNTS *counts = td->counts;
5033 if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0)
5034 ++counts->ext_intra[0][mbmi->ext_intra_mode_info.use_ext_intra_mode[0]];
5035 if (mbmi->uv_mode == DC_PRED &&
5036 mbmi->palette_mode_info.palette_size[1] == 0)
5037 ++counts->ext_intra[1][mbmi->ext_intra_mode_info.use_ext_intra_mode[1]];
5038 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5039 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005040 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005041 p_angle =
5042 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005043 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005044 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5045 }
5046 }
5047#endif // CONFIG_EXT_INTRA
5048
5049 if (bsize >= BLOCK_8X8 && output_enabled) {
5050 for (plane = 0; plane <= 1; ++plane) {
5051 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5052 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5053 xd->plane[plane].color_index_map[0];
5054 // TODO(huisu): this increases the use of token buffer. Needs stretch
5055 // test to verify.
Yaowu Xuf883b422016-08-30 14:01:10 -07005056 av1_tokenize_palette_sb(td, bsize, plane, t);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005057 }
5058 }
5059 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005060 av1_tokenize_sb(cpi, td, t, !output_enabled, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005061 } else {
5062 int ref;
5063 const int is_compound = has_second_ref(mbmi);
5064
5065 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5066 for (ref = 0; ref < 1 + is_compound; ++ref) {
5067 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5068 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005069 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5070 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005071 }
5072 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Yaowu Xuf883b422016-08-30 14:01:10 -07005073 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5074 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075
Yaowu Xuf883b422016-08-30 14:01:10 -07005076 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5077 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005078
5079#if CONFIG_OBMC
5080 if (mbmi->motion_variation == OBMC_CAUSAL) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005081#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005082 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
5083 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
5084#else
5085 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
5086 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005087#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005088 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
5089 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5090 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5091 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5092 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5093 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5094 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
5095
5096 assert(mbmi->sb_type >= BLOCK_8X8);
5097
Yaowu Xuf883b422016-08-30 14:01:10 -07005098#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005099 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5100 int len = sizeof(uint16_t);
5101 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5102 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
5103 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
5104 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5105 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
5106 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
5107 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005108#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005109 dst_buf1[0] = tmp_buf1;
5110 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
5111 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
5112 dst_buf2[0] = tmp_buf2;
5113 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
5114 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07005115#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005117#endif // CONFIG_AOM_HIGHBITDEPTH
5118 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
5119 dst_width1, dst_height1, dst_stride1);
5120 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
5121 dst_width2, dst_height2, dst_stride2);
5122 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
5123 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
5124 dst_stride1, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005125 }
5126#endif // CONFIG_OBMC
5127
Yaowu Xuf883b422016-08-30 14:01:10 -07005128 av1_encode_sb(x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005129#if CONFIG_VAR_TX
5130#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005131 if (is_rect_tx(mbmi->tx_size))
Yaowu Xuf883b422016-08-30 14:01:10 -07005132 av1_tokenize_sb(cpi, td, t, !output_enabled, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005133 else
5134#endif
Debargha Mukherjee3c42c092016-09-29 09:17:36 -07005135 av1_tokenize_sb_vartx(cpi, td, t, !output_enabled, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005136 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005138 av1_tokenize_sb(cpi, td, t, !output_enabled, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005139#endif
5140 }
5141
5142 if (output_enabled) {
5143 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
5144 !(is_inter_block(mbmi) && (mbmi->skip || seg_skip))) {
5145 const int is_inter = is_inter_block(mbmi);
5146 const int tx_size_ctx = get_tx_size_context(xd);
5147 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5148 : intra_tx_size_cat_lookup[bsize];
5149 const TX_SIZE coded_tx_size = txsize_sqr_up_map[mbmi->tx_size];
5150#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005151 assert(IMPLIES(is_rect_tx(mbmi->tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005152#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5153#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005154#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005155 if (is_rect_tx_allowed(xd, mbmi)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005156 td->counts->rect_tx[tx_size_cat][is_rect_tx(mbmi->tx_size)]++;
5157 }
Yue Chen49587a72016-09-28 17:09:47 -07005158 if (!is_rect_tx_allowed(xd, mbmi) || !is_rect_tx(mbmi->tx_size)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005159#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5160 if (is_inter)
5161 tx_partition_count_update(cm, xd, bsize, mi_row, mi_col, td->counts);
5162#if CONFIG_EXT_TX && CONFIG_RECT_TX
5163 }
5164#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005165#endif
5166 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][coded_tx_size];
5167 } else {
5168 int x, y;
5169 TX_SIZE tx_size;
5170 // The new intra coding scheme requires no change of transform size
5171 if (is_inter_block(&mi->mbmi)) {
5172 if (xd->lossless[mbmi->segment_id]) {
5173 tx_size = TX_4X4;
5174 } else {
5175 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
5176 }
5177#if CONFIG_EXT_TX && CONFIG_RECT_TX
5178 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
5179 [txsize_sqr_up_map[mbmi->tx_size]];
5180#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5181 } else {
5182 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
5183 }
5184
5185 for (y = 0; y < mi_height; y++)
5186 for (x = 0; x < mi_width; x++)
5187 if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
5188 mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;
5189 }
5190 ++td->counts->tx_size_totals[txsize_sqr_map[mbmi->tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005191 ++td->counts
5192 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005193#if CONFIG_EXT_TX
5194 if (get_ext_tx_types(mbmi->tx_size, bsize, is_inter_block(mbmi)) > 1 &&
5195 cm->base_qindex > 0 && !mbmi->skip &&
5196 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
5197 int eset = get_ext_tx_set(mbmi->tx_size, bsize, is_inter_block(mbmi));
5198 if (eset > 0) {
5199 if (is_inter_block(mbmi)) {
5200 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[mbmi->tx_size]]
5201 [mbmi->tx_type];
5202 } else {
clang-format67948d32016-09-07 22:40:40 -07005203 ++td->counts->intra_ext_tx[eset][mbmi->tx_size][mbmi->mode]
5204 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 }
5206 }
5207 }
5208#else
5209 if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
5210 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
5211 if (is_inter_block(mbmi)) {
5212 ++td->counts->inter_ext_tx[mbmi->tx_size][mbmi->tx_type];
5213 } else {
clang-format67948d32016-09-07 22:40:40 -07005214 ++td->counts->intra_ext_tx[mbmi->tx_size]
5215 [intra_mode_to_tx_type_context[mbmi->mode]]
5216 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005217 }
5218 }
5219#endif // CONFIG_EXT_TX
5220 }
5221
5222#if CONFIG_VAR_TX
5223 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
5224 is_inter_block(mbmi) && !(mbmi->skip || seg_skip)) {
5225 if (!output_enabled)
5226 tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005227#if CONFIG_EXT_TX && CONFIG_RECT_TX
5228 if (is_rect_tx(mbmi->tx_size)) {
5229 set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, xd);
5230 }
5231#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232 } else {
5233 TX_SIZE tx_size;
5234 // The new intra coding scheme requires no change of transform size
5235 if (is_inter_block(mbmi))
5236#if CONFIG_EXT_TX && CONFIG_RECT_TX
5237 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005238 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239 max_txsize_lookup[bsize]);
5240 if (txsize_sqr_map[max_txsize_rect_lookup[bsize]] <= tx_size)
5241 tx_size = max_txsize_rect_lookup[bsize];
5242 if (xd->lossless[mbmi->segment_id]) tx_size = TX_4X4;
5243 }
5244#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005245 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005246 max_txsize_lookup[bsize]);
5247#endif
5248 else
5249 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
5250 mbmi->tx_size = tx_size;
5251 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, xd);
5252 }
5253#endif
5254}
5255
5256#if CONFIG_SUPERTX
5257static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5258 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5259#if CONFIG_EXT_INTER
5260 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5261#endif // CONFIG_EXT_INTER
5262 return 0;
5263}
5264
Yaowu Xuf883b422016-08-30 14:01:10 -07005265static int check_intra_sb(AV1_COMP *cpi, const TileInfo *const tile, int mi_row,
5266 int mi_col, BLOCK_SIZE bsize, PC_TREE *pc_tree) {
5267 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005268
5269 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5270 const PARTITION_TYPE partition = pc_tree->partitioning;
5271 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5272#if CONFIG_EXT_PARTITION_TYPES
5273 int i;
5274#endif
5275
5276 assert(bsize >= BLOCK_8X8);
5277
5278 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5279
5280 switch (partition) {
5281 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5282 case PARTITION_VERT:
5283 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5284 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5285 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5286 }
5287 break;
5288 case PARTITION_HORZ:
5289 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5290 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5291 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5292 }
5293 break;
5294 case PARTITION_SPLIT:
5295 if (bsize == BLOCK_8X8) {
5296 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5297 } else {
5298 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5299 pc_tree->split[0]))
5300 return 1;
5301 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5302 pc_tree->split[1]))
5303 return 1;
5304 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5305 pc_tree->split[2]))
5306 return 1;
5307 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5308 pc_tree->split[3]))
5309 return 1;
5310 }
5311 break;
5312#if CONFIG_EXT_PARTITION_TYPES
5313 case PARTITION_HORZ_A:
5314 for (i = 0; i < 3; i++) {
5315 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5316 }
5317 break;
5318 case PARTITION_HORZ_B:
5319 for (i = 0; i < 3; i++) {
5320 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5321 }
5322 break;
5323 case PARTITION_VERT_A:
5324 for (i = 0; i < 3; i++) {
5325 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5326 }
5327 break;
5328 case PARTITION_VERT_B:
5329 for (i = 0; i < 3; i++) {
5330 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5331 }
5332 break;
5333#endif // CONFIG_EXT_PARTITION_TYPES
5334 default: assert(0);
5335 }
5336 return 0;
5337}
5338
5339static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5340 return ctx->mic.mbmi.tx_size == supertx_size;
5341}
5342
5343static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5344 PC_TREE *pc_tree) {
5345 PARTITION_TYPE partition;
5346 BLOCK_SIZE subsize;
5347
5348 partition = pc_tree->partitioning;
5349 subsize = get_subsize(bsize, partition);
5350 switch (partition) {
5351 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5352 case PARTITION_VERT:
5353 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5354 case PARTITION_HORZ:
5355 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5356 case PARTITION_SPLIT:
5357 if (bsize == BLOCK_8X8)
5358 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5359 else
5360 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5361#if CONFIG_EXT_PARTITION_TYPES
5362 case PARTITION_HORZ_A:
5363 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5364 case PARTITION_HORZ_B:
5365 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5366 case PARTITION_VERT_A:
5367 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5368 case PARTITION_VERT_B:
5369 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5370#endif // CONFIG_EXT_PARTITION_TYPES
5371 default: assert(0); return 0;
5372 }
5373}
5374
Yaowu Xuf883b422016-08-30 14:01:10 -07005375static void predict_superblock(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376#if CONFIG_EXT_INTER
5377 int mi_row_ori, int mi_col_ori,
5378#endif // CONFIG_EXT_INTER
5379 int mi_row_pred, int mi_col_pred,
5380 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5381 // Used in supertx
5382 // (mi_row_ori, mi_col_ori): location for mv
5383 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Yaowu Xuf883b422016-08-30 14:01:10 -07005384 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005385 MACROBLOCK *const x = &td->mb;
5386 MACROBLOCKD *const xd = &x->e_mbd;
5387 MODE_INFO *mi_8x8 = xd->mi[0];
5388 MODE_INFO *mi = mi_8x8;
5389 MB_MODE_INFO *mbmi = &mi->mbmi;
5390 int ref;
5391 const int is_compound = has_second_ref(mbmi);
5392
5393 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5394
5395 for (ref = 0; ref < 1 + is_compound; ++ref) {
5396 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005397 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5398 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399 }
5400
5401 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005402 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005403#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005404 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005405#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005406 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005407 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005408 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005409#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005410 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005411#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005412 mi_row_pred, mi_col_pred,
5413 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005414}
5415
Yaowu Xuf883b422016-08-30 14:01:10 -07005416static void predict_b_extend(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 const TileInfo *const tile, int block,
5418 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5419 int mi_col_pred, int mi_row_top, int mi_col_top,
5420 uint8_t *dst_buf[3], int dst_stride[3],
5421 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
5422 int output_enabled, int b_sub8x8, int bextend) {
5423 // Used in supertx
5424 // (mi_row_ori, mi_col_ori): location for mv
5425 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5426 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5427 // block: sub location of sub8x8 blocks
5428 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5429 // bextend: 1: region to predict is an extension of ori; 0: not
5430
5431 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07005432 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005433 MACROBLOCKD *const xd = &x->e_mbd;
5434 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5435 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5436 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5437 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5438
5439 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5440 mi_row_pred >= mi_row_top + mi_height_top ||
5441 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5442 mi_col_pred >= cm->mi_cols)
5443 return;
5444
5445 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5446 mi_col_ori, bsize_pred);
5447 xd->plane[0].dst.stride = dst_stride[0];
5448 xd->plane[1].dst.stride = dst_stride[1];
5449 xd->plane[2].dst.stride = dst_stride[2];
5450 xd->plane[0].dst.buf = dst_buf[0] +
5451 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5452 (c >> xd->plane[0].subsampling_x);
5453 xd->plane[1].dst.buf = dst_buf[1] +
5454 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5455 (c >> xd->plane[1].subsampling_x);
5456 xd->plane[2].dst.buf = dst_buf[2] +
5457 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5458 (c >> xd->plane[2].subsampling_x);
5459
5460 predict_superblock(cpi, td,
5461#if CONFIG_EXT_INTER
5462 mi_row_ori, mi_col_ori,
5463#endif // CONFIG_EXT_INTER
5464 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5465
5466 if (output_enabled && !bextend) update_stats(&cpi->common, td, 1);
5467}
5468
Yaowu Xuf883b422016-08-30 14:01:10 -07005469static void extend_dir(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005470 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5471 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
5472 int mi_row_top, int mi_col_top, int output_enabled,
5473 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5474 // dir: 0-lower, 1-upper, 2-left, 3-right
5475 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5476 MACROBLOCKD *xd = &td->mb.e_mbd;
5477 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5478 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5479 int xss = xd->plane[1].subsampling_x;
5480 int yss = xd->plane[1].subsampling_y;
5481 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5482
5483 BLOCK_SIZE extend_bsize;
5484 int unit, mi_row_pred, mi_col_pred;
5485
5486 if (dir == 0 || dir == 1) { // lower and upper
5487 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5488 ? BLOCK_8X8
5489 : BLOCK_16X8;
5490 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5491 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5492 mi_col_pred = mi_col;
5493
5494 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5495 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
5496 top_bsize, extend_bsize, output_enabled, b_sub8x8, 1);
5497
5498 if (mi_width > unit) {
5499 int i;
5500 for (i = 0; i < mi_width / unit - 1; i++) {
5501 mi_col_pred += unit;
5502 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5503 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
5504 dst_stride, top_bsize, extend_bsize, output_enabled,
5505 b_sub8x8, 1);
5506 }
5507 }
5508 } else if (dir == 2 || dir == 3) { // left and right
5509 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5510 ? BLOCK_8X8
5511 : BLOCK_8X16;
5512 unit = num_8x8_blocks_high_lookup[extend_bsize];
5513 mi_row_pred = mi_row;
5514 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5515
5516 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5517 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
5518 top_bsize, extend_bsize, output_enabled, b_sub8x8, 1);
5519
5520 if (mi_height > unit) {
5521 int i;
5522 for (i = 0; i < mi_height / unit - 1; i++) {
5523 mi_row_pred += unit;
5524 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5525 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
5526 dst_stride, top_bsize, extend_bsize, output_enabled,
5527 b_sub8x8, 1);
5528 }
5529 }
5530 } else {
5531 extend_bsize = BLOCK_8X8;
5532 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5533 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5534
5535 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5536 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
5537 top_bsize, extend_bsize, output_enabled, b_sub8x8, 1);
5538 }
5539}
5540
Yaowu Xuf883b422016-08-30 14:01:10 -07005541static void extend_all(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005542 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5543 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
5544 int mi_row_top, int mi_col_top, int output_enabled,
5545 uint8_t *dst_buf[3], int dst_stride[3]) {
5546 assert(block >= 0 && block < 4);
5547 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5548 mi_col_top, output_enabled, dst_buf, dst_stride, 0);
5549 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5550 mi_col_top, output_enabled, dst_buf, dst_stride, 1);
5551 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5552 mi_col_top, output_enabled, dst_buf, dst_stride, 2);
5553 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5554 mi_col_top, output_enabled, dst_buf, dst_stride, 3);
5555 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5556 mi_col_top, output_enabled, dst_buf, dst_stride, 4);
5557 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5558 mi_col_top, output_enabled, dst_buf, dst_stride, 5);
5559 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5560 mi_col_top, output_enabled, dst_buf, dst_stride, 6);
5561 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5562 mi_col_top, output_enabled, dst_buf, dst_stride, 7);
5563}
5564
5565// This function generates prediction for multiple blocks, between which
5566// discontinuity around boundary is reduced by smoothing masks. The basic
5567// smoothing mask is a soft step function along horz/vert direction. In more
5568// complicated case when a block is split into 4 subblocks, the basic mask is
5569// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5570// then applied to the 2 masked prediction mentioned above in vertical direction
5571// If the block is split into more than one level, at every stage, masked
5572// prediction is stored in dst_buf[] passed from higher level.
Yaowu Xuf883b422016-08-30 14:01:10 -07005573static void predict_sb_complex(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 const TileInfo *const tile, int mi_row,
5575 int mi_col, int mi_row_top, int mi_col_top,
5576 int output_enabled, BLOCK_SIZE bsize,
5577 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5578 int dst_stride[3], PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005579 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005580 MACROBLOCK *const x = &td->mb;
5581 MACROBLOCKD *const xd = &x->e_mbd;
5582
5583 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5584 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5585 const PARTITION_TYPE partition = pc_tree->partitioning;
5586 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5587#if CONFIG_EXT_PARTITION_TYPES
5588 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5589#endif
5590
5591 int i;
5592 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
5593 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5594 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5595 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5596 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5597 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5598 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5599
5600 assert(bsize >= BLOCK_8X8);
5601
5602 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
5603
Yaowu Xuf883b422016-08-30 14:01:10 -07005604#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5606 int len = sizeof(uint16_t);
5607 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5608 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
5609 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
5610 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5611 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
5612 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
5613 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
5614 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
5615 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
5616 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005617#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 dst_buf1[0] = tmp_buf1;
5619 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
5620 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
5621 dst_buf2[0] = tmp_buf2;
5622 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
5623 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
5624 dst_buf3[0] = tmp_buf3;
5625 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
5626 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005627#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005628 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005629#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630
5631 if (output_enabled && bsize < top_bsize)
5632 cm->counts.partition[ctx][partition]++;
5633
5634 for (i = 0; i < MAX_MB_PLANE; i++) {
5635 xd->plane[i].dst.buf = dst_buf[i];
5636 xd->plane[i].dst.stride = dst_stride[i];
5637 }
5638
5639 switch (partition) {
5640 case PARTITION_NONE:
5641 assert(bsize < top_bsize);
5642 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5643 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5644 bsize, output_enabled, 0, 0);
5645 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
5646 mi_col_top, output_enabled, dst_buf, dst_stride);
5647 break;
5648 case PARTITION_HORZ:
5649 if (bsize == BLOCK_8X8) {
5650 // Fisrt half
5651 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5652 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5653 BLOCK_8X8, output_enabled, 1, 0);
5654 if (bsize < top_bsize)
5655 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5656 mi_row_top, mi_col_top, output_enabled, dst_buf,
5657 dst_stride);
5658
5659 // Second half
5660 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5661 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
5662 top_bsize, BLOCK_8X8, output_enabled, 1, 1);
5663 if (bsize < top_bsize)
5664 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
5665 mi_row_top, mi_col_top, output_enabled, dst_buf1,
5666 dst_stride1);
5667
5668 // Smooth
5669 xd->plane[0].dst.buf = dst_buf[0];
5670 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005671 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005672 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5673 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5674 0);
5675 } else {
5676 // First half
5677 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5678 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5679 subsize, output_enabled, 0, 0);
5680 if (bsize < top_bsize)
5681 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5682 mi_row_top, mi_col_top, output_enabled, dst_buf,
5683 dst_stride);
5684 else
5685 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5686 mi_row_top, mi_col_top, output_enabled, dst_buf,
5687 dst_stride, 0);
5688
5689 if (mi_row + hbs < cm->mi_rows) {
5690 // Second half
5691 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5692 mi_col, mi_row_top, mi_col_top, dst_buf1,
5693 dst_stride1, top_bsize, subsize, output_enabled, 0,
5694 0);
5695 if (bsize < top_bsize)
5696 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
5697 mi_col, mi_row_top, mi_col_top, output_enabled, dst_buf1,
5698 dst_stride1);
5699 else
5700 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
5701 mi_col, mi_row_top, mi_col_top, output_enabled, dst_buf1,
5702 dst_stride1, 1);
5703
5704 // Smooth
5705 for (i = 0; i < MAX_MB_PLANE; i++) {
5706 xd->plane[i].dst.buf = dst_buf[i];
5707 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005708 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005709 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5710 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5711 PARTITION_HORZ, i);
5712 }
5713 }
5714 }
5715 break;
5716 case PARTITION_VERT:
5717 if (bsize == BLOCK_8X8) {
5718 // First half
5719 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5720 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5721 BLOCK_8X8, output_enabled, 1, 0);
5722 if (bsize < top_bsize)
5723 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5724 mi_row_top, mi_col_top, output_enabled, dst_buf,
5725 dst_stride);
5726
5727 // Second half
5728 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5729 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
5730 top_bsize, BLOCK_8X8, output_enabled, 1, 1);
5731 if (bsize < top_bsize)
5732 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
5733 mi_row_top, mi_col_top, output_enabled, dst_buf1,
5734 dst_stride1);
5735
5736 // Smooth
5737 xd->plane[0].dst.buf = dst_buf[0];
5738 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005739 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005740 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5741 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5742 0);
5743 } else {
5744 // bsize: not important, not useful
5745 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5746 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5747 subsize, output_enabled, 0, 0);
5748 if (bsize < top_bsize)
5749 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5750 mi_row_top, mi_col_top, output_enabled, dst_buf,
5751 dst_stride);
5752 else
5753 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5754 mi_row_top, mi_col_top, output_enabled, dst_buf,
5755 dst_stride, 3);
5756
5757 if (mi_col + hbs < cm->mi_cols) {
5758 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5759 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
5760 dst_stride1, top_bsize, subsize, output_enabled, 0,
5761 0);
5762 if (bsize < top_bsize)
5763 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
5764 mi_col + hbs, mi_row_top, mi_col_top, output_enabled,
5765 dst_buf1, dst_stride1);
5766 else
5767 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
5768 mi_col + hbs, mi_row_top, mi_col_top, output_enabled,
5769 dst_buf1, dst_stride1, 2);
5770
5771 for (i = 0; i < MAX_MB_PLANE; i++) {
5772 xd->plane[i].dst.buf = dst_buf[i];
5773 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005774 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005775 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5776 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5777 PARTITION_VERT, i);
5778 }
5779 }
5780 }
5781 break;
5782 case PARTITION_SPLIT:
5783 if (bsize == BLOCK_8X8) {
5784 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5785 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5786 BLOCK_8X8, output_enabled, 1, 0);
5787 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5788 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
5789 top_bsize, BLOCK_8X8, output_enabled, 1, 1);
5790 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5791 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
5792 top_bsize, BLOCK_8X8, output_enabled, 1, 1);
5793 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
5794 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
5795 top_bsize, BLOCK_8X8, output_enabled, 1, 1);
5796
5797 if (bsize < top_bsize) {
5798 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5799 mi_row_top, mi_col_top, output_enabled, dst_buf,
5800 dst_stride);
5801 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
5802 mi_row_top, mi_col_top, output_enabled, dst_buf1,
5803 dst_stride1);
5804 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
5805 mi_row_top, mi_col_top, output_enabled, dst_buf2,
5806 dst_stride2);
5807 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
5808 mi_row_top, mi_col_top, output_enabled, dst_buf3,
5809 dst_stride3);
5810 }
5811 } else {
5812 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
5813 mi_col_top, output_enabled, subsize, top_bsize,
5814 dst_buf, dst_stride, pc_tree->split[0]);
5815 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
5816 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
5817 mi_col_top, output_enabled, subsize, top_bsize,
5818 dst_buf1, dst_stride1, pc_tree->split[1]);
5819 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
5820 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
5821 mi_col_top, output_enabled, subsize, top_bsize,
5822 dst_buf2, dst_stride2, pc_tree->split[2]);
5823 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
5824 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
5825 mi_row_top, mi_col_top, output_enabled, subsize,
5826 top_bsize, dst_buf3, dst_stride3,
5827 pc_tree->split[3]);
5828 }
5829 for (i = 0; i < MAX_MB_PLANE; i++) {
5830 if (bsize == BLOCK_8X8 && i != 0)
5831 continue; // Skip <4x4 chroma smoothing
5832 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005833 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005834 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5835 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5836 PARTITION_VERT, i);
5837 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005838 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005839 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
5840 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5841 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07005842 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
5844 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5845 PARTITION_HORZ, i);
5846 }
5847 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005848 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005849 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
5850 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5851 PARTITION_HORZ, i);
5852 }
5853 }
5854 break;
5855#if CONFIG_EXT_PARTITION_TYPES
5856 case PARTITION_HORZ_A:
5857 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5858 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5859 bsize2, output_enabled, 0, 0);
5860 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
5861 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride);
5862
5863 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5864 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
5865 dst_stride1, top_bsize, bsize2, output_enabled, 0, 0);
5866 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
5867 mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1);
5868
5869 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5870 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
5871 top_bsize, subsize, output_enabled, 0, 0);
5872 if (bsize < top_bsize)
5873 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
5874 mi_row_top, mi_col_top, output_enabled, dst_buf2,
5875 dst_stride2);
5876 else
5877 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
5878 mi_row_top, mi_col_top, output_enabled, dst_buf2,
5879 dst_stride2, 1);
5880
5881 for (i = 0; i < MAX_MB_PLANE; i++) {
5882 xd->plane[i].dst.buf = dst_buf[i];
5883 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005884 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005885 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
5886 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5887 i);
5888 }
5889 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005890 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005891 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
5892 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5893 i);
5894 }
5895
5896 break;
5897 case PARTITION_VERT_A:
5898
5899 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5900 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5901 bsize2, output_enabled, 0, 0);
5902 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
5903 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride);
5904
5905 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5906 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
5907 top_bsize, bsize2, output_enabled, 0, 0);
5908 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
5909 mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1);
5910
5911 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5912 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
5913 dst_stride2, top_bsize, subsize, output_enabled, 0, 0);
5914 if (bsize < top_bsize)
5915 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
5916 mi_row_top, mi_col_top, output_enabled, dst_buf2,
5917 dst_stride2);
5918 else
5919 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
5920 mi_row_top, mi_col_top, output_enabled, dst_buf2,
5921 dst_stride2, 2);
5922
5923 for (i = 0; i < MAX_MB_PLANE; i++) {
5924 xd->plane[i].dst.buf = dst_buf[i];
5925 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005926 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005927 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
5928 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5929 i);
5930 }
5931 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005932 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005933 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
5934 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5935 i);
5936 }
5937 break;
5938 case PARTITION_HORZ_B:
5939
5940 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5941 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5942 subsize, output_enabled, 0, 0);
5943 if (bsize < top_bsize)
5944 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5945 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride);
5946 else
5947 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5948 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride,
5949 0);
5950
5951 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5952 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
5953 top_bsize, bsize2, output_enabled, 0, 0);
5954 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
5955 mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1);
5956
5957 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
5958 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
5959 dst_buf2, dst_stride2, top_bsize, bsize2, output_enabled,
5960 0, 0);
5961 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
5962 mi_col + hbs, mi_row_top, mi_col_top, output_enabled, dst_buf2,
5963 dst_stride2);
5964
5965 for (i = 0; i < MAX_MB_PLANE; i++) {
5966 xd->plane[i].dst.buf = dst_buf1[i];
5967 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005968 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005969 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
5970 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5971 PARTITION_VERT, i);
5972 }
5973 for (i = 0; i < MAX_MB_PLANE; i++) {
5974 xd->plane[i].dst.buf = dst_buf[i];
5975 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005976 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005977 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
5978 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5979 i);
5980 }
5981 break;
5982 case PARTITION_VERT_B:
5983
5984 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5985 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
5986 subsize, output_enabled, 0, 0);
5987 if (bsize < top_bsize)
5988 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5989 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride);
5990 else
5991 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
5992 mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride,
5993 3);
5994
5995 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5996 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
5997 dst_stride1, top_bsize, bsize2, output_enabled, 0, 0);
5998 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
5999 mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1);
6000
6001 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6002 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
6003 dst_buf2, dst_stride2, top_bsize, bsize2, output_enabled,
6004 0, 0);
6005 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
6006 mi_col + hbs, mi_row_top, mi_col_top, output_enabled, dst_buf2,
6007 dst_stride2);
6008
6009 for (i = 0; i < MAX_MB_PLANE; i++) {
6010 xd->plane[i].dst.buf = dst_buf1[i];
6011 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006012 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006013 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6014 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6015 PARTITION_HORZ, i);
6016 }
6017 for (i = 0; i < MAX_MB_PLANE; i++) {
6018 xd->plane[i].dst.buf = dst_buf[i];
6019 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006020 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6022 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6023 i);
6024 }
6025 break;
6026#endif // CONFIG_EXT_PARTITION_TYPES
6027 default: assert(0);
6028 }
6029
6030#if CONFIG_EXT_PARTITION_TYPES
6031 if (bsize < top_bsize)
6032 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6033#else
6034 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6035 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6036#endif // CONFIG_EXT_PARTITION_TYPES
6037}
6038
Yaowu Xuf883b422016-08-30 14:01:10 -07006039static void rd_supertx_sb(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040 const TileInfo *const tile, int mi_row, int mi_col,
6041 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6042 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006043 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006044 MACROBLOCK *const x = &td->mb;
6045 MACROBLOCKD *const xd = &x->e_mbd;
6046 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6047 base_rate = *tmp_rate;
6048 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6049 uint8_t *dst_buf[3];
6050 int dst_stride[3];
6051 TX_SIZE tx_size;
6052 MB_MODE_INFO *mbmi;
6053 TX_TYPE tx_type, best_tx_nostx;
6054#if CONFIG_EXT_TX
6055 int ext_tx_set;
6056#endif // CONFIG_EXT_TX
6057 int tmp_rate_tx = 0, skip_tx = 0;
6058 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6059
6060 set_skip_context(xd, mi_row, mi_col);
6061 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
6062 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 0, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006063 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006064 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6065 dst_buf[plane] = xd->plane[plane].dst.buf;
6066 dst_stride[plane] = xd->plane[plane].dst.stride;
6067 }
6068 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 0, bsize,
6069 bsize, dst_buf, dst_stride, pc_tree);
6070
6071 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6072 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6073
6074 mbmi = &xd->mi[0]->mbmi;
6075 best_tx_nostx = mbmi->tx_type;
6076
6077 *best_tx = DCT_DCT;
6078
6079 // chroma
6080 skippable_uv = 1;
6081 rate_uv = 0;
6082 dist_uv = 0;
6083 sse_uv = 0;
6084 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6085#if CONFIG_VAR_TX
6086 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6087 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6088 const struct macroblockd_plane *const pd = &xd->plane[plane];
6089 int coeff_ctx = 1;
6090
6091 this_rate = 0;
6092 this_dist = 0;
6093 pnsse = 0;
6094 pnskip = 1;
6095
6096 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006097 tx_size =
6098 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006099 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006100 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6101
Yaowu Xuf883b422016-08-30 14:01:10 -07006102 av1_subtract_plane(x, bsize, plane);
6103 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
6104 get_plane_block_size(bsize, pd), coeff_ctx, &this_rate,
6105 &this_dist, &pnsse, &pnskip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006106#else
6107 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006108 tx_size =
6109 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006110 av1_subtract_plane(x, bsize, plane);
6111 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6112 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006113#endif // CONFIG_VAR_TX
6114
6115 rate_uv += this_rate;
6116 dist_uv += this_dist;
6117 sse_uv += pnsse;
6118 skippable_uv &= pnskip;
6119 }
6120
6121 // luma
6122 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006123 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006124#if CONFIG_EXT_TX
6125 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6126#endif // CONFIG_EXT_TX
6127 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6128#if CONFIG_VAR_TX
6129 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6130 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6131 const struct macroblockd_plane *const pd = &xd->plane[0];
6132 int coeff_ctx = 1;
6133#endif // CONFIG_VAR_TX
6134#if CONFIG_EXT_TX
6135 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6136#else
6137 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6138#endif // CONFIG_EXT_TX
6139 mbmi->tx_type = tx_type;
6140
6141#if CONFIG_VAR_TX
6142 this_rate = 0;
6143 this_dist = 0;
6144 pnsse = 0;
6145 pnskip = 1;
6146
Yaowu Xuf883b422016-08-30 14:01:10 -07006147 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006148 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006149 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx, &this_rate,
6150 &this_dist, &pnsse, &pnskip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006151#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006152 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6153 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006154#endif // CONFIG_VAR_TX
6155
6156#if CONFIG_EXT_TX
6157 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6158 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6159 if (ext_tx_set > 0)
6160 this_rate +=
6161 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6162 }
6163#else
6164 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6165 this_rate != INT_MAX) {
6166 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6167 }
6168#endif // CONFIG_EXT_TX
6169 *tmp_rate = rate_uv + this_rate;
6170 *tmp_dist = dist_uv + this_dist;
6171 sse = sse_uv + pnsse;
6172 skippable = skippable_uv && pnskip;
6173 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006174 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006175 x->skip = 1;
6176 } else {
6177 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6178 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006179 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006180 x->skip = 0;
6181 } else {
6182 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006183 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006184 x->skip = 1;
6185 }
6186 }
6187 *tmp_rate += base_rate;
6188 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6189 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6190 *best_tx = tx_type;
6191 bestrd_tx = rd_tx;
6192 tmp_rate_tx = *tmp_rate;
6193 tmp_dist_tx = *tmp_dist;
6194 skip_tx = x->skip;
6195 }
6196 }
6197 *tmp_rate = tmp_rate_tx;
6198 *tmp_dist = tmp_dist_tx;
6199 x->skip = skip_tx;
6200#if CONFIG_VAR_TX
6201 for (plane = 0; plane < 1; ++plane)
6202 memset(x->blk_skip[plane], x->skip,
6203 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6204#endif // CONFIG_VAR_TX
6205 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6206}
6207#endif // CONFIG_SUPERTX