/work/svt-av1/Source/Lib/Codec/coding_unit.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright(c) 2019 Intel Corporation |
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 https://www.aomedia.org/license/software-license. 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 https://www.aomedia.org/license/patent-license. |
10 | | */ |
11 | | |
12 | | #include <stdlib.h> |
13 | | #include <stdint.h> |
14 | | |
15 | | #include "pcs.h" |
16 | | #include "utility.h" |
17 | | #include "enc_mode_config.h" |
18 | | |
19 | 6.90k | void svt_aom_largest_coding_unit_dctor(EbPtr p) { |
20 | 6.90k | SuperBlock* obj = (SuperBlock*)p; |
21 | 6.90k | EB_FREE_ARRAY(obj->av1xd); |
22 | 6.90k | EB_FREE_ARRAY(obj->final_blk_arr); |
23 | 6.90k | EB_FREE_ARRAY(obj->ptree); |
24 | 6.90k | } |
25 | | |
26 | 587k | static void setup_ptree(PARTITION_TREE* pc_tree, int index, BlockSize bsize, const int min_sq_size) { |
27 | 587k | pc_tree->bsize = bsize; |
28 | 587k | pc_tree->index = index; |
29 | | |
30 | | // If applicable, add split depths |
31 | 587k | const int sq_size = block_size_wide[bsize]; |
32 | 587k | if (sq_size > min_sq_size) { |
33 | 145k | const BlockSize subsize = get_partition_subsize(bsize, PARTITION_SPLIT); |
34 | 145k | const int sq_subsize = block_size_wide[subsize]; |
35 | 145k | int blocks_per_subdepth = (sq_subsize / min_sq_size) * (sq_subsize / min_sq_size); |
36 | 145k | int blocks_to_skip = 0; |
37 | | |
38 | 331k | for (int i = min_sq_size; i <= sq_subsize; i <<= 1, blocks_per_subdepth >>= 2) { |
39 | 186k | blocks_to_skip += blocks_per_subdepth; |
40 | 186k | } |
41 | | |
42 | 725k | for (int i = 0; i < SUB_PARTITIONS_SPLIT; ++i) { |
43 | 580k | pc_tree->sub_tree[i] = pc_tree + i * blocks_to_skip + 1; |
44 | 580k | setup_ptree(pc_tree->sub_tree[i], i, subsize, min_sq_size); |
45 | 580k | } |
46 | 145k | } |
47 | 587k | } |
48 | | |
49 | | /* |
50 | | Tasks & Questions |
51 | | -Need a GetEmptyChain function for testing sub partitions. Tie it to an Itr? |
52 | | -How many empty CUs do we need? We need to have enough for the max CU count AND |
53 | | enough for temp storage when calculating a subdivision. |
54 | | -Where do we store temp reconstructed picture data while deciding to subdivide or not? |
55 | | -Need a ReconPicture for each candidate. |
56 | | -I don't see a way around doing the copies in temp memory and then copying it in... |
57 | | */ |
58 | | EbErrorType svt_aom_largest_coding_unit_ctor(SuperBlock* larget_coding_unit_ptr, uint8_t sb_size_pix, |
59 | | uint16_t sb_origin_x, uint16_t sb_origin_y, uint16_t sb_index, |
60 | 6.90k | EncMode enc_mode, bool rtc, bool allintra, PictureControlSet* pcs) { |
61 | 6.90k | larget_coding_unit_ptr->dctor = svt_aom_largest_coding_unit_dctor; |
62 | | |
63 | | // ************ SB *************** |
64 | | // Which borderLargestCuSize is not a power of two |
65 | | |
66 | | // Which borderLargestCuSize is not a power of two |
67 | 6.90k | larget_coding_unit_ptr->pcs = pcs; |
68 | | |
69 | 6.90k | larget_coding_unit_ptr->org_x = sb_origin_x; |
70 | 6.90k | larget_coding_unit_ptr->org_y = sb_origin_y; |
71 | | |
72 | 6.90k | larget_coding_unit_ptr->index = sb_index; |
73 | 6.90k | bool disallow_sub_8x8_nsq = true; |
74 | 6.90k | bool disallow_sub_16x16_nsq = true; |
75 | 41.4k | for (uint8_t coeff_lvl = 0; coeff_lvl <= HIGH_LVL + 1; coeff_lvl++) { |
76 | 34.5k | uint8_t nsq_geom_lvl = allintra ? svt_aom_get_nsq_geom_level_allintra(enc_mode) |
77 | 34.5k | #if TUNE_SIMPLIFY_SETTINGS |
78 | 34.5k | : rtc ? svt_aom_get_nsq_geom_level_rtc() |
79 | | #else |
80 | | : rtc ? svt_aom_get_nsq_geom_level_rtc(enc_mode) |
81 | | #endif |
82 | 0 | : svt_aom_get_nsq_geom_level_default(enc_mode, coeff_lvl); |
83 | | // nsq_geom_lvl level 0 means NSQ shapes are disallowed so don't adjust based on the level |
84 | 34.5k | if (nsq_geom_lvl) { |
85 | 0 | uint8_t allow_HVA_HVB, allow_HV4, min_nsq_bsize; |
86 | 0 | svt_aom_set_nsq_geom_ctrls(NULL, nsq_geom_lvl, &allow_HVA_HVB, &allow_HV4, &min_nsq_bsize); |
87 | 0 | if (min_nsq_bsize < 8) { |
88 | 0 | disallow_sub_8x8_nsq = false; |
89 | 0 | } |
90 | 0 | if (min_nsq_bsize < 16) { |
91 | 0 | disallow_sub_16x16_nsq = false; |
92 | 0 | } |
93 | 0 | } |
94 | 34.5k | } |
95 | 6.90k | bool disallow_4x4 = allintra ? svt_aom_get_disallow_4x4_allintra(enc_mode) |
96 | 6.90k | #if TUNE_SIMPLIFY_SETTINGS |
97 | 6.90k | : rtc ? svt_aom_get_disallow_4x4_rtc() |
98 | | #else |
99 | | : rtc ? svt_aom_get_disallow_4x4_rtc(enc_mode) |
100 | | #endif |
101 | 0 | : svt_aom_get_disallow_4x4_default(enc_mode); |
102 | 6.90k | bool disallow_8x8 = allintra ? svt_aom_get_disallow_8x8_allintra() |
103 | 6.90k | : rtc ? svt_aom_get_disallow_8x8_rtc(enc_mode, pcs->frame_width, pcs->frame_height) |
104 | 0 | : svt_aom_get_disallow_8x8_default(); |
105 | 6.90k | uint32_t tot_blk_num; |
106 | 6.90k | if (sb_size_pix == 128) { |
107 | 0 | if (disallow_8x8 && disallow_sub_16x16_nsq) { |
108 | 0 | tot_blk_num = 64; |
109 | 0 | } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) { |
110 | 0 | tot_blk_num = 256; |
111 | 0 | } else if (disallow_4x4) { |
112 | 0 | tot_blk_num = 512; |
113 | 0 | } else { |
114 | 0 | tot_blk_num = 1024; |
115 | 0 | } |
116 | 6.90k | } else if (disallow_8x8 && disallow_sub_16x16_nsq) { |
117 | 0 | tot_blk_num = 16; |
118 | 6.90k | } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) { |
119 | 6.90k | tot_blk_num = 64; |
120 | 6.90k | } else if (disallow_4x4) { |
121 | 0 | tot_blk_num = 128; |
122 | 0 | } else { |
123 | 0 | tot_blk_num = 256; |
124 | 0 | } |
125 | | // Do NOT initialize the final_blk_arr here |
126 | | // Malloc maximum but only initialize it only when actually used. |
127 | | // This will help to same actually memory usage |
128 | 6.90k | EB_MALLOC_ARRAY(larget_coding_unit_ptr->final_blk_arr, tot_blk_num); |
129 | 6.90k | EB_MALLOC_ARRAY(larget_coding_unit_ptr->av1xd, 1); |
130 | | |
131 | | // Alloc ptree, which is used to store final block data/mode info for the SB that is passed |
132 | | // from encdec to EC |
133 | 6.90k | uint8_t min_bsize = disallow_8x8 ? 16 : disallow_4x4 ? 8 : 4; |
134 | 6.90k | int blocks_per_depth = (sb_size_pix / min_bsize) * (sb_size_pix / min_bsize); |
135 | 6.90k | int blocks_to_alloc = 0; |
136 | | |
137 | 34.5k | for (int i = min_bsize; i <= sb_size_pix; i <<= 1, blocks_per_depth >>= 2) { |
138 | 27.6k | blocks_to_alloc += blocks_per_depth; |
139 | 27.6k | } |
140 | 6.90k | EB_CALLOC_ARRAY(larget_coding_unit_ptr->ptree, blocks_to_alloc); |
141 | 6.90k | setup_ptree(larget_coding_unit_ptr->ptree, 0, sb_size_pix == 128 ? BLOCK_128X128 : BLOCK_64X64, min_bsize); |
142 | | |
143 | 6.90k | return EB_ErrorNone; |
144 | 6.90k | } |