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