• 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_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