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