blob: 9e27af01b4a8f2e47db1d8acf39b3adf77d720e7 [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"
Sarah Parkerf1783292017-04-05 11:55:27 -070021#include "aom_dsp/binary_codes_writer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070022#include "aom_ports/mem.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070023#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070024#include "aom_ports/system_state.h"
25
26#include "av1/common/common.h"
27#include "av1/common/entropy.h"
28#include "av1/common/entropymode.h"
29#include "av1/common/idct.h"
emilkeyder@google.comf3477632017-03-01 16:29:14 -050030#include "av1/common/mv.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070031#include "av1/common/mvref_common.h"
32#include "av1/common/pred_common.h"
33#include "av1/common/quant_common.h"
34#include "av1/common/reconintra.h"
35#include "av1/common/reconinter.h"
36#include "av1/common/seg_common.h"
37#include "av1/common/tile_common.h"
38
39#include "av1/encoder/aq_complexity.h"
40#include "av1/encoder/aq_cyclicrefresh.h"
41#include "av1/encoder/aq_variance.h"
Sarah Parkere5299862016-08-16 14:57:37 -070042#include "av1/common/warped_motion.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070043#include "av1/encoder/global_motion.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070044#include "av1/encoder/encodeframe.h"
45#include "av1/encoder/encodemb.h"
46#include "av1/encoder/encodemv.h"
Angie Chiang0397eda2017-03-15 16:57:14 -070047#if CONFIG_LV_MAP
48#include "av1/encoder/encodetxb.h"
49#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070050#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"
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020056#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070057#define IF_HBD(...) __VA_ARGS__
58#else
59#define IF_HBD(...)
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020060#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070061
Urvang Joshi52648442016-10-13 17:27:51 -070062static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
63 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
Yushin Cho6d72a2f2017-05-03 17:37:37 -070064 int mi_col, BLOCK_SIZE bsize, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070065
Yaowu Xuc27fc142016-08-22 16:08:15 -070066// This is used as a reference when computing the source variance for the
67// purposes of activity masking.
68// Eventually this should be replaced by custom no-reference routines,
69// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -070070static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070071 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
72 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
73 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
74 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
75 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
76#if CONFIG_EXT_PARTITION
77 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
78 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
79 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
80 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
81 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
82#endif // CONFIG_EXT_PARTITION
83};
84
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020085#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -070086static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070087 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
88 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
89 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
90 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
91 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
92#if CONFIG_EXT_PARTITION
93 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
94 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
95 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
96 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
97 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
98#endif // CONFIG_EXT_PARTITION
99};
100
Yaowu Xuf883b422016-08-30 14:01:10 -0700101static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
103 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
104 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
105 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
106 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
107 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
108 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
109 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
110#if CONFIG_EXT_PARTITION
111 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
112 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
113 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
114 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
115 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
116 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
117 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
118 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
119#endif // CONFIG_EXT_PARTITION
120};
121
Yaowu Xuf883b422016-08-30 14:01:10 -0700122static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700123 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
124 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
125 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
126 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
127 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
128 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
129 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
130 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
131 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
132 128 * 16,
133#if CONFIG_EXT_PARTITION
134 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
135 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
136 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
137 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
138 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
139 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
140 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
141 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
142 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
143 128 * 16
144#endif // CONFIG_EXT_PARTITION
145};
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200146#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147
Urvang Joshi52648442016-10-13 17:27:51 -0700148unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700149 const struct buf_2d *ref,
150 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700151 unsigned int sse;
152 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700153 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
155}
156
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200157#if CONFIG_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700158unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700159 const struct buf_2d *ref,
160 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700161 unsigned int var, sse;
162 switch (bd) {
163 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700164 var =
165 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
166 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700167 break;
168 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700169 var =
170 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
171 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172 break;
173 case 8:
174 default:
175 var =
176 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700177 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700178 break;
179 }
180 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
181}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200182#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183
Urvang Joshi52648442016-10-13 17:27:51 -0700184static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700185 const struct buf_2d *ref,
186 int mi_row, int mi_col,
187 BLOCK_SIZE bs) {
188 unsigned int sse, var;
189 uint8_t *last_y;
190 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
191
192 assert(last != NULL);
193 last_y =
194 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
195 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
196 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
197}
198
Yaowu Xuf883b422016-08-30 14:01:10 -0700199static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
200 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201 unsigned int var = get_sby_perpixel_diff_variance(
202 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
203 if (var < 8)
204 return BLOCK_64X64;
205 else if (var < 128)
206 return BLOCK_32X32;
207 else if (var < 2048)
208 return BLOCK_16X16;
209 else
210 return BLOCK_8X8;
211}
212
213// Lighter version of set_offsets that only sets the mode info
214// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700215static void set_mode_info_offsets(const AV1_COMP *const cpi,
216 MACROBLOCK *const x, MACROBLOCKD *const xd,
217 int mi_row, int mi_col) {
218 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700219 const int idx_str = xd->mi_stride * mi_row + mi_col;
220 xd->mi = cm->mi_grid_visible + idx_str;
221 xd->mi[0] = cm->mi + idx_str;
222 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
223}
224
Urvang Joshi52648442016-10-13 17:27:51 -0700225static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700226 const TileInfo *const tile,
227 MACROBLOCK *const x, int mi_row,
228 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700229 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700230 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800231 const int mi_width = mi_size_wide[bsize];
232 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233
Yaowu Xuc27fc142016-08-22 16:08:15 -0700234 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Jingning Hanf5a4d3b2017-08-27 23:01:19 -0700235
Jingning Han9a80e7c2017-05-23 23:39:31 -0700236 set_skip_context(xd, mi_row, mi_col);
Jingning Han331662e2017-05-30 17:03:32 -0700237 xd->above_txfm_context =
238 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
239 xd->left_txfm_context = xd->left_txfm_context_buffer +
240 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700241
242 // Set up destination pointers.
Jingning Han91d9a792017-04-18 12:01:52 -0700243 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
244 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700245
246 // Set up limit values for MV components.
247 // Mv beyond the range do not produce new/different prediction block.
Alex Converse0fa0f422017-04-24 12:51:14 -0700248 x->mv_limits.row_min =
249 -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
250 x->mv_limits.col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
251 x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
252 x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700253
Jingning Hanfaad0e12016-12-07 10:54:57 -0800254 set_plane_n4(xd, mi_width, mi_height);
Jingning Hana6923f72016-07-15 08:50:14 -0700255
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256 // Set up distance of MB to edge of frame in 1/8th pel units.
257 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
Urvang Joshi359dc2b2017-04-27 15:41:47 -0700258 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800259#if CONFIG_DEPENDENT_HORZTILES
Urvang Joshi359dc2b2017-04-27 15:41:47 -0700260 cm->dependent_horz_tiles,
261#endif // CONFIG_DEPENDENT_HORZTILES
262 cm->mi_rows, cm->mi_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263
264 // Set up source buffers.
Alex Conversef77fd0b2017-04-20 11:00:24 -0700265 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700266
267 // R/D setup.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700268 x->rdmult = cpi->rd.RDMULT;
269
Yaowu Xuf883b422016-08-30 14:01:10 -0700270 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700271 xd->tile = *tile;
272}
273
Urvang Joshi52648442016-10-13 17:27:51 -0700274static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700275 MACROBLOCK *const x, int mi_row, int mi_col,
276 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700277 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700278 MACROBLOCKD *const xd = &x->e_mbd;
279 MB_MODE_INFO *mbmi;
280 const struct segmentation *const seg = &cm->seg;
281
282 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
283
284 mbmi = &xd->mi[0]->mbmi;
Luc Trudeau780d2492017-06-15 22:26:41 -0400285#if CONFIG_CFL
286 xd->cfl->mi_row = mi_row;
287 xd->cfl->mi_col = mi_col;
288#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700289
290 // Setup segment ID.
291 if (seg->enabled) {
292 if (!cpi->vaq_refresh) {
293 const uint8_t *const map =
294 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
295 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
296 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700297 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298 } else {
299 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700301}
302
Yaowu Xuc27fc142016-08-22 16:08:15 -0700303#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700304static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700305 MB_MODE_INFO *mbmi) {
Rupert Swarbrick27e90292017-09-28 17:46:50 +0100306 InterpFilter filters[2];
307 InterpFilter default_filter = av1_unswitchable_filter(cm->interp_filter);
308
309 for (int dir = 0; dir < 2; ++dir) {
310 filters[dir] = ((!has_subpel_mv_component(xd->mi[0], xd, dir) &&
311 (mbmi->ref_frame[1] == NONE_FRAME ||
312 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
313 ? default_filter
314 : av1_extract_interp_filter(mbmi->interp_filters, dir));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700315 }
Rupert Swarbrick27e90292017-09-28 17:46:50 +0100316 mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700317}
318
319static void update_filter_type_count(FRAME_COUNTS *counts,
320 const MACROBLOCKD *xd,
321 const MB_MODE_INFO *mbmi) {
322 int dir;
323 for (dir = 0; dir < 2; ++dir) {
324 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
325 (mbmi->ref_frame[1] > INTRA_FRAME &&
326 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700327 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Rupert Swarbrick27e90292017-09-28 17:46:50 +0100328 InterpFilter filter =
329 av1_extract_interp_filter(mbmi->interp_filters, dir);
330 ++counts->switchable_interp[ctx][filter];
331 update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
332 SWITCHABLE_FILTERS);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700333 }
334 }
335}
336#endif
Debargha Mukherjee705544c2016-11-22 08:55:49 -0800337static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
Debargha Mukherjeea575d232017-04-28 17:46:47 -0700338 const MB_MODE_INFO *mbmi,
339 RD_COUNTS *rdc) {
Sebastien Alaiwan0bdea0d2017-10-02 15:15:05 +0200340 if (mode == ZEROMV || mode == ZERO_ZEROMV) {
Debargha Mukherjee265db6d2017-03-28 11:15:27 -0700341 const int num_4x4s =
342 num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
Sarah Parkerc2d38712017-01-24 15:15:41 -0800343 int ref;
344 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
Debargha Mukherjeea575d232017-04-28 17:46:47 -0700345 rdc->global_motion_used[mbmi->ref_frame[ref]] += num_4x4s;
Debargha Mukherjee705544c2016-11-22 08:55:49 -0800346 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700347 }
348}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700349
Jingning Han4470af12017-03-06 15:34:41 -0800350static void reset_tx_size(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
351 const TX_MODE tx_mode) {
352 if (xd->lossless[mbmi->segment_id]) {
353 mbmi->tx_size = TX_4X4;
354 } else if (tx_mode != TX_MODE_SELECT) {
355 mbmi->tx_size =
356 tx_size_from_tx_mode(mbmi->sb_type, tx_mode, is_inter_block(mbmi));
357 }
358}
359
Zoe Liu3be7aa62017-04-26 09:27:57 -0700360static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
361 int8_t rf_type) {
362 MACROBLOCKD *const xd = &x->e_mbd;
363 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
364
365 const int bw = xd->n8_w << MI_SIZE_LOG2;
366 const int bh = xd->n8_h << MI_SIZE_LOG2;
367 int ref_mv_idx = mbmi->ref_mv_idx;
368 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
369 CANDIDATE_MV *const curr_ref_mv_stack = mbmi_ext->ref_mv_stack[rf_type];
370
Zoe Liu3be7aa62017-04-26 09:27:57 -0700371 if (has_second_ref(mbmi)) {
372 // Special case: NEAR_NEWMV and NEW_NEARMV modes use 1 + mbmi->ref_mv_idx
373 // (like NEARMV) instead
374 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV) ref_mv_idx += 1;
375
376 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
377 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
378 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
379 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
380 mbmi->pred_mv[0] = this_mv;
381 mi_pred_mv[0] = this_mv;
382 }
383 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
384 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
385 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
386 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
387 mbmi->pred_mv[1] = this_mv;
388 mi_pred_mv[1] = this_mv;
389 }
Zoe Liu85b66462017-04-20 14:28:19 -0700390#if CONFIG_COMPOUND_SINGLEREF
391 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
392 // Special case: SR_NEAR_NEWMV uses 1 + mbmi->ref_mv_idx
393 // (like NEARMV) instead
394 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx += 1;
395
396 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
397 compound_ref1_mode(mbmi->mode) == NEWMV) {
398 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
399 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
400 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
401 mbmi->pred_mv[0] = this_mv;
402 mi_pred_mv[0] = this_mv;
403 }
404#endif // CONFIG_COMPOUND_SINGLEREF
Zoe Liu3be7aa62017-04-26 09:27:57 -0700405 } else {
Zoe Liu3be7aa62017-04-26 09:27:57 -0700406 if (mbmi->mode == NEWMV) {
407 int i;
408 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
409 int_mv this_mv = (i == 0) ? curr_ref_mv_stack[ref_mv_idx].this_mv
410 : curr_ref_mv_stack[ref_mv_idx].comp_mv;
411 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
412 mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
413 mbmi->pred_mv[i] = this_mv;
414 mi_pred_mv[i] = this_mv;
415 }
416 }
Zoe Liu3be7aa62017-04-26 09:27:57 -0700417 }
Zoe Liu3be7aa62017-04-26 09:27:57 -0700418}
Zoe Liu3be7aa62017-04-26 09:27:57 -0700419
Urvang Joshi52648442016-10-13 17:27:51 -0700420static void update_state(const AV1_COMP *const cpi, ThreadData *td,
421 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
422 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700423 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -0700424 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700425 RD_COUNTS *const rdc = &td->rd_counts;
426 MACROBLOCK *const x = &td->mb;
427 MACROBLOCKD *const xd = &x->e_mbd;
428 struct macroblock_plane *const p = x->plane;
429 struct macroblockd_plane *const pd = xd->plane;
430 MODE_INFO *mi = &ctx->mic;
431 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
432 MODE_INFO *mi_addr = xd->mi[0];
433 const struct segmentation *const seg = &cm->seg;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800434 const int bw = mi_size_wide[mi->mbmi.sb_type];
435 const int bh = mi_size_high[mi->mbmi.sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700436 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800437 const int mi_width = mi_size_wide[bsize];
438 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700439 int8_t rf_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700440
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 assert(mi->mbmi.sb_type == bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700442
443 *mi_addr = *mi;
444 *x->mbmi_ext = ctx->mbmi_ext;
445
446#if CONFIG_DUAL_FILTER
447 reset_intmv_filter_type(cm, xd, mbmi);
448#endif
449
Yaowu Xuf883b422016-08-30 14:01:10 -0700450 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Debargha Mukherjeeedced252017-10-20 00:02:00 -0700451 if (x->mbmi_ext->ref_mv_count[rf_type] > 1) {
Zoe Liu3be7aa62017-04-26 09:27:57 -0700452 set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
David Barker3dfba992017-04-03 16:10:09 +0100453 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700454
455 // If segmentation in use
456 if (seg->enabled) {
457 // For in frame complexity AQ copy the segment id from the segment map.
458 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
459 const uint8_t *const map =
460 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
461 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
Jingning Han4470af12017-03-06 15:34:41 -0800462 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700463 }
464 // Else for cyclic refresh mode update the segment map, set the segment id
465 // and then update the quantizer.
466 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700467 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
468 bsize, ctx->rate, ctx->dist, x->skip);
Jingning Han4470af12017-03-06 15:34:41 -0800469 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700470 }
471 }
472
Brennan Shacklette0b5ae82016-11-07 17:25:20 -0800473 for (i = 0; i < MAX_MB_PLANE; ++i) {
474 p[i].coeff = ctx->coeff[i];
475 p[i].qcoeff = ctx->qcoeff[i];
476 pd[i].dqcoeff = ctx->dqcoeff[i];
Brennan Shacklette0b5ae82016-11-07 17:25:20 -0800477 p[i].eobs = ctx->eobs[i];
Angie Chiang74e23072017-03-24 14:54:23 -0700478#if CONFIG_LV_MAP
479 p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
480#endif // CONFIG_LV_MAP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700481 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700482 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Sarah Parker5c6744b2017-08-25 17:27:45 -0700483#if CONFIG_MRC_TX
484 xd->mrc_mask = ctx->mrc_mask;
485#endif // CONFIG_MRC_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700486 // Restore the coding context of the MB to that that was in place
487 // when the mode was picked for it
488 for (y = 0; y < mi_height; y++)
489 for (x_idx = 0; x_idx < mi_width; x_idx++)
490 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
491 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
492 xd->mi[x_idx + y * mis] = mi_addr;
493 }
494
Thomas Davies3ab20b42017-09-19 10:30:53 +0100495#if !CONFIG_EXT_DELTA_Q
Arild Fuldseth07441162016-08-15 15:07:52 +0200496 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -0700497 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +0200498#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700499 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -0700500 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +0200501#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700502
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503 x->skip = ctx->skip;
504
Yaowu Xuc27fc142016-08-22 16:08:15 -0700505 for (i = 0; i < 1; ++i)
506 memcpy(x->blk_skip[i], ctx->blk_skip[i],
507 sizeof(uint8_t) * ctx->num_4x4_blk);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700508
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700509 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700510
511#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -0700512 {
513 unsigned int *const mode_chosen_counts =
514 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
515 if (frame_is_intra_only(cm)) {
516 static const int kf_mode_index[] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -0700517 THR_DC /*DC_PRED*/,
518 THR_V_PRED /*V_PRED*/,
519 THR_H_PRED /*H_PRED*/,
520 THR_D45_PRED /*D45_PRED*/,
521 THR_D135_PRED /*D135_PRED*/,
522 THR_D117_PRED /*D117_PRED*/,
523 THR_D153_PRED /*D153_PRED*/,
524 THR_D207_PRED /*D207_PRED*/,
525 THR_D63_PRED /*D63_PRED*/,
Urvang Joshi6be4a542016-11-03 15:24:05 -0700526 THR_SMOOTH, /*SMOOTH_PRED*/
Urvang Joshie6ca8e82017-03-15 14:57:41 -0700527#if CONFIG_SMOOTH_HV
528 THR_SMOOTH_V, /*SMOOTH_V_PRED*/
529 THR_SMOOTH_H, /*SMOOTH_H_PRED*/
530#endif // CONFIG_SMOOTH_HV
Urvang Joshi96d1c0a2017-10-10 13:15:32 -0700531 THR_PAETH /*PAETH_PRED*/,
Urvang Joshi52648442016-10-13 17:27:51 -0700532 };
533 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
534 } else {
535 // Note how often each mode chosen as best
536 ++mode_chosen_counts[ctx->best_mode_index];
537 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700538 }
539#endif
540 if (!frame_is_intra_only(cm)) {
541 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700542 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700543 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -0700544 // TODO(sarahparker): global motion stats need to be handled per-tile
545 // to be compatible with tile-based threading.
Debargha Mukherjeea575d232017-04-28 17:46:47 -0700546 update_global_motion_used(mbmi->mode, bsize, mbmi, rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700547 } else {
548 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
549 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
550 int idx, idy;
551 for (idy = 0; idy < 2; idy += num_4x4_h) {
552 for (idx = 0; idx < 2; idx += num_4x4_w) {
553 const int j = idy * 2 + idx;
Debargha Mukherjeea575d232017-04-28 17:46:47 -0700554 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi, rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700555 }
556 }
557 }
Sebastien Alaiwan1f56b8e2017-10-31 17:37:16 +0100558 if (cm->interp_filter == SWITCHABLE &&
559 mbmi->motion_mode != WARPED_CAUSAL &&
560 !is_nontrans_global_motion(xd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700561#if CONFIG_DUAL_FILTER
562 update_filter_type_count(td->counts, xd, mbmi);
563#else
Urvang Joshi454280d2016-10-14 16:51:44 -0700564 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
Rupert Swarbrick27e90292017-09-28 17:46:50 +0100565 const InterpFilter filter =
566 av1_extract_interp_filter(mbmi->interp_filters, 0);
567 ++td->counts->switchable_interp[switchable_ctx][filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700568#endif
569 }
570 }
571
572 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
573 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
574 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
575 }
576
Yunqing Wangd1d511f2017-10-05 08:44:46 -0700577 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
578 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
579 av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
Cheng Chen0a7f2f52017-10-10 15:16:09 -0700580
581#if CONFIG_JNT_COMP
582 if (has_second_ref(mbmi)) {
583 const int comp_index_ctx = get_comp_index_context(cm, xd);
584 ++td->counts->compound_index[comp_index_ctx][mbmi->compound_idx];
585 }
586#endif // CONFIG_JNT_COMP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587}
588
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +0100589#if NC_MODE_INFO
Yue Chenf27b1602017-01-13 11:11:43 -0800590static void set_mode_info_b(const AV1_COMP *const cpi,
591 const TileInfo *const tile, ThreadData *td,
592 int mi_row, int mi_col, BLOCK_SIZE bsize,
593 PICK_MODE_CONTEXT *ctx) {
594 MACROBLOCK *const x = &td->mb;
595 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
596 update_state(cpi, td, ctx, mi_row, mi_col, bsize, 1);
597}
598
599static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
600 const TileInfo *const tile, TOKENEXTRA **tp,
601 int mi_row, int mi_col, BLOCK_SIZE bsize,
602 PC_TREE *pc_tree) {
603 const AV1_COMMON *const cm = &cpi->common;
Jingning Han91f01fd2017-01-18 17:16:40 -0800604 const int hbs = mi_size_wide[bsize] / 2;
Yue Chenf27b1602017-01-13 11:11:43 -0800605 const PARTITION_TYPE partition = pc_tree->partitioning;
606 BLOCK_SIZE subsize = get_subsize(bsize, partition);
607#if CONFIG_EXT_PARTITION_TYPES
608 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
Rupert Swarbrick93c39e92017-07-12 11:11:02 +0100609 const int quarter_step = mi_size_wide[bsize] / 4;
Yue Chenf27b1602017-01-13 11:11:43 -0800610#endif
Yue Chenf27b1602017-01-13 11:11:43 -0800611
612 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
613
614 switch (partition) {
615 case PARTITION_NONE:
616 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize, &pc_tree->none);
617 break;
618 case PARTITION_VERT:
619 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
620 &pc_tree->vertical[0]);
Debargha Mukherjeeedced252017-10-20 00:02:00 -0700621 if (mi_col + hbs < cm->mi_cols) {
Yue Chenf27b1602017-01-13 11:11:43 -0800622 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
623 &pc_tree->vertical[1]);
624 }
625 break;
626 case PARTITION_HORZ:
627 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
628 &pc_tree->horizontal[0]);
Debargha Mukherjeeedced252017-10-20 00:02:00 -0700629 if (mi_row + hbs < cm->mi_rows) {
Yue Chenf27b1602017-01-13 11:11:43 -0800630 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
631 &pc_tree->horizontal[1]);
632 }
633 break;
634 case PARTITION_SPLIT:
Debargha Mukherjeeedced252017-10-20 00:02:00 -0700635 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col, subsize,
636 pc_tree->split[0]);
637 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, subsize,
638 pc_tree->split[1]);
639 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, subsize,
640 pc_tree->split[2]);
641 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, subsize,
642 pc_tree->split[3]);
Yue Chenf27b1602017-01-13 11:11:43 -0800643 break;
644#if CONFIG_EXT_PARTITION_TYPES
Rupert Swarbrick3dd33912017-09-12 14:24:11 +0100645#if CONFIG_EXT_PARTITION_TYPES_AB
646#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
647#endif
Yue Chenf27b1602017-01-13 11:11:43 -0800648 case PARTITION_HORZ_A:
649 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
650 &pc_tree->horizontala[0]);
651 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
652 &pc_tree->horizontala[1]);
653 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
654 &pc_tree->horizontala[2]);
655 break;
656 case PARTITION_HORZ_B:
657 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
658 &pc_tree->horizontalb[0]);
659 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
660 &pc_tree->horizontalb[1]);
661 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
662 &pc_tree->horizontalb[2]);
663 break;
664 case PARTITION_VERT_A:
665 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
666 &pc_tree->verticala[0]);
667 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
668 &pc_tree->verticala[1]);
669 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
670 &pc_tree->verticala[2]);
671 break;
672 case PARTITION_VERT_B:
673 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
674 &pc_tree->verticalb[0]);
675 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
676 &pc_tree->verticalb[1]);
677 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
678 &pc_tree->verticalb[2]);
679 break;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +0100680 case PARTITION_HORZ_4:
681 for (int i = 0; i < 4; ++i) {
682 int this_mi_row = mi_row + i * quarter_step;
683 if (i > 0 && this_mi_row >= cm->mi_rows) break;
684
685 set_mode_info_b(cpi, tile, td, this_mi_row, mi_col, subsize,
686 &pc_tree->horizontal4[i]);
687 }
688 break;
689 case PARTITION_VERT_4:
690 for (int i = 0; i < 4; ++i) {
691 int this_mi_col = mi_col + i * quarter_step;
692 if (i > 0 && this_mi_col >= cm->mi_cols) break;
693
694 set_mode_info_b(cpi, tile, td, mi_row, this_mi_col, subsize,
695 &pc_tree->vertical4[i]);
696 }
697 break;
Yue Chenf27b1602017-01-13 11:11:43 -0800698#endif // CONFIG_EXT_PARTITION_TYPES
699 default: assert(0 && "Invalid partition type."); break;
700 }
701}
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -0700702
703#if CONFIG_NCOBMC_ADAPT_WEIGHT
704static void av1_get_ncobmc_mode_rd(const AV1_COMP *const cpi,
705 MACROBLOCK *const x, MACROBLOCKD *const xd,
706 int bsize, const int mi_row,
707 const int mi_col, NCOBMC_MODE *mode) {
708 const AV1_COMMON *const cm = &cpi->common;
709 const int mi_width = mi_size_wide[bsize];
710 const int mi_height = mi_size_high[bsize];
711
712 assert(bsize >= BLOCK_8X8);
713
714 reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
715 cm->mi_cols);
716
717 // set up source buffers before calling the mode searching function
718 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
719
720 *mode = get_ncobmc_mode(cpi, x, xd, mi_row, mi_col, bsize);
721}
722static void get_ncobmc_intrpl_pred(const AV1_COMP *const cpi, ThreadData *td,
723 int mi_row, int mi_col, BLOCK_SIZE bsize) {
724 MACROBLOCK *const x = &td->mb;
725 MACROBLOCKD *const xd = &x->e_mbd;
726 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
727 const int mi_width = mi_size_wide[bsize];
728 const int mi_height = mi_size_high[bsize];
729 const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
730 const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
731
732 if (mi_width > mi_height) {
733 // horizontal partition
734 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
735 &mbmi->ncobmc_mode[0]);
736 xd->mi += hbs;
737 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col + hbs,
738 &mbmi->ncobmc_mode[1]);
739 } else if (mi_height > mi_width) {
740 // vertical partition
741 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
742 &mbmi->ncobmc_mode[0]);
743 xd->mi += hbs * xd->mi_stride;
744 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row + hbs, mi_col,
745 &mbmi->ncobmc_mode[1]);
746 } else {
747 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
748 &mbmi->ncobmc_mode[0]);
749 }
750 // restore the info
751 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
752 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
753}
754#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +0100755#endif // (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
Yue Chenf27b1602017-01-13 11:11:43 -0800756
Yaowu Xuf883b422016-08-30 14:01:10 -0700757void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
758 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
760 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
761 src->uv_crop_width };
762 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
763 src->uv_crop_height };
764 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
765 int i;
766
767 // Set current frame pointer.
768 x->e_mbd.cur_buf = src;
769
770 for (i = 0; i < MAX_MB_PLANE; i++)
Jingning Han91d9a792017-04-18 12:01:52 -0700771 setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type, buffers[i],
772 widths[i], heights[i], strides[i], mi_row, mi_col, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 x->e_mbd.plane[i].subsampling_x,
774 x->e_mbd.plane[i].subsampling_y);
775}
776
Urvang Joshi52648442016-10-13 17:27:51 -0700777static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 int8_t segment_id) {
779 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -0700780 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -0700781 av1_init_plane_quantizers(cpi, x, segment_id);
782 aom_clear_system_state();
783 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
784 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700785}
786
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -0700787#if CONFIG_DIST_8X8
Yushin Chob7b60c52017-07-14 16:18:52 -0700788static void dist_8x8_set_sub8x8_dst(MACROBLOCK *const x, uint8_t *dst8x8,
789 BLOCK_SIZE bsize, int bw, int bh,
790 int mi_row, int mi_col) {
Yushin Cho63927c42017-05-23 15:41:05 -0700791 MACROBLOCKD *const xd = &x->e_mbd;
792 struct macroblockd_plane *const pd = &xd->plane[0];
793 const int dst_stride = pd->dst.stride;
794 uint8_t *dst = pd->dst.buf;
795
796 assert(bsize < BLOCK_8X8);
797
798 if (bsize < BLOCK_8X8) {
799 int i, j;
Yushin Cho8ab875d2017-06-23 14:47:21 -0700800#if CONFIG_HIGHBITDEPTH
801 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
802 uint16_t *dst8x8_16 = (uint16_t *)dst8x8;
803 uint16_t *dst_sub8x8 = &dst8x8_16[((mi_row & 1) * 8 + (mi_col & 1)) << 2];
Yushin Cho63927c42017-05-23 15:41:05 -0700804
Yushin Cho8ab875d2017-06-23 14:47:21 -0700805 for (j = 0; j < bh; ++j)
806 for (i = 0; i < bw; ++i)
807 dst_sub8x8[j * 8 + i] = CONVERT_TO_SHORTPTR(dst)[j * dst_stride + i];
808 } else {
809#endif
810 uint8_t *dst_sub8x8 = &dst8x8[((mi_row & 1) * 8 + (mi_col & 1)) << 2];
811
812 for (j = 0; j < bh; ++j)
813 for (i = 0; i < bw; ++i)
814 dst_sub8x8[j * 8 + i] = dst[j * dst_stride + i];
815#if CONFIG_HIGHBITDEPTH
816 }
817#endif
Yushin Cho63927c42017-05-23 15:41:05 -0700818 }
819}
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -0700820#endif // CONFIG_DIST_8X8
Yushin Cho63927c42017-05-23 15:41:05 -0700821
Urvang Joshi52648442016-10-13 17:27:51 -0700822static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700823 MACROBLOCK *const x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -0700824 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700825#if CONFIG_EXT_PARTITION_TYPES
826 PARTITION_TYPE partition,
827#endif
828 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
829 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -0700830 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831 TileInfo *const tile_info = &tile_data->tile_info;
832 MACROBLOCKD *const xd = &x->e_mbd;
833 MB_MODE_INFO *mbmi;
834 struct macroblock_plane *const p = x->plane;
835 struct macroblockd_plane *const pd = xd->plane;
836 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
837 int i, orig_rdmult;
838
Yaowu Xuf883b422016-08-30 14:01:10 -0700839 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700840
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
842 mbmi = &xd->mi[0]->mbmi;
843 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -0700844#if CONFIG_RD_DEBUG
845 mbmi->mi_row = mi_row;
846 mbmi->mi_col = mi_col;
847#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700848#if CONFIG_EXT_PARTITION_TYPES
849 mbmi->partition = partition;
850#endif
851
852 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -0800853 p[i].coeff = ctx->coeff[i];
854 p[i].qcoeff = ctx->qcoeff[i];
855 pd[i].dqcoeff = ctx->dqcoeff[i];
Brennan Shacklette0b5ae82016-11-07 17:25:20 -0800856 p[i].eobs = ctx->eobs[i];
Angie Chiang74e23072017-03-24 14:54:23 -0700857#if CONFIG_LV_MAP
858 p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
859#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700860 }
861
862 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Sarah Parker5c6744b2017-08-25 17:27:45 -0700863#if CONFIG_MRC_TX
864 xd->mrc_mask = ctx->mrc_mask;
865#endif // CONFIG_MRC_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700866
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867 ctx->skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868
869 // Set to zero to make sure we do not use the previous encoded frame stats
870 mbmi->skip = 0;
871
Jingning Han8efdbc82017-02-19 14:40:03 -0800872 x->skip_chroma_rd =
Jingning Hand3a64432017-04-06 17:04:17 -0700873 !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
874 xd->plane[1].subsampling_y);
Jingning Han8efdbc82017-02-19 14:40:03 -0800875
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200876#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700877 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700878 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879 cpi, &x->plane[0].src, bsize, xd->bd);
880 } else {
881 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -0700882 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700883 }
884#else
885 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -0700886 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200887#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888
889 // Save rdmult before it might be changed, so it can be restored later.
890 orig_rdmult = x->rdmult;
891
892 if (aq_mode == VARIANCE_AQ) {
893 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700894 const int energy =
895 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
896 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700897 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -0700898 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899 }
900 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
901 } else if (aq_mode == COMPLEXITY_AQ) {
902 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
903 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
904 // If segment is boosted, use rdmult for that segment.
905 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -0700906 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907 }
908
909 // Find best coding mode & reconstruct the MB so it is available
910 // as a predictor for MBs that follow in the SB
911 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700912 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700913 } else {
Jingning Hanb2a01db2017-06-01 13:52:02 -0700914 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
915 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, mi_row, mi_col,
916 rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700917 } else {
Jingning Hanb2a01db2017-06-01 13:52:02 -0700918 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Jingning Hanb2a01db2017-06-01 13:52:02 -0700919 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920 }
921 }
922
923 // Examine the resulting rate and for AQ mode 2 make a segment choice.
924 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
925 (bsize >= BLOCK_16X16) &&
926 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
Zoe Liue9b15e22017-07-19 15:53:01 -0700927 cpi->refresh_alt2_ref_frame ||
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700929 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700930 }
931
932 x->rdmult = orig_rdmult;
933
934 // TODO(jingning) The rate-distortion optimization flow needs to be
935 // refactored to provide proper exit/return handle.
936 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
937
938 ctx->rate = rd_cost->rate;
939 ctx->dist = rd_cost->dist;
940}
941
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 int16_t mode_context) {
944 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 if (mode == NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 ++counts->newmv_mode[mode_ctx][0];
947 return;
948 } else {
949 ++counts->newmv_mode[mode_ctx][1];
950
951 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
952 return;
953 }
954
955 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
956 if (mode == ZEROMV) {
957 ++counts->zeromv_mode[mode_ctx][0];
958 return;
959 } else {
960 ++counts->zeromv_mode[mode_ctx][1];
961 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
962
963 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
964 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
965 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
966
967 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
968 }
969 }
970}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700971
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -0700972static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +0200973 int mi_col) {
Thomas Daviesf6936102016-09-05 16:51:31 +0100974 MACROBLOCK *x = &td->mb;
975 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700976 const MODE_INFO *const mi = xd->mi[0];
977 const MB_MODE_INFO *const mbmi = &mi->mbmi;
978 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
979 const BLOCK_SIZE bsize = mbmi->sb_type;
Yue Chena4245512017-08-31 11:58:08 -0700980 FRAME_CONTEXT *fc = xd->tile_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700981
Thomas Daviesf6936102016-09-05 16:51:31 +0100982 // delta quant applies to both intra and inter
Ryan676c25c2017-09-19 21:19:01 -0700983 int super_block_upper_left =
984 ((mi_row & MAX_MIB_MASK) == 0) && ((mi_col & MAX_MIB_MASK) == 0);
Thomas Daviesf6936102016-09-05 16:51:31 +0100985
Zoe Liu1eed2df2017-10-16 17:13:15 -0700986 const int seg_ref_active =
987 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
988
989 if (!seg_ref_active) {
990 const int skip_ctx = av1_get_skip_context(xd);
991 td->counts->skip[skip_ctx][mbmi->skip]++;
992#if CONFIG_NEW_MULTISYMBOL
993 update_cdf(fc->skip_cdfs[skip_ctx], mbmi->skip, 2);
994#endif // CONFIG_NEW_MULTISYMBOL
995 }
996
Debargha Mukherjeee30159c2017-10-08 12:04:43 -0700997 if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
Thomas Daviesf6936102016-09-05 16:51:31 +0100998 super_block_upper_left) {
999 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1000 const int absdq = abs(dq);
1001 int i;
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01001002 for (i = 0; i < AOMMIN(absdq, DELTA_Q_SMALL); ++i) {
Thomas Daviesf6936102016-09-05 16:51:31 +01001003 td->counts->delta_q[i][1]++;
1004 }
1005 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1006 xd->prev_qindex = mbmi->current_q_index;
Fangwen Fu231fe422017-04-24 17:52:29 -07001007#if CONFIG_EXT_DELTA_Q
Cheng Chena97394f2017-09-27 15:05:14 -07001008#if CONFIG_LOOPFILTER_LEVEL
1009 if (cm->delta_lf_present_flag) {
Cheng Chen880166a2017-10-02 17:48:48 -07001010 if (cm->delta_lf_multi) {
1011 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
1012 const int delta_lf =
1013 (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
1014 cm->delta_lf_res;
1015 const int abs_delta_lf = abs(delta_lf);
1016 for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
1017 td->counts->delta_lf_multi[lf_id][i][1]++;
1018 }
1019 if (abs_delta_lf < DELTA_LF_SMALL)
1020 td->counts->delta_lf_multi[lf_id][abs_delta_lf][0]++;
1021 xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
1022 }
1023 } else {
Cheng Chena97394f2017-09-27 15:05:14 -07001024 const int delta_lf =
Cheng Chen880166a2017-10-02 17:48:48 -07001025 (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
Cheng Chena97394f2017-09-27 15:05:14 -07001026 cm->delta_lf_res;
1027 const int abs_delta_lf = abs(delta_lf);
1028 for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
Cheng Chen880166a2017-10-02 17:48:48 -07001029 td->counts->delta_lf[i][1]++;
Cheng Chena97394f2017-09-27 15:05:14 -07001030 }
1031 if (abs_delta_lf < DELTA_LF_SMALL)
Cheng Chen880166a2017-10-02 17:48:48 -07001032 td->counts->delta_lf[abs_delta_lf][0]++;
1033 xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
Cheng Chena97394f2017-09-27 15:05:14 -07001034 }
Cheng Chena97394f2017-09-27 15:05:14 -07001035 }
1036#else
Fangwen Fu231fe422017-04-24 17:52:29 -07001037 if (cm->delta_lf_present_flag) {
1038 const int dlf =
1039 (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
1040 cm->delta_lf_res;
1041 const int absdlf = abs(dlf);
1042 for (i = 0; i < AOMMIN(absdlf, DELTA_LF_SMALL); ++i) {
1043 td->counts->delta_lf[i][1]++;
1044 }
1045 if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++;
1046 xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
1047 }
Cheng Chena97394f2017-09-27 15:05:14 -07001048#endif // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu231fe422017-04-24 17:52:29 -07001049#endif
Thomas Daviesf6936102016-09-05 16:51:31 +01001050 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001051 if (!frame_is_intra_only(cm)) {
1052 FRAME_COUNTS *const counts = td->counts;
Arild Fuldseth (arilfuld)6c20c782017-06-15 09:45:02 +02001053 RD_COUNTS *rdc = &td->rd_counts;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 const int inter_block = is_inter_block(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001055 if (!seg_ref_active) {
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02001056 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yue Chena4245512017-08-31 11:58:08 -07001057#if CONFIG_NEW_MULTISYMBOL
1058 update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
1059 inter_block, 2);
1060#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001061 // If the segment reference feature is enabled we have only a single
1062 // reference frame allowed for the segment so exclude it from
1063 // the reference frame counts used to work out probabilities.
1064 if (inter_block) {
1065 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001066 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001067
Jingning Hanc41a5492017-02-24 11:18:52 -08001068 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Arild Fuldseth (arilfuld)6c20c782017-06-15 09:45:02 +02001069 if (has_second_ref(mbmi))
1070 // This flag is also updated for 4x4 blocks
1071 rdc->compound_ref_used_flag = 1;
1072 else
1073 // This flag is also updated for 4x4 blocks
1074 rdc->single_ref_used_flag = 1;
Debargha Mukherjee0f248c42017-09-07 12:40:18 -07001075 if (is_comp_ref_allowed(mbmi->sb_type)) {
Jingning Hanc41a5492017-02-24 11:18:52 -08001076 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1077 [has_second_ref(mbmi)]++;
Yue Chena4245512017-08-31 11:58:08 -07001078#if CONFIG_NEW_MULTISYMBOL
1079 update_cdf(av1_get_reference_mode_cdf(cm, xd), has_second_ref(mbmi),
1080 2);
Debargha Mukherjee0f248c42017-09-07 12:40:18 -07001081#endif // CONFIG_NEW_MULTISYMBOL
Yue Chena4245512017-08-31 11:58:08 -07001082 }
Jingning Hanc41a5492017-02-24 11:18:52 -08001083 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001084
1085 if (has_second_ref(mbmi)) {
Zoe Liuc082bbc2017-05-17 13:31:37 -07001086#if CONFIG_EXT_COMP_REFS
1087 const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi)
1088 ? UNIDIR_COMP_REFERENCE
1089 : BIDIR_COMP_REFERENCE;
1090#if !USE_UNI_COMP_REFS
1091 // TODO(zoeliu): Temporarily turn off uni-directional comp refs
1092 assert(comp_ref_type == BIDIR_COMP_REFERENCE);
1093#endif // !USE_UNI_COMP_REFS
Zoe Liufcf5fa22017-06-26 16:00:38 -07001094 counts->comp_ref_type[av1_get_comp_reference_type_context(xd)]
Zoe Liuc082bbc2017-05-17 13:31:37 -07001095 [comp_ref_type]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096
Zoe Liuc082bbc2017-05-17 13:31:37 -07001097 if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
1098 const int bit = (ref0 == BWDREF_FRAME);
Zoe Liufcf5fa22017-06-26 16:00:38 -07001099 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p(xd)][0]
Zoe Liuc082bbc2017-05-17 13:31:37 -07001100 [bit]++;
1101 if (!bit) {
Zoe Liufcf5fa22017-06-26 16:00:38 -07001102 const int bit1 = (ref1 == LAST3_FRAME || ref1 == GOLDEN_FRAME);
1103 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p1(xd)][1]
1104 [bit1]++;
1105 if (bit1) {
1106 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p2(xd)]
1107 [2][ref1 == GOLDEN_FRAME]++;
1108 }
Zoe Liuc082bbc2017-05-17 13:31:37 -07001109 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001110 } else {
Zoe Liuc082bbc2017-05-17 13:31:37 -07001111#endif // CONFIG_EXT_COMP_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -07001112 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113
Zoe Liuc082bbc2017-05-17 13:31:37 -07001114 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
1115 if (!bit) {
1116 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1117 [ref0 == LAST_FRAME]++;
1118 } else {
1119 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1120 [ref0 == GOLDEN_FRAME]++;
1121 }
1122
1123 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1124 [ref1 == ALTREF_FRAME]++;
Zoe Liue9b15e22017-07-19 15:53:01 -07001125 if (ref1 != ALTREF_FRAME)
1126 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p1(cm, xd)]
1127 [1][ref1 == ALTREF2_FRAME]++;
Zoe Liuc082bbc2017-05-17 13:31:37 -07001128#if CONFIG_EXT_COMP_REFS
1129 }
1130#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131 } else {
Zoe Liue9b15e22017-07-19 15:53:01 -07001132 const int bit = (ref0 >= BWDREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133
Yaowu Xuf883b422016-08-30 14:01:10 -07001134 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001135 if (bit) {
Zoe Liue9b15e22017-07-19 15:53:01 -07001136 assert(ref0 <= ALTREF_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001137 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
Zoe Liue9b15e22017-07-19 15:53:01 -07001138 [ref0 == ALTREF_FRAME]++;
Zoe Liue9b15e22017-07-19 15:53:01 -07001139 if (ref0 != ALTREF_FRAME)
1140 counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
1141 [ref0 == ALTREF2_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001142 } else {
1143 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format55ce9e02017-02-15 22:27:12 -08001144 counts
1145 ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001146 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001147 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1148 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001149 } else {
clang-format67948d32016-09-07 22:40:40 -07001150 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1151 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001152 }
1153 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 }
1155
Zoe Liu85b66462017-04-20 14:28:19 -07001156#if CONFIG_COMPOUND_SINGLEREF
1157 if (!has_second_ref(mbmi))
1158 counts->comp_inter_mode[av1_get_inter_mode_context(xd)]
1159 [is_inter_singleref_comp_mode(mbmi->mode)]++;
1160#endif // CONFIG_COMPOUND_SINGLEREF
1161
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162 if (cm->reference_mode != COMPOUND_REFERENCE &&
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07001163 cm->allow_interintra_compound && is_interintra_allowed(mbmi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001164 const int bsize_group = size_group_lookup[bsize];
1165 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1166 counts->interintra[bsize_group][1]++;
Yue Chena4245512017-08-31 11:58:08 -07001167#if CONFIG_NEW_MULTISYMBOL
1168 update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
1169#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
Yue Chena4245512017-08-31 11:58:08 -07001171 update_cdf(fc->interintra_mode_cdf[bsize_group],
1172 mbmi->interintra_mode, INTERINTRA_MODES);
1173 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001174 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
Yue Chena4245512017-08-31 11:58:08 -07001175#if CONFIG_NEW_MULTISYMBOL
1176 update_cdf(fc->wedge_interintra_cdf[bsize],
1177 mbmi->use_wedge_interintra, 2);
1178#endif
1179 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 } else {
1181 counts->interintra[bsize_group][0]++;
Yue Chena4245512017-08-31 11:58:08 -07001182#if CONFIG_NEW_MULTISYMBOL
1183 update_cdf(fc->interintra_cdf[bsize_group], 0, 2);
1184#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001185 }
1186 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001187
Yue Chen52c51732017-07-11 15:08:30 -07001188 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
Sebastien Alaiwan48795802017-10-30 12:07:13 +01001189 const MOTION_MODE motion_allowed =
Sebastien Alaiwan1f56b8e2017-10-31 17:37:16 +01001190 motion_mode_allowed(0, xd->global_motion, xd, mi);
1191 if (mbmi->ref_frame[1] != INTRA_FRAME) {
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02001192 if (motion_allowed == WARPED_CAUSAL) {
1193 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1194 update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
1195 MOTION_MODES);
Wei-Ting Lin07ed3ab2017-08-28 17:50:25 -07001196#if CONFIG_NCOBMC_ADAPT_WEIGHT
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02001197 } else if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
1198 counts->ncobmc[mbmi->sb_type][mbmi->motion_mode]++;
1199 update_cdf(fc->ncobmc_cdf[mbmi->sb_type], mbmi->motion_mode,
1200 OBMC_FAMILY_MODES);
1201 } else if (motion_allowed == OBMC_CAUSAL) {
1202 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
1203 update_cdf(fc->obmc_cdf[mbmi->sb_type], mbmi->motion_mode, 2);
Yue Chen69f18e12016-09-08 14:48:15 -07001204 }
1205#else
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02001206 } else if (motion_allowed == OBMC_CAUSAL) {
1207 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
1208#if CONFIG_NEW_MULTISYMBOL
1209 update_cdf(fc->obmc_cdf[mbmi->sb_type],
1210 mbmi->motion_mode == OBMC_CAUSAL, 2);
1211#endif
1212 }
1213#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
1214 }
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07001215
1216#if CONFIG_NCOBMC_ADAPT_WEIGHT
Wei-Ting Lin77c41182017-07-12 15:58:35 -07001217 if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT) {
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07001218 ADAPT_OVERLAP_BLOCK ao_block =
1219 adapt_overlap_block_lookup[mbmi->sb_type];
1220 ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[0]];
Yue Chena4245512017-08-31 11:58:08 -07001221 update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[0],
1222 MAX_NCOBMC_MODES);
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07001223 if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
1224 ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[1]];
Yue Chena4245512017-08-31 11:58:08 -07001225 update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[1],
1226 MAX_NCOBMC_MODES);
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07001227 }
1228 }
1229#endif
1230
Zoe Liu85b66462017-04-20 14:28:19 -07001231 if (
1232#if CONFIG_COMPOUND_SINGLEREF
1233 is_inter_anyref_comp_mode(mbmi->mode)
1234#else // !CONFIG_COMPOUND_SINGLEREF
1235 cm->reference_mode != SINGLE_REFERENCE &&
Sarah Parker6fdc8532016-11-16 17:47:13 -08001236 is_inter_compound_mode(mbmi->mode)
Zoe Liu85b66462017-04-20 14:28:19 -07001237#endif // CONFIG_COMPOUND_SINGLEREF
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001238 && mbmi->motion_mode == SIMPLE_TRANSLATION) {
Yue Chena4245512017-08-31 11:58:08 -07001239 if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
Yue Chena4245512017-08-31 11:58:08 -07001240 counts
1241 ->compound_interinter[bsize][mbmi->interinter_compound_type]++;
1242 update_cdf(fc->compound_type_cdf[bsize],
1243 mbmi->interinter_compound_type, COMPOUND_TYPES);
Yue Chena4245512017-08-31 11:58:08 -07001244 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001245 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001246 }
1247 }
1248
1249 if (inter_block &&
1250 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08001251 int16_t mode_ctx;
Jingning Hanb2a01db2017-06-01 13:52:02 -07001252 const PREDICTION_MODE mode = mbmi->mode;
Jingning Hanb2a01db2017-06-01 13:52:02 -07001253 if (has_second_ref(mbmi)) {
1254 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1255 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
Yue Chena4245512017-08-31 11:58:08 -07001256 update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
1257 INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
Zoe Liu85b66462017-04-20 14:28:19 -07001258#if CONFIG_COMPOUND_SINGLEREF
1259 } else if (is_inter_singleref_comp_mode(mode)) {
1260 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1261 ++counts->inter_singleref_comp_mode[mode_ctx]
1262 [INTER_SINGLEREF_COMP_OFFSET(mode)];
1263#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 } else {
Jingning Hanb2a01db2017-06-01 13:52:02 -07001265 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
1266 mbmi->ref_frame, bsize, -1);
1267 update_inter_mode_stats(counts, mode, mode_ctx);
Jingning Hanb2a01db2017-06-01 13:52:02 -07001268 }
Jingning Hanb2a01db2017-06-01 13:52:02 -07001269
Cheng Chen50b0f6c2017-08-03 12:25:03 -07001270 int mode_allowed = (mbmi->mode == NEWMV);
Cheng Chen50b0f6c2017-08-03 12:25:03 -07001271 mode_allowed |= (mbmi->mode == NEW_NEWMV);
Zoe Liu85b66462017-04-20 14:28:19 -07001272#if CONFIG_COMPOUND_SINGLEREF
Cheng Chen50b0f6c2017-08-03 12:25:03 -07001273 mode_allowed |= (mbmi->mode == SR_NEW_NEWMV);
Zoe Liu85b66462017-04-20 14:28:19 -07001274#endif // CONFIG_COMPOUND_SINGLEREF
Cheng Chen50b0f6c2017-08-03 12:25:03 -07001275 if (mode_allowed) {
Jingning Hanb2a01db2017-06-01 13:52:02 -07001276 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
1277 int idx;
1278
1279 for (idx = 0; idx < 2; ++idx) {
1280 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1281 uint8_t drl_ctx =
1282 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
1283 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
1284
1285 if (mbmi->ref_mv_idx == idx) break;
1286 }
1287 }
1288 }
1289
Sebastien Alaiwan0bdea0d2017-10-02 15:15:05 +02001290 if (have_nearmv_in_inter_mode(mbmi->mode)) {
Jingning Hanb2a01db2017-06-01 13:52:02 -07001291 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
1292 int idx;
1293
1294 for (idx = 1; idx < 3; ++idx) {
1295 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1296 uint8_t drl_ctx =
1297 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
1298 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
1299
1300 if (mbmi->ref_mv_idx == idx - 1) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001301 }
1302 }
1303 }
1304 }
Alex Converse7c412ea2017-06-01 15:16:22 -07001305#if CONFIG_INTRABC
1306 } else {
RogerZhouca865462017-10-05 15:06:27 -07001307 if (av1_allow_intrabc(bsize, cm)) {
Alex Converse7c412ea2017-06-01 15:16:22 -07001308 FRAME_COUNTS *const counts = td->counts;
1309 ++counts->intrabc[mbmi->use_intrabc];
1310 } else {
1311 assert(!mbmi->use_intrabc);
1312 }
1313#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001314 }
1315}
1316
1317typedef struct {
1318 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
1319 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
1320 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
1321 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001322 TXFM_CONTEXT *p_ta;
1323 TXFM_CONTEXT *p_tl;
Jingning Han331662e2017-05-30 17:03:32 -07001324 TXFM_CONTEXT ta[2 * MAX_MIB_SIZE];
1325 TXFM_CONTEXT tl[2 * MAX_MIB_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001326} RD_SEARCH_MACROBLOCK_CONTEXT;
1327
1328static void restore_context(MACROBLOCK *x,
1329 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yushin Chod0b77ac2017-10-20 17:33:16 -07001330 int mi_col, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331 MACROBLOCKD *xd = &x->e_mbd;
1332 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001333 const int num_4x4_blocks_wide =
1334 block_size_wide[bsize] >> tx_size_wide_log2[0];
1335 const int num_4x4_blocks_high =
1336 block_size_high[bsize] >> tx_size_high_log2[0];
1337 int mi_width = mi_size_wide[bsize];
1338 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001339 for (p = 0; p < MAX_MB_PLANE; p++) {
Timothy B. Terriberry5e816432017-05-05 13:58:32 -07001340 int tx_col;
1341 int tx_row;
1342 tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
1343 tx_row = (mi_row & MAX_MIB_MASK) << (MI_SIZE_LOG2 - tx_size_high_log2[0]);
1344 memcpy(xd->above_context[p] + (tx_col >> xd->plane[p].subsampling_x),
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345 ctx->a + num_4x4_blocks_wide * p,
1346 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1347 xd->plane[p].subsampling_x);
Timothy B. Terriberry5e816432017-05-05 13:58:32 -07001348 memcpy(xd->left_context[p] + (tx_row >> xd->plane[p].subsampling_y),
Yaowu Xuc27fc142016-08-22 16:08:15 -07001349 ctx->l + num_4x4_blocks_high * p,
1350 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1351 xd->plane[p].subsampling_y);
1352 }
1353 memcpy(xd->above_seg_context + mi_col, ctx->sa,
1354 sizeof(*xd->above_seg_context) * mi_width);
1355 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
1356 sizeof(xd->left_seg_context[0]) * mi_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001357 xd->above_txfm_context = ctx->p_ta;
1358 xd->left_txfm_context = ctx->p_tl;
1359 memcpy(xd->above_txfm_context, ctx->ta,
Jingning Han331662e2017-05-30 17:03:32 -07001360 sizeof(*xd->above_txfm_context) * (mi_width << TX_UNIT_WIDE_LOG2));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001361 memcpy(xd->left_txfm_context, ctx->tl,
Jingning Han331662e2017-05-30 17:03:32 -07001362 sizeof(*xd->left_txfm_context) * (mi_height << TX_UNIT_HIGH_LOG2));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363}
1364
1365static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yushin Chod0b77ac2017-10-20 17:33:16 -07001366 int mi_row, int mi_col, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367 const MACROBLOCKD *xd = &x->e_mbd;
1368 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001369 const int num_4x4_blocks_wide =
1370 block_size_wide[bsize] >> tx_size_wide_log2[0];
1371 const int num_4x4_blocks_high =
1372 block_size_high[bsize] >> tx_size_high_log2[0];
1373 int mi_width = mi_size_wide[bsize];
1374 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001375
1376 // buffer the above/left context information of the block in search.
1377 for (p = 0; p < MAX_MB_PLANE; ++p) {
Timothy B. Terriberry5e816432017-05-05 13:58:32 -07001378 int tx_col;
1379 int tx_row;
1380 tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
1381 tx_row = (mi_row & MAX_MIB_MASK) << (MI_SIZE_LOG2 - tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001382 memcpy(ctx->a + num_4x4_blocks_wide * p,
Timothy B. Terriberry5e816432017-05-05 13:58:32 -07001383 xd->above_context[p] + (tx_col >> xd->plane[p].subsampling_x),
Yaowu Xuc27fc142016-08-22 16:08:15 -07001384 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1385 xd->plane[p].subsampling_x);
1386 memcpy(ctx->l + num_4x4_blocks_high * p,
Timothy B. Terriberry5e816432017-05-05 13:58:32 -07001387 xd->left_context[p] + (tx_row >> xd->plane[p].subsampling_y),
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1389 xd->plane[p].subsampling_y);
1390 }
1391 memcpy(ctx->sa, xd->above_seg_context + mi_col,
1392 sizeof(*xd->above_seg_context) * mi_width);
1393 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
1394 sizeof(xd->left_seg_context[0]) * mi_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001395 memcpy(ctx->ta, xd->above_txfm_context,
Jingning Han331662e2017-05-30 17:03:32 -07001396 sizeof(*xd->above_txfm_context) * (mi_width << TX_UNIT_WIDE_LOG2));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001397 memcpy(ctx->tl, xd->left_txfm_context,
Jingning Han331662e2017-05-30 17:03:32 -07001398 sizeof(*xd->left_txfm_context) * (mi_height << TX_UNIT_HIGH_LOG2));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001399 ctx->p_ta = xd->above_txfm_context;
1400 ctx->p_tl = xd->left_txfm_context;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401}
1402
Urvang Joshi52648442016-10-13 17:27:51 -07001403static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
1404 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
1405 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001406#if CONFIG_EXT_PARTITION_TYPES
1407 PARTITION_TYPE partition,
1408#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001409 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001410 MACROBLOCK *const x = &td->mb;
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001411#if (CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q | CONFIG_NCOBMC_ADAPT_WEIGHT
Yue Chenf27b1602017-01-13 11:11:43 -08001412 MACROBLOCKD *xd = &x->e_mbd;
1413 MB_MODE_INFO *mbmi;
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001414#if CONFIG_NCOBMC
Yue Chenf27b1602017-01-13 11:11:43 -08001415 int check_ncobmc;
1416#endif
Fangwen Fu4e2df092017-05-01 16:58:38 -07001417#endif
Yue Chenf27b1602017-01-13 11:11:43 -08001418
Yaowu Xuc27fc142016-08-22 16:08:15 -07001419 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1420#if CONFIG_EXT_PARTITION_TYPES
1421 x->e_mbd.mi[0]->mbmi.partition = partition;
1422#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001423 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001424#if (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
Yue Chenf27b1602017-01-13 11:11:43 -08001425 mbmi = &xd->mi[0]->mbmi;
Yue Chen52c51732017-07-11 15:08:30 -07001426 set_ref_ptrs(&cpi->common, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
1427#endif
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07001428
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001429#if (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
Sebastien Alaiwan1f56b8e2017-10-31 17:37:16 +01001430 const MOTION_MODE motion_allowed =
1431 motion_mode_allowed(0, xd->global_motion, xd, xd->mi[0]);
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001432#endif // (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07001433
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01001434#if CONFIG_NCOBMC
Sarah Parker19234cc2017-03-10 16:43:25 -08001435 check_ncobmc = is_inter_block(mbmi) && motion_allowed >= OBMC_CAUSAL;
Yue Chenf27b1602017-01-13 11:11:43 -08001436 if (!dry_run && check_ncobmc) {
1437 av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
Jingning Han91d9a792017-04-18 12:01:52 -07001438 av1_setup_dst_planes(x->e_mbd.plane, bsize,
1439 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -08001440 }
1441#endif
Jingning Hanf5a4d3b2017-08-27 23:01:19 -07001442
1443#if CONFIG_LV_MAP
1444 av1_set_coeff_buffer(cpi, x, mi_row, mi_col);
1445#endif
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07001446
1447#if CONFIG_NCOBMC_ADAPT_WEIGHT
Wei-Ting Lin3122b7d2017-08-30 17:26:58 -07001448 if (dry_run == OUTPUT_ENABLED && !frame_is_intra_only(&cpi->common)) {
Wei-Ting Lin5f8f7a12017-08-31 14:39:52 -07001449 if (motion_allowed >= NCOBMC_ADAPT_WEIGHT && is_inter_block(mbmi)) {
Wei-Ting Lin3122b7d2017-08-30 17:26:58 -07001450 get_ncobmc_intrpl_pred(cpi, td, mi_row, mi_col, bsize);
1451 av1_check_ncobmc_adapt_weight_rd(cpi, x, mi_row, mi_col);
1452 }
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07001453 av1_setup_dst_planes(x->e_mbd.plane, bsize,
1454 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
1455 }
1456#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
1457
Yushin Cho6d72a2f2017-05-03 17:37:37 -07001458 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001459
Jingning Hanf5a4d3b2017-08-27 23:01:19 -07001460#if CONFIG_LV_MAP
1461 if (dry_run == 0)
1462 x->cb_offset += block_size_wide[bsize] * block_size_high[bsize];
1463#endif
1464
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001465 if (!dry_run) {
Fangwen Fu4e2df092017-05-01 16:58:38 -07001466#if CONFIG_EXT_DELTA_Q
1467 mbmi = &xd->mi[0]->mbmi;
Debargha Mukherjeee30159c2017-10-08 12:04:43 -07001468 if (bsize == cpi->common.sb_size && mbmi->skip == 1 &&
Fangwen Fu4e2df092017-05-01 16:58:38 -07001469 cpi->common.delta_lf_present_flag) {
Cheng Chena97394f2017-09-27 15:05:14 -07001470#if CONFIG_LOOPFILTER_LEVEL
1471 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
1472 mbmi->curr_delta_lf[lf_id] = xd->prev_delta_lf[lf_id];
1473#endif // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu4e2df092017-05-01 16:58:38 -07001474 mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
1475 }
1476#endif
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001477 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001478 }
1479}
1480
Urvang Joshi52648442016-10-13 17:27:51 -07001481static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
1482 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
1483 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
1484 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001485 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001486 MACROBLOCK *const x = &td->mb;
1487 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse55c6bde2017-01-12 15:55:31 -08001488 const int hbs = mi_size_wide[bsize] / 2;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01001489#if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
1490 const int qbs = mi_size_wide[bsize] / 4;
1491#endif
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001492 const int is_partition_root = bsize >= BLOCK_8X8;
1493 const int ctx = is_partition_root
Alex Converse55c6bde2017-01-12 15:55:31 -08001494 ? partition_plane_context(xd, mi_row, mi_col,
1495#if CONFIG_UNPOISON_PARTITION_CTX
1496 mi_row + hbs < cm->mi_rows,
1497 mi_col + hbs < cm->mi_cols,
1498#endif
1499 bsize)
1500 : -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001501 const PARTITION_TYPE partition = pc_tree->partitioning;
1502 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
1503#if CONFIG_EXT_PARTITION_TYPES
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001504 int quarter_step = mi_size_wide[bsize] / 4;
1505 int i;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01001506#if !CONFIG_EXT_PARTITION_TYPES_AB
1507 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
Debargha Mukherjeeedced252017-10-20 00:02:00 -07001508#endif // !CONFIG_EXT_PARTITION_TYPES_AB
1509#endif // CONFIG_EXT_PARTITION_TYPES
Yaowu Xuc27fc142016-08-22 16:08:15 -07001510
1511 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1512
Alex Converse55c6bde2017-01-12 15:55:31 -08001513 if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001514
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515 switch (partition) {
1516 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001517 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518#if CONFIG_EXT_PARTITION_TYPES
1519 partition,
1520#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001521 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001522 break;
1523 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001524 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001525#if CONFIG_EXT_PARTITION_TYPES
1526 partition,
1527#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001528 &pc_tree->vertical[0], rate);
Debargha Mukherjeeedced252017-10-20 00:02:00 -07001529 if (mi_col + hbs < cm->mi_cols) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001530 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001531#if CONFIG_EXT_PARTITION_TYPES
1532 partition,
1533#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001534 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001535 }
1536 break;
1537 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001538 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001539#if CONFIG_EXT_PARTITION_TYPES
1540 partition,
1541#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001542 &pc_tree->horizontal[0], rate);
Debargha Mukherjeeedced252017-10-20 00:02:00 -07001543 if (mi_row + hbs < cm->mi_rows) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001544 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545#if CONFIG_EXT_PARTITION_TYPES
1546 partition,
1547#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001548 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001549 }
1550 break;
1551 case PARTITION_SPLIT:
Debargha Mukherjeeedced252017-10-20 00:02:00 -07001552 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
1553 pc_tree->split[0], rate);
1554 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
1555 pc_tree->split[1], rate);
1556 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
1557 pc_tree->split[2], rate);
1558 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run, subsize,
1559 pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001560 break;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01001561
Yaowu Xuc27fc142016-08-22 16:08:15 -07001562#if CONFIG_EXT_PARTITION_TYPES
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01001563#if CONFIG_EXT_PARTITION_TYPES_AB
1564 case PARTITION_HORZ_A:
1565 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
1566 get_subsize(bsize, PARTITION_HORZ_4), partition,
1567 &pc_tree->horizontala[0], rate);
1568 encode_b(cpi, tile, td, tp, mi_row + qbs, mi_col, dry_run,
1569 get_subsize(bsize, PARTITION_HORZ_4), partition,
1570 &pc_tree->horizontala[1], rate);
1571 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
1572 partition, &pc_tree->horizontala[2], rate);
1573 break;
1574 case PARTITION_HORZ_B:
1575 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
1576 &pc_tree->horizontalb[0], rate);
1577 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run,
1578 get_subsize(bsize, PARTITION_HORZ_4), partition,
1579 &pc_tree->horizontalb[1], rate);
1580 if (mi_row + 3 * qbs < cm->mi_rows)
1581 encode_b(cpi, tile, td, tp, mi_row + 3 * qbs, mi_col, dry_run,
1582 get_subsize(bsize, PARTITION_HORZ_4), partition,
1583 &pc_tree->horizontalb[2], rate);
1584 break;
1585 case PARTITION_VERT_A:
1586 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
1587 get_subsize(bsize, PARTITION_VERT_4), partition,
1588 &pc_tree->verticala[0], rate);
1589 encode_b(cpi, tile, td, tp, mi_row, mi_col + qbs, dry_run,
1590 get_subsize(bsize, PARTITION_VERT_4), partition,
1591 &pc_tree->verticala[1], rate);
1592 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
1593 partition, &pc_tree->verticala[2], rate);
1594
1595 break;
1596 case PARTITION_VERT_B:
1597 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
1598 &pc_tree->verticalb[0], rate);
1599 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run,
1600 get_subsize(bsize, PARTITION_VERT_4), partition,
1601 &pc_tree->verticalb[1], rate);
1602 if (mi_col + 3 * qbs < cm->mi_cols)
1603 encode_b(cpi, tile, td, tp, mi_row, mi_col + 3 * qbs, dry_run,
1604 get_subsize(bsize, PARTITION_VERT_4), partition,
1605 &pc_tree->verticalb[2], rate);
1606 break;
1607#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001608 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001609 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
1610 &pc_tree->horizontala[0], rate);
1611 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
1612 partition, &pc_tree->horizontala[1], rate);
1613 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
1614 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001615 break;
1616 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001617 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
1618 &pc_tree->horizontalb[0], rate);
1619 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
1620 partition, &pc_tree->horizontalb[1], rate);
1621 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
1622 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001623 break;
1624 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001625 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
1626 &pc_tree->verticala[0], rate);
1627 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
1628 partition, &pc_tree->verticala[1], rate);
1629 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
1630 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001631
1632 break;
1633 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001634 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
1635 &pc_tree->verticalb[0], rate);
1636 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
1637 partition, &pc_tree->verticalb[1], rate);
1638 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
1639 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001640 break;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01001641#endif
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001642 case PARTITION_HORZ_4:
1643 for (i = 0; i < 4; ++i) {
1644 int this_mi_row = mi_row + i * quarter_step;
1645 if (i > 0 && this_mi_row >= cm->mi_rows) break;
1646
1647 encode_b(cpi, tile, td, tp, this_mi_row, mi_col, dry_run, subsize,
1648 partition, &pc_tree->horizontal4[i], rate);
1649 }
1650 break;
1651 case PARTITION_VERT_4:
1652 for (i = 0; i < 4; ++i) {
1653 int this_mi_col = mi_col + i * quarter_step;
1654 if (i > 0 && this_mi_col >= cm->mi_cols) break;
1655
1656 encode_b(cpi, tile, td, tp, mi_row, this_mi_col, dry_run, subsize,
1657 partition, &pc_tree->vertical4[i], rate);
1658 }
1659 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001660#endif // CONFIG_EXT_PARTITION_TYPES
1661 default: assert(0 && "Invalid partition type."); break;
1662 }
1663
1664#if CONFIG_EXT_PARTITION_TYPES
1665 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
1666#else
1667 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1668 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1669#endif // CONFIG_EXT_PARTITION_TYPES
1670}
1671
1672// Check to see if the given partition size is allowed for a specified number
1673// of mi block rows and columns remaining in the image.
1674// If not then return the largest allowed partition size
1675static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
1676 int cols_left, int *bh, int *bw) {
1677 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001678 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679 } else {
1680 for (; bsize > 0; bsize -= 3) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08001681 *bh = mi_size_high[bsize];
1682 *bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001683 if ((*bh <= rows_left) && (*bw <= cols_left)) {
1684 break;
1685 }
1686 }
1687 }
1688 return bsize;
1689}
1690
Yaowu Xuf883b422016-08-30 14:01:10 -07001691static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001692 int bh_in, int bw_in,
1693 int mi_rows_remaining,
1694 int mi_cols_remaining, BLOCK_SIZE bsize,
1695 MODE_INFO **mib) {
1696 int bh = bh_in;
1697 int r, c;
1698 for (r = 0; r < cm->mib_size; r += bh) {
1699 int bw = bw_in;
1700 for (c = 0; c < cm->mib_size; c += bw) {
1701 const int index = r * cm->mi_stride + c;
1702 mib[index] = mi + index;
1703 mib[index]->mbmi.sb_type = find_partition_size(
1704 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
1705 }
1706 }
1707}
1708
1709// This function attempts to set all mode info entries in a given superblock
1710// to the same block partition size.
1711// However, at the bottom and right borders of the image the requested size
1712// may not be allowed in which case this code attempts to choose the largest
1713// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07001714static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715 MODE_INFO **mib, int mi_row, int mi_col,
1716 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001717 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001718 const int mi_rows_remaining = tile->mi_row_end - mi_row;
1719 const int mi_cols_remaining = tile->mi_col_end - mi_col;
1720 int block_row, block_col;
1721 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001722 int bh = mi_size_high[bsize];
1723 int bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001724
1725 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
1726
1727 // Apply the requested partition size to the SB if it is all "in image"
1728 if ((mi_cols_remaining >= cm->mib_size) &&
1729 (mi_rows_remaining >= cm->mib_size)) {
1730 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
1731 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
1732 int index = block_row * cm->mi_stride + block_col;
1733 mib[index] = mi_upper_left + index;
1734 mib[index]->mbmi.sb_type = bsize;
1735 }
1736 }
1737 } else {
1738 // Else this is a partial SB.
1739 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
1740 mi_cols_remaining, bsize, mib);
1741 }
1742}
1743
Yaowu Xuf883b422016-08-30 14:01:10 -07001744static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745 TileDataEnc *tile_data, MODE_INFO **mib,
1746 TOKENEXTRA **tp, int mi_row, int mi_col,
1747 BLOCK_SIZE bsize, int *rate, int64_t *dist,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001748 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001749 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001750 TileInfo *const tile_info = &tile_data->tile_info;
1751 MACROBLOCK *const x = &td->mb;
1752 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001753 const int bs = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001754 const int hbs = bs / 2;
1755 int i;
Jingning Han6fc515e2017-04-07 11:30:09 -07001756 const int pl = (bsize >= BLOCK_8X8)
1757 ? partition_plane_context(xd, mi_row, mi_col,
Alex Converse55c6bde2017-01-12 15:55:31 -08001758#if CONFIG_UNPOISON_PARTITION_CTX
Jingning Han6fc515e2017-04-07 11:30:09 -07001759 mi_row + hbs < cm->mi_rows,
1760 mi_col + hbs < cm->mi_cols,
Alex Converse55c6bde2017-01-12 15:55:31 -08001761#endif
Jingning Han6fc515e2017-04-07 11:30:09 -07001762 bsize)
1763 : 0;
1764 const PARTITION_TYPE partition =
1765 (bsize >= BLOCK_8X8) ? get_partition(cm, mi_row, mi_col, bsize)
1766 : PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001767 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
1768 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001769 RD_STATS last_part_rdc, none_rdc, chosen_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001770 BLOCK_SIZE sub_subsize = BLOCK_4X4;
1771 int splits_below = 0;
1772 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
1773 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07001774 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yushin Chod0b77ac2017-10-20 17:33:16 -07001775
Yaowu Xuc27fc142016-08-22 16:08:15 -07001776 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1777
1778 assert(num_4x4_blocks_wide_lookup[bsize] ==
1779 num_4x4_blocks_high_lookup[bsize]);
1780
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001781 av1_invalid_rd_stats(&last_part_rdc);
1782 av1_invalid_rd_stats(&none_rdc);
1783 av1_invalid_rd_stats(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001784
1785 pc_tree->partitioning = partition;
1786
Jingning Han331662e2017-05-30 17:03:32 -07001787 xd->above_txfm_context =
1788 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
1789 xd->left_txfm_context = xd->left_txfm_context_buffer +
1790 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001791 save_context(x, &x_ctx, mi_row, mi_col, bsize);
1792
1793 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
1794 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07001795 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796 }
1797
1798 if (do_partition_search &&
1799 cpi->sf.partition_search_type == SEARCH_PARTITION &&
1800 cpi->sf.adjust_partitioning_from_last_frame) {
1801 // Check if any of the sub blocks are further split.
1802 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
1803 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
1804 splits_below = 1;
1805 for (i = 0; i < 4; i++) {
1806 int jj = i >> 1, ii = i & 0x01;
1807 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
1808 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
1809 splits_below = 0;
1810 }
1811 }
1812 }
1813
1814 // If partition is not none try none unless each of the 4 splits are split
1815 // even further..
1816 if (partition != PARTITION_NONE && !splits_below &&
1817 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
1818 pc_tree->partitioning = PARTITION_NONE;
1819 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820#if CONFIG_EXT_PARTITION_TYPES
1821 PARTITION_NONE,
1822#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07001823 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001824
1825 if (none_rdc.rate < INT_MAX) {
Yue Chenb23d00a2017-07-28 17:01:21 -07001826 none_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
Urvang Joshi70006e42017-06-14 16:08:55 -07001827 none_rdc.rdcost = RDCOST(x->rdmult, none_rdc.rate, none_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 }
1829
1830 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001831 mib[0]->mbmi.sb_type = bs_type;
1832 pc_tree->partitioning = partition;
1833 }
1834 }
1835
1836 switch (partition) {
1837 case PARTITION_NONE:
1838 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001839#if CONFIG_EXT_PARTITION_TYPES
1840 PARTITION_NONE,
1841#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07001842 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001843 break;
1844 case PARTITION_HORZ:
1845 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001846#if CONFIG_EXT_PARTITION_TYPES
1847 PARTITION_HORZ,
1848#endif
1849 subsize, &pc_tree->horizontal[0], INT64_MAX);
1850 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
1851 mi_row + hbs < cm->mi_rows) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001852 RD_STATS tmp_rdc;
Urvang Joshi454280d2016-10-14 16:51:44 -07001853 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001854 av1_init_rd_stats(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07001855 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001856 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Yushin Cho6d72a2f2017-05-03 17:37:37 -07001857 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859#if CONFIG_EXT_PARTITION_TYPES
1860 PARTITION_HORZ,
1861#endif
1862 subsize, &pc_tree->horizontal[1], INT64_MAX);
1863 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001864 av1_invalid_rd_stats(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001865 break;
1866 }
1867 last_part_rdc.rate += tmp_rdc.rate;
1868 last_part_rdc.dist += tmp_rdc.dist;
1869 last_part_rdc.rdcost += tmp_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 }
1871 break;
1872 case PARTITION_VERT:
1873 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001874#if CONFIG_EXT_PARTITION_TYPES
1875 PARTITION_VERT,
1876#endif
1877 subsize, &pc_tree->vertical[0], INT64_MAX);
1878 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
1879 mi_col + hbs < cm->mi_cols) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001880 RD_STATS tmp_rdc;
Urvang Joshi454280d2016-10-14 16:51:44 -07001881 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001882 av1_init_rd_stats(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07001883 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001884 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Yushin Cho6d72a2f2017-05-03 17:37:37 -07001885 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001886 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001887#if CONFIG_EXT_PARTITION_TYPES
1888 PARTITION_VERT,
1889#endif
1890 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
1891 INT64_MAX);
1892 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001893 av1_invalid_rd_stats(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001894 break;
1895 }
1896 last_part_rdc.rate += tmp_rdc.rate;
1897 last_part_rdc.dist += tmp_rdc.dist;
1898 last_part_rdc.rdcost += tmp_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899 }
1900 break;
1901 case PARTITION_SPLIT:
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902 last_part_rdc.rate = 0;
1903 last_part_rdc.dist = 0;
1904 last_part_rdc.rdcost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905 for (i = 0; i < 4; i++) {
1906 int x_idx = (i & 1) * hbs;
1907 int y_idx = (i >> 1) * hbs;
1908 int jj = i >> 1, ii = i & 0x01;
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001909 RD_STATS tmp_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1911 continue;
1912
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001913 av1_init_rd_stats(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 rd_use_partition(cpi, td, tile_data,
1915 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
1916 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02001917 &tmp_rdc.dist, i != 3, pc_tree->split[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001918 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001919 av1_invalid_rd_stats(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001920 break;
1921 }
1922 last_part_rdc.rate += tmp_rdc.rate;
1923 last_part_rdc.dist += tmp_rdc.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924 }
1925 break;
1926#if CONFIG_EXT_PARTITION_TYPES
1927 case PARTITION_VERT_A:
1928 case PARTITION_VERT_B:
1929 case PARTITION_HORZ_A:
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01001930 case PARTITION_HORZ_B:
1931 case PARTITION_HORZ_4:
1932 case PARTITION_VERT_4: assert(0 && "Cannot handle extended partiton types");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001933#endif // CONFIG_EXT_PARTITION_TYPES
1934 default: assert(0); break;
1935 }
1936
1937 if (last_part_rdc.rate < INT_MAX) {
Yue Chenb23d00a2017-07-28 17:01:21 -07001938 last_part_rdc.rate += x->partition_cost[pl][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001939 last_part_rdc.rdcost =
Urvang Joshi70006e42017-06-14 16:08:55 -07001940 RDCOST(x->rdmult, last_part_rdc.rate, last_part_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001941 }
1942
1943 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
1944 cpi->sf.partition_search_type == SEARCH_PARTITION &&
1945 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
1946 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
1947 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
1948 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
1949 chosen_rdc.rate = 0;
1950 chosen_rdc.dist = 0;
Yushin Chod0b77ac2017-10-20 17:33:16 -07001951
Yaowu Xuc27fc142016-08-22 16:08:15 -07001952 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001953 pc_tree->partitioning = PARTITION_SPLIT;
1954
1955 // Split partition.
1956 for (i = 0; i < 4; i++) {
1957 int x_idx = (i & 1) * hbs;
1958 int y_idx = (i >> 1) * hbs;
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001959 RD_STATS tmp_rdc;
Yushin Chod0b77ac2017-10-20 17:33:16 -07001960
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1962 continue;
1963
1964 save_context(x, &x_ctx, mi_row, mi_col, bsize);
1965 pc_tree->split[i]->partitioning = PARTITION_NONE;
1966 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
1967 &tmp_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001968#if CONFIG_EXT_PARTITION_TYPES
1969 PARTITION_SPLIT,
1970#endif
1971 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
1972
1973 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001974 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07001975 av1_invalid_rd_stats(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976 break;
1977 }
1978
1979 chosen_rdc.rate += tmp_rdc.rate;
1980 chosen_rdc.dist += tmp_rdc.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981
1982 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001983 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
1984 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985
Yue Chenb23d00a2017-07-28 17:01:21 -07001986 chosen_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001987 }
1988 if (chosen_rdc.rate < INT_MAX) {
Yue Chenb23d00a2017-07-28 17:01:21 -07001989 chosen_rdc.rate += x->partition_cost[pl][PARTITION_SPLIT];
Urvang Joshi70006e42017-06-14 16:08:55 -07001990 chosen_rdc.rdcost = RDCOST(x->rdmult, chosen_rdc.rate, chosen_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001991 }
1992 }
1993
1994 // If last_part is better set the partitioning to that.
1995 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
1996 mib[0]->mbmi.sb_type = bsize;
1997 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
1998 chosen_rdc = last_part_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001999 }
2000 // If none was better set the partitioning to that.
2001 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2002 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2003 chosen_rdc = none_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002004 }
2005
2006 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2007
2008 // We must have chosen a partitioning and encoding or we'll fail later on.
2009 // No other opportunities for success.
2010 if (bsize == cm->sb_size)
2011 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2012
2013 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002014 if (bsize == cm->sb_size) {
2015 // NOTE: To get estimate for rate due to the tokens, use:
2016 // int rate_coeffs = 0;
2017 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2018 // bsize, pc_tree, &rate_coeffs);
2019 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2020 pc_tree, NULL);
2021 } else {
2022 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2023 pc_tree, NULL);
2024 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025 }
2026
2027 *rate = chosen_rdc.rate;
2028 *dist = chosen_rdc.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002029}
2030
2031/* clang-format off */
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002032static const BLOCK_SIZE min_partition_size[BLOCK_SIZES_ALL] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002033 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
Yaowu Xuc27fc142016-08-22 16:08:15 -07002034 BLOCK_4X4, // 4x4
2035 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2036 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2037 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2038 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2039#if CONFIG_EXT_PARTITION
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002040 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 64x128, 128x64, 128x128
Yaowu Xuc27fc142016-08-22 16:08:15 -07002041#endif // CONFIG_EXT_PARTITION
Rupert Swarbrick72678572017-08-02 12:05:26 +01002042 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
Rupert Swarbrick2fa6e1c2017-09-11 12:38:10 +01002043 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
2044#if CONFIG_EXT_PARTITION
2045 BLOCK_16X16, BLOCK_16X16 // 32x128, 128x32
2046#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002047};
2048
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002049static const BLOCK_SIZE max_partition_size[BLOCK_SIZES_ALL] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002050 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 2x2, 2x4, 4x2
Yaowu Xuc27fc142016-08-22 16:08:15 -07002051 BLOCK_8X8, // 4x4
2052 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2053 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2054 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2055 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2056#if CONFIG_EXT_PARTITION
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002057 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 64x128, 128x64, 128x128
Yaowu Xuc27fc142016-08-22 16:08:15 -07002058#endif // CONFIG_EXT_PARTITION
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002059 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 4x16, 16x4, 8x32
Rupert Swarbrick2fa6e1c2017-09-11 12:38:10 +01002060 BLOCK_32X32, BLOCK_LARGEST, BLOCK_LARGEST, // 32x8, 16x64, 64x16
2061#if CONFIG_EXT_PARTITION
2062 BLOCK_LARGEST, BLOCK_LARGEST // 32x128, 128x32
2063#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002064};
2065
2066// Next square block size less or equal than current block size.
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002067static const BLOCK_SIZE next_square_size[BLOCK_SIZES_ALL] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002068 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
Yaowu Xuc27fc142016-08-22 16:08:15 -07002069 BLOCK_4X4, // 4x4
2070 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2071 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2072 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2073 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2074#if CONFIG_EXT_PARTITION
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002075 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128, // 64x128, 128x64, 128x128
Yaowu Xuc27fc142016-08-22 16:08:15 -07002076#endif // CONFIG_EXT_PARTITION
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01002077 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
Rupert Swarbrick2fa6e1c2017-09-11 12:38:10 +01002078 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
2079#if CONFIG_EXT_PARTITION
2080 BLOCK_32X32, BLOCK_32X32 // 32x128, 128x32
2081#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002082};
2083/* clang-format on */
2084
2085// Look at all the mode_info entries for blocks that are part of this
2086// partition and find the min and max values for sb_type.
2087// At the moment this is designed to work on a superblock but could be
2088// adjusted to use a size parameter.
2089//
2090// The min and max are assumed to have been initialized prior to calling this
2091// function so repeat calls can accumulate a min and max of more than one
2092// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002093static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002094 MACROBLOCKD *xd, MODE_INFO **mib,
2095 BLOCK_SIZE *min_block_size,
2096 BLOCK_SIZE *max_block_size) {
2097 int i, j;
2098 int index = 0;
2099
2100 // Check the sb_type for each block that belongs to this region.
2101 for (i = 0; i < cm->mib_size; ++i) {
2102 for (j = 0; j < cm->mib_size; ++j) {
2103 MODE_INFO *mi = mib[index + j];
2104 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002105 *min_block_size = AOMMIN(*min_block_size, sb_type);
2106 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002107 }
2108 index += xd->mi_stride;
2109 }
2110}
2111
2112// Look at neighboring blocks and set a min and max partition size based on
2113// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002114static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002115 MACROBLOCKD *const xd, int mi_row,
2116 int mi_col, BLOCK_SIZE *min_block_size,
2117 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002118 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002119 MODE_INFO **mi = xd->mi;
2120 const int left_in_image = xd->left_available && mi[-1];
2121 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
2122 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2123 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2124 int bh, bw;
2125 BLOCK_SIZE min_size = BLOCK_4X4;
2126 BLOCK_SIZE max_size = BLOCK_LARGEST;
2127
2128 // Trap case where we do not have a prediction.
2129 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2130 // Default "min to max" and "max to min"
2131 min_size = BLOCK_LARGEST;
2132 max_size = BLOCK_4X4;
2133
2134 // NOTE: each call to get_sb_partition_size_range() uses the previous
2135 // passed in values for min and max as a starting point.
2136 // Find the min and max partition used in previous frame at this location
2137 if (cm->frame_type != KEY_FRAME) {
2138 MODE_INFO **prev_mi =
2139 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
2140 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
2141 }
2142 // Find the min and max partition sizes used in the left superblock
2143 if (left_in_image) {
2144 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
2145 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
2146 }
2147 // Find the min and max partition sizes used in the above suprblock.
2148 if (above_in_image) {
2149 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
2150 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
2151 }
2152
2153 // Adjust observed min and max for "relaxed" auto partition case.
2154 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2155 min_size = min_partition_size[min_size];
2156 max_size = max_partition_size[max_size];
2157 }
2158 }
2159
2160 // Check border cases where max and min from neighbors may not be legal.
2161 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
2162 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07002163 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002164
2165 // Test for blocks at the edge of the active image.
2166 // This may be the actual edge of the image or where there are formatting
2167 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07002168 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002169 min_size = BLOCK_4X4;
2170 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002171 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002172 }
2173
2174 // When use_square_partition_only is true, make sure at least one square
2175 // partition is allowed by selecting the next smaller square size as
2176 // *min_block_size.
2177 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002178 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002179 }
2180
Yaowu Xuf883b422016-08-30 14:01:10 -07002181 *min_block_size = AOMMIN(min_size, cm->sb_size);
2182 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002183}
2184
2185// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07002186static void set_partition_range(const AV1_COMMON *const cm,
2187 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002188 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07002189 BLOCK_SIZE *const min_bs,
2190 BLOCK_SIZE *const max_bs) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08002191 const int mi_width = mi_size_wide[bsize];
2192 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002193 int idx, idy;
2194
Yaowu Xuc27fc142016-08-22 16:08:15 -07002195 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07002196 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
Debargha Mukherjeee30159c2017-10-08 12:04:43 -07002197 BLOCK_SIZE min_size = cm->sb_size; // default values
Urvang Joshi52648442016-10-13 17:27:51 -07002198 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002199
2200 if (prev_mi) {
2201 for (idy = 0; idy < mi_height; ++idy) {
2202 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07002203 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
2204 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002205 min_size = AOMMIN(min_size, bs);
2206 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002207 }
2208 }
2209 }
2210
2211 if (xd->left_available) {
2212 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07002213 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
2214 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002215 min_size = AOMMIN(min_size, bs);
2216 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217 }
2218 }
2219
2220 if (xd->up_available) {
2221 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07002222 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
2223 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002224 min_size = AOMMIN(min_size, bs);
2225 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226 }
2227 }
2228
2229 if (min_size == max_size) {
2230 min_size = min_partition_size[min_size];
2231 max_size = max_partition_size[max_size];
2232 }
2233
Yaowu Xuf883b422016-08-30 14:01:10 -07002234 *min_bs = AOMMIN(min_size, cm->sb_size);
2235 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002236}
2237
2238static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2239 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
2240}
2241
2242static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2243 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
2244}
2245
2246#if CONFIG_FP_MB_STATS
2247const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002248 0, 10, 10, 30, 40, 40, 60, 80, 80, 90, 100, 100, 120,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002249#if CONFIG_EXT_PARTITION
2250 // TODO(debargha): What are the correct numbers here?
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002251 130, 130, 150
Yaowu Xuc27fc142016-08-22 16:08:15 -07002252#endif // CONFIG_EXT_PARTITION
2253};
2254const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002255 0, 3, 3, 7, 15, 15, 30, 40, 40, 60, 80, 80, 120,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256#if CONFIG_EXT_PARTITION
2257 // TODO(debargha): What are the correct numbers here?
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002258 160, 160, 240
Yaowu Xuc27fc142016-08-22 16:08:15 -07002259#endif // CONFIG_EXT_PARTITION
2260};
2261const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002262 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002263#if CONFIG_EXT_PARTITION
2264 // TODO(debargha): What are the correct numbers here?
Cheng Chen50b0f6c2017-08-03 12:25:03 -07002265 8, 8, 10
Yaowu Xuc27fc142016-08-22 16:08:15 -07002266#endif // CONFIG_EXT_PARTITION
2267};
2268
2269typedef enum {
2270 MV_ZERO = 0,
2271 MV_LEFT = 1,
2272 MV_UP = 2,
2273 MV_RIGHT = 3,
2274 MV_DOWN = 4,
2275 MV_INVALID
2276} MOTION_DIRECTION;
2277
2278static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
2279 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
2280 return MV_ZERO;
2281 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
2282 return MV_LEFT;
2283 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
2284 return MV_RIGHT;
2285 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
2286 return MV_UP;
2287 } else {
2288 return MV_DOWN;
2289 }
2290}
2291
2292static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
2293 MOTION_DIRECTION that_mv) {
2294 if (this_mv == that_mv) {
2295 return 0;
2296 } else {
2297 return abs(this_mv - that_mv) == 2 ? 2 : 1;
2298 }
2299}
2300#endif
2301
2302#if CONFIG_EXT_PARTITION_TYPES
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002303// Try searching for an encoding for the given subblock. Returns zero if the
2304// rdcost is already too high (to tell the caller not to bother searching for
2305// encodings of further subblocks)
2306static int rd_try_subblock(const AV1_COMP *const cpi, ThreadData *td,
2307 TileDataEnc *tile_data, TOKENEXTRA **tp,
2308 int is_first, int is_last, int mi_row, int mi_col,
2309 BLOCK_SIZE subsize, RD_STATS *best_rdc,
2310 RD_STATS *sum_rdc, RD_STATS *this_rdc,
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002311 PARTITION_TYPE partition,
2312 PICK_MODE_CONTEXT *prev_ctx,
2313 PICK_MODE_CONTEXT *this_ctx) {
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002314#define RTS_X_RATE_NOCOEF_ARG
2315#define RTS_MAX_RDCOST best_rdc->rdcost
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002316
2317 MACROBLOCK *const x = &td->mb;
2318
2319 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, prev_ctx);
2320
2321 // On the first time around, write the rd stats straight to sum_rdc. Also, we
2322 // should treat sum_rdc as containing zeros (even if it doesn't) to avoid
2323 // having to zero it at the start.
2324 if (is_first) this_rdc = sum_rdc;
2325 const int64_t spent_rdcost = is_first ? 0 : sum_rdc->rdcost;
2326 const int64_t rdcost_remaining = best_rdc->rdcost - spent_rdcost;
2327
2328 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, this_rdc,
2329 RTS_X_RATE_NOCOEF_ARG partition, subsize, this_ctx,
2330 rdcost_remaining);
2331
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002332 if (!is_first) {
2333 if (this_rdc->rate == INT_MAX) {
2334 sum_rdc->rdcost = INT64_MAX;
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002335 } else {
2336 sum_rdc->rate += this_rdc->rate;
2337 sum_rdc->dist += this_rdc->dist;
2338 sum_rdc->rdcost += this_rdc->rdcost;
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002339 }
2340 }
2341
2342 if (sum_rdc->rdcost >= RTS_MAX_RDCOST) return 0;
2343
2344 if (!is_last) {
2345 update_state(cpi, td, this_ctx, mi_row, mi_col, subsize, 1);
2346 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
2347 NULL);
2348 }
2349
2350 return 1;
2351
2352#undef RTS_X_RATE_NOCOEF_ARG
2353#undef RTS_MAX_RDCOST
2354}
2355
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02002356static void rd_test_partition3(const AV1_COMP *const cpi, ThreadData *td,
2357 TileDataEnc *tile_data, TOKENEXTRA **tp,
2358 PC_TREE *pc_tree, RD_STATS *best_rdc,
2359 PICK_MODE_CONTEXT ctxs[3],
2360 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
2361 BLOCK_SIZE bsize, PARTITION_TYPE partition,
2362 int mi_row0, int mi_col0, BLOCK_SIZE subsize0,
2363 int mi_row1, int mi_col1, BLOCK_SIZE subsize1,
2364 int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002365 MACROBLOCK *const x = &td->mb;
2366 MACROBLOCKD *const xd = &x->e_mbd;
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002367 RD_STATS sum_rdc, this_rdc;
Debargha Mukherjeeab8bf502017-10-05 09:10:39 -07002368#if CONFIG_UNPOISON_PARTITION_CTX
2369 const AV1_COMMON *const cm = &cpi->common;
2370 const int hbs = mi_size_wide[bsize] / 2;
2371 const int has_rows = mi_row + hbs < cm->mi_rows;
2372 const int has_cols = mi_col + hbs < cm->mi_cols;
2373#endif // CONFIG_UNPOISON_PARTITION_CTX
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02002374#if CONFIG_EXT_PARTITION_TYPES_AB
Urvang Joshi52648442016-10-13 17:27:51 -07002375 const AV1_COMMON *const cm = &cpi->common;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01002376#endif
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002377#define RTP_STX_TRY_ARGS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002378
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002379 if (!rd_try_subblock(cpi, td, tile_data, tp, 1, 0, mi_row0, mi_col0, subsize0,
2380 best_rdc, &sum_rdc, &this_rdc,
2381 RTP_STX_TRY_ARGS partition, ctx, &ctxs[0]))
2382 return;
2383
2384 if (!rd_try_subblock(cpi, td, tile_data, tp, 0, 0, mi_row1, mi_col1, subsize1,
2385 best_rdc, &sum_rdc, &this_rdc,
2386 RTP_STX_TRY_ARGS partition, &ctxs[0], &ctxs[1]))
2387 return;
2388
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01002389// With the new layout of mixed partitions for PARTITION_HORZ_B and
2390// PARTITION_VERT_B, the last subblock might start past halfway through the
2391// main block, so we might signal it even though the subblock lies strictly
2392// outside the image. In that case, we won't spend any bits coding it and the
2393// difference (obviously) doesn't contribute to the error.
2394#if CONFIG_EXT_PARTITION_TYPES_AB
2395 const int try_block2 = mi_row2 < cm->mi_rows && mi_col2 < cm->mi_cols;
2396#else
2397 const int try_block2 = 1;
2398#endif
2399 if (try_block2 &&
2400 !rd_try_subblock(cpi, td, tile_data, tp, 0, 1, mi_row2, mi_col2, subsize2,
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002401 best_rdc, &sum_rdc, &this_rdc,
2402 RTP_STX_TRY_ARGS partition, &ctxs[1], &ctxs[2]))
2403 return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002404
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002405 if (sum_rdc.rdcost >= best_rdc->rdcost) return;
2406
2407 int pl = partition_plane_context(xd, mi_row, mi_col,
2408#if CONFIG_UNPOISON_PARTITION_CTX
2409 has_rows, has_cols,
2410#endif
2411 bsize);
2412 sum_rdc.rate += x->partition_cost[pl][partition];
2413 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002414
2415 if (sum_rdc.rdcost >= best_rdc->rdcost) return;
2416
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01002417 *best_rdc = sum_rdc;
2418 pc_tree->partitioning = partition;
2419
2420#undef RTP_STX_TRY_ARGS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002421}
2422#endif // CONFIG_EXT_PARTITION_TYPES
2423
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002424#if CONFIG_DIST_8X8
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002425static int64_t dist_8x8_yuv(const AV1_COMP *const cpi, MACROBLOCK *const x,
2426 uint8_t *y_src_8x8) {
2427 MACROBLOCKD *const xd = &x->e_mbd;
2428 int64_t dist_8x8, dist_8x8_uv, total_dist;
2429 const int src_stride = x->plane[0].src.stride;
2430 uint8_t *decoded_8x8;
2431 int plane;
2432
2433#if CONFIG_HIGHBITDEPTH
2434 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2435 decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
2436 else
2437#endif
2438 decoded_8x8 = (uint8_t *)x->decoded_8x8;
2439
2440 dist_8x8 = av1_dist_8x8(cpi, x, y_src_8x8, src_stride, decoded_8x8, 8,
2441 BLOCK_8X8, 8, 8, 8, 8, x->qindex)
2442 << 4;
2443
2444 // Compute chroma distortion for a luma 8x8 block
2445 dist_8x8_uv = 0;
2446
2447 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
2448 const int src_stride_uv = x->plane[plane].src.stride;
2449 const int dst_stride_uv = xd->plane[plane].dst.stride;
2450 // uv buff pointers now (i.e. the last sub8x8 block) is the same
2451 // to those at the first sub8x8 block because
2452 // uv buff pointer is set only once at first sub8x8 block in a 8x8.
2453 uint8_t *src_uv = x->plane[plane].src.buf;
2454 uint8_t *dst_uv = xd->plane[plane].dst.buf;
2455 unsigned sse;
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002456 const BLOCK_SIZE plane_bsize =
2457 AOMMAX(BLOCK_4X4, get_plane_block_size(BLOCK_8X8, &xd->plane[plane]));
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002458 cpi->fn_ptr[plane_bsize].vf(src_uv, src_stride_uv, dst_uv, dst_stride_uv,
2459 &sse);
2460 dist_8x8_uv += (int64_t)sse << 4;
2461 }
2462
2463 return total_dist = dist_8x8 + dist_8x8_uv;
2464}
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002465#endif // CONFIG_DIST_8X8
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002466
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
2468// unlikely to be selected depending on previous rate-distortion optimization
2469// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07002470static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471 TileDataEnc *tile_data, TOKENEXTRA **tp,
2472 int mi_row, int mi_col, BLOCK_SIZE bsize,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02002473 RD_STATS *rd_cost, int64_t best_rd,
2474 PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07002475 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002476 TileInfo *const tile_info = &tile_data->tile_info;
2477 MACROBLOCK *const x = &td->mb;
2478 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002479 const int mi_step = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002480 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07002481 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07002482 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Alex Converse55c6bde2017-01-12 15:55:31 -08002483#if CONFIG_UNPOISON_PARTITION_CTX
2484 const int hbs = mi_size_wide[bsize] / 2;
2485 const int has_rows = mi_row + hbs < cm->mi_rows;
2486 const int has_cols = mi_col + hbs < cm->mi_cols;
2487#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002488 int tmp_partition_cost[PARTITION_TYPES];
Alex Converse55c6bde2017-01-12 15:55:31 -08002489#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002490 BLOCK_SIZE subsize;
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07002491 RD_STATS this_rdc, sum_rdc, best_rdc;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002492 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
2493 int do_square_split = bsize_at_least_8x8;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002494 const int pl = bsize_at_least_8x8
Alex Converse55c6bde2017-01-12 15:55:31 -08002495 ? partition_plane_context(xd, mi_row, mi_col,
2496#if CONFIG_UNPOISON_PARTITION_CTX
2497 has_rows, has_cols,
2498#endif
2499 bsize)
Yaowu Xu281def72017-04-12 08:26:55 -07002500 : 0;
Yaowu Xuba9dd8a2017-09-07 17:50:49 -07002501 const int *partition_cost =
2502 pl >= 0 ? x->partition_cost[pl] : x->partition_cost[0];
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002503
Urvang Joshi52648442016-10-13 17:27:51 -07002504 int do_rectangular_split = 1;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01002505#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
Yaowu Xuc27fc142016-08-22 16:08:15 -07002506 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2507#endif
2508
2509 // Override skipping rectangular partition operations for edge blocks
2510 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
2511 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
2512 const int xss = x->e_mbd.plane[1].subsampling_x;
2513 const int yss = x->e_mbd.plane[1].subsampling_y;
2514
2515 BLOCK_SIZE min_size = x->min_partition_size;
2516 BLOCK_SIZE max_size = x->max_partition_size;
2517
2518#if CONFIG_FP_MB_STATS
2519 unsigned int src_diff_var = UINT_MAX;
2520 int none_complexity = 0;
2521#endif
2522
2523 int partition_none_allowed = !force_horz_split && !force_vert_split;
2524 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07002525 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002526 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07002527 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002528
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529 (void)*tp_orig;
2530
Alex Converse55c6bde2017-01-12 15:55:31 -08002531#if !CONFIG_UNPOISON_PARTITION_CTX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002532 if (force_horz_split || force_vert_split) {
2533 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
2534
2535 if (!force_vert_split) { // force_horz_split only
2536 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
2537 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002538 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002539 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002540 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541 } else if (!force_horz_split) { // force_vert_split only
2542 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
2543 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002544 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002545 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002546 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002547 } else { // force_ horz_split && force_vert_split horz_split
2548 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
2549 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
2550 tmp_partition_cost[PARTITION_SPLIT] = 0;
2551 }
2552
2553 partition_cost = tmp_partition_cost;
2554 }
Alex Converse55c6bde2017-01-12 15:55:31 -08002555#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556
Yaowu Xuc27fc142016-08-22 16:08:15 -07002557#ifndef NDEBUG
2558 // Nothing should rely on the default value of this array (which is just
2559 // leftover from encoding the previous block. Setting it to magic number
2560 // when debugging.
2561 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
2562#endif // NDEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07002563
Jingning Hanc709e1f2016-12-06 14:48:09 -08002564 assert(mi_size_wide[bsize] == mi_size_high[bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002565
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07002566 av1_init_rd_stats(&this_rdc);
2567 av1_init_rd_stats(&sum_rdc);
2568 av1_invalid_rd_stats(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569 best_rdc.rdcost = best_rd;
2570
2571 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2572
2573 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07002574 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575
2576 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07002577 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578 ((pc_tree->index == 0 || pc_tree->index == 3) +
2579 get_chessboard_index(cm->current_video_frame)) &
2580 0x1;
2581
2582 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
2583 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
2584 }
2585
2586 // Determine partition types in search according to the speed features.
2587 // The threshold set here has to be of square block size.
2588 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07002589 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
2590 // Note: Further partitioning is NOT allowed when bsize == min_size already.
2591 const int partition_allowed = (bsize <= max_size && bsize > min_size);
2592 partition_none_allowed &= no_partition_allowed;
2593 partition_horz_allowed &= partition_allowed || force_horz_split;
2594 partition_vert_allowed &= partition_allowed || force_vert_split;
2595 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002596 }
2597 if (cpi->sf.use_square_partition_only) {
2598 partition_horz_allowed &= force_horz_split;
2599 partition_vert_allowed &= force_vert_split;
2600 }
2601
Jingning Han331662e2017-05-30 17:03:32 -07002602 xd->above_txfm_context =
2603 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
2604 xd->left_txfm_context = xd->left_txfm_context_buffer +
2605 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002606 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2607
2608#if CONFIG_FP_MB_STATS
2609 if (cpi->use_fp_mb_stats) {
2610 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2611 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
2612 mi_col, bsize);
2613 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002614
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615 // Decide whether we shall split directly and skip searching NONE by using
2616 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07002617 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002618 partition_none_allowed && src_diff_var > 4 &&
2619 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
2620 int mb_row = mi_row >> 1;
2621 int mb_col = mi_col >> 1;
2622 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07002623 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002624 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07002625 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002626 int r, c;
2627
2628 // compute a complexity measure, basically measure inconsistency of motion
2629 // vectors obtained from the first pass in the current block
2630 for (r = mb_row; r < mb_row_end; r++) {
2631 for (c = mb_col; c < mb_col_end; c++) {
2632 const int mb_index = r * cm->mb_cols + c;
2633
2634 MOTION_DIRECTION this_mv;
2635 MOTION_DIRECTION right_mv;
2636 MOTION_DIRECTION bottom_mv;
2637
2638 this_mv =
2639 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
2640
2641 // to its right
2642 if (c != mb_col_end - 1) {
2643 right_mv = get_motion_direction_fp(
2644 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
2645 none_complexity += get_motion_inconsistency(this_mv, right_mv);
2646 }
2647
2648 // to its bottom
2649 if (r != mb_row_end - 1) {
2650 bottom_mv = get_motion_direction_fp(
2651 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
2652 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
2653 }
2654
2655 // do not count its left and top neighbors to avoid double counting
2656 }
2657 }
2658
2659 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
2660 partition_none_allowed = 0;
2661 }
2662 }
2663#endif
2664
2665 // PARTITION_NONE
2666 if (partition_none_allowed) {
2667 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002668#if CONFIG_EXT_PARTITION_TYPES
2669 PARTITION_NONE,
2670#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002671 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07002673 if (bsize_at_least_8x8) {
Yaowu Xu897dd192017-08-02 18:41:56 -07002674 const int pt_cost = partition_cost[PARTITION_NONE] < INT_MAX
2675 ? partition_cost[PARTITION_NONE]
2676 : 0;
2677 this_rdc.rate += pt_cost;
Urvang Joshi70006e42017-06-14 16:08:55 -07002678 this_rdc.rdcost = RDCOST(x->rdmult, this_rdc.rate, this_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679 }
2680
2681 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07002682 // Adjust dist breakout threshold according to the partition size.
2683 const int64_t dist_breakout_thr =
2684 cpi->sf.partition_search_breakout_dist_thr >>
2685 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
2686 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
2687 const int rate_breakout_thr =
2688 cpi->sf.partition_search_breakout_rate_thr *
2689 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002690
2691 best_rdc = this_rdc;
Urvang Joshi52648442016-10-13 17:27:51 -07002692 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002693
2694 // If all y, u, v transform blocks in this partition are skippable, and
2695 // the dist & rate are within the thresholds, the partition search is
2696 // terminated for current branch of the partition search tree.
2697 // The dist & rate thresholds are set to 0 at speed 0 to disable the
2698 // early termination at that speed.
2699 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07002700 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002701 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07002702 do_square_split = 0;
2703 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002704 }
2705
2706#if CONFIG_FP_MB_STATS
2707 // Check if every 16x16 first pass block statistics has zero
2708 // motion and the corresponding first pass residue is small enough.
2709 // If that is the case, check the difference variance between the
2710 // current frame and the last frame. If the variance is small enough,
2711 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07002712 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002713 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
2714 int mb_row = mi_row >> 1;
2715 int mb_col = mi_col >> 1;
2716 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07002717 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002718 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07002719 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002720 int r, c;
2721
2722 int skip = 1;
2723 for (r = mb_row; r < mb_row_end; r++) {
2724 for (c = mb_col; c < mb_col_end; c++) {
2725 const int mb_index = r * cm->mb_cols + c;
2726 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
2727 FPMB_MOTION_ZERO_MASK) ||
2728 !(cpi->twopass.this_frame_mb_stats[mb_index] &
2729 FPMB_ERROR_SMALL_MASK)) {
2730 skip = 0;
2731 break;
2732 }
2733 }
2734 if (skip == 0) {
2735 break;
2736 }
2737 }
2738 if (skip) {
2739 if (src_diff_var == UINT_MAX) {
2740 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2741 src_diff_var = get_sby_perpixel_diff_variance(
2742 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
2743 }
2744 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07002745 do_square_split = 0;
2746 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747 }
2748 }
2749 }
2750#endif
2751 }
2752 }
Yushin Chod0b77ac2017-10-20 17:33:16 -07002753
Yaowu Xuc27fc142016-08-22 16:08:15 -07002754 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2755 }
2756
2757 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07002758 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002759
Yaowu Xu049a7882017-09-07 08:55:54 -07002760 int64_t temp_best_rdcost = best_rdc.rdcost;
Yaowu Xu049a7882017-09-07 08:55:54 -07002761
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 // PARTITION_SPLIT
2763 // TODO(jingning): use the motion vectors given by the above search as
2764 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07002765 if (do_square_split) {
2766 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002767 subsize = get_subsize(bsize, PARTITION_SPLIT);
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002768 int idx;
2769 for (idx = 0; idx < 4 && sum_rdc.rdcost < temp_best_rdcost; ++idx) {
2770 const int x_idx = (idx & 1) * mi_step;
2771 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xu049a7882017-09-07 08:55:54 -07002772
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002773 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2774 continue;
2775
2776 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
2777
2778 pc_tree->split[idx]->index = idx;
2779 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx,
2780 subsize, &this_rdc, temp_best_rdcost - sum_rdc.rdcost,
2781 pc_tree->split[idx]);
2782
2783 if (this_rdc.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002784 sum_rdc.rdcost = INT64_MAX;
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002785 break;
2786 } else {
2787 sum_rdc.rate += this_rdc.rate;
2788 sum_rdc.dist += this_rdc.dist;
2789 sum_rdc.rdcost += this_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 }
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002791 }
2792 reached_last_index = (idx == 4);
Yushin Cho63927c42017-05-23 15:41:05 -07002793
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002794#if CONFIG_DIST_8X8
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002795 if (x->using_dist_8x8 && reached_last_index &&
2796 sum_rdc.rdcost != INT64_MAX && bsize == BLOCK_8X8) {
2797 const int src_stride = x->plane[0].src.stride;
2798 int64_t dist_8x8;
2799 dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride - 4);
2800 if (x->tune_metric == AOM_TUNE_PSNR) assert(sum_rdc.dist == dist_8x8);
2801 sum_rdc.dist = dist_8x8;
2802 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002803 }
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002804#endif // CONFIG_DIST_8X8
Yaowu Xuc27fc142016-08-22 16:08:15 -07002805
Urvang Joshi52648442016-10-13 17:27:51 -07002806 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002807 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
Urvang Joshi70006e42017-06-14 16:08:55 -07002808 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002809
2810 if (sum_rdc.rdcost < best_rdc.rdcost) {
2811 best_rdc = sum_rdc;
Yaowu Xu049a7882017-09-07 08:55:54 -07002812 temp_best_rdcost = best_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002813 pc_tree->partitioning = PARTITION_SPLIT;
2814 }
Urvang Joshi52648442016-10-13 17:27:51 -07002815 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002816 // skip rectangular partition test when larger block size
2817 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07002818 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002819 }
Yushin Chod0b77ac2017-10-20 17:33:16 -07002820
Yaowu Xuc27fc142016-08-22 16:08:15 -07002821 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2822 } // if (do_split)
2823
2824 // PARTITION_HORZ
2825 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07002826 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07002828 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2830 partition_none_allowed)
2831 pc_tree->horizontal[0].pred_interp_filter =
Rupert Swarbrick27e90292017-09-28 17:46:50 +01002832 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
2833
Yaowu Xuc27fc142016-08-22 16:08:15 -07002834 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002835#if CONFIG_EXT_PARTITION_TYPES
2836 PARTITION_HORZ,
2837#endif
2838 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
2839
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002840 if (sum_rdc.rdcost < temp_best_rdcost && !force_horz_split) {
Urvang Joshi454280d2016-10-14 16:51:44 -07002841 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
2842 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002843 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Yushin Cho6d72a2f2017-05-03 17:37:37 -07002844 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845
Urvang Joshi454280d2016-10-14 16:51:44 -07002846 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847
Yaowu Xuc27fc142016-08-22 16:08:15 -07002848 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2849 partition_none_allowed)
2850 pc_tree->horizontal[1].pred_interp_filter =
Rupert Swarbrick27e90292017-09-28 17:46:50 +01002851 av1_extract_interp_filter(ctx_h->mic.mbmi.interp_filters, 0);
2852
Yaowu Xuc27fc142016-08-22 16:08:15 -07002853 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
2854#if CONFIG_EXT_PARTITION_TYPES
2855 PARTITION_HORZ,
2856#endif
2857 subsize, &pc_tree->horizontal[1],
2858 best_rdc.rdcost - sum_rdc.rdcost);
Yushin Cho63927c42017-05-23 15:41:05 -07002859
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002860#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07002861 if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
Yushin Cho63927c42017-05-23 15:41:05 -07002862 update_state(cpi, td, &pc_tree->horizontal[1], mi_row + mi_step, mi_col,
2863 subsize, DRY_RUN_NORMAL);
2864 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row + mi_step, mi_col,
2865 subsize, NULL);
2866 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002867#endif // CONFIG_DIST_8X8
Yushin Cho63927c42017-05-23 15:41:05 -07002868
Yaowu Xuc27fc142016-08-22 16:08:15 -07002869 if (this_rdc.rate == INT_MAX) {
2870 sum_rdc.rdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 } else {
2872 sum_rdc.rate += this_rdc.rate;
2873 sum_rdc.dist += this_rdc.dist;
2874 sum_rdc.rdcost += this_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002875 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002876#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07002877 if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
2878 bsize == BLOCK_8X8) {
Yushin Cho63927c42017-05-23 15:41:05 -07002879 const int src_stride = x->plane[0].src.stride;
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002880 int64_t dist_8x8;
2881 dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride);
Yushin Cho1cd34622017-10-06 13:00:41 -07002882 if (x->tune_metric == AOM_TUNE_PSNR) assert(sum_rdc.dist == dist_8x8);
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002883 sum_rdc.dist = dist_8x8;
Urvang Joshi70006e42017-06-14 16:08:55 -07002884 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yushin Cho63927c42017-05-23 15:41:05 -07002885 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002886#endif // CONFIG_DIST_8X8
Yaowu Xuc27fc142016-08-22 16:08:15 -07002887 }
2888
Yaowu Xuc27fc142016-08-22 16:08:15 -07002889 if (sum_rdc.rdcost < best_rdc.rdcost) {
2890 sum_rdc.rate += partition_cost[PARTITION_HORZ];
Urvang Joshi70006e42017-06-14 16:08:55 -07002891 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002892 if (sum_rdc.rdcost < best_rdc.rdcost) {
2893 best_rdc = sum_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002894 pc_tree->partitioning = PARTITION_HORZ;
2895 }
2896 }
Yushin Chod0b77ac2017-10-20 17:33:16 -07002897
Yaowu Xuc27fc142016-08-22 16:08:15 -07002898 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2899 }
2900
2901 // PARTITION_VERT
2902 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07002903 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002904 subsize = get_subsize(bsize, PARTITION_VERT);
2905
Urvang Joshi454280d2016-10-14 16:51:44 -07002906 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002907
Yaowu Xuc27fc142016-08-22 16:08:15 -07002908 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2909 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07002910 pc_tree->vertical[0].pred_interp_filter =
Rupert Swarbrick27e90292017-09-28 17:46:50 +01002911 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
2912
Yaowu Xuc27fc142016-08-22 16:08:15 -07002913 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002914#if CONFIG_EXT_PARTITION_TYPES
2915 PARTITION_VERT,
2916#endif
2917 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
Rupert Swarbrick0a2299b2017-10-03 17:57:42 +01002918 const int64_t vert_max_rdcost = best_rdc.rdcost;
Debargha Mukherjeeedced252017-10-20 00:02:00 -07002919 if (sum_rdc.rdcost < vert_max_rdcost && !force_vert_split) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002920 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
2921 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Yushin Cho6d72a2f2017-05-03 17:37:37 -07002922 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002923
Urvang Joshi454280d2016-10-14 16:51:44 -07002924 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002925
Yaowu Xuc27fc142016-08-22 16:08:15 -07002926 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2927 partition_none_allowed)
2928 pc_tree->vertical[1].pred_interp_filter =
Rupert Swarbrick27e90292017-09-28 17:46:50 +01002929 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
2930
Yaowu Xuc27fc142016-08-22 16:08:15 -07002931 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
2932#if CONFIG_EXT_PARTITION_TYPES
2933 PARTITION_VERT,
2934#endif
2935 subsize, &pc_tree->vertical[1],
2936 best_rdc.rdcost - sum_rdc.rdcost);
Yushin Cho63927c42017-05-23 15:41:05 -07002937
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002938#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07002939 if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
Yushin Cho63927c42017-05-23 15:41:05 -07002940 update_state(cpi, td, &pc_tree->vertical[1], mi_row, mi_col + mi_step,
2941 subsize, DRY_RUN_NORMAL);
2942 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col + mi_step,
2943 subsize, NULL);
2944 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002945#endif // CONFIG_DIST_8X8
Yushin Cho63927c42017-05-23 15:41:05 -07002946
Yaowu Xuc27fc142016-08-22 16:08:15 -07002947 if (this_rdc.rate == INT_MAX) {
2948 sum_rdc.rdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002949 } else {
2950 sum_rdc.rate += this_rdc.rate;
2951 sum_rdc.dist += this_rdc.dist;
2952 sum_rdc.rdcost += this_rdc.rdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002954#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07002955 if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
2956 bsize == BLOCK_8X8) {
Yushin Chob7b60c52017-07-14 16:18:52 -07002957 int64_t dist_8x8;
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002958 dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4);
Yushin Cho1cd34622017-10-06 13:00:41 -07002959 if (x->tune_metric == AOM_TUNE_PSNR) assert(sum_rdc.dist == dist_8x8);
Yushin Cho8e75e8b2017-09-12 16:33:28 -07002960 sum_rdc.dist = dist_8x8;
Urvang Joshi70006e42017-06-14 16:08:55 -07002961 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yushin Cho63927c42017-05-23 15:41:05 -07002962 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07002963#endif // CONFIG_DIST_8X8
Yaowu Xuc27fc142016-08-22 16:08:15 -07002964 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002965
2966 if (sum_rdc.rdcost < best_rdc.rdcost) {
2967 sum_rdc.rate += partition_cost[PARTITION_VERT];
Urvang Joshi70006e42017-06-14 16:08:55 -07002968 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002969 if (sum_rdc.rdcost < best_rdc.rdcost) {
2970 best_rdc = sum_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002971 pc_tree->partitioning = PARTITION_VERT;
2972 }
2973 }
Yushin Chod0b77ac2017-10-20 17:33:16 -07002974
Yaowu Xuc27fc142016-08-22 16:08:15 -07002975 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2976 }
2977
2978#if CONFIG_EXT_PARTITION_TYPES
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01002979 const int ext_partition_allowed =
2980 do_rectangular_split && bsize > BLOCK_8X8 && partition_none_allowed;
2981
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01002982 // horz4_partition_allowed and vert4_partition_allowed encode the requirement
2983 // that we don't choose a block size that wouldn't be allowed by this
2984 // subsampling (stored in the xss and yss variables).
2985 //
2986 // We definitely can't allow (say) a 16x4 block if yss > xss because it would
2987 // subsample to 16x2, which doesn't have an enum. Also, there's no BLOCK_8X2
2988 // or BLOCK_2X8, so we can't do 4:1 or 1:4 partitions for BLOCK_16X16 if there
2989 // is any subsampling.
Debargha Mukherjeeab68ddb2017-10-19 21:16:54 -07002990 const int horz4_partition_allowed =
2991 ext_partition_allowed && partition_horz_allowed;
2992 const int vert4_partition_allowed =
2993 ext_partition_allowed && partition_vert_allowed;
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01002994
2995#if CONFIG_EXT_PARTITION_TYPES_AB
2996 // The alternative AB partitions are allowed iff the corresponding 4:1
2997 // partitions are allowed.
2998 const int horzab_partition_allowed = horz4_partition_allowed;
2999 const int vertab_partition_allowed = vert4_partition_allowed;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003000#else
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003001 // The standard AB partitions are allowed whenever ext-partition-types are
3002 // allowed
3003 const int horzab_partition_allowed = ext_partition_allowed;
3004 const int vertab_partition_allowed = ext_partition_allowed;
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003005#endif
3006
Yaowu Xuc27fc142016-08-22 16:08:15 -07003007 // PARTITION_HORZ_A
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003008 if (partition_horz_allowed && horzab_partition_allowed) {
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003009#if CONFIG_EXT_PARTITION_TYPES_AB
3010 rd_test_partition3(
3011 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontala,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003012 ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_A, mi_row, mi_col,
3013 get_subsize(bsize, PARTITION_HORZ_4), mi_row + mi_step / 2, mi_col,
3014 get_subsize(bsize, PARTITION_HORZ_4), mi_row + mi_step, mi_col,
3015 get_subsize(bsize, PARTITION_HORZ));
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003016#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003017 subsize = get_subsize(bsize, PARTITION_HORZ_A);
3018 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07003019 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003020 PARTITION_HORZ_A, mi_row, mi_col, bsize2, mi_row,
3021 mi_col + mi_step, bsize2, mi_row + mi_step, mi_col,
3022 subsize);
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003023#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003024 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3025 }
3026 // PARTITION_HORZ_B
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003027 if (partition_horz_allowed && horzab_partition_allowed) {
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003028#if CONFIG_EXT_PARTITION_TYPES_AB
3029 rd_test_partition3(
3030 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontalb,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003031 ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_B, mi_row, mi_col,
3032 get_subsize(bsize, PARTITION_HORZ), mi_row + mi_step, mi_col,
3033 get_subsize(bsize, PARTITION_HORZ_4), mi_row + 3 * mi_step / 2, mi_col,
3034 get_subsize(bsize, PARTITION_HORZ_4));
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003035#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 subsize = get_subsize(bsize, PARTITION_HORZ_B);
3037 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07003038 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003039 PARTITION_HORZ_B, mi_row, mi_col, subsize,
3040 mi_row + mi_step, mi_col, bsize2, mi_row + mi_step,
3041 mi_col + mi_step, bsize2);
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003042#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3044 }
3045 // PARTITION_VERT_A
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003046 if (partition_vert_allowed && vertab_partition_allowed) {
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003047#if CONFIG_EXT_PARTITION_TYPES_AB
3048 rd_test_partition3(
3049 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticala,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003050 ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_A, mi_row, mi_col,
3051 get_subsize(bsize, PARTITION_VERT_4), mi_row, mi_col + mi_step / 2,
3052 get_subsize(bsize, PARTITION_VERT_4), mi_row, mi_col + mi_step,
3053 get_subsize(bsize, PARTITION_VERT));
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003054#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055 subsize = get_subsize(bsize, PARTITION_VERT_A);
3056 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07003057 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003058 PARTITION_VERT_A, mi_row, mi_col, bsize2,
3059 mi_row + mi_step, mi_col, bsize2, mi_row,
3060 mi_col + mi_step, subsize);
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003061#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003062 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3063 }
3064 // PARTITION_VERT_B
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003065 if (partition_vert_allowed && vertab_partition_allowed) {
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003066#if CONFIG_EXT_PARTITION_TYPES_AB
3067 rd_test_partition3(
3068 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticalb,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003069 ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_B, mi_row, mi_col,
3070 get_subsize(bsize, PARTITION_VERT), mi_row, mi_col + mi_step,
3071 get_subsize(bsize, PARTITION_VERT_4), mi_row, mi_col + 3 * mi_step / 2,
3072 get_subsize(bsize, PARTITION_VERT_4));
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003073#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003074 subsize = get_subsize(bsize, PARTITION_VERT_B);
3075 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07003076 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003077 PARTITION_VERT_B, mi_row, mi_col, subsize, mi_row,
3078 mi_col + mi_step, bsize2, mi_row + mi_step,
3079 mi_col + mi_step, bsize2);
Rupert Swarbrick3dd33912017-09-12 14:24:11 +01003080#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3082 }
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003083
3084 // PARTITION_HORZ_4
3085 // TODO(david.barker): For this and PARTITION_VERT_4,
3086 // * Add support for BLOCK_16X16 once we support 2x8 and 8x2 blocks for the
3087 // chroma plane
3088 // * Add support for supertx
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003089 if (horz4_partition_allowed && !force_horz_split &&
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003090 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003091 const int quarter_step = mi_size_high[bsize] / 4;
3092 PICK_MODE_CONTEXT *ctx_prev = ctx_none;
3093
3094 subsize = get_subsize(bsize, PARTITION_HORZ_4);
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003095
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003096 for (int i = 0; i < 4; ++i) {
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003097 int this_mi_row = mi_row + i * quarter_step;
3098
3099 if (i > 0 && this_mi_row >= cm->mi_rows) break;
3100
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003101 PICK_MODE_CONTEXT *ctx_this = &pc_tree->horizontal4[i];
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003102
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003103 if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3),
3104 this_mi_row, mi_col, subsize, &best_rdc, &sum_rdc,
3105 &this_rdc, PARTITION_HORZ_4, ctx_prev, ctx_this))
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003106 break;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003107
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003108 ctx_prev = ctx_this;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003109 }
3110
3111 if (sum_rdc.rdcost < best_rdc.rdcost) {
3112 sum_rdc.rate += partition_cost[PARTITION_HORZ_4];
3113 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3114 if (sum_rdc.rdcost < best_rdc.rdcost) {
3115 best_rdc = sum_rdc;
3116 pc_tree->partitioning = PARTITION_HORZ_4;
3117 }
3118 }
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003119 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003120 }
3121 // PARTITION_VERT_4
Rupert Swarbrickfc2ac952017-10-11 13:05:31 +01003122 if (vert4_partition_allowed && !force_vert_split &&
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003123 (do_rectangular_split || av1_active_v_edge(cpi, mi_row, mi_step))) {
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003124 const int quarter_step = mi_size_wide[bsize] / 4;
3125 PICK_MODE_CONTEXT *ctx_prev = ctx_none;
3126
3127 subsize = get_subsize(bsize, PARTITION_VERT_4);
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003128
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003129 for (int i = 0; i < 4; ++i) {
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003130 int this_mi_col = mi_col + i * quarter_step;
3131
3132 if (i > 0 && this_mi_col >= cm->mi_cols) break;
3133
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003134 PICK_MODE_CONTEXT *ctx_this = &pc_tree->vertical4[i];
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003135
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003136 if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3), mi_row,
3137 this_mi_col, subsize, &best_rdc, &sum_rdc, &this_rdc,
3138 PARTITION_VERT_4, ctx_prev, ctx_this))
3139 break;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003140
Rupert Swarbrick0e653f92017-09-12 12:58:27 +01003141 ctx_prev = ctx_this;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003142 }
3143
3144 if (sum_rdc.rdcost < best_rdc.rdcost) {
3145 sum_rdc.rate += partition_cost[PARTITION_VERT_4];
3146 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3147 if (sum_rdc.rdcost < best_rdc.rdcost) {
3148 best_rdc = sum_rdc;
3149 pc_tree->partitioning = PARTITION_VERT_4;
3150 }
3151 }
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003152 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003153 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003154#endif // CONFIG_EXT_PARTITION_TYPES
3155
3156 // TODO(jbb): This code added so that we avoid static analysis
3157 // warning related to the fact that best_rd isn't used after this
3158 // point. This code should be refactored so that the duplicate
3159 // checks occur in some sub function and thus are used...
3160 (void)best_rd;
3161 *rd_cost = best_rdc;
Yushin Choc0f6bf22017-06-09 16:08:02 -07003162
Yaowu Xuc27fc142016-08-22 16:08:15 -07003163 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
3164 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003165 if (bsize == cm->sb_size) {
Sebastien Alaiwan1bc94fc2017-10-31 10:25:17 +01003166#if NC_MODE_INFO
Yue Chenf27b1602017-01-13 11:11:43 -08003167 set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
3168#endif
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07003169
Jingning Hanf5a4d3b2017-08-27 23:01:19 -07003170#if CONFIG_LV_MAP
3171 x->cb_offset = 0;
3172#endif
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07003173
3174#if CONFIG_NCOBMC_ADAPT_WEIGHT
3175 set_sb_mi_boundaries(cm, xd, mi_row, mi_col);
3176#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003177 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
3178 pc_tree, NULL);
3179 } else {
3180 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
3181 pc_tree, NULL);
3182 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003183 }
3184
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07003185#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07003186 if (x->using_dist_8x8 && best_rdc.rate < INT_MAX &&
3187 best_rdc.dist < INT64_MAX && bsize == BLOCK_4X4 && pc_tree->index == 3) {
Yushin Cho63927c42017-05-23 15:41:05 -07003188 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
3189 pc_tree, NULL);
3190 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07003191#endif // CONFIG_DIST_8X8
Yushin Cho63927c42017-05-23 15:41:05 -07003192
Yaowu Xuc27fc142016-08-22 16:08:15 -07003193 if (bsize == cm->sb_size) {
Yushin Chod0b77ac2017-10-20 17:33:16 -07003194#if !CONFIG_LV_MAP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003195 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003196#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003197 assert(best_rdc.rate < INT_MAX);
3198 assert(best_rdc.dist < INT64_MAX);
3199 } else {
3200 assert(tp_orig == *tp);
3201 }
3202}
3203
Yaowu Xuf883b422016-08-30 14:01:10 -07003204static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003205 TileDataEnc *tile_data, int mi_row,
3206 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003207 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003208 const TileInfo *const tile_info = &tile_data->tile_info;
3209 MACROBLOCK *const x = &td->mb;
3210 MACROBLOCKD *const xd = &x->e_mbd;
3211 SPEED_FEATURES *const sf = &cpi->sf;
3212 int mi_col;
3213#if CONFIG_EXT_PARTITION
3214 const int leaf_nodes = 256;
3215#else
3216 const int leaf_nodes = 64;
3217#endif // CONFIG_EXT_PARTITION
3218
3219 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07003220 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221
Thomas Daviesf6936102016-09-05 16:51:31 +01003222 // Reset delta for every tile
3223 if (cm->delta_q_present_flag)
3224 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
Fangwen Fu231fe422017-04-24 17:52:29 -07003225#if CONFIG_EXT_DELTA_Q
Cheng Chena97394f2017-09-27 15:05:14 -07003226 if (cm->delta_lf_present_flag) {
3227#if CONFIG_LOOPFILTER_LEVEL
3228 if (mi_row == tile_info->mi_row_start)
3229 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
3230 xd->prev_delta_lf[lf_id] = 0;
3231#endif // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu231fe422017-04-24 17:52:29 -07003232 if (mi_row == tile_info->mi_row_start) xd->prev_delta_lf_from_base = 0;
Cheng Chena97394f2017-09-27 15:05:14 -07003233 }
Fangwen Fu231fe422017-04-24 17:52:29 -07003234#endif
Thomas Daviesf6936102016-09-05 16:51:31 +01003235
Yaowu Xuc27fc142016-08-22 16:08:15 -07003236 // Code each SB in the row
3237 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
3238 mi_col += cm->mib_size) {
3239 const struct segmentation *const seg = &cm->seg;
3240 int dummy_rate;
3241 int64_t dummy_dist;
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07003242 RD_STATS dummy_rdc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003243 int i;
3244 int seg_skip = 0;
3245
3246 const int idx_str = cm->mi_stride * mi_row + mi_col;
3247 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
3248 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
3249
Jingning Han00803a72017-10-25 16:04:34 -07003250#if CONFIG_LV_MAP
Jingning Han8f661602017-08-19 08:16:50 -07003251 av1_fill_coeff_costs(&td->mb, xd->tile_ctx);
Jingning Han24b0cf92017-08-18 22:50:18 -07003252#else
hui subd57abe2017-07-24 18:14:03 -07003253 av1_fill_token_costs_from_cdf(x->token_head_costs,
3254 x->e_mbd.tile_ctx->coef_head_cdfs);
3255 av1_fill_token_costs_from_cdf(x->token_tail_costs,
3256 x->e_mbd.tile_ctx->coef_tail_cdfs);
Jingning Han24b0cf92017-08-18 22:50:18 -07003257#endif
Yue Chena4245512017-08-31 11:58:08 -07003258 av1_fill_mode_rates(cm, x, xd->tile_ctx);
hui subd57abe2017-07-24 18:14:03 -07003259
Yaowu Xuc27fc142016-08-22 16:08:15 -07003260 if (sf->adaptive_pred_interp_filter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003261 for (i = 0; i < leaf_nodes; ++i) {
3262 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
3263 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
3264 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
3265 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
3266 }
3267 }
3268
Hui Su1ddf2312017-08-19 15:21:34 -07003269 x->tx_rd_record.num = x->tx_rd_record.index_start = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07003270 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271 pc_root->index = 0;
3272
3273 if (seg->enabled) {
3274 const uint8_t *const map =
3275 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
3276 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
3277 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
3278 }
RogerZhou3b635242017-09-19 10:06:46 -07003279#if CONFIG_AMVR
RogerZhou10a03802017-10-26 11:49:48 -07003280 xd->cur_frame_force_integer_mv = cm->cur_frame_force_integer_mv;
RogerZhou3b635242017-09-19 10:06:46 -07003281#endif
Thomas Davies3ab20b42017-09-19 10:30:53 +01003282
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003283 if (cm->delta_q_present_flag) {
Thomas Daviesf6936102016-09-05 16:51:31 +01003284 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02003285 int sb_row = mi_row >> 3;
3286 int sb_col = mi_col >> 3;
3287 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
3288 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01003289
3290 // Ensure divisibility of delta_qindex by delta_q_res
3291 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
3292 int qmask = ~(cm->delta_q_res - 1);
3293 int current_qindex = clamp(cm->base_qindex + offset_qindex,
3294 cm->delta_q_res, 256 - cm->delta_q_res);
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003295
Thomas Daviesf6936102016-09-05 16:51:31 +01003296 current_qindex =
3297 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
3298 cm->base_qindex;
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003299 assert(current_qindex > 0);
Thomas Daviesf6936102016-09-05 16:51:31 +01003300
Arild Fuldseth07441162016-08-15 15:07:52 +02003301 xd->delta_qindex = current_qindex - cm->base_qindex;
Debargha Mukherjeee30159c2017-10-08 12:04:43 -07003302 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
Arild Fuldseth07441162016-08-15 15:07:52 +02003303 xd->mi[0]->mbmi.current_q_index = current_qindex;
Fangwen Fu6160df22017-04-24 09:45:51 -07003304#if !CONFIG_EXT_DELTA_Q
Arild Fuldseth07441162016-08-15 15:07:52 +02003305 xd->mi[0]->mbmi.segment_id = 0;
Fangwen Fu6160df22017-04-24 09:45:51 -07003306#endif // CONFIG_EXT_DELTA_Q
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07003307 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Fangwen Fu231fe422017-04-24 17:52:29 -07003308#if CONFIG_EXT_DELTA_Q
3309 if (cpi->oxcf.deltaq_mode == DELTA_Q_LF) {
3310 int j, k;
3311 int lfmask = ~(cm->delta_lf_res - 1);
3312 int current_delta_lf_from_base = offset_qindex / 2;
3313 current_delta_lf_from_base =
3314 ((current_delta_lf_from_base + cm->delta_lf_res / 2) & lfmask);
3315
3316 // pre-set the delta lf for loop filter. Note that this value is set
3317 // before mi is assigned for each block in current superblock
3318 for (j = 0; j < AOMMIN(cm->mib_size, cm->mi_rows - mi_row); j++) {
3319 for (k = 0; k < AOMMIN(cm->mib_size, cm->mi_cols - mi_col); k++) {
3320 cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
Cheng Chenaff479f2017-10-26 16:53:10 -07003321 .mbmi.current_delta_lf_from_base = clamp(
3322 current_delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
Cheng Chena97394f2017-09-27 15:05:14 -07003323#if CONFIG_LOOPFILTER_LEVEL
3324 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
3325 cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
Cheng Chenaff479f2017-10-26 16:53:10 -07003326 .mbmi.curr_delta_lf[lf_id] =
3327 clamp(current_delta_lf_from_base, -MAX_LOOP_FILTER,
3328 MAX_LOOP_FILTER);
Cheng Chena97394f2017-09-27 15:05:14 -07003329 }
3330#endif // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu231fe422017-04-24 17:52:29 -07003331 }
3332 }
3333 }
3334#endif // CONFIG_EXT_DELTA_Q
Arild Fuldseth07441162016-08-15 15:07:52 +02003335 }
Arild Fuldseth07441162016-08-15 15:07:52 +02003336
Yaowu Xuc27fc142016-08-22 16:08:15 -07003337 x->source_variance = UINT_MAX;
3338 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
3339 BLOCK_SIZE bsize;
3340 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
3341 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
3342 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
3343 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003344 &dummy_rate, &dummy_dist, 1, pc_root);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003345 } else if (cpi->partition_search_skippable_frame) {
3346 BLOCK_SIZE bsize;
3347 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
3348 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
3349 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
3350 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003351 &dummy_rate, &dummy_dist, 1, pc_root);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003352 } else {
3353 // If required set upper and lower partition size limits
3354 if (sf->auto_min_max_partition_size) {
3355 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
3356 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
3357 &x->min_partition_size, &x->max_partition_size);
3358 }
3359 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
Sebastien Alaiwan0cf54d42017-10-16 16:10:04 +02003360 &dummy_rdc, INT64_MAX, pc_root);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 }
Cheng Chen5ad5b282017-10-05 16:36:06 -07003362#if CONFIG_LPF_SB
3363 if (USE_LOOP_FILTER_SUPERBLOCK) {
3364 // apply deblocking filtering right after each superblock is encoded.
3365 const int guess_filter_lvl = FAKE_FILTER_LEVEL;
3366 av1_loop_filter_frame(get_frame_new_buffer(cm), cm, xd, guess_filter_lvl,
3367 0, 1, mi_row, mi_col);
3368 }
3369#endif // CONFIG_LPF_SB
Yaowu Xuc27fc142016-08-22 16:08:15 -07003370 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003371}
3372
Yaowu Xuf883b422016-08-30 14:01:10 -07003373static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003374 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07003375 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 MACROBLOCKD *const xd = &x->e_mbd;
3377
3378 // Copy data over into macro block data structures.
Alex Conversef77fd0b2017-04-20 11:00:24 -07003379 av1_setup_src_planes(x, cpi->source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003380
Yaowu Xuf883b422016-08-30 14:01:10 -07003381 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003382}
3383
Cheng Chen0a7f2f52017-10-10 15:16:09 -07003384#if !CONFIG_REF_ADAPT && !CONFIG_JNT_COMP
Yaowu Xuf883b422016-08-30 14:01:10 -07003385static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003386 const int ref_flags = cpi->ref_frame_flags;
3387
3388 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
3389 return 0;
3390 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003391 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003392 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
Zoe Liu3ac20932017-08-30 16:35:55 -07003393 !!(ref_flags & AOM_BWD_FLAG) + !!(ref_flags & AOM_ALT2_FLAG) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003394 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003395 }
3396}
Zoe Liub05e5d12017-02-07 14:32:53 -08003397#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07003398
Yaowu Xuf883b422016-08-30 14:01:10 -07003399static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003400 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003401 // We will not update the golden frame with an internal overlay frame
3402 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
3403 cpi->rc.is_src_frame_ext_arf)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003404 return ALTREF_FRAME;
Sebastien Alaiwan365e6442017-10-16 11:35:00 +02003405 else if (cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
Zoe Liue9b15e22017-07-19 15:53:01 -07003406 cpi->refresh_alt_ref_frame)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003407 return GOLDEN_FRAME;
3408 else
3409 // TODO(zoeliu): To investigate whether a frame_type other than
3410 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
3411 return LAST_FRAME;
3412}
3413
Thomas Daedef636d5c2017-06-29 13:48:27 -07003414static TX_MODE select_tx_mode(const AV1_COMP *cpi) {
3415 if (cpi->common.all_lossless) return ONLY_4X4;
Nathan E. Eggea33304f2017-06-28 20:48:34 -04003416#if CONFIG_VAR_TX_NO_TX_MODE
3417 return TX_MODE_SELECT;
3418#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003419 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08003420 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003421 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
Debargha Mukherjee51666862017-10-24 14:29:13 -07003422 cpi->sf.tx_size_search_method == USE_FAST_RD)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003423 return TX_MODE_SELECT;
3424 else
3425 return cpi->common.tx_mode;
Nathan E. Eggea33304f2017-06-28 20:48:34 -04003426#endif // CONFIG_VAR_TX_NO_TX_MODE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003427}
3428
Yaowu Xuf883b422016-08-30 14:01:10 -07003429void av1_init_tile_data(AV1_COMP *cpi) {
3430 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 const int tile_cols = cm->tile_cols;
3432 const int tile_rows = cm->tile_rows;
3433 int tile_col, tile_row;
3434 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
3435 unsigned int tile_tok = 0;
3436
3437 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003438 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
Yaowu Xubf6ad902017-04-28 11:03:33 -07003439 CHECK_MEM_ERROR(
3440 cm, cpi->tile_data,
3441 aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003442 cpi->allocated_tiles = tile_cols * tile_rows;
3443
3444 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
3445 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
3446 TileDataEnc *const tile_data =
3447 &cpi->tile_data[tile_row * tile_cols + tile_col];
3448 int i, j;
Rupert Swarbrick93c39e92017-07-12 11:11:02 +01003449 for (i = 0; i < BLOCK_SIZES_ALL; ++i) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450 for (j = 0; j < MAX_MODES; ++j) {
3451 tile_data->thresh_freq_fact[i][j] = 32;
3452 tile_data->mode_map[i][j] = j;
3453 }
3454 }
3455 }
3456 }
3457
3458 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
3459 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
3460 TileInfo *const tile_info =
3461 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07003462 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003463
3464 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
3465 pre_tok = cpi->tile_tok[tile_row][tile_col];
3466 tile_tok = allocated_tokens(*tile_info);
3467 }
3468 }
3469}
3470
Yaowu Xuf883b422016-08-30 14:01:10 -07003471void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
3472 int tile_col) {
3473 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003474 TileDataEnc *const this_tile =
3475 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
3476 const TileInfo *const tile_info = &this_tile->tile_info;
3477 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
3478 int mi_row;
Yushin Choc49ef3a2017-03-13 17:27:25 -07003479
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08003480#if CONFIG_DEPENDENT_HORZTILES
Fangwen Fu73126c02017-02-08 22:37:47 -08003481 if ((!cm->dependent_horz_tiles) || (tile_row == 0) ||
3482 tile_info->tg_horz_boundary) {
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08003483 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
3484 }
3485#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003486 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08003487#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003488
3489 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07003490 this_tile->m_search_count = 0; // Count of motion search hits.
3491 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
3492 td->mb.m_search_count_ptr = &this_tile->m_search_count;
3493 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Thomas Daviesf77d4ad2017-01-10 18:55:42 +00003494 this_tile->tctx = *cm->fc;
3495 td->mb.e_mbd.tile_ctx = &this_tile->tctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003496
Luc Trudeauf8164152017-04-11 16:20:51 -04003497#if CONFIG_CFL
Luc Trudeaubaeb3752017-04-24 11:19:25 -04003498 MACROBLOCKD *const xd = &td->mb.e_mbd;
3499 xd->cfl = &this_tile->cfl;
Luc Trudeaudac5e392017-06-05 15:52:02 -04003500 cfl_init(xd->cfl, cm);
Luc Trudeauf8164152017-04-11 16:20:51 -04003501#endif
3502
Angie Chiang04808932017-08-28 12:06:08 -07003503#if CONFIG_LOOPFILTERING_ACROSS_TILES
David Barkerc1018ad2017-08-29 12:05:02 +01003504 if (!cm->loop_filter_across_tiles_enabled)
3505 av1_setup_across_tile_boundary_info(cm, tile_info);
Angie Chiang04808932017-08-28 12:06:08 -07003506#endif
Yi Luof190a162017-07-13 16:16:56 -07003507
Hui Su1ddf2312017-08-19 15:21:34 -07003508 av1_crc_calculator_init(&td->mb.tx_rd_record.crc_calculator, 24, 0x5D6DCB);
3509
Yaowu Xuc27fc142016-08-22 16:08:15 -07003510 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
3511 mi_row += cm->mib_size) {
3512 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
3513 }
3514
3515 cpi->tok_count[tile_row][tile_col] =
3516 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
3517 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
3518}
3519
Yaowu Xuf883b422016-08-30 14:01:10 -07003520static void encode_tiles(AV1_COMP *cpi) {
3521 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003522 int tile_col, tile_row;
3523
Yaowu Xuf883b422016-08-30 14:01:10 -07003524 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003525
3526 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
3527 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07003528 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529}
3530
3531#if CONFIG_FP_MB_STATS
3532static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07003533 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003534 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
3535 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
3536
3537 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
3538
3539 *this_frame_mb_stats = mb_stats_in;
3540
3541 return 1;
3542}
3543#endif
3544
Debargha Mukherjee5f35e582017-04-25 18:05:18 -07003545#define GLOBAL_TRANS_TYPES_ENC 3 // highest motion model to search
David Barkerd7c8bd52017-09-25 14:47:29 +01003546static int gm_get_params_cost(const WarpedMotionParams *gm,
3547 const WarpedMotionParams *ref_gm, int allow_hp) {
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003548 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
3549 int params_cost = 0;
Sarah Parkerf1783292017-04-05 11:55:27 -07003550 int trans_bits, trans_prec_diff;
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003551 switch (gm->wmtype) {
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003552 case AFFINE:
3553 case ROTZOOM:
Sarah Parkerf1783292017-04-05 11:55:27 -07003554 params_cost += aom_count_signed_primitive_refsubexpfin(
3555 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
3556 (ref_gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
3557 (gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
Debargha Mukherjee1a2b35f2017-10-21 10:41:46 -07003558 params_cost += aom_count_signed_primitive_refsubexpfin(
3559 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
3560 (ref_gm->wmmat[3] >> GM_ALPHA_PREC_DIFF),
3561 (gm->wmmat[3] >> GM_ALPHA_PREC_DIFF));
3562 if (gm->wmtype >= AFFINE) {
Sarah Parkerf1783292017-04-05 11:55:27 -07003563 params_cost += aom_count_signed_primitive_refsubexpfin(
3564 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
Debargha Mukherjee1a2b35f2017-10-21 10:41:46 -07003565 (ref_gm->wmmat[4] >> GM_ALPHA_PREC_DIFF),
3566 (gm->wmmat[4] >> GM_ALPHA_PREC_DIFF));
Sarah Parkerf1783292017-04-05 11:55:27 -07003567 params_cost += aom_count_signed_primitive_refsubexpfin(
3568 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
3569 (ref_gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
3570 (1 << GM_ALPHA_PREC_BITS),
3571 (gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003572 }
3573 // Fallthrough intended
3574 case TRANSLATION:
Sarah Parkerf1783292017-04-05 11:55:27 -07003575 trans_bits = (gm->wmtype == TRANSLATION)
3576 ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
3577 : GM_ABS_TRANS_BITS;
3578 trans_prec_diff = (gm->wmtype == TRANSLATION)
3579 ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
3580 : GM_TRANS_PREC_DIFF;
3581 params_cost += aom_count_signed_primitive_refsubexpfin(
3582 (1 << trans_bits) + 1, SUBEXPFIN_K,
3583 (ref_gm->wmmat[0] >> trans_prec_diff),
3584 (gm->wmmat[0] >> trans_prec_diff));
3585 params_cost += aom_count_signed_primitive_refsubexpfin(
3586 (1 << trans_bits) + 1, SUBEXPFIN_K,
3587 (ref_gm->wmmat[1] >> trans_prec_diff),
3588 (gm->wmmat[1] >> trans_prec_diff));
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003589 // Fallthrough intended
3590 case IDENTITY: break;
3591 default: assert(0);
3592 }
3593 return (params_cost << AV1_PROB_COST_SHIFT);
3594}
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003595
3596static int do_gm_search_logic(SPEED_FEATURES *const sf, int num_refs_using_gm,
3597 int frame) {
3598 (void)num_refs_using_gm;
3599 (void)frame;
3600 switch (sf->gm_search_type) {
3601 case GM_FULL_SEARCH: return 1;
3602 case GM_REDUCED_REF_SEARCH:
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003603 return !(frame == LAST2_FRAME || frame == LAST3_FRAME);
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003604 case GM_DISABLE_SEARCH: return 0;
3605 default: assert(0);
3606 }
3607 return 1;
3608}
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003609
hui sud9a812b2017-07-06 14:34:37 -07003610// Estimate if the source frame is screen content, based on the portion of
3611// blocks that have no more than 4 (experimentally selected) luma colors.
hui su105b72c2017-07-13 10:36:23 -07003612static int is_screen_content(const uint8_t *src,
3613#if CONFIG_HIGHBITDEPTH
3614 int use_hbd, int bd,
3615#endif // CONFIG_HIGHBITDEPTH
3616 int stride, int width, int height) {
hui sud9a812b2017-07-06 14:34:37 -07003617 assert(src != NULL);
3618 int counts = 0;
3619 const int blk_w = 16;
3620 const int blk_h = 16;
3621 const int limit = 4;
3622 for (int r = 0; r + blk_h <= height; r += blk_h) {
3623 for (int c = 0; c + blk_w <= width; c += blk_w) {
3624 const int n_colors =
hui su105b72c2017-07-13 10:36:23 -07003625#if CONFIG_HIGHBITDEPTH
3626 use_hbd ? av1_count_colors_highbd(src + r * stride + c, stride, blk_w,
3627 blk_h, bd)
3628 :
3629#endif // CONFIG_HIGHBITDEPTH
3630 av1_count_colors(src + r * stride + c, stride, blk_w, blk_h);
hui sud9a812b2017-07-06 14:34:37 -07003631 if (n_colors > 1 && n_colors <= limit) counts++;
3632 }
3633 }
3634 // The threshold is 10%.
3635 return counts * blk_h * blk_w * 10 > width * height;
3636}
hui sud9a812b2017-07-06 14:34:37 -07003637
Yaowu Xuf883b422016-08-30 14:01:10 -07003638static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003639 ThreadData *const td = &cpi->td;
3640 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07003641 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003642 MACROBLOCKD *const xd = &x->e_mbd;
3643 RD_COUNTS *const rdc = &cpi->td.rd_counts;
3644 int i;
Zoe Liu453aef62017-04-19 15:35:17 -07003645 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003646
Yi Luof8e87b42017-04-14 17:20:27 -07003647#if CONFIG_ADAPT_SCAN
3648 av1_deliver_eob_threshold(cm, xd);
3649#endif
3650
Yaowu Xuf883b422016-08-30 14:01:10 -07003651 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
3652 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Yushin Cho55104332017-08-14 16:15:43 -07003653#if CONFIG_DIST_8X8
3654 x->using_dist_8x8 = cpi->oxcf.using_dist_8x8;
3655 x->tune_metric = cpi->oxcf.tuning;
3656#endif
Dengca8d24d2016-10-17 14:06:35 +08003657 cm->setup_mi(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658
3659 xd->mi = cm->mi_grid_visible;
3660 xd->mi[0] = cm->mi;
3661
Yaowu Xuf883b422016-08-30 14:01:10 -07003662 av1_zero(*td->counts);
Yaowu Xuf883b422016-08-30 14:01:10 -07003663 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003664
Alex Converse74ad0912017-07-18 10:22:58 -07003665 if (frame_is_intra_only(cm)) {
Alex Converse74ad0912017-07-18 10:22:58 -07003666 cm->allow_screen_content_tools =
3667 cpi->oxcf.content == AOM_CONTENT_SCREEN ||
3668 is_screen_content(cpi->source->y_buffer,
hui su105b72c2017-07-13 10:36:23 -07003669#if CONFIG_HIGHBITDEPTH
Alex Converse74ad0912017-07-18 10:22:58 -07003670 cpi->source->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
hui su105b72c2017-07-13 10:36:23 -07003671#endif // CONFIG_HIGHBITDEPTH
Alex Converse74ad0912017-07-18 10:22:58 -07003672 cpi->source->y_stride, cpi->source->y_width,
3673 cpi->source->y_height);
Alex Converse74ad0912017-07-18 10:22:58 -07003674 }
hui sud9a812b2017-07-06 14:34:37 -07003675
RogerZhoud15e7c12017-09-26 08:49:28 -07003676#if CONFIG_HASH_ME
3677 if (cpi->oxcf.pass != 1 && cpi->common.allow_screen_content_tools) {
3678 // add to hash table
3679 const int pic_width = cpi->source->y_crop_width;
3680 const int pic_height = cpi->source->y_crop_height;
3681 uint32_t *block_hash_values[2][2];
3682 int8_t *is_block_same[2][3];
3683 int k, j;
3684
3685 for (k = 0; k < 2; k++) {
3686 for (j = 0; j < 2; j++) {
3687 CHECK_MEM_ERROR(cm, block_hash_values[k][j],
3688 aom_malloc(sizeof(uint32_t) * pic_width * pic_height));
3689 }
3690
3691 for (j = 0; j < 3; j++) {
3692 CHECK_MEM_ERROR(cm, is_block_same[k][j],
3693 aom_malloc(sizeof(int8_t) * pic_width * pic_height));
3694 }
3695 }
3696
3697 av1_hash_table_create(&cm->cur_frame->hash_table);
3698 av1_generate_block_2x2_hash_value(cpi->source, block_hash_values[0],
3699 is_block_same[0]);
3700 av1_generate_block_hash_value(cpi->source, 4, block_hash_values[0],
3701 block_hash_values[1], is_block_same[0],
3702 is_block_same[1]);
RogerZhouca865462017-10-05 15:06:27 -07003703 av1_add_to_hash_map_by_row_with_precal_data(
3704 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
3705 pic_width, pic_height, 4);
RogerZhoud15e7c12017-09-26 08:49:28 -07003706 av1_generate_block_hash_value(cpi->source, 8, block_hash_values[1],
3707 block_hash_values[0], is_block_same[1],
3708 is_block_same[0]);
3709 av1_add_to_hash_map_by_row_with_precal_data(
3710 &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
3711 pic_width, pic_height, 8);
3712 av1_generate_block_hash_value(cpi->source, 16, block_hash_values[0],
3713 block_hash_values[1], is_block_same[0],
3714 is_block_same[1]);
3715 av1_add_to_hash_map_by_row_with_precal_data(
3716 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
3717 pic_width, pic_height, 16);
3718 av1_generate_block_hash_value(cpi->source, 32, block_hash_values[1],
3719 block_hash_values[0], is_block_same[1],
3720 is_block_same[0]);
3721 av1_add_to_hash_map_by_row_with_precal_data(
3722 &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
3723 pic_width, pic_height, 32);
3724 av1_generate_block_hash_value(cpi->source, 64, block_hash_values[0],
3725 block_hash_values[1], is_block_same[0],
3726 is_block_same[1]);
3727 av1_add_to_hash_map_by_row_with_precal_data(
3728 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
3729 pic_width, pic_height, 64);
3730
3731 for (k = 0; k < 2; k++) {
3732 for (j = 0; j < 2; j++) {
3733 aom_free(block_hash_values[k][j]);
3734 }
3735
3736 for (j = 0; j < 3; j++) {
3737 aom_free(is_block_same[k][j]);
3738 }
3739 }
3740 }
3741#endif
3742
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07003743#if CONFIG_NCOBMC_ADAPT_WEIGHT
3744 alloc_ncobmc_pred_buffer(xd);
3745#endif
3746
Debargha Mukherjeea575d232017-04-28 17:46:47 -07003747 av1_zero(rdc->global_motion_used);
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003748 av1_zero(cpi->gmparams_cost);
Alex Conversef77fd0b2017-04-20 11:00:24 -07003749 if (cpi->common.frame_type == INTER_FRAME && cpi->source &&
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003750 !cpi->global_motion_search_done) {
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003751 YV12_BUFFER_CONFIG *ref_buf[TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752 int frame;
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003753 double params_by_motion[RANSAC_NUM_MOTIONS * (MAX_PARAMDIM - 1)];
3754 const double *params_this_motion;
3755 int inliers_by_motion[RANSAC_NUM_MOTIONS];
3756 WarpedMotionParams tmp_wm_params;
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003757 static const double kIdentityParams[MAX_PARAMDIM - 1] = {
3758 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
3759 };
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003760 int num_refs_using_gm = 0;
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003761
Yaowu Xuc27fc142016-08-22 16:08:15 -07003762 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003763 ref_buf[frame] = get_ref_frame_buffer(cpi, frame);
3764 int pframe;
David Barkerd7c8bd52017-09-25 14:47:29 +01003765 cm->global_motion[frame] = default_warp_params;
3766 const WarpedMotionParams *ref_params =
3767 cm->error_resilient_mode ? &default_warp_params
3768 : &cm->prev_frame->global_motion[frame];
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003769 // check for duplicate buffer
3770 for (pframe = LAST_FRAME; pframe < frame; ++pframe) {
3771 if (ref_buf[frame] == ref_buf[pframe]) break;
3772 }
3773 if (pframe < frame) {
3774 memcpy(&cm->global_motion[frame], &cm->global_motion[pframe],
3775 sizeof(WarpedMotionParams));
3776 } else if (ref_buf[frame] &&
Debargha Mukherjee65e159b2017-07-11 12:03:04 -07003777 ref_buf[frame]->y_crop_width == cpi->source->y_crop_width &&
3778 ref_buf[frame]->y_crop_height == cpi->source->y_crop_height &&
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003779 do_gm_search_logic(&cpi->sf, num_refs_using_gm, frame)) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08003780 TransformationType model;
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003781 const int64_t ref_frame_error = av1_frame_error(
3782#if CONFIG_HIGHBITDEPTH
3783 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
3784#endif // CONFIG_HIGHBITDEPTH
3785 ref_buf[frame]->y_buffer, ref_buf[frame]->y_stride,
Sarah Parker81f6ecd2017-05-26 16:10:11 -07003786 cpi->source->y_buffer, cpi->source->y_width, cpi->source->y_height,
3787 cpi->source->y_stride);
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003788
3789 if (ref_frame_error == 0) continue;
3790
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08003791 aom_clear_system_state();
Debargha Mukherjee5f35e582017-04-25 18:05:18 -07003792 for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES_ENC; ++model) {
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003793 int64_t best_warp_error = INT64_MAX;
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003794 // Initially set all params to identity.
3795 for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
3796 memcpy(params_by_motion + (MAX_PARAMDIM - 1) * i, kIdentityParams,
3797 (MAX_PARAMDIM - 1) * sizeof(*params_by_motion));
3798 }
3799
3800 compute_global_motion_feature_based(
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003801 model, cpi->source, ref_buf[frame],
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003802#if CONFIG_HIGHBITDEPTH
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003803 cpi->common.bit_depth,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003804#endif // CONFIG_HIGHBITDEPTH
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003805 inliers_by_motion, params_by_motion, RANSAC_NUM_MOTIONS);
3806
3807 for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
3808 if (inliers_by_motion[i] == 0) continue;
3809
3810 params_this_motion = params_by_motion + (MAX_PARAMDIM - 1) * i;
3811 convert_model_to_params(params_this_motion, &tmp_wm_params);
3812
3813 if (tmp_wm_params.wmtype != IDENTITY) {
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003814 const int64_t warp_error = refine_integerized_param(
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003815 &tmp_wm_params, tmp_wm_params.wmtype,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003816#if CONFIG_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08003817 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003818#endif // CONFIG_HIGHBITDEPTH
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003819 ref_buf[frame]->y_buffer, ref_buf[frame]->y_width,
3820 ref_buf[frame]->y_height, ref_buf[frame]->y_stride,
3821 cpi->source->y_buffer, cpi->source->y_width,
Sarah Parker3e85f672017-06-15 09:04:32 -07003822 cpi->source->y_height, cpi->source->y_stride, 5,
Sarah Parker81f6ecd2017-05-26 16:10:11 -07003823 best_warp_error);
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003824 if (warp_error < best_warp_error) {
3825 best_warp_error = warp_error;
emilkeyder@google.comf3477632017-03-01 16:29:14 -05003826 // Save the wm_params modified by refine_integerized_param()
3827 // rather than motion index to avoid rerunning refine() below.
3828 memcpy(&(cm->global_motion[frame]), &tmp_wm_params,
3829 sizeof(WarpedMotionParams));
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08003830 }
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08003831 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003832 }
Debargha Mukherjee3b6c5442017-03-30 08:22:00 -07003833 if (cm->global_motion[frame].wmtype <= AFFINE)
3834 if (!get_shear_params(&cm->global_motion[frame]))
David Barkerd7c8bd52017-09-25 14:47:29 +01003835 cm->global_motion[frame] = default_warp_params;
Debargha Mukherjee3b6c5442017-03-30 08:22:00 -07003836
Debargha Mukherjeee832d572017-04-07 14:40:43 -07003837 if (cm->global_motion[frame].wmtype == TRANSLATION) {
3838 cm->global_motion[frame].wmmat[0] =
3839 convert_to_trans_prec(cm->allow_high_precision_mv,
3840 cm->global_motion[frame].wmmat[0]) *
3841 GM_TRANS_ONLY_DECODE_FACTOR;
3842 cm->global_motion[frame].wmmat[1] =
3843 convert_to_trans_prec(cm->allow_high_precision_mv,
3844 cm->global_motion[frame].wmmat[1]) *
3845 GM_TRANS_ONLY_DECODE_FACTOR;
Sarah Parker13d06622017-03-10 17:03:28 -08003846 }
Debargha Mukherjeee832d572017-04-07 14:40:43 -07003847
3848 // If the best error advantage found doesn't meet the threshold for
3849 // this motion type, revert to IDENTITY.
3850 if (!is_enough_erroradvantage(
emilkeyder@google.com6e3557c2017-03-27 10:52:53 -04003851 (double)best_warp_error / ref_frame_error,
David Barkerd7c8bd52017-09-25 14:47:29 +01003852 gm_get_params_cost(&cm->global_motion[frame], ref_params,
Debargha Mukherjeee832d572017-04-07 14:40:43 -07003853 cm->allow_high_precision_mv))) {
David Barkerd7c8bd52017-09-25 14:47:29 +01003854 cm->global_motion[frame] = default_warp_params;
Debargha Mukherjeee832d572017-04-07 14:40:43 -07003855 }
Debargha Mukherjeee832d572017-04-07 14:40:43 -07003856 if (cm->global_motion[frame].wmtype != IDENTITY) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08003858 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003859 }
Debargha Mukherjee2a9d7462017-05-04 17:37:52 -07003860 if (cm->global_motion[frame].wmtype != IDENTITY) num_refs_using_gm++;
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003861 cpi->gmparams_cost[frame] =
David Barkerd7c8bd52017-09-25 14:47:29 +01003862 gm_get_params_cost(&cm->global_motion[frame], ref_params,
Sarah Parkerf1783292017-04-05 11:55:27 -07003863 cm->allow_high_precision_mv) +
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07003864 cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
3865 cpi->gmtype_cost[IDENTITY];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003866 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003867 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003868 }
David Barkercba7da72017-09-14 11:24:27 +01003869 memcpy(cm->cur_frame->global_motion, cm->global_motion,
3870 TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003871
3872 for (i = 0; i < MAX_SEGMENTS; ++i) {
3873 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07003874 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003875 : cm->base_qindex;
3876 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
3877 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
Yue Cheneeacc4c2017-01-17 17:29:17 -08003878 xd->qindex[i] = qindex;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879 }
Thomas Daedef636d5c2017-06-29 13:48:27 -07003880 cm->all_lossless = all_lossless(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003881 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
3882
Thomas Daedef636d5c2017-06-29 13:48:27 -07003883 cm->tx_mode = select_tx_mode(cpi);
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003884
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003885 // Fix delta q resolution for the moment
3886 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
Fangwen Fu6160df22017-04-24 09:45:51 -07003887// Set delta_q_present_flag before it is used for the first time
3888#if CONFIG_EXT_DELTA_Q
Fangwen Fu231fe422017-04-24 17:52:29 -07003889 cm->delta_lf_res = DEFAULT_DELTA_LF_RES;
3890 // update delta_q_present_flag and delta_lf_present_flag based on base_qindex
Fangwen Fu6160df22017-04-24 09:45:51 -07003891 cm->delta_q_present_flag &= cm->base_qindex > 0;
Fangwen Fu231fe422017-04-24 17:52:29 -07003892 cm->delta_lf_present_flag &= cm->base_qindex > 0;
Fangwen Fu6160df22017-04-24 09:45:51 -07003893#else
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003894 cm->delta_q_present_flag =
3895 cpi->oxcf.aq_mode == DELTA_AQ && cm->base_qindex > 0;
Fangwen Fu6160df22017-04-24 09:45:51 -07003896#endif // CONFIG_EXT_DELTA_Q
Arild Fuldseth (arilfuld)54de7d62017-03-20 13:07:11 +01003897
Yaowu Xuf883b422016-08-30 14:01:10 -07003898 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003899
Yaowu Xuf883b422016-08-30 14:01:10 -07003900 av1_initialize_rd_consts(cpi);
3901 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003902 init_encode_frame_mb_context(cpi);
Thomas Daviesf6936102016-09-05 16:51:31 +01003903
Yaowu Xuc27fc142016-08-22 16:08:15 -07003904 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
3905 // show_exisiting_frame=1, nor can it take a frame not used as
3906 // a reference, it is probable that by the time it is being
3907 // referred to, the frame buffer it originally points to may
3908 // already get expired and have been reassigned to the current
3909 // newly coded frame. Hence, we need to check whether this is
3910 // the case, and if yes, we have 2 choices:
3911 // (1) Simply disable the use of previous frame mvs; or
3912 // (2) Have cm->prev_frame point to one reference frame buffer,
3913 // e.g. LAST_FRAME.
David Barker40a42d42017-05-09 15:07:32 +01003914 if (!enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003915 // Reassign the LAST_FRAME buffer to cm->prev_frame.
David Barker40a42d42017-05-09 15:07:32 +01003916 cm->prev_frame = last_fb_buf_idx != INVALID_IDX
3917 ? &cm->buffer_pool->frame_bufs[last_fb_buf_idx]
3918 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919 }
David Barker40a42d42017-05-09 15:07:32 +01003920
3921#if CONFIG_TEMPMV_SIGNALING
Rupert Swarbrick1f990a62017-07-11 11:09:33 +01003922 cm->use_prev_frame_mvs &= frame_can_use_prev_frame_mvs(cm);
David Barker40a42d42017-05-09 15:07:32 +01003923#else
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003924 if (cm->prev_frame) {
3925 cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
3926#if CONFIG_FRAME_SUPERRES
3927 cm->width == cm->last_width &&
3928 cm->height == cm->last_height &&
3929#else
3930 cm->width == cm->prev_frame->buf.y_crop_width &&
3931 cm->height == cm->prev_frame->buf.y_crop_height &&
3932#endif // CONFIG_FRAME_SUPERRES
3933 !cm->intra_only && cm->last_show_frame;
3934 } else {
3935 cm->use_prev_frame_mvs = 0;
3936 }
David Barker40a42d42017-05-09 15:07:32 +01003937#endif // CONFIG_TEMPMV_SIGNALING
Yaowu Xuc27fc142016-08-22 16:08:15 -07003938
3939 // Special case: set prev_mi to NULL when the previous mode info
3940 // context cannot be used.
3941 cm->prev_mi =
3942 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
3943
Jingning Han9777afc2016-10-20 15:17:43 -07003944 x->txb_split_count = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07003945 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003946
Jingning Hanea255c92017-09-29 08:12:09 -07003947#if CONFIG_MFMV
Jingning Hanffbb0f92017-08-24 11:52:21 -07003948 av1_setup_motion_field(cm);
Jingning Hanea255c92017-09-29 08:12:09 -07003949#endif // CONFIG_MFMV
Jingning Hanc723b342017-08-24 11:19:46 -07003950
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951 {
Yaowu Xuf883b422016-08-30 14:01:10 -07003952 struct aom_usec_timer emr_timer;
3953 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954
3955#if CONFIG_FP_MB_STATS
3956 if (cpi->use_fp_mb_stats) {
3957 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
3958 &cpi->twopass.this_frame_mb_stats);
3959 }
3960#endif
3961
Yi Luof190a162017-07-13 16:16:56 -07003962 av1_setup_frame_boundary_info(cm);
3963
Yaowu Xuc27fc142016-08-22 16:08:15 -07003964 // If allowed, encoding tiles in parallel with one thread handling one tile.
3965 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
3966 // 1 tile rows, as it uses the single above_context et al arrays from
3967 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07003968 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
3969 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003970 else
3971 encode_tiles(cpi);
3972
Yaowu Xuf883b422016-08-30 14:01:10 -07003973 aom_usec_timer_mark(&emr_timer);
3974 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 }
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07003976#if CONFIG_NCOBMC_ADAPT_WEIGHT
3977 free_ncobmc_pred_buffer(xd);
3978#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979
3980#if 0
3981 // Keep record of the total distortion this time around for future use
3982 cpi->last_frame_distortion = cpi->frame_distortion;
3983#endif
3984}
3985
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003986static void make_consistent_compound_tools(AV1_COMMON *cm) {
3987 (void)cm;
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003988 if (frame_is_intra_only(cm) || cm->reference_mode == COMPOUND_REFERENCE)
3989 cm->allow_interintra_compound = 0;
Zoe Liu85b66462017-04-20 14:28:19 -07003990#if CONFIG_COMPOUND_SINGLEREF
3991 if (frame_is_intra_only(cm))
3992#else // !CONFIG_COMPOUND_SINGLEREF
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003993 if (frame_is_intra_only(cm) || cm->reference_mode == SINGLE_REFERENCE)
Zoe Liu85b66462017-04-20 14:28:19 -07003994#endif // CONFIG_COMPOUND_SINGLEREF
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003995 cm->allow_masked_compound = 0;
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003996}
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003997
Yaowu Xuf883b422016-08-30 14:01:10 -07003998void av1_encode_frame(AV1_COMP *cpi) {
3999 AV1_COMMON *const cm = &cpi->common;
Sarah Parkere68a3e42017-02-16 14:03:24 -08004000#if CONFIG_EXT_TX
4001 // Indicates whether or not to use a default reduced set for ext-tx
4002 // rather than the potential full set of 16 transforms
4003 cm->reduced_tx_set_used = 0;
4004#endif // CONFIG_EXT_TX
Angie Chiang6dbffbf2017-10-06 16:59:54 -07004005#if CONFIG_ADAPT_SCAN
4006 cm->use_adapt_scan = 1;
4007 // TODO(angiebird): call av1_init_scan_order only when use_adapt_scan
4008 // switches from 1 to 0
4009 if (cm->use_adapt_scan == 0) av1_init_scan_order(cm);
4010#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004011
Zoe Liu17af2742017-10-06 10:36:42 -07004012#if CONFIG_FRAME_MARKER
4013 if (cm->show_frame == 0) {
4014 int arf_offset = AOMMIN(
4015 (MAX_GF_INTERVAL - 1),
4016 cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
Zoe Liu17af2742017-10-06 10:36:42 -07004017 int brf_offset =
4018 cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
4019 arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
Zoe Liu17af2742017-10-06 10:36:42 -07004020 cm->frame_offset = cm->current_video_frame + arf_offset;
4021 } else {
4022 cm->frame_offset = cm->current_video_frame;
4023 }
4024 av1_setup_frame_buf_refs(cm);
4025#if CONFIG_FRAME_SIGN_BIAS
4026 av1_setup_frame_sign_bias(cm);
4027#endif // CONFIG_FRAME_SIGN_BIAS
4028#endif // CONFIG_FRAME_MARKER
4029
Yaowu Xuc27fc142016-08-22 16:08:15 -07004030 // In the longer term the encoder should be generalized to match the
4031 // decoder such that we allow compound where one of the 3 buffers has a
4032 // different sign bias and that buffer is then the fixed ref. However, this
4033 // requires further work in the rd loop. For now the only supported encoder
4034 // side behavior is where the ALT ref buffer has opposite sign bias to
4035 // the other two.
4036 if (!frame_is_intra_only(cm)) {
Zoe Liu5a978832017-08-15 16:33:34 -07004037#if !CONFIG_ONE_SIDED_COMPOUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07004038 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4039 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4040 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4041 cm->ref_frame_sign_bias[LAST_FRAME])) {
4042 cpi->allow_comp_inter_inter = 0;
4043 } else {
Zoe Liu5a978832017-08-15 16:33:34 -07004044#endif // !CONFIG_ONE_SIDED_COMPOUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045 cpi->allow_comp_inter_inter = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 cm->comp_fwd_ref[0] = LAST_FRAME;
4047 cm->comp_fwd_ref[1] = LAST2_FRAME;
4048 cm->comp_fwd_ref[2] = LAST3_FRAME;
4049 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4050 cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liue9b15e22017-07-19 15:53:01 -07004051 cm->comp_bwd_ref[1] = ALTREF2_FRAME;
4052 cm->comp_bwd_ref[2] = ALTREF_FRAME;
Zoe Liu5a978832017-08-15 16:33:34 -07004053#if !CONFIG_ONE_SIDED_COMPOUND // Normative in encoder
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 }
Zoe Liu5a978832017-08-15 16:33:34 -07004055#endif // !CONFIG_ONE_SIDED_COMPOUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07004056 } else {
4057 cpi->allow_comp_inter_inter = 0;
4058 }
4059
4060 if (cpi->sf.frame_parameter_update) {
4061 int i;
4062 RD_OPT *const rd_opt = &cpi->rd;
4063 FRAME_COUNTS *counts = cpi->td.counts;
4064 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4065
4066 // This code does a single RD pass over the whole frame assuming
4067 // either compound, single or hybrid prediction as per whatever has
4068 // worked best for that type of frame in the past.
4069 // It also predicts whether another coding mode would have worked
4070 // better than this coding mode. If that is the case, it remembers
4071 // that for subsequent frames.
4072 // It does the same analysis for transform size selection also.
4073 //
4074 // TODO(zoeliu): To investigate whether a frame_type other than
4075 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4076 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4077 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4078 const int is_alt_ref = frame_type == ALTREF_FRAME;
4079
Zoe Liub05e5d12017-02-07 14:32:53 -08004080/* prediction (compound, single or hybrid) mode selection */
4081#if CONFIG_REF_ADAPT
4082 // NOTE(zoeliu): "is_alt_ref" is true only for OVERLAY/INTNL_OVERLAY frames
4083 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4084 cm->reference_mode = SINGLE_REFERENCE;
4085 else
4086 cm->reference_mode = REFERENCE_MODE_SELECT;
4087#else
Todd Nguyen8493f912017-07-20 12:45:12 -07004088#if CONFIG_BGSPRITE
4089 (void)is_alt_ref;
4090 if (!cpi->allow_comp_inter_inter)
4091#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092 if (is_alt_ref || !cpi->allow_comp_inter_inter)
Todd Nguyen8493f912017-07-20 12:45:12 -07004093#endif // CONFIG_BGSPRITE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004094 cm->reference_mode = SINGLE_REFERENCE;
Cheng Chen0a7f2f52017-10-10 15:16:09 -07004095#if !CONFIG_JNT_COMP
Yaowu Xuc27fc142016-08-22 16:08:15 -07004096 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4097 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4098 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4099 cm->reference_mode = COMPOUND_REFERENCE;
4100 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4101 cm->reference_mode = SINGLE_REFERENCE;
Cheng Chen0a7f2f52017-10-10 15:16:09 -07004102#endif // CONFIG_JNT_COMP
Yaowu Xuc27fc142016-08-22 16:08:15 -07004103 else
4104 cm->reference_mode = REFERENCE_MODE_SELECT;
Zoe Liub05e5d12017-02-07 14:32:53 -08004105#endif // CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07004106
4107#if CONFIG_DUAL_FILTER
4108 cm->interp_filter = SWITCHABLE;
4109#endif
4110
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07004111 make_consistent_compound_tools(cm);
Arild Fuldseth (arilfuld)6c20c782017-06-15 09:45:02 +02004112
4113 rdc->single_ref_used_flag = 0;
4114 rdc->compound_ref_used_flag = 0;
4115
Yaowu Xuc27fc142016-08-22 16:08:15 -07004116 encode_frame_internal(cpi);
4117
4118 for (i = 0; i < REFERENCE_MODES; ++i)
4119 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4120
4121 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Arild Fuldseth (arilfuld)6c20c782017-06-15 09:45:02 +02004122 // Use a flag that includes 4x4 blocks
4123 if (rdc->compound_ref_used_flag == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004124 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004125 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08004126#if !CONFIG_REF_ADAPT
Arild Fuldseth (arilfuld)6c20c782017-06-15 09:45:02 +02004127 // Use a flag that includes 4x4 blocks
4128 } else if (rdc->single_ref_used_flag == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004129 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004130 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08004131#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07004132 }
4133 }
Debargha Mukherjee4374e432017-05-26 16:57:37 -07004134 make_consistent_compound_tools(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004135
Yue Chend6bdd462017-07-19 16:05:43 -07004136#if CONFIG_RECT_TX_EXT
4137 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0 &&
4138 counts->quarter_tx_size[1] == 0)
4139#else
Jingning Han9777afc2016-10-20 15:17:43 -07004140 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Yue Chend6bdd462017-07-19 16:05:43 -07004141#endif
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004142 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004143 } else {
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07004144 make_consistent_compound_tools(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004145 encode_frame_internal(cpi);
4146 }
4147}
4148
Jingning Hand3a64432017-04-06 17:04:17 -07004149static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
4150 const MODE_INFO *mi, const MODE_INFO *above_mi,
4151 const MODE_INFO *left_mi, const int intraonly,
4152 const int mi_row, const int mi_col) {
Yue Chena4245512017-08-31 11:58:08 -07004153 FRAME_CONTEXT *fc = xd->tile_ctx;
hui su4d668d72017-04-27 12:10:37 -07004154 const MB_MODE_INFO *const mbmi = &mi->mbmi;
4155 const PREDICTION_MODE y_mode = mbmi->mode;
Luc Trudeaud6d9eee2017-07-12 12:36:50 -04004156 const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
Nathan E. Egge5bb3a742017-06-30 12:47:43 -04004157 (void)counts;
hui su4d668d72017-04-27 12:10:37 -07004158 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004159
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004160 if (intraonly) {
Yue Chena4245512017-08-31 11:58:08 -07004161#if CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004162 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
4163 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
4164 ++counts->kf_y_mode[above][left][y_mode];
Yue Chena4245512017-08-31 11:58:08 -07004165#endif // CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004166 update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, 0), y_mode,
4167 INTRA_MODES);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168 } else {
Yue Chena4245512017-08-31 11:58:08 -07004169#if CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004170 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
James Zern01a9d702017-08-25 19:09:33 +00004171#endif // CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004172 update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
4173 }
Yue Chena4245512017-08-31 11:58:08 -07004174
hui su4d668d72017-04-27 12:10:37 -07004175#if CONFIG_FILTER_INTRA
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004176 if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0) {
4177 const int use_filter_intra_mode =
4178 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
4179 ++counts->filter_intra[0][use_filter_intra_mode];
Yue Chen57b8ff62017-10-10 23:37:31 -07004180#if CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004181 ++counts->filter_intra_mode[0][mbmi->filter_intra_mode_info
4182 .filter_intra_mode[0]];
Yue Chen57b8ff62017-10-10 23:37:31 -07004183#endif // CONFIG_ENTROPY_STATS
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004184 update_cdf(fc->filter_intra_mode_cdf[0],
4185 mbmi->filter_intra_mode_info.filter_intra_mode[0],
4186 FILTER_INTRA_MODES);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004187 }
Debargha Mukherjeeedced252017-10-20 00:02:00 -07004188#endif // CONFIG_FILTER_INTRA
Joe Young3ca43bf2017-10-06 15:12:46 -07004189#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
4190 if (av1_is_directional_mode(mbmi->mode, bsize) &&
4191 av1_use_angle_delta(bsize)) {
4192#if CONFIG_ENTROPY_STATS
4193 ++counts->angle_delta[mbmi->mode - V_PRED]
4194 [mbmi->angle_delta[0] + MAX_ANGLE_DELTA];
4195#endif
4196 update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
4197 mbmi->angle_delta[0] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
4198 }
4199#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
Yaowu Xuc27fc142016-08-22 16:08:15 -07004200
Jingning Hand3a64432017-04-06 17:04:17 -07004201 if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
4202 xd->plane[1].subsampling_y))
4203 return;
Joe Young3ca43bf2017-10-06 15:12:46 -07004204#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
4205 if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
4206 av1_use_angle_delta(bsize)) {
4207#if CONFIG_ENTROPY_STATS
4208 ++counts->angle_delta[mbmi->uv_mode - V_PRED]
4209 [mbmi->angle_delta[1] + MAX_ANGLE_DELTA];
4210#endif
4211 update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
4212 mbmi->angle_delta[1] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
4213 }
4214#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
Nathan E. Egge6bdc40f2017-06-18 19:02:23 -04004215#if CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004216 ++counts->uv_mode[y_mode][uv_mode];
Nathan E. Egge6bdc40f2017-06-18 19:02:23 -04004217#endif // CONFIG_ENTROPY_STATS
Hui Su814f41e2017-10-02 12:21:24 -07004218 update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004219}
4220
Yue Chendab2ca92017-10-16 17:48:48 -07004221#if CONFIG_NEW_MULTISYMBOL
4222// TODO(anybody) We can add stats accumulation here to train entropy models for
4223// palette modes
4224static void update_palette_cdf(MACROBLOCKD *xd, const MODE_INFO *mi) {
4225 FRAME_CONTEXT *fc = xd->tile_ctx;
4226 const MB_MODE_INFO *const mbmi = &mi->mbmi;
4227 const MODE_INFO *const above_mi = xd->above_mi;
4228 const MODE_INFO *const left_mi = xd->left_mi;
4229 const BLOCK_SIZE bsize = mbmi->sb_type;
4230 const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
4231
4232 assert(bsize >= BLOCK_8X8 && bsize <= BLOCK_LARGEST);
4233 const int block_palette_idx = bsize - BLOCK_8X8;
4234
4235 if (mbmi->mode == DC_PRED) {
4236 const int n = pmi->palette_size[0];
4237 int palette_y_mode_ctx = 0;
4238 if (above_mi) {
4239 palette_y_mode_ctx +=
4240 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
4241 }
4242 if (left_mi) {
4243 palette_y_mode_ctx +=
4244 (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
4245 }
4246 update_cdf(fc->palette_y_mode_cdf[block_palette_idx][palette_y_mode_ctx],
4247 n > 0, 2);
4248 }
4249
4250 if (mbmi->uv_mode == UV_DC_PRED) {
4251 const int n = pmi->palette_size[1];
4252 const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0);
4253 update_cdf(fc->palette_uv_mode_cdf[palette_uv_mode_ctx], n > 0, 2);
4254 }
4255}
4256#endif
4257
Jingning Han9777afc2016-10-20 15:17:43 -07004258static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07004259 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07004260 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004261 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4262 const int tx_row = blk_row >> 1;
4263 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07004264 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
4265 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Jingning Han331662e2017-05-30 17:03:32 -07004266 int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
4267 xd->left_txfm_context + blk_row,
Jingning Hanc8b89362016-11-01 10:28:53 -07004268 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004269 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
4270
Yaowu Xuc27fc142016-08-22 16:08:15 -07004271 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
David Barker16c64e32017-08-23 16:54:59 +01004272 assert(tx_size > TX_4X4);
4273
4274 if (depth == MAX_VARTX_DEPTH) {
4275// Don't add to counts in this case
4276#if CONFIG_RECT_TX_EXT
4277 if (tx_size == plane_tx_size)
4278#endif
4279 mbmi->tx_size = tx_size;
4280 txfm_partition_update(xd->above_txfm_context + blk_col,
4281 xd->left_txfm_context + blk_row, tx_size, tx_size);
4282 return;
4283 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004284
Yue Chend6bdd462017-07-19 16:05:43 -07004285#if CONFIG_RECT_TX_EXT
4286 if (tx_size == plane_tx_size ||
Cheng Chen50b0f6c2017-08-03 12:25:03 -07004287 mbmi->tx_size == quarter_txsize_lookup[mbmi->sb_type])
Yue Chend6bdd462017-07-19 16:05:43 -07004288#else
Cheng Chen50b0f6c2017-08-03 12:25:03 -07004289 if (tx_size == plane_tx_size)
Yue Chend6bdd462017-07-19 16:05:43 -07004290#endif
Cheng Chen50b0f6c2017-08-03 12:25:03 -07004291 {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004292 ++counts->txfm_partition[ctx][0];
Yue Chen171c17d2017-10-16 18:08:22 -07004293#if CONFIG_NEW_MULTISYMBOL
4294 update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 0, 2);
4295#endif
Yue Chend6bdd462017-07-19 16:05:43 -07004296#if CONFIG_RECT_TX_EXT
4297 if (tx_size == plane_tx_size)
4298#endif
4299 mbmi->tx_size = tx_size;
Jingning Han331662e2017-05-30 17:03:32 -07004300 txfm_partition_update(xd->above_txfm_context + blk_col,
4301 xd->left_txfm_context + blk_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004302 } else {
Jingning Hana9336322016-11-02 15:45:07 -07004303 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4304 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004305 int i;
Jingning Hana9336322016-11-02 15:45:07 -07004306
Yaowu Xuc27fc142016-08-22 16:08:15 -07004307 ++counts->txfm_partition[ctx][1];
Yue Chen171c17d2017-10-16 18:08:22 -07004308#if CONFIG_NEW_MULTISYMBOL
4309 update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 1, 2);
4310#endif
Jingning Han9777afc2016-10-20 15:17:43 -07004311 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004312
David Barker16c64e32017-08-23 16:54:59 +01004313 if (sub_txs == TX_4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004314 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
4315 mbmi->tx_size = TX_4X4;
Jingning Han331662e2017-05-30 17:03:32 -07004316 txfm_partition_update(xd->above_txfm_context + blk_col,
4317 xd->left_txfm_context + blk_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004318 return;
4319 }
4320
4321 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07004322 int offsetr = (i >> 1) * bs;
4323 int offsetc = (i & 0x01) * bs;
4324 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
4325 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004326 }
4327 }
4328}
4329
Jingning Han9777afc2016-10-20 15:17:43 -07004330static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
4331 BLOCK_SIZE plane_bsize, int mi_row,
4332 int mi_col, FRAME_COUNTS *td_counts) {
4333 MACROBLOCKD *xd = &x->e_mbd;
Jingning Han9ca05b72017-01-03 14:41:36 -08004334 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4335 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Rupert Swarbrick4e7b7d62017-09-28 17:30:44 +01004336 TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
Jingning Hana9336322016-11-02 15:45:07 -07004337 const int bh = tx_size_high_unit[max_tx_size];
4338 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004339 int idx, idy;
Sarah Parkerd25ef8c2017-10-06 12:17:30 -07004340 int init_depth =
4341 (mi_height != mi_width) ? RECT_VARTX_DEPTH_INIT : SQR_VARTX_DEPTH_INIT;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004342
Jingning Han331662e2017-05-30 17:03:32 -07004343 xd->above_txfm_context =
4344 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
4345 xd->left_txfm_context = xd->left_txfm_context_buffer +
4346 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004347
4348 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07004349 for (idx = 0; idx < mi_width; idx += bw)
Sarah Parkerd25ef8c2017-10-06 12:17:30 -07004350 update_txfm_count(x, xd, td_counts, max_tx_size, init_depth, idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351}
4352
4353static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
4354 int blk_col) {
4355 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4356 const int tx_row = blk_row >> 1;
4357 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07004358 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
4359 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004360 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
4361
Yaowu Xuc27fc142016-08-22 16:08:15 -07004362 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4363
4364 if (tx_size == plane_tx_size) {
4365 mbmi->tx_size = tx_size;
Jingning Han331662e2017-05-30 17:03:32 -07004366 txfm_partition_update(xd->above_txfm_context + blk_col,
4367 xd->left_txfm_context + blk_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004368
4369 } else {
Jingning Hana9336322016-11-02 15:45:07 -07004370 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4371 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004372 int i;
4373
4374 if (tx_size == TX_8X8) {
4375 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
4376 mbmi->tx_size = TX_4X4;
Jingning Han331662e2017-05-30 17:03:32 -07004377 txfm_partition_update(xd->above_txfm_context + blk_col,
4378 xd->left_txfm_context + blk_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 return;
4380 }
4381
4382 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004383 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07004384 int offsetr = (i >> 1) * bsl;
4385 int offsetc = (i & 0x01) * bsl;
4386 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004387 }
4388 }
4389}
4390
Urvang Joshi52648442016-10-13 17:27:51 -07004391static void tx_partition_set_contexts(const AV1_COMMON *const cm,
4392 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
4393 int mi_row, int mi_col) {
Jingning Han9ca05b72017-01-03 14:41:36 -08004394 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4395 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Rupert Swarbrick4e7b7d62017-09-28 17:30:44 +01004396 TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
Jingning Hana9336322016-11-02 15:45:07 -07004397 const int bh = tx_size_high_unit[max_tx_size];
4398 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004399 int idx, idy;
4400
Jingning Han331662e2017-05-30 17:03:32 -07004401 xd->above_txfm_context =
4402 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
4403 xd->left_txfm_context = xd->left_txfm_context_buffer +
4404 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004405
4406 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07004407 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004408 set_txfm_context(xd, max_tx_size, idy, idx);
4409}
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410
Angie Chiangb14b73f2017-04-13 16:26:00 -07004411void av1_update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
Angie Chiangcd9b03f2017-04-16 13:37:13 -07004412#if CONFIG_TXK_SEL
Jingning Han7eab9ff2017-07-06 10:12:54 -07004413 int blk_row, int blk_col, int block, int plane,
Angie Chiangb14b73f2017-04-13 16:26:00 -07004414#endif
4415 BLOCK_SIZE bsize, TX_SIZE tx_size,
4416 FRAME_COUNTS *counts) {
4417 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4418 int is_inter = is_inter_block(mbmi);
Yue Chena4245512017-08-31 11:58:08 -07004419 FRAME_CONTEXT *fc = xd->tile_ctx;
Hui Su98b0b3e2017-09-19 13:54:02 -07004420#if !CONFIG_ENTROPY_STATS
4421 (void)counts;
4422#endif // !CONFIG_ENTROPY_STATS
Jingning Han243b66b2017-06-23 12:11:47 -07004423
Angie Chiangcd9b03f2017-04-16 13:37:13 -07004424#if !CONFIG_TXK_SEL
Angie Chiangb14b73f2017-04-13 16:26:00 -07004425 TX_TYPE tx_type = mbmi->tx_type;
4426#else
Jingning Han7eab9ff2017-07-06 10:12:54 -07004427 (void)blk_row;
4428 (void)blk_col;
Angie Chiang39b06eb2017-04-14 09:52:29 -07004429 // Only y plane's tx_type is updated
4430 if (plane > 0) return;
Jingning Han19b5c8f2017-07-06 15:10:12 -07004431 TX_TYPE tx_type =
4432 av1_get_tx_type(PLANE_TYPE_Y, xd, blk_row, blk_col, block, tx_size);
Angie Chiangb14b73f2017-04-13 16:26:00 -07004433#endif
4434#if CONFIG_EXT_TX
4435 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
4436 cm->base_qindex > 0 && !mbmi->skip &&
4437 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
4438 const int eset =
4439 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
4440 if (eset > 0) {
Lester Lu432012f2017-08-17 14:39:29 -07004441#if !CONFIG_LGT_FROM_PRED
Hui Suddbcde22017-09-18 17:22:02 -07004442 const TxSetType tx_set_type = get_ext_tx_set_type(
4443 tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Angie Chiangb14b73f2017-04-13 16:26:00 -07004444 if (is_inter) {
Yue Chena4245512017-08-31 11:58:08 -07004445 update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
Hui Suddbcde22017-09-18 17:22:02 -07004446 av1_ext_tx_ind[tx_set_type][tx_type],
4447 av1_num_ext_tx_set[tx_set_type]);
Hui Su98b0b3e2017-09-19 13:54:02 -07004448#if CONFIG_ENTROPY_STATS
Angie Chiangb14b73f2017-04-13 16:26:00 -07004449 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
Hui Su98b0b3e2017-09-19 13:54:02 -07004450#endif // CONFIG_ENTROPY_STATS
Angie Chiangb14b73f2017-04-13 16:26:00 -07004451 } else {
Yue Chen57b8ff62017-10-10 23:37:31 -07004452#if CONFIG_FILTER_INTRA
4453 PREDICTION_MODE intra_dir;
4454 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0])
4455 intra_dir = fimode_to_intradir[mbmi->filter_intra_mode_info
4456 .filter_intra_mode[0]];
4457 else
4458 intra_dir = mbmi->mode;
4459#if CONFIG_ENTROPY_STATS
4460 ++counts
4461 ->intra_ext_tx[eset][txsize_sqr_map[tx_size]][intra_dir][tx_type];
4462#endif // CONFIG_ENTROPY_STATS
4463 update_cdf(
4464 fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][intra_dir],
4465 av1_ext_tx_ind[tx_set_type][tx_type],
4466 av1_num_ext_tx_set[tx_set_type]);
4467#else
Hui Su98b0b3e2017-09-19 13:54:02 -07004468#if CONFIG_ENTROPY_STATS
Angie Chiangb14b73f2017-04-13 16:26:00 -07004469 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
4470 [tx_type];
Hui Su98b0b3e2017-09-19 13:54:02 -07004471#endif // CONFIG_ENTROPY_STATS
Yue Chena4245512017-08-31 11:58:08 -07004472 update_cdf(
4473 fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][mbmi->mode],
Hui Suddbcde22017-09-18 17:22:02 -07004474 av1_ext_tx_ind[tx_set_type][tx_type],
4475 av1_num_ext_tx_set[tx_set_type]);
Yue Chen57b8ff62017-10-10 23:37:31 -07004476#endif
Angie Chiangb14b73f2017-04-13 16:26:00 -07004477 }
Lester Lu432012f2017-08-17 14:39:29 -07004478#else
4479 (void)tx_type;
4480 (void)fc;
4481 if (is_inter) {
4482 if (LGT_FROM_PRED_INTER) {
4483 if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
4484 ++counts->inter_lgt[txsize_sqr_map[tx_size]][mbmi->use_lgt];
4485#if CONFIG_ENTROPY_STATS
4486 if (!mbmi->use_lgt)
4487 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
4488 else
4489#endif // CONFIG_ENTROPY_STATS
4490 mbmi->tx_type = DCT_DCT;
4491 } else {
4492#if CONFIG_ENTROPY_STATS
4493 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
4494#endif // CONFIG_ENTROPY_STATS
4495 }
4496 } else {
4497 if (LGT_FROM_PRED_INTRA) {
4498 if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
4499 ++counts->intra_lgt[txsize_sqr_map[tx_size]][mbmi->mode]
4500 [mbmi->use_lgt];
4501#if CONFIG_ENTROPY_STATS
4502 if (!mbmi->use_lgt)
4503 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
4504 [tx_type];
4505 else
4506#endif // CONFIG_ENTROPY_STATS
4507 mbmi->tx_type = DCT_DCT;
4508 } else {
4509#if CONFIG_ENTROPY_STATS
4510 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
4511 [tx_type];
4512#endif // CONFIG_ENTROPY_STATS
4513 }
4514 }
4515#endif // CONFIG_LGT_FROM_PRED
Angie Chiangb14b73f2017-04-13 16:26:00 -07004516 }
4517 }
4518#else
4519 (void)bsize;
4520 if (tx_size < TX_32X32 &&
4521 ((!cm->seg.enabled && cm->base_qindex > 0) ||
4522 (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
4523 !mbmi->skip &&
4524 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
4525 if (is_inter) {
Hui Su98b0b3e2017-09-19 13:54:02 -07004526#if CONFIG_ENTROPY_STATS
Angie Chiangb14b73f2017-04-13 16:26:00 -07004527 ++counts->inter_ext_tx[tx_size][tx_type];
Hui Su98b0b3e2017-09-19 13:54:02 -07004528#endif // CONFIG_ENTROPY_STATS
Yue Chena4245512017-08-31 11:58:08 -07004529 update_cdf(fc->inter_ext_tx_cdf[tx_size], av1_ext_tx_ind[tx_type],
4530 TX_TYPES);
Angie Chiangb14b73f2017-04-13 16:26:00 -07004531 } else {
Hui Su98b0b3e2017-09-19 13:54:02 -07004532#if CONFIG_ENTROPY_STATS
Angie Chiangb14b73f2017-04-13 16:26:00 -07004533 ++counts->intra_ext_tx[tx_size][intra_mode_to_tx_type_context[mbmi->mode]]
4534 [tx_type];
Hui Su98b0b3e2017-09-19 13:54:02 -07004535#endif // CONFIG_ENTROPY_STATS
Yue Chena4245512017-08-31 11:58:08 -07004536 update_cdf(
4537 fc->intra_ext_tx_cdf[tx_size]
4538 [intra_mode_to_tx_type_context[mbmi->mode]],
4539 av1_ext_tx_ind[tx_type], TX_TYPES);
Angie Chiangb14b73f2017-04-13 16:26:00 -07004540 }
4541 }
4542#endif // CONFIG_EXT_TX
4543}
4544
Urvang Joshi52648442016-10-13 17:27:51 -07004545static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
4546 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
Yushin Cho6d72a2f2017-05-03 17:37:37 -07004547 int mi_col, BLOCK_SIZE bsize, int *rate) {
Urvang Joshi52648442016-10-13 17:27:51 -07004548 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004549 MACROBLOCK *const x = &td->mb;
4550 MACROBLOCKD *const xd = &x->e_mbd;
4551 MODE_INFO **mi_8x8 = xd->mi;
4552 MODE_INFO *mi = mi_8x8[0];
4553 MB_MODE_INFO *mbmi = &mi->mbmi;
4554 const int seg_skip =
4555 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
4556 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08004557 const int mi_width = mi_size_wide[bsize];
4558 const int mi_height = mi_size_high[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08004559 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004560 const BLOCK_SIZE block_size = bsize;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004561
Jingning Han94ea1aa2016-11-08 12:10:46 -08004562 if (!is_inter) {
Luc Trudeau32306c22017-08-14 14:44:26 -04004563#if CONFIG_CFL
Luc Trudeaub05eeae2017-08-18 15:14:30 -04004564 xd->cfl->store_y = 1;
Luc Trudeau32306c22017-08-14 14:44:26 -04004565#endif // CONFIG_CFL
Yaowu Xuc27fc142016-08-22 16:08:15 -07004566 int plane;
4567 mbmi->skip = 1;
hui su4d668d72017-04-27 12:10:37 -07004568 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
Jingning Han18c53c82017-02-17 14:49:57 -08004569 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
4570 mi_row, mi_col);
hui su4d668d72017-04-27 12:10:37 -07004571 }
Luc Trudeau32306c22017-08-14 14:44:26 -04004572#if CONFIG_CFL
Luc Trudeaufcca37a2017-08-14 15:05:07 -04004573 xd->cfl->store_y = 0;
Luc Trudeau32306c22017-08-14 14:44:26 -04004574#endif // CONFIG_CFL
hui su4d668d72017-04-27 12:10:37 -07004575 if (!dry_run) {
Jingning Hand3a64432017-04-06 17:04:17 -07004576 sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
Jingning Han36fe3202017-02-20 22:31:49 -08004577 frame_is_intra_only(cm), mi_row, mi_col);
Yue Chendab2ca92017-10-16 17:48:48 -07004578#if CONFIG_NEW_MULTISYMBOL
4579 if (av1_allow_palette(cm->allow_screen_content_tools, bsize))
4580 update_palette_cdf(xd, mi);
4581#endif
hui su5db97432016-10-14 16:10:14 -07004582 }
Yushin Choa8810392017-09-06 15:16:14 -07004583
Sarah Parker9c0e4512017-08-15 16:23:53 -07004584 if (bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004585 for (plane = 0; plane <= 1; ++plane) {
Sarah Parker9c0e4512017-08-15 16:23:53 -07004586 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
4587 if (!dry_run)
Sarah Parker99e7daa2017-08-29 10:30:13 -07004588 av1_tokenize_color_map(x, plane, 0, t, bsize, mbmi->tx_size,
4589 PALETTE_MAP);
Sarah Parker9c0e4512017-08-15 16:23:53 -07004590 else if (dry_run == DRY_RUN_COSTCOEFFS)
Sarah Parker99e7daa2017-08-29 10:30:13 -07004591 rate += av1_cost_color_map(x, plane, 0, bsize, mbmi->tx_size,
4592 PALETTE_MAP);
Sarah Parker9c0e4512017-08-15 16:23:53 -07004593 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004594 }
4595 }
Yushin Choa8810392017-09-06 15:16:14 -07004596
Jingning Hane67b38a2016-11-04 10:30:00 -07004597 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Angie Chiang0397eda2017-03-15 16:57:14 -07004598#if CONFIG_LV_MAP
4599 av1_update_txb_context(cpi, td, dry_run, block_size, rate, mi_row, mi_col);
4600#else // CONFIG_LV_MAP
Jingning Han18c53c82017-02-17 14:49:57 -08004601 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
Angie Chiang0397eda2017-03-15 16:57:14 -07004602#endif // CONFIG_LV_MAP
Yaowu Xuc27fc142016-08-22 16:08:15 -07004603 } else {
4604 int ref;
4605 const int is_compound = has_second_ref(mbmi);
4606
4607 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
4608 for (ref = 0; ref < 1 + is_compound; ++ref) {
4609 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Alex Converse28744302017-04-13 14:46:22 -07004610#if CONFIG_INTRABC
4611 assert(IMPLIES(!is_intrabc_block(mbmi), cfg));
4612#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004613 assert(cfg != NULL);
Alex Converse28744302017-04-13 14:46:22 -07004614#endif // !CONFIG_INTRABC
Yaowu Xuf883b422016-08-30 14:01:10 -07004615 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
4616 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004617 }
Sebastien Alaiwan0bdea0d2017-10-02 15:15:05 +02004618#if CONFIG_COMPOUND_SINGLEREF
Zoe Liu85b66462017-04-20 14:28:19 -07004619 // Single ref compound mode
4620 if (!is_compound && is_inter_singleref_comp_mode(mbmi->mode)) {
4621 xd->block_refs[1] = xd->block_refs[0];
4622 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[0]);
4623#if CONFIG_INTRABC
4624 assert(IMPLIES(!is_intrabc_block(mbmi), cfg));
4625#else
4626 assert(cfg != NULL);
4627#endif // !CONFIG_INTRABC
4628 av1_setup_pre_planes(xd, 1, cfg, mi_row, mi_col, &xd->block_refs[1]->sf);
4629 }
Sebastien Alaiwan0bdea0d2017-10-02 15:15:05 +02004630#endif // CONFIG_COMPOUND_SINGLEREF
Yue Chen69f18e12016-09-08 14:48:15 -07004631
Urvang Joshi686d4fd2017-07-13 11:36:40 -07004632 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, block_size);
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07004633
4634#if !CONFIG_NCOBMC_ADAPT_WEIGHT
Yue Chencb60b182016-10-13 15:18:22 -07004635 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chenf27b1602017-01-13 11:11:43 -08004636#if CONFIG_NCOBMC
4637 if (dry_run == OUTPUT_ENABLED)
4638 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
4639 else
4640#endif
4641 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004642 }
Wei-Ting Lin01d4d8f2017-08-03 17:04:12 -07004643#else
4644 if (mbmi->motion_mode == OBMC_CAUSAL) {
4645 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
4646 } else if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT &&
4647 dry_run == OUTPUT_ENABLED) {
4648 int p;
4649 for (p = 0; p < MAX_MB_PLANE; ++p) {
4650 get_pred_from_intrpl_buf(xd, mi_row, mi_col, block_size, p);
4651 }
4652 }
4653#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004654
Jingning Han18c53c82017-02-17 14:49:57 -08004655 av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
Jingning Hane67b38a2016-11-04 10:30:00 -07004656 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Han9ca05b72017-01-03 14:41:36 -08004657 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size,
4658 rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004659 }
4660
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07004661#if CONFIG_DIST_8X8
Yushin Cho55104332017-08-14 16:15:43 -07004662 if (x->using_dist_8x8 && bsize < BLOCK_8X8) {
Yushin Chob7b60c52017-07-14 16:18:52 -07004663 dist_8x8_set_sub8x8_dst(x, (uint8_t *)x->decoded_8x8, bsize,
4664 block_size_wide[bsize], block_size_high[bsize],
4665 mi_row, mi_col);
Yushin Cho63927c42017-05-23 15:41:05 -07004666 }
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07004667#endif // CONFIG_DIST_8X8
Yushin Cho63927c42017-05-23 15:41:05 -07004668
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004669 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07004670 TX_SIZE tx_size =
4671 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
Jingning Han5d2ed972017-03-06 12:19:54 -08004672 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id] &&
Debargha Mukherjee11812962017-10-29 15:16:14 -07004673 mbmi->sb_type > BLOCK_4X4 && !(is_inter && (mbmi->skip || seg_skip))) {
Jingning Han581d1692017-01-05 16:03:54 -08004674 if (is_inter) {
4675 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
4676 } else {
Jingning Han1341cba2017-05-25 13:23:08 -07004677 if (tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
Jingning Han581d1692017-01-05 16:03:54 -08004678 }
Jingning Han581d1692017-01-05 16:03:54 -08004679
Sebastien Alaiwanfb838772017-10-24 12:02:54 +02004680#if CONFIG_RECT_TX_EXT
Yue Chen56e226e2017-05-02 16:21:40 -07004681 if (is_quarter_tx_allowed(xd, mbmi, is_inter) &&
Yue Chend6bdd462017-07-19 16:05:43 -07004682 quarter_txsize_lookup[bsize] != max_txsize_rect_lookup[bsize] &&
4683 (mbmi->tx_size == quarter_txsize_lookup[bsize] ||
4684 mbmi->tx_size == max_txsize_rect_lookup[bsize])) {
Yue Chen3dd03e32017-10-17 15:39:52 -07004685 const int use_qttx = mbmi->tx_size == quarter_txsize_lookup[bsize];
4686 ++td->counts->quarter_tx_size[use_qttx];
4687#if CONFIG_NEW_MULTISYMBOL
4688 update_cdf(xd->tile_ctx->quarter_tx_size_cdf, use_qttx, 2);
4689#endif
Yue Chen56e226e2017-05-02 16:21:40 -07004690 }
Yue Chend6bdd462017-07-19 16:05:43 -07004691#endif
Debargha Mukherjee11812962017-10-29 15:16:14 -07004692#if CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004693 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Debargha Mukherjee11812962017-10-29 15:16:14 -07004694#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004695 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07004696 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07004697 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08004699 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004700 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07004701 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004702 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07004703 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004704 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004705 } else {
Debargha Mukherjee11812962017-10-29 15:16:14 -07004706#if CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08004707 intra_tx_size = tx_size;
4708#else
Jingning Hane67b38a2016-11-04 10:30:00 -07004709 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Debargha Mukherjee11812962017-10-29 15:16:14 -07004710#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004711 }
Debargha Mukherjee11812962017-10-29 15:16:14 -07004712#if CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08004713 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
4714 [txsize_sqr_up_map[tx_size]];
Debargha Mukherjee11812962017-10-29 15:16:14 -07004715#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004716
Urvang Joshi454280d2016-10-14 16:51:44 -07004717 for (j = 0; j < mi_height; j++)
4718 for (i = 0; i < mi_width; i++)
4719 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07004720 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07004721
Jingning Hane67b38a2016-11-04 10:30:00 -07004722 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
Jingning Han2d4fafa2017-05-26 11:35:05 -07004723 if (intra_tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004724 }
Jingning Han9777afc2016-10-20 15:17:43 -07004725
Angie Chiangcd9b03f2017-04-16 13:37:13 -07004726#if !CONFIG_TXK_SEL
Angie Chiangb14b73f2017-04-13 16:26:00 -07004727 av1_update_tx_type_count(cm, xd, bsize, tx_size, td->counts);
4728#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004729 }
4730
Debargha Mukherjee6ea917e2017-10-19 09:31:29 -07004731 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type > BLOCK_4X4 && is_inter &&
4732 !(mbmi->skip || seg_skip) && !xd->lossless[mbmi->segment_id]) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01004733 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004734 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07004735 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004736 // The new intra coding scheme requires no change of transform size
Ryan84a6f202017-09-25 12:37:33 -07004737 if (is_inter) {
4738 if (xd->lossless[mbmi->segment_id]) {
4739 tx_size = TX_4X4;
4740 } else {
4741 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
4742 }
4743 } else {
Jingning Han3daa4fd2017-01-20 10:33:50 -08004744 tx_size = (bsize > BLOCK_4X4) ? tx_size : TX_4X4;
Ryan84a6f202017-09-25 12:37:33 -07004745 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004746 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08004747 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004748 }
Hui Su9fa96232017-10-23 15:46:04 -07004749#if CONFIG_CFL
Luc Trudeaub05eeae2017-08-18 15:14:30 -04004750 CFL_CTX *const cfl = xd->cfl;
Luc Trudeaub05eeae2017-08-18 15:14:30 -04004751 if (is_inter_block(mbmi) &&
4752 !is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
4753 cfl->subsampling_y)) {
4754 cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
4755 }
Hui Su9fa96232017-10-23 15:46:04 -07004756#endif // CONFIG_CFL
Yaowu Xuc27fc142016-08-22 16:08:15 -07004757}