• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_H__
17 #define __HI_MATH_H__
18 
19 #include "hi_type.h"
20 
21 #ifdef __cplusplus
22 #if __cplusplus
23 extern "C" {
24 #endif
25 #endif /* __cplusplus */
26 
27 /*
28  * ABS(x)                 absolute value of x
29  * SIGN(x)                sign of x
30  * CMP(x,y)               0 if x == y; 1 if x > y; -1 if x < y
31  */
32 #define ABS(x)          ((x) >= 0 ? (x) : (-(x)))
33 #define _SIGN(x)         ((x) >= 0 ? 1 : (-1))
34 #define CMP(x, y)        (((x) == (y)) ? 0 : (((x) > (y)) ? 1 : (-1)))
35 
36 /*
37  * MAX2(x,y)              maximum of x and y
38  * MIN2(x,y)              minimum of x and y
39  * MAX3(x,y,z)            maximum of x, y and z
40  * MIN3(x,y,z)            minimum of x, y and z
41  * MEDIAN(x,y,z)          median of x,y,z
42  * MEAN2(x,y)             mean of x,y
43  */
44 #define MAX2(x, y)        ((x) > (y) ? (x) : (y))
45 #ifndef MIN2
46 #define MIN2(x, y)        ((x) < (y) ? (x) : (y))
47 #endif
48 #define MAX3(x, y, z)     ((x) > (y) ? MAX2(x, z) : MAX2(y, z))
49 #define MIN3(x, y, z)     ((x) < (y) ? MIN2(x, z) : MIN2(y, z))
50 #define MEDIAN(x, y, z)   (((x) + (y) + (z) - MAX3(x, y, z)) - MIN3(x, y, z))
51 #define MEAN2(x, y)       (((x) + (y)) >> 1)
52 
53 /*
54  * CLIP3(x,min,max)       clip x within [min,max]
55  * WRAP_MAX(x,max,min)    wrap to min if x equal max
56  * WRAP_MIN(x,min,max)    wrap to max if x equal min
57  * VALUE_BETWEEN(x,min.max)   True if x is between [min,max] inclusively.
58  */
59 #define CLIP_MIN(x, min)          (((x) >= (min)) ? (x) : (min))
60 #define CLIP3(x, min, max)         ((x) < (min) ? (min) : ((x) > (max) ? (max) :(x)))
61 #define CLIP_MAX(x, max)          ((x) > (max) ? (max) : (x))
62 #define WRAP_MAX(x, max, min)      ((x) >= (max) ? (min) : (x))
63 #define WRAP_MIN(x, min, max)      ((x) <= (min) ? (max) : (x))
64 #define VALUE_BETWEEN(x, min, max) (((x) >= (min)) && ((x) <= (max)))
65 
66 /*
67  * MULTI_OF_2_POWER(x,a)  whether x is multiple of a(a must be power of 2)
68  * HI_ALIGN_DOWN(x,a)     floor x to multiple of a(a must be power of 2)
69  * HI_ALIGN_UP(x, a)            align x to multiple of a
70  *
71  * Example:
72  * HI_ALIGN_UP(5,4) = 8
73  * HI_ALIGN_DOWN(5,4)   = 4
74  */
75 #define MULTI_OF_2_POWER(x, a)    (!((x) & ((a) - 1)))
76 #define HICEILING(x, a)           (((x) + (a) - 1) / (a))
77 
78 #define HI_ALIGN_UP(x, a)           ((((x) + ((a) - 1)) / (a)) * (a))
79 #define HI_ALIGN_DOWN(x, a)         (((x) / (a)) * (a))
80 #define ALIGN_UP(x, a)              ((((x) + ((a) - 1)) / (a)) * (a))
81 #define ALIGN_DOWN(x, a)            (((x) / (a)) * (a))
82 
83 #define DIV_UP(x, a)             (((x) + ((a) - 1)) / (a))
84 
85 /*
86  * Get the span between two unsigned number, such as
87  * SPAN(HI_U32, 200, 100) is 200 - 100 = 100
88  * SPAN(HI_U32, 100, 200) is 0xFFFFFFFF - 200 + 100
89  * SPAN(HI_U64, 100, 200) is 0xFFFFFFFFFFFFFFFF - 200 + 100
90  */
91 #define SPAN(type, begin, end) \
92 ({                             \
93     type b = (begin);          \
94     type e = (end);            \
95     (type)((b >= e) ? (b - e) : (b + ((~((type)0)) - e))); \
96 })
97 
98 /*
99  * ENDIAN32(x,y)              little endian <---> big endian
100  * IS_LITTLE_END()            whether the system is little end mode
101  */
102 #define  ENDIAN32(x)                   \
103     (((x) << 24) |                     \
104     (((x) & 0x0000ff00) << 8) |        \
105     (((x) & 0x00ff0000) >> 8) |        \
106     (((x) >> 24) & 0x000000ff))
107 
108 /*
109  * ENDIAN16(x,y)              little endian <---> big endian
110  * IS_LITTLE_END()            whether the system is little end mode
111  */
112 #define  ENDIAN16(x)    ((((x) << 8) & 0xff00) | (((x) >> 8) & 255))
113 
IS_LITTLE_END(void)114 __inline static HI_BOOL IS_LITTLE_END(void)
115 {
116     union unEND_TEST_U {
117         HI_CHAR cTest[4];
118         HI_U32 u32Test;
119     } unEndTest;
120 
121     unEndTest.cTest[0] = 0x01;
122     unEndTest.cTest[1] = 0x02;
123     unEndTest.cTest[2] = 0x03;
124     unEndTest.cTest[3] = 0x04;
125 
126     return (unEndTest.u32Test > 0x01020304) ? (HI_TRUE) : (HI_FALSE);
127 }
128 
129 /*
130  * FRACTION32(de,nu)          fraction: nu(minator) / de(nominator).
131  * NUMERATOR32(x)              of x(x is fraction)
132  * DENOMINATOR32(x)           Denominator of x(x is fraction)
133 
134  * represent fraction in 32 bit. LSB 16 is numerator, MSB 16 is denominator
135  * It is integer if denominator is 0.
136  */
137 #define FRACTION32(de, nu)       (((de) << 16) | (nu))
138 #define NUMERATOR32(x)          ((x) & 0xffff)
139 #define DENOMINATOR32(x)        ((x) >> 16)
140 
141 /*
142  * RGB(r,g,b)    assemble the r,g,b to 24bit color
143  * RGB_R(c)      get RED   from 24bit color
144  * RGB_G(c)      get GREEN from 24bit color
145  * RGB_B(c)      get BLUE  from 24bit color
146  */
147 #define RGB(r, g, b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff))
148 #define RGB_R(c)   (((c) & 0xff0000) >> 16)
149 #define RGB_G(c)   (((c) & 0xff00) >> 8)
150 #define RGB_B(c)   ((c) & 0xff)
151 
152 /*
153  * YUV(y,u,v)    assemble the y,u,v to 30bit color
154  * YUV_Y(c)      get Y from 30bit color
155  * YUV_U(c)      get U from 30bit color
156  * YUV_V(c)      get V from 30bit color
157  */
158 #define YUV(y, u, v) ((((y) & 0x03ff) << 20) | (((u) & 0x03ff) << 10) | ((v) & 0x03ff))
159 #define YUV_Y(c)   (((c) & 0x3ff00000) >> 20)
160 #define YUV_U(c)   (((c) & 0x000ffc00) >> 10)
161 #define YUV_V(c)   ((c) & 0x000003ff)
162 
163 /*
164  * YUV_8BIT(y,u,v)    assemble the y,u,v to 24bit color
165  * YUV_8BIT_Y(c)      get Y from 24bit color
166  * YUV_8BIT_U(c)      get U from 24bit color
167  * YUV_8BIT_V(c)      get V from 24bit color
168  */
169 #define YUV_8BIT(y, u, v) ((((y) & 0xff) << 16) | (((u) & 0xff) << 8) | ((v) & 0xff))
170 #define YUV_8BIT_Y(c)   (((c) & 0xff0000) >> 16)
171 #define YUV_8BIT_U(c)   (((c) & 0xff00) >> 8)
172 #define YUV_8BIT_V(c)   ((c) & 0xff)
173 
174 /*
175  * Rgb2Yc(r, g, b, *y, *u, *u)    convert r,g,b to y,u,v
176  * Rgb2Yuv(rgb)             convert rgb to yuv
177  */
Rgb2Yc(HI_U16 r,HI_U16 g,HI_U16 b,HI_U16 * py,HI_U16 * pcb,HI_U16 * pcr)178 __inline static HI_VOID Rgb2Yc(HI_U16 r, HI_U16 g, HI_U16 b, HI_U16 *py, HI_U16 *pcb, HI_U16 *pcr)
179 {
180     /* Y */
181     *py = (HI_U16)((((r * 66 + g * 129 + b * 25) >> 8) + 16) << 2);
182 
183     /* Cb */
184     *pcb = (HI_U16)(((((b * 112 - r * 38) - g * 74) >> 8) + 128) << 2);
185 
186     /* Cr */
187     *pcr = (HI_U16)(((((r * 112 - g * 94) - b * 18) >> 8) + 128) << 2);
188 }
189 
Rgb2Yuv(HI_U32 u32Rgb)190 __inline static HI_U32 Rgb2Yuv(HI_U32 u32Rgb)
191 {
192     HI_U16 y, u, v;
193 
194     Rgb2Yc(RGB_R(u32Rgb), RGB_G(u32Rgb), RGB_B(u32Rgb), &y, &u, &v);
195 
196     return YUV(y, u, v);
197 }
198 
Rgb2Yc_full(HI_U16 r,HI_U16 g,HI_U16 b,HI_U16 * py,HI_U16 * pcb,HI_U16 * pcr)199 __inline static HI_VOID Rgb2Yc_full(HI_U16 r, HI_U16 g, HI_U16 b, HI_U16 *py, HI_U16 *pcb, HI_U16 *pcr)
200 {
201     HI_U16 py_temp, pcb_temp, pcr_temp;
202 
203     py_temp = (HI_U16)(((r * 76 + g * 150 + b * 29) >> 8) * 4);
204     pcb_temp = (HI_U16)(CLIP_MIN(((((b * 130 - r * 44) - g * 86) >> 8) + 128), 0) * 4);
205     pcr_temp = (HI_U16)(CLIP_MIN(((((r * 130 - g * 109) - b * 21) >> 8) + 128), 0) * 4);
206 
207     *py = MAX2(MIN2(py_temp, 1023), 0);
208     *pcb = MAX2(MIN2(pcb_temp, 1023), 0);
209     *pcr = MAX2(MIN2(pcr_temp, 1023), 0);
210 }
211 
Rgb2Yuv_full(HI_U32 u32Rgb)212 __inline static HI_U32 Rgb2Yuv_full(HI_U32 u32Rgb)
213 {
214     HI_U16 y, u, v;
215 
216     Rgb2Yc_full(RGB_R(u32Rgb), RGB_G(u32Rgb), RGB_B(u32Rgb), &y, &u, &v);
217 
218     return YUV(y, u, v);
219 }
220 
221 /*
222  * Rgb2Yc_8BIT(r, g, b, *y, *u, *u)    convert r,g,b to y,u,v
223  * Rgb2Yuv_8BIT(rgb)                   convert rgb to yuv
224  */
Rgb2Yc_8BIT(HI_U8 r,HI_U8 g,HI_U8 b,HI_U8 * py,HI_U8 * pcb,HI_U8 * pcr)225 __inline static HI_VOID Rgb2Yc_8BIT(HI_U8 r, HI_U8 g, HI_U8 b, HI_U8 *py, HI_U8 *pcb, HI_U8 *pcr)
226 {
227     /* Y */
228     *py = (HI_U8)(((r * 66 + g * 129 + b * 25) >> 8) + 16);
229 
230     /* Cb */
231     *pcb = (HI_U8)((((b * 112 - r * 38) - g * 74) >> 8) + 128);
232 
233     /* Cr */
234     *pcr = (HI_U8)((((r * 112 - g * 94) - b * 18) >> 8) + 128);
235 }
236 
Rgb2Yuv_8BIT(HI_U32 u32Rgb)237 __inline static HI_U32 Rgb2Yuv_8BIT(HI_U32 u32Rgb)
238 {
239     HI_U8 y, u, v;
240 
241     Rgb2Yc_8BIT(RGB_R(u32Rgb), RGB_G(u32Rgb), RGB_B(u32Rgb), &y, &u, &v);
242 
243     return YUV_8BIT(y, u, v);
244 }
245 
Rgb2Yc_full_8BIT(HI_U8 r,HI_U8 g,HI_U8 b,HI_U8 * py,HI_U8 * pcb,HI_U8 * pcr)246 __inline static HI_VOID Rgb2Yc_full_8BIT(HI_U8 r, HI_U8 g, HI_U8 b, HI_U8 *py, HI_U8 *pcb, HI_U8 *pcr)
247 {
248     HI_S16 py_temp, pcb_temp, pcr_temp;
249 
250     py_temp = (r * 76 + g * 150 + b * 29) >> 8;
251     pcb_temp = (((b * 130 - r * 44) - g * 86) >> 8) + 128;
252     pcr_temp = (((r * 130 - g * 109) - b * 21) >> 8) + 128;
253 
254     *py = MAX2(MIN2(py_temp, 255), 0);
255     *pcb = MAX2(MIN2(pcb_temp, 255), 0);
256     *pcr = MAX2(MIN2(pcr_temp, 255), 0);
257 }
258 
Rgb2Yuv_full_8BIT(HI_U32 u32Rgb)259 __inline static HI_U32 Rgb2Yuv_full_8BIT(HI_U32 u32Rgb)
260 {
261     HI_U8 y, u, v;
262 
263     Rgb2Yc_full_8BIT(RGB_R(u32Rgb), RGB_G(u32Rgb), RGB_B(u32Rgb), &y, &u, &v);
264 
265     return YUV_8BIT(y, u, v);
266 }
267 
268 /*
269  * FpsControl Using Sample:
270  *  FPS_CTRL_S g_stFpsCtrl;
271  *
272  *  Take 12 frame uniform in 25.
273  *  InitFps(&g_stFpsCtrl, 25, 12);
274  *
275  *  {
276  *       if(FpsControl(&g_stFpsCtrl)) printf("Yes, this frame should be token");
277  *  }
278  *
279  */
280 typedef struct hiFPS_CTRL_S {
281     HI_U32 u32Ffps; /* Full frame rate    */
282     HI_U32 u32Tfps; /* Target frame rate  */
283     HI_U32 u32FrmKey; /* update key frame   */
284 } FPS_CTRL_S;
285 
InitFps(FPS_CTRL_S * pFrmCtrl,HI_U32 u32FullFps,HI_U32 u32TagFps)286 __inline static HI_VOID InitFps(FPS_CTRL_S *pFrmCtrl, HI_U32 u32FullFps, HI_U32 u32TagFps)
287 {
288     pFrmCtrl->u32Ffps   = u32FullFps;
289     pFrmCtrl->u32Tfps   = u32TagFps;
290     pFrmCtrl->u32FrmKey = 0;
291 }
292 
FpsControl(FPS_CTRL_S * pFrmCtrl)293 __inline static HI_BOOL FpsControl(FPS_CTRL_S *pFrmCtrl)
294 {
295     HI_BOOL bReturn = HI_FALSE;
296 
297     pFrmCtrl->u32FrmKey += pFrmCtrl->u32Tfps;
298     if (pFrmCtrl->u32FrmKey >= pFrmCtrl->u32Ffps) {
299         pFrmCtrl->u32FrmKey -= pFrmCtrl->u32Ffps;
300         bReturn = HI_TRUE;
301     }
302 
303     return bReturn;
304 }
305 
GetLowAddr(HI_U64 u64Phyaddr)306 __inline static HI_U32 GetLowAddr(HI_U64 u64Phyaddr)
307 {
308     return (HI_U32)u64Phyaddr;
309 }
310 
GetHighAddr(HI_U64 u64Phyaddr)311 __inline static HI_U32 GetHighAddr(HI_U64 u64Phyaddr)
312 {
313     return (HI_U32)(u64Phyaddr >> 32);
314 }
315 
316 #define hi_usleep(usec) \
317     do { \
318         usleep(usec); \
319     } while (0)
320 
321 #ifdef __cplusplus
322 #if __cplusplus
323 }
324 #endif
325 #endif /* __cplusplus */
326 
327 #endif /* __HI_MATH_H__ */
328 
329