1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * 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.
10 */
11
12 #include "av1/encoder/context_tree.h"
13 #include "av1/encoder/encoder.h"
14 #include "av1/encoder/rd.h"
15
av1_copy_tree_context(PICK_MODE_CONTEXT * dst_ctx,PICK_MODE_CONTEXT * src_ctx)16 void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
17 PICK_MODE_CONTEXT *src_ctx) {
18 dst_ctx->mic = src_ctx->mic;
19 dst_ctx->mbmi_ext_best = src_ctx->mbmi_ext_best;
20
21 dst_ctx->num_4x4_blk = src_ctx->num_4x4_blk;
22 dst_ctx->skippable = src_ctx->skippable;
23 #if CONFIG_INTERNAL_STATS
24 dst_ctx->best_mode_index = src_ctx->best_mode_index;
25 #endif // CONFIG_INTERNAL_STATS
26
27 memcpy(dst_ctx->blk_skip, src_ctx->blk_skip,
28 sizeof(uint8_t) * src_ctx->num_4x4_blk);
29 av1_copy_array(dst_ctx->tx_type_map, src_ctx->tx_type_map,
30 src_ctx->num_4x4_blk);
31
32 dst_ctx->rd_stats = src_ctx->rd_stats;
33 dst_ctx->rd_mode_is_ready = src_ctx->rd_mode_is_ready;
34 }
35
av1_setup_shared_coeff_buffer(const SequenceHeader * const seq_params,PC_TREE_SHARED_BUFFERS * shared_bufs,struct aom_internal_error_info * error)36 void av1_setup_shared_coeff_buffer(const SequenceHeader *const seq_params,
37 PC_TREE_SHARED_BUFFERS *shared_bufs,
38 struct aom_internal_error_info *error) {
39 const int num_planes = seq_params->monochrome ? 1 : MAX_MB_PLANE;
40 const int max_sb_square_y = 1 << num_pels_log2_lookup[seq_params->sb_size];
41 const int max_sb_square_uv = max_sb_square_y >> (seq_params->subsampling_x +
42 seq_params->subsampling_y);
43 for (int i = 0; i < num_planes; i++) {
44 const int max_num_pix =
45 (i == AOM_PLANE_Y) ? max_sb_square_y : max_sb_square_uv;
46 AOM_CHECK_MEM_ERROR(error, shared_bufs->coeff_buf[i],
47 aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
48 AOM_CHECK_MEM_ERROR(error, shared_bufs->qcoeff_buf[i],
49 aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
50 AOM_CHECK_MEM_ERROR(error, shared_bufs->dqcoeff_buf[i],
51 aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
52 }
53 }
54
av1_free_shared_coeff_buffer(PC_TREE_SHARED_BUFFERS * shared_bufs)55 void av1_free_shared_coeff_buffer(PC_TREE_SHARED_BUFFERS *shared_bufs) {
56 for (int i = 0; i < 3; i++) {
57 aom_free(shared_bufs->coeff_buf[i]);
58 aom_free(shared_bufs->qcoeff_buf[i]);
59 aom_free(shared_bufs->dqcoeff_buf[i]);
60 shared_bufs->coeff_buf[i] = NULL;
61 shared_bufs->qcoeff_buf[i] = NULL;
62 shared_bufs->dqcoeff_buf[i] = NULL;
63 }
64 }
65
av1_alloc_pmc(const struct AV1_COMP * const cpi,BLOCK_SIZE bsize,PC_TREE_SHARED_BUFFERS * shared_bufs)66 PICK_MODE_CONTEXT *av1_alloc_pmc(const struct AV1_COMP *const cpi,
67 BLOCK_SIZE bsize,
68 PC_TREE_SHARED_BUFFERS *shared_bufs) {
69 PICK_MODE_CONTEXT *volatile ctx = NULL;
70 const AV1_COMMON *const cm = &cpi->common;
71 struct aom_internal_error_info error;
72
73 if (setjmp(error.jmp)) {
74 av1_free_pmc(ctx, av1_num_planes(cm));
75 return NULL;
76 }
77 error.setjmp = 1;
78
79 AOM_CHECK_MEM_ERROR(&error, ctx, aom_calloc(1, sizeof(*ctx)));
80 ctx->rd_mode_is_ready = 0;
81
82 const int num_planes = av1_num_planes(cm);
83 const int num_pix = block_size_wide[bsize] * block_size_high[bsize];
84 const int num_blk = num_pix / 16;
85
86 AOM_CHECK_MEM_ERROR(&error, ctx->blk_skip,
87 aom_calloc(num_blk, sizeof(*ctx->blk_skip)));
88 AOM_CHECK_MEM_ERROR(&error, ctx->tx_type_map,
89 aom_calloc(num_blk, sizeof(*ctx->tx_type_map)));
90 ctx->num_4x4_blk = num_blk;
91
92 for (int i = 0; i < num_planes; ++i) {
93 ctx->coeff[i] = shared_bufs->coeff_buf[i];
94 ctx->qcoeff[i] = shared_bufs->qcoeff_buf[i];
95 ctx->dqcoeff[i] = shared_bufs->dqcoeff_buf[i];
96 AOM_CHECK_MEM_ERROR(&error, ctx->eobs[i],
97 aom_memalign(32, num_blk * sizeof(*ctx->eobs[i])));
98 AOM_CHECK_MEM_ERROR(
99 &error, ctx->txb_entropy_ctx[i],
100 aom_memalign(32, num_blk * sizeof(*ctx->txb_entropy_ctx[i])));
101 }
102
103 if (num_pix <= MAX_PALETTE_SQUARE) {
104 for (int i = 0; i < 2; ++i) {
105 if (cm->features.allow_screen_content_tools) {
106 AOM_CHECK_MEM_ERROR(
107 &error, ctx->color_index_map[i],
108 aom_memalign(32, num_pix * sizeof(*ctx->color_index_map[i])));
109 } else {
110 ctx->color_index_map[i] = NULL;
111 }
112 }
113 }
114
115 av1_invalid_rd_stats(&ctx->rd_stats);
116
117 return ctx;
118 }
119
av1_reset_pmc(PICK_MODE_CONTEXT * ctx)120 void av1_reset_pmc(PICK_MODE_CONTEXT *ctx) {
121 av1_zero_array(ctx->blk_skip, ctx->num_4x4_blk);
122 av1_zero_array(ctx->tx_type_map, ctx->num_4x4_blk);
123 av1_invalid_rd_stats(&ctx->rd_stats);
124 }
125
av1_free_pmc(PICK_MODE_CONTEXT * ctx,int num_planes)126 void av1_free_pmc(PICK_MODE_CONTEXT *ctx, int num_planes) {
127 if (ctx == NULL) return;
128
129 aom_free(ctx->blk_skip);
130 ctx->blk_skip = NULL;
131 aom_free(ctx->tx_type_map);
132 for (int i = 0; i < num_planes; ++i) {
133 ctx->coeff[i] = NULL;
134 ctx->qcoeff[i] = NULL;
135 ctx->dqcoeff[i] = NULL;
136 aom_free(ctx->eobs[i]);
137 ctx->eobs[i] = NULL;
138 aom_free(ctx->txb_entropy_ctx[i]);
139 ctx->txb_entropy_ctx[i] = NULL;
140 }
141
142 for (int i = 0; i < 2; ++i) {
143 if (ctx->color_index_map[i]) {
144 aom_free(ctx->color_index_map[i]);
145 ctx->color_index_map[i] = NULL;
146 }
147 }
148
149 aom_free(ctx);
150 }
151
av1_alloc_pc_tree_node(BLOCK_SIZE bsize)152 PC_TREE *av1_alloc_pc_tree_node(BLOCK_SIZE bsize) {
153 PC_TREE *pc_tree = NULL;
154 struct aom_internal_error_info error;
155
156 AOM_CHECK_MEM_ERROR(&error, pc_tree, aom_calloc(1, sizeof(*pc_tree)));
157
158 pc_tree->partitioning = PARTITION_NONE;
159 pc_tree->block_size = bsize;
160 pc_tree->index = 0;
161
162 pc_tree->none = NULL;
163 for (int i = 0; i < 2; ++i) {
164 pc_tree->horizontal[i] = NULL;
165 pc_tree->vertical[i] = NULL;
166 }
167
168 #if !CONFIG_REALTIME_ONLY
169 for (int i = 0; i < 3; ++i) {
170 pc_tree->horizontala[i] = NULL;
171 pc_tree->horizontalb[i] = NULL;
172 pc_tree->verticala[i] = NULL;
173 pc_tree->verticalb[i] = NULL;
174 }
175 for (int i = 0; i < 4; ++i) {
176 pc_tree->horizontal4[i] = NULL;
177 pc_tree->vertical4[i] = NULL;
178 }
179 #endif
180 for (int i = 0; i < 4; ++i) {
181 pc_tree->split[i] = NULL;
182 }
183
184 return pc_tree;
185 }
186
187 #define FREE_PMC_NODE(CTX) \
188 do { \
189 av1_free_pmc(CTX, num_planes); \
190 CTX = NULL; \
191 } while (0)
192
av1_free_pc_tree_recursive(PC_TREE * pc_tree,int num_planes,int keep_best,int keep_none)193 void av1_free_pc_tree_recursive(PC_TREE *pc_tree, int num_planes, int keep_best,
194 int keep_none) {
195 if (pc_tree == NULL) return;
196
197 const PARTITION_TYPE partition = pc_tree->partitioning;
198
199 if (!keep_none && (!keep_best || (partition != PARTITION_NONE)))
200 FREE_PMC_NODE(pc_tree->none);
201
202 for (int i = 0; i < 2; ++i) {
203 if (!keep_best || (partition != PARTITION_HORZ))
204 FREE_PMC_NODE(pc_tree->horizontal[i]);
205 if (!keep_best || (partition != PARTITION_VERT))
206 FREE_PMC_NODE(pc_tree->vertical[i]);
207 }
208 #if !CONFIG_REALTIME_ONLY
209 for (int i = 0; i < 3; ++i) {
210 if (!keep_best || (partition != PARTITION_HORZ_A))
211 FREE_PMC_NODE(pc_tree->horizontala[i]);
212 if (!keep_best || (partition != PARTITION_HORZ_B))
213 FREE_PMC_NODE(pc_tree->horizontalb[i]);
214 if (!keep_best || (partition != PARTITION_VERT_A))
215 FREE_PMC_NODE(pc_tree->verticala[i]);
216 if (!keep_best || (partition != PARTITION_VERT_B))
217 FREE_PMC_NODE(pc_tree->verticalb[i]);
218 }
219 for (int i = 0; i < 4; ++i) {
220 if (!keep_best || (partition != PARTITION_HORZ_4))
221 FREE_PMC_NODE(pc_tree->horizontal4[i]);
222 if (!keep_best || (partition != PARTITION_VERT_4))
223 FREE_PMC_NODE(pc_tree->vertical4[i]);
224 }
225 #endif
226 if (!keep_best || (partition != PARTITION_SPLIT)) {
227 for (int i = 0; i < 4; ++i) {
228 if (pc_tree->split[i] != NULL) {
229 av1_free_pc_tree_recursive(pc_tree->split[i], num_planes, 0, 0);
230 pc_tree->split[i] = NULL;
231 }
232 }
233 }
234
235 if (!keep_best && !keep_none) aom_free(pc_tree);
236 }
237
av1_setup_sms_tree(AV1_COMP * const cpi,ThreadData * td)238 void av1_setup_sms_tree(AV1_COMP *const cpi, ThreadData *td) {
239 // The structure 'sms_tree' is used to store the simple motion search data for
240 // partition pruning in inter frames. Hence, the memory allocations and
241 // initializations related to it are avoided for allintra encoding mode.
242 if (cpi->oxcf.kf_cfg.key_freq_max == 0) return;
243
244 AV1_COMMON *const cm = &cpi->common;
245 const int stat_generation_stage = is_stat_generation_stage(cpi);
246 const int is_sb_size_128 = cm->seq_params->sb_size == BLOCK_128X128;
247 const int tree_nodes =
248 av1_get_pc_tree_nodes(is_sb_size_128, stat_generation_stage);
249 int sms_tree_index = 0;
250 SIMPLE_MOTION_DATA_TREE *this_sms;
251 int square_index = 1;
252 int nodes;
253
254 aom_free(td->sms_tree);
255 CHECK_MEM_ERROR(cm, td->sms_tree,
256 aom_calloc(tree_nodes, sizeof(*td->sms_tree)));
257 this_sms = &td->sms_tree[0];
258
259 if (!stat_generation_stage) {
260 const int leaf_factor = is_sb_size_128 ? 4 : 1;
261 const int leaf_nodes = 256 * leaf_factor;
262
263 // Sets up all the leaf nodes in the tree.
264 for (sms_tree_index = 0; sms_tree_index < leaf_nodes; ++sms_tree_index) {
265 SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
266 tree->block_size = square[0];
267 }
268
269 // Each node has 4 leaf nodes, fill each block_size level of the tree
270 // from leafs to the root.
271 for (nodes = leaf_nodes >> 2; nodes > 0; nodes >>= 2) {
272 for (int i = 0; i < nodes; ++i) {
273 SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
274 tree->block_size = square[square_index];
275 for (int j = 0; j < 4; j++) tree->split[j] = this_sms++;
276 ++sms_tree_index;
277 }
278 ++square_index;
279 }
280 } else {
281 // Allocation for firstpass/LAP stage
282 // TODO(Mufaddal): refactor square_index to use a common block_size macro
283 // from firstpass.c
284 SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
285 square_index = 2;
286 tree->block_size = square[square_index];
287 }
288
289 // Set up the root node for the largest superblock size
290 td->sms_root = &td->sms_tree[tree_nodes - 1];
291 }
292
av1_free_sms_tree(ThreadData * td)293 void av1_free_sms_tree(ThreadData *td) {
294 if (td->sms_tree != NULL) {
295 aom_free(td->sms_tree);
296 td->sms_tree = NULL;
297 }
298 }
299