You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
9.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
* Description: header file of math
*/
#ifndef __SOC_MATH_H__
#define __SOC_MATH_H__
#include "td_type.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/*
* soc_abs(x) absolute value of x
* soc_sign(x) sign of x
* soc_cmp(x,y) 0 if x==y; 1 if x>y; -1 if x<y
*/
#define soc_abs(x) ((x) >= 0 ? (x) : (-(x)))
#define soc_sign(x) ((x) >= 0 ? 1 : (-1))
#define soc_cmp(x, y) (((x) == (y)) ? 0 : (((x) > (y)) ? 1 : (-1)))
/*
* max2(x,y) maximum of x and y
* min2(x,y) minimum of x and y
* max3(x,y,z) maximum of x, y and z
* min3(x,y,z) minimun of x, y and z
* median(x,y,z) median of x,y,z
* mean2(x,y) mean of x,y
*/
#ifndef max2
#define max2(x, y) ((x) > (y) ? (x) : (y))
#endif
#ifndef min2
#define min2(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef max3
#define max3(x, y, z) ((x) > (y) ? max2(x, z) : max2(y, z))
#endif
#ifndef min3
#define min3(x, y, z) ((x) < (y) ? min2(x, z) : min2(y, z))
#endif
#define median(x, y, z) (((x) + (y) + (z) - max3(x, y, z)) - min3(x, y, z))
#define mean2(x, y) (((x) + (y)) >> 1)
/*
* clip3(x,min,max) clip x within [min,max]
* wrap_max(x,max,min) wrap to min if x equal max
* wrap_min(x,min,max) wrap to max if x equal min
* value_between(x,min.max) True if x is between [min,max] inclusively.
*/
#define clip3(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
#define wrap_max(x, max, min) ((x) >= (max) ? (min) : (x))
#define wrap_min(x, min, max) ((x) <= (min) ? (max) : (x))
#define value_between(x, min, max) (((x) >= (min)) && ((x) <= (max)))
/*
* multi_of_2_power(x,a) whether x is multiple of a(a must be power of 2)
* ceiling_2_power(x,a) ceiling x to multiple of a(a must be power of 2)
* floor_2_power(x,a) floor x to multiple of a(a must be power of 2)
* socalign(x, a) align x to multiple of a
*
* Example:
* ceiling_2_power(5,4) result is 8
* floor_2_power(5,4) result is 4
*/
#define multi_of_2_power(x, a) (!((x) & ((a) - 1)))
#define ceiling_2_power(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
#define floor_2_power(x, a) ((x) & (~((a) - 1)))
#define socalign(x, a) ((a) * (((x) + (a) - 1) / (a)))
#define socceiling(x, a) (((x) + (a) - 1) / (a))
#define socalign_up(x, a) ((((x) + (a) - 1) / (a)) * (a))
#define socalign_down(x, a) ((x) - (x) % (a))
#define socalign_closest(x, divisor) \
do { \
typeof(x)__x = x; \
typeof(divisor)__d = divisor; \
(((typeof(x)) - 1) > 0 || ((typeof(divisor)) - 1) > 0 || (__x) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : \
(((__x) - ((__d) / 2)) / (__d)); \
} while (0)
#if defined(SOC_DDRC_CHANNEL_DUAL)
#define soc_sys_get_stride(w) \
((((w) % 256) == 0) ? (w) : (((((w) / 256) % 2) == 0) ? ((((w) / 256) + 1) * 256) : ((((w) / 256) + 2) * 256)))
#elif defined(SOC_DDRC_CHANNEL_SINGLE)
#define soc_sys_get_stride(w) (socalign(w, 64))
#else
#define soc_sys_get_stride(w) (((w) + 63) / 64 * 64)
#endif
/*
* Get the span between two unsinged number, such as
* span(td_u32, 100, 200) is 200 - 100 = 100
* span(td_u32, 200, 100) is 0xFFFFFFFF - 200 + 100
* span(td_u64, 200, 100) is 0xFFFFFFFFFFFFFFFF - 200 + 100
*/
#define span(type, begin, end) \
do { \
type b = (begin); \
type e = (end); \
(type)((b >= e) ? (b - e) : (b + ((~((type)0)) - e))); \
} while (0)
/*
* endian32(x,y) little endian <---> big endian
* is_little_end() whether the system is little end mode
*/
#define endian32(x) (((x) << 24) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff))
typedef union un_end_test {
td_char ctest[4]; /* 4 <20><>ʾʹ<CABE><CAB9>4<EFBFBD><34><EFBFBD>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>˵<EFBFBD><CBB5><EFBFBD>ֵ */
td_u32 test;
} end_test_info;
__inline static td_bool is_little_end(void)
{
end_test_info end_test;
end_test.ctest[0] = 0x01; /* 0 <20><>ʾ<EFBFBD><CABE>1<EFBFBD><31><EFBFBD>ֽ<EFBFBD>λ<EFBFBD><CEBB> */
end_test.ctest[1] = 0x02; /* 1 <20><>ʾ<EFBFBD><CABE>2<EFBFBD><32><EFBFBD>ֽ<EFBFBD>λ<EFBFBD><CEBB> */
end_test.ctest[2] = 0x03; /* 2 <20><>ʾ<EFBFBD><CABE>3<EFBFBD><33><EFBFBD>ֽ<EFBFBD>λ<EFBFBD><CEBB> */
end_test.ctest[3] = 0x04; /* 3 <20><>ʾ<EFBFBD><CABE>4<EFBFBD><34><EFBFBD>ֽ<EFBFBD>λ<EFBFBD><CEBB> */
return (end_test.test > 0x01020304) ? (TD_TRUE) : (TD_FALSE);
}
/*
* fraction32(de,nu) fraction: nu(minator) / de(nominator).
* numerator32(x) of x(x is fraction)
* denominator32(x) Denominator of x(x is fraction)
* represent fraction in 32 bit. LSB 16 is numerator, MSB 16 is denominator
* It is integer if denominator is 0.
*/
#define fraction32(de, nu) (((de) << 16) | (nu))
#define numerator32(x) ((x)&0xffff)
#define denominator32(x) ((x) >> 16)
/* *****************************************************************************
* rgb(r,g,b) assemble the r,g,b to 24bit color
* rgb_r(c) get RED from 24bit color
* rgb_g(c) get GREEN from 24bit color
* rgb_b(c) get BLUE from 24bit color
* **************************************************************************** */
#define rgb(r, g, b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff))
#define rgb_r(c) (((c) & 0xff0000) >> 16)
#define rgb_g(c) (((c) & 0xff00) >> 8)
#define rgb_b(c) ((c) & 0xff)
/*
* yuv(y,u,v) assemble the y,u,v to 24bit color
* yuv_y(c) get Y from 24bit color
* yuv_u(c) get U from 24bit color
* yuv_v(c) get V from 24bit color
*/
#define yuv(y, u, v) ((((y) & 0xff) << 16) | (((u) & 0xff) << 8) | ((v) & 0xff))
#define yuv_y(c) (((c) & 0xff0000) >> 16)
#define yuv_u(c) (((c) & 0xff00) >> 8)
#define yuv_v(c) ((c) & 0xff)
/* *****************************************************************************
* rgb2yc(r, g, b, *y, *u, *u) convert r,g,b to y,u,v
* rgb2yuv(rgb_data, *yuv) convert rgb to yuv
* **************************************************************************** */
__inline static td_void rgb2yc(td_u8 r, td_u8 g, td_u8 b, td_u8 *py, td_u8 *pcb, td_u8 *pcr)
{
/* Y */
*py = (td_u8)(((r * 66 + g * 129 + b * 25) >> 8) + 16); /* 66 129 25 8 16 <20><>ʾrgbתyc<79><63>ʽ<EFBFBD><CABD>׼<EFBFBD><D7BC>ʽ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD> */
/* Cb */
*pcb = (td_u8)((((b * 112 - r * 38) - g * 74) >> 8) + 128); /* 112 38 74 8 128 <20><>ʾrgbתyc<79><63>ʽ<EFBFBD><CABD>׼<EFBFBD><D7BC>ʽ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD> */
/* Cr */
*pcr = (td_u8)((((r * 112 - g * 94) - b * 18) >> 8) + 128); /* 112 94 18 8 128 <20><>ʾrgbתyc<79><63>ʽ<EFBFBD><CABD>׼<EFBFBD><D7BC>ʽ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD> */
}
__inline static td_u32 rgb2yuv(td_u32 rgb_data)
{
td_u8 y, u, v;
rgb2yc(rgb_r(rgb_data), rgb_g(rgb_data), rgb_b(rgb_data), &y, &u, &v);
return yuv(y, u, v);
}
/* *****************************************************************************
* GetYCFromRGB(rgb_data, *y, *cbcr) convert rgb to yyyy, uvuv,
* **************************************************************************** */
__inline static td_void get_yc_from_rgb(td_u32 rgb_data, td_u32 *py, td_u32 *pc)
{
td_u8 y, cb, cr;
td_u32 color_y, color_c;
rgb2yc(rgb_r(rgb_data), rgb_g(rgb_data), rgb_b(rgb_data), &y, &cb, &cr);
/* 24 16 18 8 <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>color_yƫ<79><C6AB>λ<EFBFBD><CEBB> */
color_y = ((y & 0xFF) << 24) + ((y & 0xFF) << 16) + ((y & 0xFF) << 8) + (y & 0xFF);
color_c = ((cb & 0xFF) << 24) + ((cb & 0xFF) << 8); /* 24 8 <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>color_cƫ<63><C6AB>λ<EFBFBD><CEBB> */
color_c = color_c + ((cr & 0xFF) << 16) + (cr & 0xFF); /* 16 <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>color_cƫ<63><C6AB>λ<EFBFBD><CEBB> */
*py = color_y;
*pc = color_c;
}
/* ******************************************************************************
* fps_control Useing Sample:
* fps_ctrl g_stFpsCtrl;
*
* Take 12 frame uniform in 25.
* call like this : init_fps(&g_stFpsCtrl, 25, 12)
* if fps_control(&g_stFpsCtrl) return true
* then printf "Yes, this frmae should be token"
*
* ***************************************************************************** */
typedef struct soc_fps_ctrl {
td_u32 ffps; /* Full frame rate */
td_u32 tfps; /* Target frame rate */
td_u32 frm_key; /* update key frame */
} fps_ctrl;
__inline static td_void init_fps(fps_ctrl *frm_cttl_ptr, td_u32 full_fps, td_u32 tag_fps)
{
frm_cttl_ptr->ffps = full_fps;
frm_cttl_ptr->tfps = tag_fps;
frm_cttl_ptr->frm_key = 0;
}
__inline static td_bool fps_control(fps_ctrl *frm_cttl_ptr)
{
td_bool ret = TD_FALSE;
frm_cttl_ptr->frm_key += frm_cttl_ptr->tfps;
if (frm_cttl_ptr->frm_key >= frm_cttl_ptr->ffps) {
frm_cttl_ptr->frm_key -= frm_cttl_ptr->ffps;
ret = TD_TRUE;
}
return ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* __SOC_MATH_H__ */