Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : #ifndef EbUtility_h
7 : #define EbUtility_h
8 :
9 : #include "EbDefinitions.h"
10 :
11 : #ifdef __cplusplus
12 : extern "C" {
13 : #endif
14 : /****************************
15 : * UTILITY FUNCTIONS
16 : ****************************/
17 : typedef struct BlockList_s
18 : {
19 : uint8_t list_size;
20 : uint16_t blk_mds_table[3]; //stores a max of 3 redundant blocks
21 : }BlockList_t;
22 :
23 : void build_blk_geom();
24 : typedef struct BlockGeom
25 : {
26 : uint8_t depth; // depth of the block
27 : PART shape; // P_N..P_V4 . P_S is not used.
28 : uint8_t origin_x; // orgin x from topleft of sb
29 : uint8_t origin_y; // orgin x from topleft of sb
30 :
31 : uint8_t d1i; // index of the block in d1 dimension 0..24 (0 is parent square, 1 top half of H , ...., 24:last quarter of V4)
32 : uint16_t sqi_mds; // index of the parent square in md scan.
33 : uint8_t totns; // max number of ns blocks within one partition 1..4 (N:1,H:2,V:2,HA:3,HB:3,VA:3,VB:3,H4:4,V4:4)
34 : uint8_t nsi; // non square index within a partition 0..totns-1
35 : uint8_t similar; // 1: means that this block is similar (same shape/location) to another
36 : uint8_t quadi; // parent square is in which quadrant 0..3
37 : uint8_t redund; // 1: means that this block is redundant to another
38 : BlockList_t redund_list; // the list where the block is redundant
39 : BlockList_t similar_list;
40 :
41 : uint8_t bwidth; // block width
42 : uint8_t bheight; // block height
43 : uint8_t bwidth_uv; // block width for Chroma 4:2:0
44 : uint8_t bheight_uv; // block height for Chroma 4:2:0
45 : uint8_t bwidth_log2; // block width log2
46 : uint8_t bheight_log2; // block height log2
47 : BlockSize bsize; // bloc size
48 : BlockSize bsize_uv; // bloc size for Chroma 4:2:0
49 : uint16_t txb_count[MAX_VARTX_DEPTH + 1]; //4-2-1
50 : TxSize txsize[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT];
51 : TxSize txsize_uv[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT];
52 : uint16_t tx_org_x[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //orgin is SB
53 : uint16_t tx_org_y[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //origin is SB
54 : uint16_t tx_boff_x[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //block offset , origin is block
55 : uint16_t tx_boff_y[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //block offset , origin is block
56 : uint8_t tx_width[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //tx_size_wide
57 : uint8_t tx_height[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //tx_size_wide
58 : uint8_t tx_width_uv[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //tx_size_wide
59 : uint8_t tx_height_uv[MAX_VARTX_DEPTH + 1][MAX_TXB_COUNT]; //tx_size_wide
60 :
61 : uint16_t blkidx_mds; // block index in md scan
62 : uint16_t blkidx_dps; // block index in depth scan
63 : int32_t has_uv;
64 : int32_t sq_size;
65 : int32_t is_last_quadrant; // only for square bloks, is this the fourth quadrant block?
66 : } BlockGeom;
67 :
68 : static const BlockSize ss_size_lookup[BlockSizeS_ALL][2][2] = {
69 : // ss_x == 0 ss_x == 0 ss_x == 1 ss_x == 1
70 : // ss_y == 0 ss_y == 1 ss_y == 0 ss_y == 1
71 : { { BLOCK_4X4, BLOCK_4X4 }, { BLOCK_4X4, BLOCK_4X4 } },
72 : { { BLOCK_4X8, BLOCK_4X4 }, { BLOCK_INVALID, BLOCK_4X4 } },
73 : { { BLOCK_8X4, BLOCK_INVALID}, { BLOCK_4X4, BLOCK_4X4 } },
74 : { { BLOCK_8X8, BLOCK_8X4 }, { BLOCK_4X8, BLOCK_4X4 } },
75 : { { BLOCK_8X16, BLOCK_8X8 }, { BLOCK_INVALID, BLOCK_4X8 } },
76 : { { BLOCK_16X8, BLOCK_INVALID}, { BLOCK_8X8, BLOCK_8X4 } },
77 : { { BLOCK_16X16, BLOCK_16X8 }, { BLOCK_8X16, BLOCK_8X8 } },
78 : { { BLOCK_16X32, BLOCK_16X16 }, { BLOCK_INVALID, BLOCK_8X16 } },
79 : { { BLOCK_32X16, BLOCK_INVALID}, { BLOCK_16X16, BLOCK_16X8 } },
80 : { { BLOCK_32X32, BLOCK_32X16 }, { BLOCK_16X32, BLOCK_16X16 } },
81 : { { BLOCK_32X64, BLOCK_32X32 }, { BLOCK_INVALID, BLOCK_16X32 } },
82 : { { BLOCK_64X32, BLOCK_INVALID}, { BLOCK_32X32, BLOCK_32X16 } },
83 : { { BLOCK_64X64, BLOCK_64X32 }, { BLOCK_32X64, BLOCK_32X32 } },
84 : { { BLOCK_64X128, BLOCK_64X64 }, { BLOCK_INVALID, BLOCK_32X64 } },
85 : { { BLOCK_128X64, BLOCK_INVALID }, { BLOCK_64X64, BLOCK_64X32 } },
86 : { { BLOCK_128X128, BLOCK_128X64 }, { BLOCK_64X128, BLOCK_64X64 } },
87 : { { BLOCK_4X16, BLOCK_4X8 }, { BLOCK_INVALID, BLOCK_4X8 } },
88 : { { BLOCK_16X4, BLOCK_INVALID}, { BLOCK_8X4, BLOCK_8X4 } },
89 : { { BLOCK_8X32, BLOCK_8X16 }, { BLOCK_INVALID, BLOCK_4X16 } },
90 : { { BLOCK_32X8, BLOCK_INVALID }, { BLOCK_16X8, BLOCK_16X4 } },
91 : { { BLOCK_16X64, BLOCK_16X32 }, { BLOCK_INVALID, BLOCK_8X32 } },
92 : { { BLOCK_64X16, BLOCK_INVALID }, { BLOCK_32X16, BLOCK_32X8 } }
93 : };
94 63078634 : static INLINE BlockSize get_plane_block_size(BlockSize bsize,
95 : int32_t subsampling_x,
96 : int32_t subsampling_y) {
97 63078634 : if (bsize == BLOCK_INVALID) return BLOCK_INVALID;
98 63078634 : return ss_size_lookup[bsize][subsampling_x][subsampling_y];
99 : }
100 :
101 1699522 : static INLINE TxSize av1_get_max_uv_txsize(BlockSize bsize, int32_t subsampling_x,
102 : int32_t subsampling_y)
103 : {
104 : const BlockSize plane_bsize =
105 1699522 : get_plane_block_size(bsize, subsampling_x, subsampling_y);
106 1699612 : TxSize uv_tx = TX_INVALID;
107 1699612 : if (plane_bsize < BlockSizeS_ALL)
108 1699622 : uv_tx = max_txsize_rect_lookup[plane_bsize];
109 1699612 : return av1_get_adjusted_tx_size(uv_tx);
110 : }
111 :
112 : #define NOT_USED_VALUE 0
113 : static const uint32_t parent_depth_offset[2][6] =
114 : { /*64x64*/ { NOT_USED_VALUE, 832, 208, 52, 8 ,NOT_USED_VALUE},
115 : /*128x128*/{ NOT_USED_VALUE,3320 , 832 ,208,52,8 }
116 : };
117 : static const uint32_t ns_depth_offset[2][6] =
118 : { /*64x64*/ { 1101 , 269 ,61,9,1 ,NOT_USED_VALUE},
119 : /*128x128*/{ 4421 , 1101 ,269 ,61,9,1 }
120 : };
121 : static const uint32_t d1_depth_offset[2][6] =
122 : { /*64x64*/ { 25,25,25, 5 ,1 ,NOT_USED_VALUE} ,
123 : /*128x128*/{ 17 , 25,25,25, 5 ,1 }
124 : };
125 :
126 : const BlockGeom * get_blk_geom_mds(uint32_t bidx_mds);
127 :
128 : // CU Stats Helper Functions
129 : typedef struct CodedUnitStats
130 : {
131 : uint8_t depth;
132 : uint8_t size;
133 : uint8_t size_log2;
134 : uint16_t origin_x;
135 : uint16_t origin_y;
136 : uint8_t cu_num_in_depth;
137 : uint8_t parent32x32_index;
138 : } CodedUnitStats;
139 :
140 : // PU Stats Helper Functions
141 : typedef struct PredictionUnitStats
142 : {
143 : uint8_t width;
144 : uint8_t height;
145 : uint8_t offset_x;
146 : uint8_t offset_y;
147 : } PredictionUnitStats;
148 :
149 : // TU Stats Helper Functions
150 : typedef struct TransformUnitStats
151 : {
152 : uint8_t depth;
153 : uint8_t offset_x;
154 : uint8_t offset_y;
155 : } TransformUnitStats;
156 :
157 : extern void *eb_aom_memalign(size_t align, size_t size);
158 : extern void *eb_aom_malloc(size_t size);
159 : extern void eb_aom_free(void *memblk);
160 : extern void *eb_aom_memset16(void *dest, int32_t val, size_t length);
161 :
162 : extern uint64_t log2f_high_precision(uint64_t x, uint8_t precision);
163 :
164 : extern const CodedUnitStats* get_coded_unit_stats(const uint32_t cuIdx);
165 : extern const TransformUnitStats* get_transform_unit_stats(const uint32_t tuIdx);
166 :
167 : #define PU_ORIGIN_ADJUST(cu_origin, cu_size, offset) ((((cu_size) * (offset)) >> 2) + (cu_origin))
168 : #define PU_SIZE_ADJUST(cu_size, puSize) (((cu_size) * (puSize)) >> 2)
169 :
170 : #define TU_ORIGIN_ADJUST(cu_origin, cu_size, offset) ((((cu_size) * (offset)) >> 2) + (cu_origin))
171 : #define TU_SIZE_ADJUST(cu_size, tuDepth) ((cu_size) >> (tuDepth))
172 :
173 : extern EbErrorType z_order_increment(uint32_t *x_loc, uint32_t *y_loc);
174 : extern void ZOrderIncrementWithLevel(
175 : uint32_t *x_loc,
176 : uint32_t *y_loc,
177 : uint32_t *level,
178 : uint32_t *index);
179 :
180 : extern uint32_t Log2f(uint32_t x);
181 : extern uint64_t Log2f64(uint64_t x);
182 : extern uint32_t endian_swap(uint32_t ui);
183 :
184 : /****************************
185 : * MACROS
186 : ****************************/
187 :
188 : #ifdef _MSC_VER
189 : #define MULTI_LINE_MACRO_BEGIN do {
190 : #define MULTI_LINE_MACRO_END \
191 : __pragma(warning(push)) \
192 : __pragma(warning(disable:4127)) \
193 : } while(0) \
194 : __pragma(warning(pop))
195 : #else
196 : #define MULTI_LINE_MACRO_BEGIN do {
197 : #define MULTI_LINE_MACRO_END } while(0)
198 : #endif
199 :
200 : //**************************************************
201 : // MACROS
202 : //**************************************************
203 : #define MAX(x, y) ((x)>(y)?(x):(y))
204 : #define MIN(x, y) ((x)<(y)?(x):(y))
205 : #define MEDIAN(a,b,c) ((a)>(b)?(a)>?(b)>?(b)::(a):(b)>?(a)>?(a)::(b))
206 : #define CLIP3(min_val, max_val, a) (((a)<(min_val)) ? (min_val) : (((a)>(max_val)) ? (max_val) :(a)))
207 : #define CLIP3EQ(min_val, max_val, a) (((a)<=(min_val)) ? (min_val) : (((a)>=(max_val)) ? (max_val) :(a)))
208 : #define BITDEPTH_MIDRANGE_VALUE(precision) (1 << ((precision) - 1))
209 : #define SWAP(a, b) MULTI_LINE_MACRO_BEGIN (a) ^= (b); (b) ^= (a); (a) ^= (b); MULTI_LINE_MACRO_END
210 : #define ABS(a) (((a) < 0) ? (-(a)) : (a))
211 : #define EB_ABS_DIFF(a,b) ((a) > (b) ? ((a) - (b)) : ((b) - (a)))
212 : #define EB_DIFF_SQR(a,b) (((a) - (b)) * ((a) - (b)))
213 : #define SQR(x) ((x)*(x))
214 : #define POW2(x) (1 << (x))
215 : #define SIGN(a,b) (((a - b) < 0) ? (-1) : ((a - b) > 0) ? (1) : 0)
216 : #define ROUND(a) (a >= 0) ? ( a + 1/2) : (a - 1/2);
217 : #define UNSIGNED_DEC(x) MULTI_LINE_MACRO_BEGIN (x) = (((x) > 0) ? ((x) - 1) : 0); MULTI_LINE_MACRO_END
218 : #define CIRCULAR_ADD(x,max) (((x) >= (max)) ? ((x) - (max)) : ((x) < 0) ? ((max) + (x)) : (x))
219 : #define CIRCULAR_ADD_UNSIGNED(x,max) (((x) >= (max)) ? ((x) - (max)) : (x))
220 : #define CEILING(x,base) ((((x) + (base) - 1) / (base)) * (base))
221 : #define POW2_CHECK(x) ((x) == ((x) & (-((int32_t)(x)))))
222 : #define ROUND_UP_MUL_8(x) ((x) + ((8 - ((x) & 0x7)) & 0x7))
223 : #define ROUND_UP_MULT(x,mult) ((x) + (((mult) - ((x) & ((mult)-1))) & ((mult)-1)))
224 :
225 : // rounds down to the next power of two
226 : #define FLOOR_POW2(x) \
227 : MULTI_LINE_MACRO_BEGIN \
228 : (x) |= ((x) >> 1); \
229 : (x) |= ((x) >> 2); \
230 : (x) |= ((x) >> 4); \
231 : (x) |= ((x) >> 8); \
232 : (x) |= ((x) >>16); \
233 : (x) -= ((x) >> 1); \
234 : MULTI_LINE_MACRO_END
235 :
236 : // rounds up to the next power of two
237 : #define CEIL_POW2(x) \
238 : MULTI_LINE_MACRO_BEGIN \
239 : (x) -= 1; \
240 : (x) |= ((x) >> 1); \
241 : (x) |= ((x) >> 2); \
242 : (x) |= ((x) >> 4); \
243 : (x) |= ((x) >> 8); \
244 : (x) |= ((x) >>16); \
245 : (x) += 1; \
246 : MULTI_LINE_MACRO_END
247 :
248 : // Calculates the Log2 floor of the integer 'x'
249 : // Intended to only be used for macro definitions
250 : #define LOG2F Log2f_SSE2
251 :
252 : #define LOG2F_8(x) ( \
253 : ((x) < 0x0002u) ? 0u : \
254 : ((x) < 0x0004u) ? 1u : \
255 : ((x) < 0x0008u) ? 2u : \
256 : ((x) < 0x0010u) ? 3u : \
257 : ((x) < 0x0020u) ? 4u : \
258 : ((x) < 0x0040u) ? 5u :6u )
259 :
260 : #define TWO_D_INDEX(x, y, stride) \
261 : (((y) * (stride)) + (x))
262 :
263 : // MAX_CU_COUNT is used to find the total number of partitions for the max partition depth and for
264 : // each parent partition up to the root partition level (i.e. SB level).
265 :
266 : // MAX_CU_COUNT is given by SUM from k=1 to n (4^(k-1)), reduces by using the following finite sum
267 : // SUM from k=1 to n (q^(k-1)) = (q^n - 1)/(q-1) => (4^n - 1) / 3
268 : #define MAX_CU_COUNT(max_depth_count) ((((1 << (max_depth_count)) * (1 << (max_depth_count))) - 1)/3)
269 :
270 : //**************************************************
271 : // CONSTANTS
272 : //**************************************************
273 : #define MIN_UNSIGNED_VALUE 0
274 : #define MAX_UNSIGNED_VALUE ~0u
275 : #define MIN_SIGNED_VALUE ~0 - ((signed) (~0u >> 1))
276 : #define MAX_SIGNED_VALUE ((signed) (~0u >> 1))
277 :
278 : // Helper functions for EbLinkedListNode.
279 :
280 : // concatenate two linked list, and return the pointer to the new concatenated list
281 : EbLinkedListNode* concat_eb_linked_list(EbLinkedListNode* a, EbLinkedListNode* b);
282 :
283 : // split a linked list into two. return the pointer to a linked list whose nodes meets the condition
284 : // predicate_func(node) == TRUE, the rest of the nodes will be collected into another linked list to which (*restLL) is
285 : // set. Does not gaurantee the original order of the nodes.
286 :
287 : EbLinkedListNode* split_eb_linked_list(EbLinkedListNode* input, EbLinkedListNode** restLL, EbBool(*predicate_func)(EbLinkedListNode*));
288 :
289 : #define MINI_GOP_MAX_COUNT 15
290 : #define MINI_GOP_WINDOW_MAX_COUNT 8 // widow subdivision: 8 x 3L
291 :
292 : #define MIN_HIERARCHICAL_LEVEL 2
293 : static const uint32_t mini_gop_offset[4] = { 1, 3, 7, 31 };
294 :
295 : typedef struct MiniGopStats
296 : {
297 : uint32_t hierarchical_levels;
298 : uint32_t start_index;
299 : uint32_t end_index;
300 : uint32_t lenght;
301 : } MiniGopStats;
302 : extern const MiniGopStats* get_mini_gop_stats(const uint32_t mini_gop_index);
303 : typedef enum MiniGopIndex {
304 : L6_INDEX = 0,
305 : L5_0_INDEX = 1,
306 : L4_0_INDEX = 2,
307 : L3_0_INDEX = 3,
308 : L3_1_INDEX = 4,
309 : L4_1_INDEX = 5,
310 : L3_2_INDEX = 6,
311 : L3_3_INDEX = 7,
312 : L5_1_INDEX = 8,
313 : L4_2_INDEX = 9,
314 : L3_4_INDEX = 10,
315 : L3_5_INDEX = 11,
316 : L4_3_INDEX = 12,
317 : L3_6_INDEX = 13,
318 : L3_7_INDEX = 14
319 : } MiniGopIndex;
320 :
321 : #ifdef __cplusplus
322 : }
323 : #endif
324 :
325 : #endif // EbUtility_h
|