Use pc_root pointer in ThreadData to allocate PC_TREE root
In this CL, the existing pointer 'rt_pc_root' in ThreadData
structure has been renamed to 'pc_root' which is used to
allocate the PC_TREE node for all encoding modes. This
facilitates invoking av1_free_pc_tree_recursive() during
encoder_destroy() in order to prevent potential memory leaks
in case of early termination.
Bug: aomedia:3276
Change-Id: I872b4cb8a45d4089c58ad5e578b452878e907c30
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 55d7b76..d57da82 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -523,7 +523,7 @@
MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
- PC_TREE *const pc_root = td->rt_pc_root;
+ PC_TREE *const pc_root = td->pc_root;
#if CONFIG_RT_ML_PARTITIONING
if (sf->part_sf.partition_search_type == ML_BASED_PARTITION) {
@@ -731,9 +731,9 @@
av1_restore_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex = backup_current_qindex;
- PC_TREE *const pc_root = av1_alloc_pc_tree_node(bsize);
+ td->pc_root = av1_alloc_pc_tree_node(bsize);
av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
- &cur_rdc, cur_rdc, pc_root, sms_tree, NULL,
+ &cur_rdc, cur_rdc, td->pc_root, sms_tree, NULL,
SB_DRY_PASS, NULL);
if ((rdc_winner.rdcost > cur_rdc.rdcost) ||
@@ -787,11 +787,12 @@
#if CONFIG_COLLECT_COMPONENT_TIMING
start_timing(cpi, rd_use_partition_time);
#endif
- PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
- &dummy_rate, &dummy_dist, 1, pc_root);
- av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0,
+ &dummy_rate, &dummy_dist, 1, td->pc_root);
+ av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
sf->part_sf.partition_search_type);
+ td->pc_root = NULL;
#if CONFIG_COLLECT_COMPONENT_TIMING
end_timing(cpi, rd_use_partition_time);
#endif
@@ -803,11 +804,12 @@
const BLOCK_SIZE bsize =
seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
- PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
- &dummy_rate, &dummy_dist, 1, pc_root);
- av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0,
+ &dummy_rate, &dummy_dist, 1, td->pc_root);
+ av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
sf->part_sf.partition_search_type);
+ td->pc_root = NULL;
} else {
// The most exhaustive recursive partition search
SuperBlockEnc *sb_enc = &x->sb_enc;
@@ -872,15 +874,15 @@
av1_rd_partition_search(cpi, td, tile_data, tp, sms_root, mi_row,
mi_col, sb_size, &this_rdc);
} else {
- PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
- &dummy_rdc, dummy_rdc, pc_root, sms_root, NULL,
- SB_SINGLE_PASS, NULL);
+ &dummy_rdc, dummy_rdc, td->pc_root, sms_root,
+ NULL, SB_SINGLE_PASS, NULL);
}
#else
- PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
- &dummy_rdc, dummy_rdc, pc_root, sms_root, NULL,
+ &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
SB_SINGLE_PASS, NULL);
#endif // CONFIG_PARTITION_SEARCH_ORDER
} else {
@@ -890,9 +892,9 @@
(SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats)));
av1_backup_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
mi_col);
- PC_TREE *const pc_root_p0 = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
- &dummy_rdc, dummy_rdc, pc_root_p0, sms_root, NULL,
+ &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
SB_DRY_PASS, NULL);
// Second pass
@@ -904,9 +906,9 @@
av1_restore_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
mi_col);
- PC_TREE *const pc_root_p1 = av1_alloc_pc_tree_node(sb_size);
+ td->pc_root = av1_alloc_pc_tree_node(sb_size);
av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
- &dummy_rdc, dummy_rdc, pc_root_p1, sms_root, NULL,
+ &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
SB_WET_PASS, NULL);
aom_free(td->mb.sb_fp_stats);
td->mb.sb_fp_stats = NULL;
@@ -1987,12 +1989,13 @@
// Preallocate the pc_tree for realtime coding to reduce the cost of
// memory allocation.
const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
- td->rt_pc_root = use_nonrd_mode
- ? av1_alloc_pc_tree_node(cm->seq_params->sb_size)
- : NULL;
+ td->pc_root = use_nonrd_mode
+ ? av1_alloc_pc_tree_node(cm->seq_params->sb_size)
+ : NULL;
encode_tiles(cpi);
- av1_free_pc_tree_recursive(td->rt_pc_root, av1_num_planes(cm), 0, 0,
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
}
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 735668c..04c2d87 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1478,8 +1478,8 @@
// store source variance and log of source variance of each 4x4 sub-block
// for subsequent retrieval.
Block4x4VarInfo *src_var_info_of_4x4_sub_blocks;
- // The pc tree root for RTC non-rd case.
- PC_TREE *rt_pc_root;
+ // Pointer to pc tree root.
+ PC_TREE *pc_root;
} ThreadData;
struct EncWorkerData;
diff --git a/av1/encoder/encoder_alloc.h b/av1/encoder/encoder_alloc.h
index 2ca6450..f61bb80 100644
--- a/av1/encoder/encoder_alloc.h
+++ b/av1/encoder/encoder_alloc.h
@@ -235,6 +235,10 @@
aom_free(cpi->td.mb.sb_fp_stats);
cpi->td.mb.sb_fp_stats = NULL;
+ av1_free_pc_tree_recursive(cpi->td.pc_root, av1_num_planes(cm), 0, 0,
+ cpi->sf.part_sf.partition_search_type);
+ cpi->td.pc_root = NULL;
+
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++) {
aom_free(cpi->td.mb.intrabc_hash_info.hash_value_buffer[i][j]);
@@ -486,6 +490,9 @@
thread_data->td->mb.sb_stats_cache = NULL;
aom_free(thread_data->td->mb.sb_fp_stats);
thread_data->td->mb.sb_fp_stats = NULL;
+ av1_free_pc_tree_recursive(thread_data->td->pc_root, num_planes, 0, 0,
+ SEARCH_PARTITION);
+ thread_data->td->pc_root = NULL;
aom_free(thread_data->td);
}
}
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 24538b4..af567ba 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -621,7 +621,7 @@
// Preallocate the pc_tree for realtime coding to reduce the cost of memory
// allocation.
- thread_data->td->rt_pc_root =
+ thread_data->td->pc_root =
cpi->sf.rt_sf.use_nonrd_pick_mode
? av1_alloc_pc_tree_node(cm->seq_params->sb_size)
: NULL;
@@ -720,8 +720,9 @@
// encoding and loop filter stage.
launch_loop_filter_rows(cm, thread_data, enc_row_mt, mib_size_log2);
}
- av1_free_pc_tree_recursive(thread_data->td->rt_pc_root, av1_num_planes(cm), 0,
- 0, cpi->sf.part_sf.partition_search_type);
+ av1_free_pc_tree_recursive(thread_data->td->pc_root, av1_num_planes(cm), 0, 0,
+ cpi->sf.part_sf.partition_search_type);
+ thread_data->td->pc_root = NULL;
error_info->setjmp = 0;
return 1;
}
@@ -751,7 +752,7 @@
// Preallocate the pc_tree for realtime coding to reduce the cost of memory
// allocation.
- thread_data->td->rt_pc_root =
+ thread_data->td->pc_root =
cpi->sf.rt_sf.use_nonrd_pick_mode
? av1_alloc_pc_tree_node(cm->seq_params->sb_size)
: NULL;
@@ -768,9 +769,9 @@
av1_encode_tile(cpi, thread_data->td, tile_row, tile_col);
}
- av1_free_pc_tree_recursive(thread_data->td->rt_pc_root, av1_num_planes(cm), 0,
- 0, cpi->sf.part_sf.partition_search_type);
-
+ av1_free_pc_tree_recursive(thread_data->td->pc_root, av1_num_planes(cm), 0, 0,
+ cpi->sf.part_sf.partition_search_type);
+ thread_data->td->pc_root = NULL;
error_info->setjmp = 0;
return 1;
}
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 9f2d3d4..cdd649c5 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -4831,7 +4831,6 @@
features.frame_height = cpi->frame_info.frame_height;
features.block_size = bsize;
av1_ext_part_send_features(ext_part_controller, &features);
- PC_TREE *pc_tree;
// rd mode search (dry run) for a valid partition decision from the ml model.
aom_partition_decision_t partition_decision;
@@ -4843,26 +4842,28 @@
// First, let's take the easy approach.
// We require that the ml model has to provide partition decisions for the
// whole superblock.
- pc_tree = av1_alloc_pc_tree_node(bsize);
- build_pc_tree_from_part_decision(&partition_decision, bsize, pc_tree);
+ td->pc_root = av1_alloc_pc_tree_node(bsize);
+ build_pc_tree_from_part_decision(&partition_decision, bsize, td->pc_root);
const RD_STATS this_rdcost = rd_search_for_fixed_partition(
- cpi, td, tile_data, tp, sms_root, mi_row, mi_col, bsize, pc_tree);
+ cpi, td, tile_data, tp, sms_root, mi_row, mi_col, bsize, td->pc_root);
aom_partition_stats_t stats;
update_partition_stats(&this_rdcost, &stats);
av1_ext_part_send_partition_stats(ext_part_controller, &stats);
if (!partition_decision.is_final_decision) {
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
}
} while (!partition_decision.is_final_decision);
// Encode with the selected mode and partition.
set_cb_offsets(x->cb_offset, 0, 0);
encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
- pc_tree, NULL);
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ td->pc_root, NULL);
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
return true;
}
@@ -5165,12 +5166,11 @@
features.frame_height = cpi->frame_info.frame_height;
features.block_size = bsize;
av1_ext_part_send_features(ext_part_controller, &features);
- PC_TREE *pc_tree;
- pc_tree = av1_alloc_pc_tree_node(bsize);
+ td->pc_root = av1_alloc_pc_tree_node(bsize);
RD_STATS rdcost;
const bool valid_partition =
- recursive_partition(cpi, td, tile_data, tp, sms_root, pc_tree, mi_row,
+ recursive_partition(cpi, td, tile_data, tp, sms_root, td->pc_root, mi_row,
mi_col, bsize, &rdcost);
if (!valid_partition) {
return false;
@@ -5179,9 +5179,10 @@
// Encode with the selected mode and partition.
set_cb_offsets(x->cb_offset, 0, 0);
encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
- pc_tree, NULL);
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ td->pc_root, NULL);
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
return true;
}
@@ -5221,43 +5222,46 @@
RD_STATS *rdcost = NULL;
int i = 0;
do {
- PC_TREE *const pc_tree = av1_alloc_pc_tree_node(bsize);
- num_configs = read_partition_tree(cpi, pc_tree, i);
+ td->pc_root = av1_alloc_pc_tree_node(bsize);
+ num_configs = read_partition_tree(cpi, td->pc_root, i);
if (i == 0) {
CHECK_MEM_ERROR(cm, rdcost, aom_calloc(num_configs, sizeof(*rdcost)));
}
if (num_configs <= 0) {
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
aom_free(rdcost);
aom_internal_error(cm->error, AOM_CODEC_ERROR, "Invalid configs.");
}
- verify_write_partition_tree(cpi, pc_tree, bsize, i, mi_row, mi_col);
+ verify_write_partition_tree(cpi, td->pc_root, bsize, i, mi_row, mi_col);
// Encode the block with the given partition tree. Get rdcost and encoding
// time.
- rdcost[i] = rd_search_for_fixed_partition(cpi, td, tile_data, tp, sms_root,
- mi_row, mi_col, bsize, pc_tree);
+ rdcost[i] = rd_search_for_fixed_partition(
+ cpi, td, tile_data, tp, sms_root, mi_row, mi_col, bsize, td->pc_root);
if (rdcost[i].rdcost < min_rdcost) {
min_rdcost = rdcost[i].rdcost;
best_idx = i;
*best_rd_cost = rdcost[i];
}
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
++i;
} while (i < num_configs);
// Encode with the partition configuration with the smallest rdcost.
- PC_TREE *const pc_tree = av1_alloc_pc_tree_node(bsize);
- read_partition_tree(cpi, pc_tree, best_idx);
+ td->pc_root = av1_alloc_pc_tree_node(bsize);
+ read_partition_tree(cpi, td->pc_root, best_idx);
rd_search_for_fixed_partition(cpi, td, tile_data, tp, sms_root, mi_row,
- mi_col, bsize, pc_tree);
+ mi_col, bsize, td->pc_root);
set_cb_offsets(x->cb_offset, 0, 0);
encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
- pc_tree, NULL);
- av1_free_pc_tree_recursive(pc_tree, av1_num_planes(cm), 0, 0,
+ td->pc_root, NULL);
+ av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
cpi->sf.part_sf.partition_search_type);
+ td->pc_root = NULL;
aom_free(rdcost);
++cpi->sb_counter;
@@ -5730,9 +5734,12 @@
set_cb_offsets(x->cb_offset, 0, 0);
encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, run_type, bsize,
pc_tree, NULL);
+ assert(pc_tree == td->pc_root);
// Dealloc the whole PC_TREE after a superblock is done.
av1_free_pc_tree_recursive(pc_tree, num_planes, 0, 0,
cpi->sf.part_sf.partition_search_type);
+ pc_tree = NULL;
+ td->pc_root = NULL;
pc_tree_dealloc = 1;
} else if (should_do_dry_run_encode_for_current_block(
cm->seq_params->sb_size, x->sb_enc.max_partition_size,