/* * Copyright (c) 2016, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#define FREE_PMC_NODE(CTX) \ do { \
av1_free_pmc(CTX, num_planes); \
CTX = NULL; \
} while (0)
void av1_free_pc_tree_recursive(PC_TREE *pc_tree, int num_planes, int keep_best, int keep_none,
PARTITION_SEARCH_TYPE partition_search_type) { if (pc_tree == NULL) return;
// Avoid freeing of extended partitions as they are not supported when // partition_search_type is VAR_BASED_PARTITION. if (partition_search_type == VAR_BASED_PARTITION && !keep_best &&
!keep_none) {
FREE_PMC_NODE(pc_tree->none);
for (int i = 0; i < 2; ++i) {
FREE_PMC_NODE(pc_tree->horizontal[i]);
FREE_PMC_NODE(pc_tree->vertical[i]);
}
#if !defined(NDEBUG) && !CONFIG_REALTIME_ONLY for (int i = 0; i < 3; ++i) {
assert(pc_tree->horizontala[i] == NULL);
assert(pc_tree->horizontalb[i] == NULL);
assert(pc_tree->verticala[i] == NULL);
assert(pc_tree->verticalb[i] == NULL);
} for (int i = 0; i < 4; ++i) {
assert(pc_tree->horizontal4[i] == NULL);
assert(pc_tree->vertical4[i] == NULL);
} #endif
for (int i = 0; i < 4; ++i) { if (pc_tree->split[i] != NULL) {
av1_free_pc_tree_recursive(pc_tree->split[i], num_planes, 0, 0,
partition_search_type);
pc_tree->split[i] = NULL;
}
}
aom_free(pc_tree); return;
}
if (!keep_none && (!keep_best || (partition != PARTITION_NONE)))
FREE_PMC_NODE(pc_tree->none);
for (int i = 0; i < 2; ++i) { if (!keep_best || (partition != PARTITION_HORZ))
FREE_PMC_NODE(pc_tree->horizontal[i]); if (!keep_best || (partition != PARTITION_VERT))
FREE_PMC_NODE(pc_tree->vertical[i]);
} #if !CONFIG_REALTIME_ONLY for (int i = 0; i < 3; ++i) { if (!keep_best || (partition != PARTITION_HORZ_A))
FREE_PMC_NODE(pc_tree->horizontala[i]); if (!keep_best || (partition != PARTITION_HORZ_B))
FREE_PMC_NODE(pc_tree->horizontalb[i]); if (!keep_best || (partition != PARTITION_VERT_A))
FREE_PMC_NODE(pc_tree->verticala[i]); if (!keep_best || (partition != PARTITION_VERT_B))
FREE_PMC_NODE(pc_tree->verticalb[i]);
} for (int i = 0; i < 4; ++i) { if (!keep_best || (partition != PARTITION_HORZ_4))
FREE_PMC_NODE(pc_tree->horizontal4[i]); if (!keep_best || (partition != PARTITION_VERT_4))
FREE_PMC_NODE(pc_tree->vertical4[i]);
} #endif if (!keep_best || (partition != PARTITION_SPLIT)) { for (int i = 0; i < 4; ++i) { if (pc_tree->split[i] != NULL) {
av1_free_pc_tree_recursive(pc_tree->split[i], num_planes, 0, 0,
partition_search_type);
pc_tree->split[i] = NULL;
}
}
}
if (!keep_best && !keep_none) aom_free(pc_tree);
}
int av1_setup_sms_tree(AV1_COMP *const cpi, ThreadData *td) { // The structure 'sms_tree' is used to store the simple motion search data for // partition pruning in inter frames. Hence, the memory allocations and // initializations related to it are avoided for allintra encoding mode. if (cpi->oxcf.kf_cfg.key_freq_max == 0) return 0;
AV1_COMMON *const cm = &cpi->common; constint stat_generation_stage = is_stat_generation_stage(cpi); constint is_sb_size_128 = cm->seq_params->sb_size == BLOCK_128X128; constint tree_nodes =
av1_get_pc_tree_nodes(is_sb_size_128, stat_generation_stage); int sms_tree_index = 0;
SIMPLE_MOTION_DATA_TREE *this_sms; int square_index = 1; int nodes;
// Sets up all the leaf nodes in the tree. for (sms_tree_index = 0; sms_tree_index < leaf_nodes; ++sms_tree_index) {
SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
tree->block_size = square[0];
}
// Each node has 4 leaf nodes, fill each block_size level of the tree // from leafs to the root. for (nodes = leaf_nodes >> 2; nodes > 0; nodes >>= 2) { for (int i = 0; i < nodes; ++i) {
SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
tree->block_size = square[square_index]; for (int j = 0; j < 4; j++) tree->split[j] = this_sms++;
++sms_tree_index;
}
++square_index;
}
} else { // Allocation for firstpass/LAP stage // TODO(Mufaddal): refactor square_index to use a common block_size macro // from firstpass.c
SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
square_index = 2;
tree->block_size = square[square_index];
}
// Set up the root node for the largest superblock size
td->sms_root = &td->sms_tree[tree_nodes - 1]; return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.