1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef __HI_MATH_ADAPT_H__
17 #define __HI_MATH_ADAPT_H__
18
19 #include "hi_type.h"
20 #include "hi_math.h"
21
22 #ifdef __cplusplus
23 #if __cplusplus
24 extern "C" {
25 #endif
26 #endif /* __cplusplus */
27
28 /*
29 * hi_abs(x) absolute value of x
30 * sign(x) sign of x
31 * cmp(x,y) 0 if x==y; 1 if x>y; -1 if x<y
32 */
33 #define hi_abs(x) ((x) >= 0 ? (x) : (-(x)))
34 #define _sign(x) ((x) >= 0 ? 1 : (-1))
35 #define cmp(x, y) (((x) == (y)) ? 0 : (((x) > (y)) ? 1 : (-1)))
36
37 /*
38 * hi_max2(x,y) maximum of x and y
39 * hi_min2(x,y) minimum of x and y
40 * hi_max3(x,y,z) maximum of x, y and z
41 * hi_min3(x,y,z) minimum of x, y and z
42 * median(x,y,z) median of x,y,z
43 * mean2(x,y) mean of x,y
44 */
45 #define hi_max2(x, y) ((x) > (y) ? (x) : (y))
46 #define hi_min2(x, y) ((x) < (y) ? (x) : (y))
47 #define hi_max3(x, y, z) ((x) > (y) ? hi_max2(x, z) : hi_max2(y, z))
48 #define hi_min3(x, y, z) ((x) < (y) ? hi_min2(x, z) : hi_min2(y, z))
49 #define median(x, y, z) (((x) + (y) + (z) - hi_max3(x, y, z)) - hi_min3(x, y, z))
50 #define mean2(x, y) (((x) + (y)) >> 1)
51
52 /*
53 * clip3(x,min,max) clip x within [min,max]
54 * wrap_max(x,max,min) wrap to min if x equal max
55 * wrap_min(x,min,max) wrap to max if x equal min
56 * value_between(x,min.max) True if x is between [min,max] inclusively.
57 */
58 #define clip_min(x, min) (((x) >= (min)) ? (x) : (min))
59 #define clip3(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
60 #define clip_max(x, max) ((x) > (max) ? (max) : (x))
61 #define wrap_max(x, max, min) ((x) >= (max) ? (min) : (x))
62 #define wrap_min(x, min, max) ((x) <= (min) ? (max) : (x))
63 #define value_between(x, min, max) (((x) >= (min)) && ((x) <= (max)))
64
65 /*
66 * multi_of_2_power(x,a) whether x is multiple of a(a must be power of 2)
67 * align_down(x,a) floor x to multiple of a(a must be power of 2)
68 * align_up(x, a) align x to multiple of a
69 *
70 * Example:
71 * align_up(5,4) = 8
72 * align_down(5,4) = 4
73 */
74 #define multi_of_2_power(x, a) (!((x) & ((a) - 1)))
75 #define hiceiling(x, a) (((x) + (a) - 1) / (a))
76
77 #define align_up(x, a) ((((x) + ((a) - 1)) / (a)) * (a))
78 #define align_down(x, a) (((x) / (a)) * (a))
79
80 #define div_up(x, a) (((x) + ((a) - 1)) / (a))
81
82 /*
83 * Get the span between two unsigned number, such as
84 * span(hi_u32, 100, 200) is 200 - 100 = 100
85 * span(hi_u32, 200, 100) is 0xFFFFFFFF - 200 + 100
86 * span(hi_u64, 200, 100) is 0xFFFFFFFFFFFFFFFF - 200 + 100
87 */
88 #define span(type, begin, end) \
89 ({ \
90 type b = (begin); \
91 type e = (end); \
92 (type)((b >= e) ? (b - e) : (b + ((~((type)0)) - e))); \
93 })
94
95 /*
96 * endian32(x,y) little endian <---> big endian
97 */
98 #define endian32(x) \
99 (((x) << 24) | \
100 (((x) & 0x0000ff00) << 8) | \
101 (((x) & 0x00ff0000) >> 8) | \
102 (((x) >> 24) & 0x000000ff))
103
104 /*
105 * endian16(x,y) little endian <---> big endian
106 * is_little_end() whether the system is little end mode
107 */
108 #define endian16(x) ((((x) << 8) & 0xff00) | (((x) >> 8) & 255))
is_little_end(void)109 __inline static hi_bool is_little_end(void)
110 {
111 union un_end_test_u {
112 hi_char test[4];
113 hi_u32 test_full;
114 } un_end_test;
115
116 un_end_test.test[0] = 0x01;
117 un_end_test.test[1] = 0x02;
118 un_end_test.test[2] = 0x03;
119 un_end_test.test[3] = 0x04;
120
121 return (un_end_test.test_full > 0x01020304) ? (HI_TRUE) : (HI_FALSE);
122 }
123
124 /*
125 * fraction32(de,nu) fraction: nu(minator) / de(nominator).
126 * numerator32(x) of x(x is fraction)
127 * denominator32(x) Denominator of x(x is fraction)
128
129 * represent fraction in 32 bit. LSB 16 is numerator, MSB 16 is denominator
130 * It is integer if denominator is 0.
131 */
132 #define fraction32(de, nu) (((de) << 16) | (nu))
133 #define numerator32(x) ((x) & 0xffff)
134 #define denominator32(x) ((x) >> 16)
135
136 /*
137 * rgb(r,g,b) assemble the r,g,b to 24bit color
138 * rgb_r(c) get RED from 24bit color
139 * rgb_g(c) get GREEN from 24bit color
140 * rgb_b(c) get BLUE from 24bit color
141 */
142 #define rgb(r, g, b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff))
143 #define rgb_r(c) (((c) & 0xff0000) >> 16)
144 #define rgb_g(c) (((c) & 0xff00) >> 8)
145 #define rgb_b(c) ((c) & 0xff)
146
147 /*
148 * yuv(y,u,v) assemble the y,u,v to 30bit color
149 * yuv_y(c) get Y from 30bit color
150 * yuv_u(c) get U from 30bit color
151 * yuv_v(c) get V from 30bit color
152 */
153 #define yuv(y, u, v) ((((y) & 0x03ff) << 20) | (((u) & 0x03ff) << 10) | ((v) & 0x03ff))
154 #define yuv_y(c) (((c) & 0x3ff00000) >> 20)
155 #define yuv_u(c) (((c) & 0x000ffc00) >> 10)
156 #define yuv_v(c) ((c) & 0x000003ff)
157
158 /*
159 * yuv_8bit(y,u,v) assemble the y,u,v to 24bit color
160 * yuv_8bit_y(c) get Y from 24bit color
161 * yuv_8bit_u(c) get U from 24bit color
162 * yuv_8bit_v(c) get V from 24bit color
163 */
164 #define yuv_8bit(y, u, v) ((((y) & 0xff) << 16) | (((u) & 0xff) << 8) | ((v) & 0xff))
165 #define yuv_8bit_y(c) (((c) & 0xff0000) >> 16)
166 #define yuv_8bit_u(c) (((c) & 0xff00) >> 8)
167 #define yuv_8bit_v(c) ((c) & 0xff)
168 /*
169 * rgb2_yc(r, g, b, *y, *u, *u) convert r,g,b to y,u,v
170 * rgb2_yuv(rgb) convert rgb to yuv
171 */
rgb2_yc(hi_u16 r,hi_u16 g,hi_u16 b,hi_u16 * py,hi_u16 * pcb,hi_u16 * pcr)172 __inline static hi_void rgb2_yc(hi_u16 r, hi_u16 g, hi_u16 b, hi_u16 *py, hi_u16 *pcb, hi_u16 *pcr)
173 {
174 /* Y */
175 *py = (hi_u16)((((r * 66 + g * 129 + b * 25) >> 8) + 16) << 2);
176
177 /* cb */
178 *pcb = (hi_u16)(((((b * 112 - r * 38) - g * 74) >> 8) + 128) << 2);
179
180 /* cr */
181 *pcr = (hi_u16)(((((r * 112 - g * 94) - b * 18) >> 8) + 128) << 2);
182 }
183
rgb2_yuv(hi_u32 rgb)184 __inline static hi_u32 rgb2_yuv(hi_u32 rgb)
185 {
186 hi_u16 y, u, v;
187
188 rgb2_yc(rgb_r(rgb), rgb_g(rgb), rgb_b(rgb), &y, &u, &v);
189
190 return yuv(y, u, v);
191 }
192
rgb2_yc_full(hi_u16 r,hi_u16 g,hi_u16 b,hi_u16 * py,hi_u16 * pcb,hi_u16 * pcr)193 __inline static hi_void rgb2_yc_full(hi_u16 r, hi_u16 g, hi_u16 b, hi_u16 *py, hi_u16 *pcb, hi_u16 *pcr)
194 {
195 hi_u16 py_temp, pcb_temp, pcr_temp;
196
197 py_temp = (hi_u16)(((r * 76 + g * 150 + b * 29) >> 8) * 4);
198 pcb_temp = (hi_u16)(clip_min(((((b * 130 - r * 44) - g * 86) >> 8) + 128), 0) * 4);
199 pcr_temp = (hi_u16)(clip_min(((((r * 130 - g * 109) - b * 21) >> 8) + 128), 0) * 4);
200
201 *py = hi_max2(hi_min2(py_temp, 1023), 0);
202 *pcb = hi_max2(hi_min2(pcb_temp, 1023), 0);
203 *pcr = hi_max2(hi_min2(pcr_temp, 1023), 0);
204 }
205
rgb2_yuv_full(hi_u32 rgb)206 __inline static hi_u32 rgb2_yuv_full(hi_u32 rgb)
207 {
208 hi_u16 y, u, v;
209
210 rgb2_yc_full(rgb_r(rgb), rgb_g(rgb), rgb_b(rgb), &y, &u, &v);
211
212 return yuv(y, u, v);
213 }
214
215 /*
216 * rgb2_yc_8_bit(r, g, b, *y, *u, *u) convert r,g,b to y,u,v
217 * rgb2_yuv_8_bit(rgb) convert rgb to yuv
218 */
rgb2_yc_8_bit(hi_u8 r,hi_u8 g,hi_u8 b,hi_u8 * py,hi_u8 * pcb,hi_u8 * pcr)219 __inline static hi_void rgb2_yc_8_bit(hi_u8 r, hi_u8 g, hi_u8 b, hi_u8 *py, hi_u8 *pcb, hi_u8 *pcr)
220 {
221 /* Y */
222 *py = (hi_u8)(((r * 66 + g * 129 + b * 25) >> 8) + 16);
223
224 /* cb */
225 *pcb = (hi_u8)((((b * 112 - r * 38) - g * 74) >> 8) + 128);
226
227 /* cr */
228 *pcr = (hi_u8)((((r * 112 - g * 94) - b * 18) >> 8) + 128);
229 }
230
rgb2_yuv_8_bit(hi_u32 rgb)231 __inline static hi_u32 rgb2_yuv_8_bit(hi_u32 rgb)
232 {
233 hi_u8 y, u, v;
234
235 rgb2_yc_8_bit(rgb_r(rgb), rgb_g(rgb), rgb_b(rgb), &y, &u, &v);
236
237 return yuv_8bit(y, u, v);
238 }
239
rgb2_yc_full_8_bit(hi_u8 r,hi_u8 g,hi_u8 b,hi_u8 * py,hi_u8 * pcb,hi_u8 * pcr)240 __inline static hi_void rgb2_yc_full_8_bit(hi_u8 r, hi_u8 g, hi_u8 b, hi_u8 *py, hi_u8 *pcb, hi_u8 *pcr)
241 {
242 hi_s16 py_temp, pcb_temp, pcr_temp;
243
244 py_temp = (r * 76 + g * 150 + b * 29) >> 8;
245 pcb_temp = (((b * 130 - r * 44) - g * 86) >> 8) + 128;
246 pcr_temp = (((r * 130 - g * 109) - b * 21) >> 8) + 128;
247
248 *py = hi_max2(hi_min2(py_temp, 255), 0);
249 *pcb = hi_max2(hi_min2(pcb_temp, 255), 0);
250 *pcr = hi_max2(hi_min2(pcr_temp, 255), 0);
251 }
252
rgb2_yuv_full_8_bit(hi_u32 rgb)253 __inline static hi_u32 rgb2_yuv_full_8_bit(hi_u32 rgb)
254 {
255 hi_u8 y, u, v;
256
257 rgb2_yc_full_8_bit(rgb_r(rgb), rgb_g(rgb), rgb_b(rgb), &y, &u, &v);
258
259 return yuv_8bit(y, u, v);
260 }
261
262 /*
263 * fps_control using sample:
264 * fps_ctrl g_fps_ctrl;
265 *
266 * take 12 frame uniform in 25.
267 * init_fps(&g_fps_ctrl, 25, 12);
268 *
269 * {
270 * if(fps_control(&g_fps_ctrl)) printf("yes, this frmae should be token");
271 * }
272 *
273 */
274 typedef struct {
275 hi_u32 ffps; /* full frame rate */
276 hi_u32 tfps; /* target frame rate */
277 hi_u32 frm_key; /* update key frame */
278 } fps_ctrl;
279
init_fps(fps_ctrl * frm_ctrl,hi_u32 full_fps,hi_u32 tag_fps)280 __inline static hi_void init_fps(fps_ctrl *frm_ctrl, hi_u32 full_fps, hi_u32 tag_fps)
281 {
282 frm_ctrl->ffps = full_fps;
283 frm_ctrl->tfps = tag_fps;
284 frm_ctrl->frm_key = 0;
285 }
286
fps_control(fps_ctrl * frm_ctrl)287 __inline static hi_bool fps_control(fps_ctrl *frm_ctrl)
288 {
289 hi_bool ret = HI_FALSE;
290
291 frm_ctrl->frm_key += frm_ctrl->tfps;
292 if (frm_ctrl->frm_key >= frm_ctrl->ffps) {
293 frm_ctrl->frm_key -= frm_ctrl->ffps;
294 ret = HI_TRUE;
295 }
296
297 return ret;
298 }
299
get_low_addr(hi_u64 phyaddr)300 __inline static hi_u32 get_low_addr(hi_u64 phyaddr)
301 {
302 return (hi_u32)phyaddr;
303 }
304
get_high_addr(hi_u64 phyaddr)305 __inline static hi_u32 get_high_addr(hi_u64 phyaddr)
306 {
307 return (hi_u32)(phyaddr >> 32);
308 }
309
310 #ifdef __cplusplus
311 #if __cplusplus
312 }
313 #endif
314 #endif /* __cplusplus */
315
316 #endif /* __HI_ADAPT_MATH_H__ */
317
318