diff --git a/src/error.c b/src/error.c index 5c4d2ee..f94c84f 100644 --- a/src/error.c +++ b/src/error.c @@ -28,7 +28,7 @@ char *errstr(int error) { case I6_SYS_MOD_AO: error |= (V4_SYS_MOD_AO << 16); break; case I6_SYS_MOD_LDC: - error |= (V4_SYS_MOD_FISHEYE << 16); break; + error |= (V4_SYS_MOD_GDC << 16); break; case I6_SYS_MOD_CIPHER: error |= (0x4D << 16); break; case I6_SYS_MOD_IVE: @@ -58,7 +58,7 @@ char *errstr(int error) { case I6C_SYS_MOD_AO: error |= (V4_SYS_MOD_AO << 16); break; case I6C_SYS_MOD_LDC: - error |= (V4_SYS_MOD_FISHEYE << 16); break; + error |= (V4_SYS_MOD_GDC << 16); break; case I6C_SYS_MOD_CIPHER: error |= (0x4D << 16); break; case I6C_SYS_MOD_IVE: @@ -88,7 +88,7 @@ char *errstr(int error) { case I6F_SYS_MOD_AO: error |= (V4_SYS_MOD_AO << 16); break; case I6F_SYS_MOD_LDC: - error |= (V4_SYS_MOD_FISHEYE << 16); break; + error |= (V4_SYS_MOD_GDC << 16); break; case I6F_SYS_MOD_CIPHER: error |= (0x4D << 16); break; case I6F_SYS_MOD_IVE: diff --git a/src/hal/hisi/v3_aud.h b/src/hal/hisi/v3_aud.h new file mode 100644 index 0000000..d252afa --- /dev/null +++ b/src/hal/hisi/v3_aud.h @@ -0,0 +1,126 @@ +#pragma once + +#include "v3_common.h" + +#define V3_AUD_CHN_NUM 2 + +typedef enum { + V3_AUD_BIT_8, + V3_AUD_BIT_16, + V3_AUD_BIT_24 +} v3_aud_bit; + +typedef enum { + V3_AUD_INTF_I2S_MASTER, + V3_AUD_INTF_I2S_SLAVE, + V3_AUD_INTF_PCM_SLAVE_STD, + V3_AUD_INTF_PCM_SLAVE_NSTD, + V3_AUD_INTF_PCM_MASTER_STD, + V3_AUD_INTF_PCM_MASTER_NSTD, + V3_AUD_INTF_END +} v3_aud_intf; + +typedef struct { + // Accept industry standards from + // 8000 to 96000Hz, plus 64000Hz + int rate; + v3_aud_bit bit; + v3_aud_intf intf; + int stereoOn; + // 8-to-16 bit, expand mode + int expandOn; + unsigned int frmNum; + unsigned int packNumPerFrm; + unsigned int chnNum; + unsigned int syncRxClkOn; +} v3_aud_cnf; + +typedef struct { + v3_aud_bit bit; + int stereoOn; + void *addr[2]; + unsigned int phy[2]; + unsigned long long timestamp; + unsigned int sequence; + unsigned int length; + unsigned int poolId[2]; +} v3_aud_frm; + +typedef struct { + v3_aud_frm frame; + char isValid; + char isSysBound; +} v3_aud_efrm; + +typedef struct { + void *handle, *handleGoke; + + int (*fnDisableDevice)(int device); + int (*fnEnableDevice)(int device); + int (*fnSetDeviceConfig)(int device, v3_aud_cnf *config); + + int (*fnDisableChannel)(int device, int channel); + int (*fnEnableChannel)(int device, int channel); + + int (*fnFreeFrame)(int device, int channel, v3_aud_frm *frame, v3_aud_efrm *encFrame); + int (*fnGetFrame)(int device, int channel, v3_aud_frm *frame, v3_aud_efrm *encFrame, int millis); +} v3_aud_impl; + +static int v3_aud_load(v3_aud_impl *aud_lib) { + if (!(aud_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_aud] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnDisableDevice = (int(*)(int device)) + dlsym(aud_lib->handle, "HI_MPI_AI_Disable"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_Disable!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnEnableDevice = (int(*)(int device)) + dlsym(aud_lib->handle, "HI_MPI_AI_Enable"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_Enable!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnSetDeviceConfig = (int(*)(int device, v3_aud_cnf *config)) + dlsym(aud_lib->handle, "HI_MPI_AI_SetPubAttr"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_SetPubAttr!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnDisableChannel = (int(*)(int device, int channel)) + dlsym(aud_lib->handle, "HI_MPI_AI_DisableChn"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_DisableChn!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnEnableChannel = (int(*)(int device, int channel)) + dlsym(aud_lib->handle, "HI_MPI_AI_EnableChn"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_EnableChn!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnFreeFrame = (int(*)(int device, int channel, v3_aud_frm *frame, v3_aud_efrm *encFrame)) + dlsym(aud_lib->handle, "HI_MPI_AI_ReleaseFrame"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_ReleaseFrame!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnGetFrame = (int(*)(int device, int channel, v3_aud_frm *frame, v3_aud_efrm *encFrame, int millis)) + dlsym(aud_lib->handle, "HI_MPI_AI_GetFrame"))) { + fprintf(stderr, "[v3_aud] Failed to acquire symbol HI_MPI_AI_GetFrame!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_aud_unload(v3_aud_impl *aud_lib) { + if (aud_lib->handle) dlclose(aud_lib->handle); + aud_lib->handle = NULL; + if (aud_lib->handleGoke) dlclose(aud_lib->handleGoke); + aud_lib->handleGoke = NULL; + memset(aud_lib, 0, sizeof(*aud_lib)); +} \ No newline at end of file diff --git a/src/hal/hisi/v3_common.h b/src/hal/hisi/v3_common.h new file mode 100644 index 0000000..4fac809 --- /dev/null +++ b/src/hal/hisi/v3_common.h @@ -0,0 +1,125 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "../types.h" + +#define V3_ERROR(x, ...) \ + do { \ + fprintf(stderr, "[v3_hal] \033[31m"); \ + fprintf(stderr, (x), ##__VA_ARGS__); \ + fprintf(stderr, "\033[0m"); \ + return EXIT_FAILURE; \ + } while (0) + +typedef enum { + V3_BAYER_RG, + V3_BAYER_GR, + V3_BAYER_GB, + V3_BAYER_BG, + V3_BAYER_END +} v3_common_bayer; + +typedef enum { + V3_COMPR_NONE, + V3_COMPR_SEG, + V3_COMPR_SEG128, + V3_COMPR_LINE, + V3_COMPR_FRAME, + V3_COMPR_END +} v3_common_compr; + +typedef enum { + V3_PIXFMT_1BPP, + V3_PIXFMT_2BPP, + V3_PIXFMT_4BPP, + V3_PIXFMT_8BPP, + V3_PIXFMT_RGB444, + V3_PIXFMT_ARGB4444, + V3_PIXFMT_RGB555, + V3_PIXFMT_RGB565, + V3_PIXFMT_ARGB1555, + V3_PIXFMT_RGB888, + V3_PIXFMT_ARGB8888, + V3_PIXFMT_RGB888P, + V3_PIXFMT_RGB_BAYER_8BPP, + V3_PIXFMT_RGB_BAYER_10BPP, + V3_PIXFMT_RGB_BAYER_12BPP, + V3_PIXFMT_RGB_BAYER_14BPP, + V3_PIXFMT_RGB_BAYER_16BPP, + V3_PIXFMT_YUV_A422, + V3_PIXFMT_YUV_A444, + V3_PIXFMT_YUV422P, + V3_PIXFMT_YUV420P, + V3_PIXFMT_YUV444P, + V3_PIXFMT_YUV422SP, + V3_PIXFMT_YUV420SP, + V3_PIXFMT_YUV444SP, + V3_PIXFMT_YUV422_UYVY, + V3_PIXFMT_YUV422_YUYV, + V3_PIXFMT_YUV422_VYUY, + V3_PIXFMT_YCbCrP, + V3_PIXFMT_YUV400, + V3_PIXFMT_END +} v3_common_pixfmt; + +typedef enum { + V3_PREC_8BPP, + V3_PREC_10BPP, + V3_PREC_12BPP, + V3_PREC_14BPP, + V3_PREC_16BPP, + V3_PREC_END +} v3_common_prec; + +typedef enum { + V3_VIDFMT_LINEAR, + V3_VIDFMT_TILE_256X16, + V3_VIDFMT_TILE_64X16, + V3_VIDFMT_END +} v3_common_vidfmt; + +typedef enum { + V3_WDR_NONE, + V3_WDR_BUILTIN, + V3_WDR_QUDRA, + V3_WDR_2TO1_LINE, + V3_WDR_2TO1_FRAME, + V3_WDR_2TO1_FRAME_FULLRATE, + V3_WDR_3TO1_LINE, + V3_WDR_3TO1_FRAME, + V3_WDR_3TO1_FRAME_FULLRATE, + V3_WDR_4TO1_LINE, + V3_WDR_4TO1_FRAME, + V3_WDR_4TO1_FRAME_FULLRATE, + V3_WDR_END +} v3_common_wdr; + +typedef struct { + unsigned int topWidth; + unsigned int bottomWidth; + unsigned int leftWidth; + unsigned int rightWidth; + unsigned int color; +} v3_common_bord; + +typedef struct { + unsigned int width; + unsigned int height; +} v3_common_dim; + +typedef struct { + int x; + int y; +} v3_common_pnt; + +typedef struct { + int x; + int y; + unsigned int width; + unsigned int height; +} v3_common_rect; diff --git a/src/hal/hisi/v3_config.h b/src/hal/hisi/v3_config.h new file mode 100644 index 0000000..9ebb02e --- /dev/null +++ b/src/hal/hisi/v3_config.h @@ -0,0 +1,536 @@ +#pragma once + +#include "v3_common.h" +#include "v3_isp.h" +#include "v3_snr.h" +#include "v3_vi.h" + +#include +#include +#include + +#include "../config.h" +#include "../tools.h" + +typedef struct { + // [sensor] + char sensor_type[128]; + v3_common_wdr mode; + char dll_file[256]; + + // [mode] + v3_snr_input input_mode; + + // [mipi] + v3_snr_mipi mipi; + + // [lvds] + v3_snr_lvds lvds; + + // [isp_image] + v3_isp_dev isp; + + // [vi_dev] + v3_vi_dev videv; + + // [vi_chn] + v3_vi_chn vichn; +} v3_config_impl; + +extern v3_config_impl v3_config; + +static enum ConfigError v3_parse_config_lvds( + struct IniConfig *ini, const char *section, v3_snr_lvds *lvds) { + enum ConfigError err; + { + const char *possible_values[] = { + "HI_WDR_MODE_NONE", "HI_WDR_MODE_2F", "HI_WDR_MODE_3F", + "HI_WDR_MODE_4F", "HI_WDR_MODE_DOL_2F", "HI_WDR_MODE_DOL_3F", + "HI_WDR_MODE_DOL_4F"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "wdr_mode", (void*)&lvds->wdr, possible_values, + count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "LVDS_SYNC_MODE_SOL", "LVDS_SYNC_MODE_SAV"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "sync_mode", (void*)&lvds->syncSavOn, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "RAW_DATA_8BIT", "RAW_DATA_10BIT", "RAW_DATA_12BIT", + "RAW_DATA_14BIT", "RAW_DATA_16BIT"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "raw_data_type", (void*)&lvds->prec, + possible_values, count, 1); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "LVDS_ENDIAN_LITTLE", "LVDS_ENDIAN_BIG"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "data_endian", (void*)&lvds->dataBeOn, + possible_values, count, 1); + if (err != CONFIG_OK) + return err; + err = parse_enum( + ini, section, "sync_code_endian", (void*)&lvds->syncBeOn, + possible_values, count, 1); + if (err != CONFIG_OK) + return err; + } + int laneId[4]; + err = parse_array(ini, section, "lane_id", laneId, 4); + if (err != CONFIG_OK) + return err; + else for (char i = 0; i < 4; i++) + lvds->laneId[i] = (short)laneId[i]; + char syncname[16]; + int synccode[128]; + for (int i = 0; i < 8; i++) { + sprintf(syncname, "sync_code_%d", i); + err = parse_array(ini, section, syncname, synccode + i * 16, 16); + if (err != CONFIG_OK) + return err; + } + for (int j = 0; j < 32; j++) + lvds->syncCode[j] = (unsigned short)synccode[j]; + return CONFIG_OK; +} + +static enum ConfigError v3_parse_config_videv( + struct IniConfig *ini, const char *section, v3_vi_dev *device) { + enum ConfigError err; + memset(device, 0, sizeof(*device)); + { + const char *possible_values[] = { + "VI_MODE_BT656", "VI_MODE_BT601", + "VI_MODE_DIGITAL_CAMERA", "VI_MODE_INTERLEAVED", + "VI_MODE_MIPI", "VI_MODE_LVDS", + "VI_MODE_HISPI"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "input_mod", (void*)&device->intf, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_WORK_MODE_1Multiplex", "VI_WORK_MODE_2Multiplex", + "VI_WORK_MODE_4Multiplex"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "work_mod", (void*)&device->work, possible_values, + count, 0); + if (err != CONFIG_OK) + device->work = V3_VI_WORK_1MULTIPLEX; + } + err = parse_uint32(ini, section, "mask_0", 0, UINT_MAX - 1, &device->cmpntMask[0]); + if (err != CONFIG_OK) + return err; + err = parse_uint32(ini, section, "mask_1", 0, UINT_MAX - 1, &device->cmpntMask[1]); + if (err != CONFIG_OK) + return err; + unsigned int maskNum; + err = parse_uint32(ini, section, "mask_num", 0, 2, &maskNum); + if (err != CONFIG_OK) + return err; + if (maskNum < 1) device->cmpntMask[1] = UINT_MAX; + if (maskNum < 2) device->cmpntMask[0] = UINT_MAX; + { + const char *possible_values[] = { + "VI_SCAN_INTERLACED", "VI_SCAN_PROGRESSIVE"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "scan_mode", (void*)&device->progressiveOn, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_DATA_SEQ_VUVU", "VI_DATA_SEQ_UVUV", + "VI_DATA_SEQ_UYVY", "VI_DATA_SEQ_VYUY", + "VI_DATA_SEQ_YUYV", "VI_DATA_SEQ_YVYU"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "data_seq", (void*)&device->seq, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = {"VI_VSYNC_FIELD", "VI_VSYNC_PULSE"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "vsync", (void*)&device->sync.vsyncPulse, possible_values, + count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_VSYNC_NEG_HIGH", "VI_VSYNC_NEG_LOW"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "vsyncneg", (void*)&device->sync.vsyncInv, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_HSYNC_VALID_SIGNAL", "VI_HSYNC_PULSE"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "hsync", (void*)&device->sync.hsyncPulse, possible_values, + count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_HSYNC_NEG_HIGH", "VI_HSYNC_NEG_LOW"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "hsyncneg", (void*)&device->sync.hsyncInv, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_VSYNC_NORM_PULSE", "VI_VSYNC_VALID_SIGNAL"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "vsyncvalid", (void*)&device->sync.vsyncValid, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "VI_VSYNC_VALID_NEG_HIGH", "VI_VSYNC_VALID_NEG_LOW"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "vsyncvalidneg", (void*)&device->sync.vsyncValidInv, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + err = parse_int( + ini, section, "timingblank_hsynchfb", 0, INT_MAX, + &device->sync.timing.hsyncFront); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_hsyncact", 0, INT_MAX, + &device->sync.timing.hsyncWidth); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_hsynchbb", 0, INT_MAX, + &device->sync.timing.hsyncBack); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvfb", 0, INT_MAX, + &device->sync.timing.vsyncFront); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvact", 0, INT_MAX, + &device->sync.timing.vsyncWidth); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvbb", 0, INT_MAX, + &device->sync.timing.vsyncBack); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvbfb", 0, INT_MAX, + &device->sync.timing.vsyncIntrlFront); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvbact", 0, INT_MAX, + &device->sync.timing.vsyncIntrlWidth); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "timingblank_vsyncvbbb", 0, INT_MAX, + &device->sync.timing.vsyncIntrlBack); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, section, "datarev", 0, INT_MAX, &device->dataRevOn); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, section, "devrect_x", 0, INT_MAX, &device->rect.x); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, section, "devrect_y", 0, INT_MAX, &device->rect.y); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, section, "devrect_w", 0, INT_MAX, &device->rect.width); + if (err != CONFIG_OK) + return err; + int height; + err = parse_int(ini, section, "devrect_h", 0, INT_MAX, &device->rect.height); + if (err != CONFIG_OK) + return err; + + if (device->intf == V3_VI_INTF_MIPI || device->intf == V3_VI_INTF_LVDS) + device->rgbModeOn = 1; + else device->rgbModeOn = 0; + + return CONFIG_OK; +} + +static enum ConfigError v3_parse_config_vichn( + struct IniConfig *ini, const char *section, v3_vi_chn *channel) { + enum ConfigError err; + err = parse_int(ini, section, "caprect_x", 0, INT_MAX, &channel->capt.x); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, section, "caprect_y", 0, INT_MAX,&channel->capt.y); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "caprect_width", 0, INT_MAX, &channel->capt.width); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "caprect_height", 0, INT_MAX, &channel->capt.height); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "destsize_width", 0, INT_MAX, &channel->dest.width); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "destsize_height", 0, INT_MAX, &channel->dest.height); + if (err != CONFIG_OK) + return err; + { + const char *possible_values[] = { + "VI_CAPSEL_TOP", "VI_CAPSEL_BOTTOM", "VI_CAPSEL_BOTH"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "capsel", (void *)&channel->field, possible_values, + count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "PIXEL_FORMAT_RGB_1BPP", + "PIXEL_FORMAT_RGB_2BPP", + "PIXEL_FORMAT_RGB_4BPP", + "PIXEL_FORMAT_RGB_8BPP", + "PIXEL_FORMAT_RGB_444", + "PIXEL_FORMAT_RGB_4444", + "PIXEL_FORMAT_RGB_555", + "PIXEL_FORMAT_RGB_565", + "PIXEL_FORMAT_RGB_1555", + "PIXEL_FORMAT_RGB_888", + "PIXEL_FORMAT_RGB_8888", + "PIXEL_FORMAT_RGB_PLANAR_888", + "PIXEL_FORMAT_RGB_BAYER_8BPP", + "PIXEL_FORMAT_RGB_BAYER_10BPP", + "PIXEL_FORMAT_RGB_BAYER_12BPP", + "PIXEL_FORMAT_RGB_BAYER_14BPP", + "PIXEL_FORMAT_RGB_BAYER", + "PIXEL_FORMAT_YUV_A422", + "PIXEL_FORMAT_YUV_A444", + "PIXEL_FORMAT_YUV_PLANAR_422", + "PIXEL_FORMAT_YUV_PLANAR_420", + "PIXEL_FORMAT_YUV_PLANAR_444", + "PIXEL_FORMAT_YUV_SEMIPLANAR_422", + "PIXEL_FORMAT_YUV_SEMIPLANAR_420", + "PIXEL_FORMAT_YUV_SEMIPLANAR_444", + "PIXEL_FORMAT_UYVY_PACKAGE_422", + "PIXEL_FORMAT_YUYV_PACKAGE_422", + "PIXEL_FORMAT_VYUY_PACKAGE_422", + "PIXEL_FORMAT_YCbCr_PLANAR", + "PIXEL_FORMAT_YUV_400"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "pixformat", (void *)&channel->pixFmt, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + { + const char *possible_values[] = { + "COMPRESS_MODE_NONE", "COMPRESS_MODE_SEG", "COMPRESS_MODE_SEG128", + "COMPRESS_MODE_LINE", "COMPRESS_MODE_FRAME"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, section, "compressmode", (void *)&channel->compress, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + err = parse_int( + ini, section, "srcframerate", INT_MIN, INT_MAX, &channel->srcFps); + if (err != CONFIG_OK) + return err; + err = parse_int( + ini, section, "framerate", INT_MIN, INT_MAX, &channel->dstFps); + if (err != CONFIG_OK) + return err; + return CONFIG_OK; +} + +static enum ConfigError v3_parse_config_isp( + struct IniConfig *ini, const char *section, v3_isp_dev *isp) { + enum ConfigError err; + + err = parse_int(ini, "isp_image", "isp_x", 0, INT_MAX, &isp->capt.x); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, "isp_image", "isp_y", 0, INT_MAX, &isp->capt.y); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, "isp_image", "isp_w", 0, INT_MAX, &isp->capt.width); + if (err != CONFIG_OK) + return err; + err = parse_int(ini, "isp_image", "isp_h", 0, INT_MAX, &isp->capt.height); + if (err != CONFIG_OK) + return err; + int value; + err = parse_int( + ini, "isp_image", "isp_framerate", 0, INT_MAX, &value); + if (err != CONFIG_OK) + return err; + else isp->framerate = value * 1.0f; + { + const char *possible_values[] = { + "BAYER_RGGB", "BAYER_GRBG", "BAYER_GBRG", "BAYER_BGGR"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + ini, "isp_image", "isp_bayer", (void*)&isp->bayer, + possible_values, count, 0); + if (err != CONFIG_OK) + return err; + } + return CONFIG_OK; +} + +static enum ConfigError v3_parse_sensor_config(char *path, v3_config_impl *config) { + if (config == NULL) + return (enum ConfigError)-1; + memset(config, 0, sizeof(config)); + struct IniConfig ini; + memset(&ini, 0, sizeof(ini)); + enum ConfigError err; + + // load config file to string + if (!open_config(&ini, path)) + return (enum ConfigError)-1; + + find_sections(&ini); + + // [sensor] + err = parse_param_value(&ini, "sensor", "sensor_type", config->sensor_type); + if (err != CONFIG_OK) + goto RET_ERR; + { + const char *possible_values[] = { + "WDR_MODE_NONE", + "WDR_MODE_BUILT_IN", + "WDR_MODE_QUDRA", + "WDR_MODE_2To1_LINE", + "WDR_MODE_2To1_FRAME", + "WDR_MODE_2To1_FRAME_FULL_RATE", + "WDR_MODE_3To1_LINE", + "WDR_MODE_3To1_FRAME", + "WDR_MODE_3To1_FRAME_FULL_RATE", + "WDR_MODE_4To1_LINE", + "WDR_MODE_4To1_FRAME", + "WDR_MODE_4To1_FRAME_FULL_RATE"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + &ini, "sensor", "mode", (void*)&config->mode, possible_values, + count, 0); + if (err != CONFIG_OK) + goto RET_ERR; + } + err = parse_param_value(&ini, "sensor", "dllfile", config->dll_file); + if (err != CONFIG_OK) + goto RET_ERR; + + // [mode] + { + const char *possible_values[] = { + "INPUT_MODE_MIPI", "INPUT_MODE_SUBLVDS", "INPUT_MODE_LVDS", + "INPUT_MODE_HISPI", "INPUT_MODE_CMOS_18V", "INPUT_MODE_CMOS_33V", + "INPUT_MODE_BT1120", "INPUT_MODE_BYPASS"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + &ini, "mode", "input_mode", (void*)&config->input_mode, + possible_values, count, 0); + if (err != CONFIG_OK) + config->input_mode = V3_SNR_INPUT_MIPI; + } + + if (config->input_mode == V3_SNR_INPUT_MIPI) { + // [mipi] + { + const char *possible_values[] = {"RAW_DATA_8BIT", "RAW_DATA_10BIT", + "RAW_DATA_12BIT", "RAW_DATA_14BIT", + "RAW_DATA_16BIT"}; + const int count = sizeof(possible_values) / sizeof(const char *); + err = parse_enum( + &ini, "mipi", "data_type", (void *)&config->mipi.prec, + possible_values, count, 1); + if (err != CONFIG_OK) + goto RET_ERR; + } + int laneId[4]; + err = parse_array(&ini, "mipi", "lane_id", (int*)&laneId, 4); + if (err != CONFIG_OK) + goto RET_ERR; + else for (char i = 0; i < 4; i++) + config->mipi.laneId[i] = laneId[i]; + } else if (config->input_mode == V3_SNR_INPUT_LVDS) { + // [lvds] + err = v3_parse_config_lvds(&ini, "lvds", &config->lvds); + if (err != CONFIG_OK) + goto RET_ERR; + } + + // [isp_image] + err = v3_parse_config_isp(&ini, "isp_image", &config->isp); + if (err != CONFIG_OK) + goto RET_ERR; + + // [vi_dev] + err = v3_parse_config_videv(&ini, "vi_dev", &config->videv); + if (err != CONFIG_OK) + goto RET_ERR; + // [vi_chn] + err = v3_parse_config_vichn(&ini, "vi_chn", &config->vichn); + if (err != CONFIG_OK) + goto RET_ERR; + + v3_config = *config; + free(ini.str); + return CONFIG_OK; +RET_ERR: + free(ini.str); + return err; +} \ No newline at end of file diff --git a/src/hal/hisi/v3_isp.h b/src/hal/hisi/v3_isp.h new file mode 100644 index 0000000..defeb0f --- /dev/null +++ b/src/hal/hisi/v3_isp.h @@ -0,0 +1,145 @@ +#pragma once + +#include "v3_common.h" + +extern int (*fnISP_AlgRegisterDehaze)(int); +extern int (*fnISP_AlgRegisterDrc)(int); +extern int (*fnISP_AlgRegisterLdci)(int); +extern int (*fnMPI_ISP_IrAutoRunOnce)(int, void*); + +typedef struct { + int id; + char libName[20]; +} v3_isp_alg; + +typedef struct { + v3_common_rect capt; + float framerate; + v3_common_bayer bayer; +} v3_isp_dev; + +typedef struct { + void *handle, *handleDehaze, *handleDrc, *handleLdci, *handleIrAuto, *handleAwb, *handleAe; + + int (*fnExit)(int pipe); + int (*fnInit)(int pipe); + int (*fnMemInit)(int pipe); + int (*fnRun)(int pipe); + + int (*fnSetDeviceConfig)(int pipe, v3_isp_dev *config); + + int (*fnRegisterAE)(int pipe, v3_isp_alg *library); + int (*fnRegisterAWB)(int pipe, v3_isp_alg *library); + int (*fnUnregisterAE)(int pipe, v3_isp_alg *library); + int (*fnUnregisterAWB)(int pipe, v3_isp_alg *library); +} v3_isp_impl; + +static int v3_isp_load(v3_isp_impl *isp_lib) { + if (!(isp_lib->handle = dlopen("libisp.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(isp_lib->handleAe = dlopen("lib_hiae.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(isp_lib->handleAwb = dlopen("lib_hiawb.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(isp_lib->handleLdci = dlopen("lib_hildci.so", RTLD_LAZY | RTLD_GLOBAL))|| + !(isp_lib->handleDehaze = dlopen("lib_hidehaze.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(isp_lib->handleDrc = dlopen("lib_hidrc.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_isp] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(fnISP_AlgRegisterDehaze = (int(*)(int)) + dlsym(isp_lib->handleDehaze, "ISP_AlgRegisterDehaze"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol ISP_AlgRegisterDehaze!\n"); + return EXIT_FAILURE; + } + + if (!(fnISP_AlgRegisterDrc = (int(*)(int)) + dlsym(isp_lib->handleDrc, "ISP_AlgRegisterDrc"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol ISP_AlgRegisterDrc!\n"); + return EXIT_FAILURE; + } + + if (!(fnISP_AlgRegisterLdci = (int(*)(int)) + dlsym(isp_lib->handleLdci, "ISP_AlgRegisterLdci"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol ISP_AlgRegisterLdci!\n"); + return EXIT_FAILURE; + } + + if (!(fnMPI_ISP_IrAutoRunOnce = (int(*)(int, void*)) + dlsym(isp_lib->handleIrAuto, "MPI_ISP_IrAutoRunOnce"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol MPI_ISP_IrAutoRunOnce!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnExit = (int(*)(int pipe)) + dlsym(isp_lib->handle, "HI_MPI_ISP_Exit"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_ISP_Exit!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnInit = (int(*)(int pipe)) + dlsym(isp_lib->handle, "HI_MPI_ISP_Init"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_ISP_Init!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnMemInit = (int(*)(int pipe)) + dlsym(isp_lib->handle, "HI_MPI_ISP_MemInit"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_ISP_MemInit!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnRun = (int(*)(int pipe)) + dlsym(isp_lib->handle, "HI_MPI_ISP_Run"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_ISP_Run!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnSetDeviceConfig = (int(*)(int pipe, v3_isp_dev *config)) + dlsym(isp_lib->handle, "HI_MPI_ISP_SetPubAttr"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_ISP_SetPubAttr!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnRegisterAE = (int(*)(int pipe, v3_isp_alg *library)) + dlsym(isp_lib->handleAe, "HI_MPI_AE_Register"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_AE_Register!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnRegisterAWB = (int(*)(int pipe, v3_isp_alg *library)) + dlsym(isp_lib->handleAwb, "HI_MPI_AWB_Register"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_AWB_Register!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnUnregisterAE = (int(*)(int pipe, v3_isp_alg *library)) + dlsym(isp_lib->handleAe, "HI_MPI_AE_UnRegister"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_AE_UnRegister!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnUnregisterAWB = (int(*)(int pipe, v3_isp_alg *library)) + dlsym(isp_lib->handleAwb, "HI_MPI_AWB_UnRegister"))) { + fprintf(stderr, "[v3_isp] Failed to acquire symbol HI_MPI_AWB_UnRegister!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_isp_unload(v3_isp_impl *isp_lib) { + if (isp_lib->handleAe) dlclose(isp_lib->handleAe); + isp_lib->handleAe = NULL; + if (isp_lib->handleAwb) dlclose(isp_lib->handleAwb); + isp_lib->handleAwb = NULL; + if (isp_lib->handleIrAuto) dlclose(isp_lib->handleIrAuto); + isp_lib->handleIrAuto = NULL; + if (isp_lib->handleLdci) dlclose(isp_lib->handleLdci); + isp_lib->handleLdci = NULL; + if (isp_lib->handleDrc) dlclose(isp_lib->handleDrc); + isp_lib->handleDrc = NULL; + if (isp_lib->handleDehaze) dlclose(isp_lib->handleDehaze); + isp_lib->handleDehaze = NULL; + if (isp_lib->handle) dlclose(isp_lib->handle); + isp_lib->handle = NULL; + memset(isp_lib, 0, sizeof(*isp_lib)); +} diff --git a/src/hal/hisi/v3_rgn.h b/src/hal/hisi/v3_rgn.h new file mode 100644 index 0000000..3164a00 --- /dev/null +++ b/src/hal/hisi/v3_rgn.h @@ -0,0 +1,205 @@ +#pragma once + +#include "v3_common.h" +#include "v3_sys.h" + +typedef enum { + V3_RGN_BLK_8, + V3_RGN_BLK_16, + V3_RGN_BLK_32, + V3_RGN_BLK_64, + V3_RGN_BLK_END +} v3_rgn_blk; + +typedef enum { + V3_RGN_TYPE_OVERLAY, + V3_RGN_TYPE_COVER, + V3_RGN_TYPE_COVEREX, + V3_RGN_TYPE_OVERLAYEX, + V3_RGN_TYPE_MOSAIC, + V3_RGN_TYPE_END +} v3_rgn_type; + +typedef struct { + v3_common_pixfmt pixFmt; + v3_common_dim size; + void *data; +} v3_rgn_bmp; + +typedef struct { + v3_common_dim invColArea; + unsigned int lumThresh; + unsigned int highThanOn; + int invColOn; +} v3_rgn_inv; + +typedef struct { + v3_common_pnt point; + unsigned int fgAlpha; + unsigned int bgAlpha; + // Accepts values from 0-7 + unsigned int layer; + int adsQualOn; + int quality; + int qualOff; + v3_rgn_inv invert; +} v3_rgn_ovlc; + +typedef struct { + int solidOn; + unsigned int lineThick; + v3_common_pnt point[4]; +} v3_rgn_qdr; + +typedef struct { + int quadRangleOn; + union { + v3_common_rect rect; + v3_rgn_qdr quadR; + }; + unsigned int color; + unsigned int layer; + int absOrRatioCoord; +} v3_rgn_covc; + +typedef struct { + v3_common_pnt point; + unsigned int fgAlpha; + unsigned int bgAlpha; + // Accepts values from 0-15 + unsigned int layer; +} v3_rgn_ovlxc; + +typedef struct { + int quadRangleOn; + union { + v3_common_rect rect; + v3_rgn_qdr quadR; + }; + unsigned int color; + unsigned int layer; +} v3_rgn_covxc; + +typedef struct { + v3_common_rect rect; + v3_rgn_blk blkSize; + // Accepts values from 0-3 + unsigned int layer; +} v3_rgn_mosc; + +typedef struct { + int show; + v3_rgn_type type; + union { + v3_rgn_ovlc overlay; + v3_rgn_covc cover; + v3_rgn_covxc coverex; + v3_rgn_ovlxc overlayex; + v3_rgn_mosc mosaic; + }; +} v3_rgn_chn; + +typedef struct { + v3_common_pixfmt pixFmt; + unsigned int bgColor; + v3_common_dim size; + unsigned int canvas; +} v3_rgn_ovl; + +typedef struct { + v3_rgn_type type; + union { + v3_rgn_ovl overlay; + v3_rgn_ovl overlayex; + }; +} v3_rgn_cnf; + +typedef struct { + void *handle, *handleGoke; + + int (*fnCreateRegion)(unsigned int handle, v3_rgn_cnf *config); + int (*fnDestroyRegion)(unsigned int handle); + int (*fnGetRegionConfig)(unsigned int handle, v3_rgn_cnf *config); + int (*fnSetRegionConfig)(unsigned int handle, v3_rgn_cnf *config); + + int (*fnAttachChannel)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config); + int (*fnDetachChannel)(unsigned int handle, v3_sys_bind *dest); + int (*fnGetChannelConfig)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config); + int (*fnSetChannelConfig)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config); + + int (*fnSetBitmap)(unsigned int handle, v3_rgn_bmp *bitmap); +} v3_rgn_impl; + +static int v3_rgn_load(v3_rgn_impl *rgn_lib) { + if ( !(rgn_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL)) && + + (!(rgn_lib->handleGoke = dlopen("libgk_api.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(rgn_lib->handle = dlopen("libhi_mpi.so", RTLD_LAZY | RTLD_GLOBAL)))) { + fprintf(stderr, "[v3_rgn] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnCreateRegion = (int(*)(unsigned int handle, v3_rgn_cnf *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_Create"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_Create!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnDestroyRegion = (int(*)(unsigned int handle)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_Destroy"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_Destroy!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnGetRegionConfig = (int(*)(unsigned int handle, v3_rgn_cnf *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_GetAttr"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_GetAttr!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnSetRegionConfig = (int(*)(unsigned int handle, v3_rgn_cnf *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_SetAttr"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_SetAttr!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnAttachChannel = (int(*)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_AttachToChn"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_AttachToChn!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnDetachChannel = (int(*)(unsigned int handle, v3_sys_bind *dest)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_DetachFromChn"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_DetachFromChn!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnGetChannelConfig = (int(*)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_GetDisplayAttr"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_GetDisplayAttr!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnSetChannelConfig = (int(*)(unsigned int handle, v3_sys_bind *dest, v3_rgn_chn *config)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_SetDisplayAttr"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_SetDisplayAttr!\n"); + return EXIT_FAILURE; + } + + if (!(rgn_lib->fnSetBitmap = (int(*)(unsigned int handle, v3_rgn_bmp *bitmap)) + dlsym(rgn_lib->handle, "HI_MPI_RGN_SetBitMap"))) { + fprintf(stderr, "[v3_rgn] Failed to acquire symbol HI_MPI_RGN_SetBitMap!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_rgn_unload(v3_rgn_impl *rgn_lib) { + if (rgn_lib->handle) dlclose(rgn_lib->handle); + rgn_lib->handle = NULL; + if (rgn_lib->handleGoke) dlclose(rgn_lib->handleGoke); + rgn_lib->handleGoke = NULL; + memset(rgn_lib, 0, sizeof(*rgn_lib)); +} \ No newline at end of file diff --git a/src/hal/hisi/v3_snr.h b/src/hal/hisi/v3_snr.h new file mode 100644 index 0000000..c2e0a21 --- /dev/null +++ b/src/hal/hisi/v3_snr.h @@ -0,0 +1,116 @@ +#pragma once + +#include "v3_common.h" + +#include +#include + +#define V3_SNR_IOC_MAGIC 'm' +#define V3_SNR_LVDS_LANE_NUM 4 +#define V3_SNR_MIPI_LANE_NUM 4 +#define V3_SNR_WDR_VC_NUM 4 + +enum { + V3_SNR_CMD_CONF_DEV = 1, + V3_SNR_CMD_CONF_EDGE, + V3_SNR_CMD_CONF_MSB, + V3_SNR_CMD_CONF_CMV, + V3_SNR_CMD_RST_SENS, + V3_SNR_CMD_UNRST_SENS, + V3_SNR_CMD_RST_MIPI, + V3_SNR_CMD_UNRST_MIPI, + V3_SNR_CMD_CONF_CROP +}; + +typedef enum { + V3_SNR_INPUT_MIPI, + V3_SNR_INPUT_SUBLVDS, + V3_SNR_INPUT_LVDS, + V3_SNR_INPUT_HISPI, + V3_SNR_INPUT_CMOS_18V, + V3_SNR_INPUT_CMOS_33V, + V3_SNR_INPUT_BT1120, + V3_SNR_INPUT_END +} v3_snr_input; + +typedef enum { + V3_SNR_LFID_NONE, + V3_SNR_LFID_INSAV, + V3_SNR_LFID_INDATA, + V3_SNR_LFID_END +} v3_snr_lfid; + +typedef enum { + V3_SNR_LVSYNCT_NORMAL, + V3_SNR_LVSYNCT_SHARE, + V3_SNR_LVSYNCT_HCONNECT, + V3_SNR_LVSYNCT_END +} v3_snr_lvsynct; + +typedef enum { + V3_SNR_LWDR_NONE, + V3_SNR_LWDR_2F, + V3_SNR_LWDR_3F, + V3_SNR_LWDR_4F, + V3_SNR_LWDR_DOL2F, + V3_SNR_LWDR_DOL3F, + V3_SNR_LWDR_DOL4F, + V3_SNR_LWDR_END +} v3_snr_lwdr; + +typedef enum { + V3_SNR_MWDR_NONE, + V3_SNR_MWDR_VC, + V3_SNR_MWDR_DT, + V3_SNR_MWDR_DOL, + V3_SNR_MWDR_END +} v3_snr_mwdr; + +typedef struct { + v3_snr_lfid type; + unsigned char outputFil; +} v3_snr_fid; + +typedef struct { + v3_snr_lvsynct type; + unsigned short hBlank1; + unsigned short hBlank2; +} v3_snr_lvsync; + +typedef struct { + v3_common_dim dest; + v3_common_prec prec; + v3_snr_lwdr wdr; + int syncSavOn; + v3_snr_lvsync vsync; + v3_snr_fid fid; + int dataBeOn; + int syncBeOn; + // Value -1 signifies a lane is disabled + short laneId[V3_SNR_LVDS_LANE_NUM]; + /* Each lane has two virtual channel, each has four params + If syncSavOn is false: SOF, EOF, SOL, EOL + If syncSavOn is true: invalid sav, invalid eav, valid sav, valid eav */ + unsigned short syncCode[V3_SNR_LVDS_LANE_NUM * V3_SNR_WDR_VC_NUM * 4]; +} v3_snr_lvds; + +typedef struct { + v3_common_prec prec; + v3_snr_mwdr mode; + // Value -1 signifies a lane is disabled + short laneId[V3_SNR_MIPI_LANE_NUM]; + union { + short wdrVcType[V3_SNR_WDR_VC_NUM]; + }; +} v3_snr_mipi; + +typedef struct { + unsigned int device; + v3_snr_input input; + union { + v3_snr_mipi mipi; + v3_snr_lvds lvds; + }; +} v3_snr_dev; + +static const char v3_snr_endp[] = {"/dev/hi_mipi"}; \ No newline at end of file diff --git a/src/hal/hisi/v3_sys.h b/src/hal/hisi/v3_sys.h new file mode 100644 index 0000000..129bdab --- /dev/null +++ b/src/hal/hisi/v3_sys.h @@ -0,0 +1,169 @@ +#pragma once + +#include "v3_common.h" + +#define V3_SYS_API "1.0" + +typedef enum { + V3_SYS_MOD_CMPI, + V3_SYS_MOD_VB, + V3_SYS_MOD_SYS, + V3_SYS_MOD_RGN, + V3_SYS_MOD_CHNL, + V3_SYS_MOD_VDEC, + V3_SYS_MOD_GROUP, + V3_SYS_MOD_VPSS, + V3_SYS_MOD_VENC, + V3_SYS_MOD_VDA, + V3_SYS_MOD_H264E, + V3_SYS_MOD_JPEGE, + V3_SYS_MOD_MPEG4E, + V3_SYS_MOD_H264D, + V3_SYS_MOD_JPEGD, + V3_SYS_MOD_VOU, + V3_SYS_MOD_VIU, + V3_SYS_MOD_DSU, + V3_SYS_MOD_VALG, + V3_SYS_MOD_RC, + V3_SYS_MOD_AIO, + V3_SYS_MOD_AI, + V3_SYS_MOD_AO, + V3_SYS_MOD_AENC, + V3_SYS_MOD_ADEC, + V3_SYS_MOD_AVENC, + V3_SYS_MOD_PCIV, + V3_SYS_MOD_PCIVFMW, + V3_SYS_MOD_ISP, + V3_SYS_MOD_IVE, + V3_SYS_MOD_DCCM = 31, + V3_SYS_MOD_DCCS, + V3_SYS_MOD_PROC, + V3_SYS_MOD_LOG, + V3_SYS_MOD_MST_LOG, + V3_SYS_MOD_VD, + V3_SYS_MOD_VCMP = 38, + V3_SYS_MOD_FB, + V3_SYS_MOD_HDMI, + V3_SYS_MOD_VOIE, + V3_SYS_MOD_TDE, + V3_SYS_MOD_USR, + V3_SYS_MOD_VEDU, + V3_SYS_MOD_VGS, + V3_SYS_MOD_H265E, + V3_SYS_MOD_FD, + V3_SYS_MOD_ODT, + V3_SYS_MOD_VQA, + V3_SYS_MOD_LPR, + V3_SYS_MOD_FISHEYE, + V3_SYS_MOD_PHOTO, + V3_SYS_MOD_EXTAO, + V3_SYS_MOD_END +} v3_sys_mod; + +typedef enum { + V3_SYS_OPER_VIOFF_VPSSOFF, + V3_SYS_OPER_VIOFF_VPSSON, + V3_SYS_OPER_VION_VPSSOFF, + V3_SYS_OPER_VION_VPSSON, + V3_SYS_OPER_VIPARA_VPSSOFF, + V3_SYS_OPER_VIPARA_VPSSPARA, + V3_SYS_OPER_END +} v3_sys_oper; + +typedef struct { + v3_sys_mod module; + int device; + int channel; +} v3_sys_bind; + +typedef struct { + char version[64]; +} v3_sys_ver; + +typedef struct { + void *handle, *handleVoiceEngine, *handleDnvqe, *handleUpvqe; + + int (*fnExit)(void); + int (*fnGetChipId)(unsigned int *chip); + int (*fnGetVersion)(v3_sys_ver *version); + + int (*fnInit)(void); + int (*fnSetAlignment)(unsigned int *width); + + int (*fnBind)(v3_sys_bind *source, v3_sys_bind *dest); + int (*fnUnbind)(v3_sys_bind *source, v3_sys_bind *dest); + + int (*fnGetViVpssMode)(unsigned int *onlineOn); +} v3_sys_impl; + +static int v3_sys_load(v3_sys_impl *sys_lib) { + if (!(sys_lib->handleUpvqe = dlopen("libupvqe.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(sys_lib->handleDnvqe = dlopen("libdnvqe.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(sys_lib->handleVoiceEngine = dlopen("libVoiceEngine.so", RTLD_LAZY | RTLD_GLOBAL)) || + !(sys_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_sys] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnExit = (int(*)(void)) + dlsym(sys_lib->handle, "HI_MPI_SYS_Exit"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_Exit!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnGetChipId = (int(*)(unsigned int *chip)) + dlsym(sys_lib->handle, "HI_MPI_SYS_GetChipId"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_GetChipId!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnGetVersion = (int(*)(v3_sys_ver *version)) + dlsym(sys_lib->handle, "HI_MPI_SYS_GetVersion"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_GetVersion!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnInit = (int(*)(void)) + dlsym(sys_lib->handle, "HI_MPI_SYS_Init"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_Init!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnSetAlignment = (int(*)(unsigned int *width)) + dlsym(sys_lib->handle, "HI_MPI_SYS_SetConf"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_SetConf!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnBind = (int(*)(v3_sys_bind *source, v3_sys_bind *dest)) + dlsym(sys_lib->handle, "HI_MPI_SYS_Bind"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_Bind!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnUnbind = (int(*)(v3_sys_bind *source, v3_sys_bind *dest)) + dlsym(sys_lib->handle, "HI_MPI_SYS_UnBind"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_UnBind!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnGetViVpssMode = (int(*)(unsigned int *onlineOn)) + dlsym(sys_lib->handle, "HI_MPI_SYS_GetViVpssMode"))) { + fprintf(stderr, "[v3_sys] Failed to acquire symbol HI_MPI_SYS_GetViVpssMode!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_sys_unload(v3_sys_impl *sys_lib) { + if (sys_lib->handleUpvqe) dlclose(sys_lib->handleUpvqe); + sys_lib->handleUpvqe = NULL; + if (sys_lib->handleDnvqe) dlclose(sys_lib->handleDnvqe); + sys_lib->handleDnvqe = NULL; + if (sys_lib->handleVoiceEngine) dlclose(sys_lib->handleVoiceEngine); + sys_lib->handleVoiceEngine = NULL; + if (sys_lib->handle) dlclose(sys_lib->handle); + sys_lib->handle = NULL; + memset(sys_lib, 0, sizeof(*sys_lib)); +} \ No newline at end of file diff --git a/src/hal/hisi/v3_vb.h b/src/hal/hisi/v3_vb.h new file mode 100644 index 0000000..80b4820 --- /dev/null +++ b/src/hal/hisi/v3_vb.h @@ -0,0 +1,126 @@ +#pragma once + +#include "v3_common.h" + +typedef enum { + V3_VB_JPEG_MASK = 0x1, + V3_VB_USERINFO_MASK = 0x2, + V3_VB_ISPINFO_MASK = 0x4, + V3_VB_ISPSTAT_MASK = 0x8, + V3_VB_DNG_MASK = 0x10 +} v3_vb_supl; + +typedef struct { + unsigned int count; + struct { + unsigned int blockSize; + unsigned int blockCnt; + char heapName[16]; + int rempVirtOn; + } comm[16]; +} v3_vb_pool; + +typedef struct { + void *handle; + + int (*fnConfigPool)(v3_vb_pool *config); + int (*fnConfigSupplement)(v3_vb_supl *value); + int (*fnExit)(void); + int (*fnInit)(void); +} v3_vb_impl; + +static int v3_vb_load(v3_vb_impl *vb_lib) { + if (!(vb_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_vb] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(vb_lib->fnConfigPool = (int(*)(v3_vb_pool *config)) + dlsym(vb_lib->handle, "HI_MPI_VB_SetConf"))) { + fprintf(stderr, "[v3_vb] Failed to acquire symbol HI_MPI_VB_SetConf!\n"); + return EXIT_FAILURE; + } + + if (!(vb_lib->fnConfigSupplement = (int(*)(v3_vb_supl *value)) + dlsym(vb_lib->handle, "HI_MPI_VB_SetSupplementConf"))) { + fprintf(stderr, "[v3_vb] Failed to acquire symbol HI_MPI_VB_SetSupplementConf!\n"); + return EXIT_FAILURE; + } + + if (!(vb_lib->fnExit = (int(*)(void)) + dlsym(vb_lib->handle, "HI_MPI_VB_Exit"))) { + fprintf(stderr, "[v3_vb] Failed to acquire symbol HI_MPI_VB_Exit!\n"); + return EXIT_FAILURE; + } + + if (!(vb_lib->fnInit = (int(*)(void)) + dlsym(vb_lib->handle, "HI_MPI_VB_Init"))) { + fprintf(stderr, "[v3_vb] Failed to acquire symbol HI_MPI_VB_Init!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_vb_unload(v3_vb_impl *vb_lib) { + if (vb_lib->handle) dlclose(vb_lib->handle); + vb_lib->handle = NULL; + memset(vb_lib, 0, sizeof(*vb_lib)); +} + +inline static unsigned int v3_buffer_calculate_vi( + unsigned int width, unsigned int height, v3_common_pixfmt pixFmt, + v3_common_compr compr, unsigned int alignWidth) +{ + unsigned int bitWidth; + unsigned int size = 0, stride = 0; + unsigned int cmpRatioLine = 1600, cmpRatioFrame = 2000; + + if (!alignWidth) + alignWidth = 16; + else if (alignWidth > 64) + alignWidth = 64; + else + alignWidth = ALIGN_UP(alignWidth, 16); + + switch (pixFmt) { + case V3_PIXFMT_RGB_BAYER_8BPP: bitWidth = 8; break; + case V3_PIXFMT_RGB_BAYER_10BPP: bitWidth = 10; break; + case V3_PIXFMT_RGB_BAYER_12BPP: bitWidth = 12; break; + case V3_PIXFMT_RGB_BAYER_14BPP: bitWidth = 14; break; + case V3_PIXFMT_RGB_BAYER_16BPP: bitWidth = 16; break; + default: bitWidth = 0; break; + } + + if (compr == V3_COMPR_NONE) { + stride = ALIGN_UP(ALIGN_UP(width * bitWidth, 8) / 8, + alignWidth); + size = stride * height; + } else if (compr == V3_COMPR_LINE) { + unsigned int temp = ALIGN_UP( + (16 + width * bitWidth * 1000UL / + cmpRatioLine + 8192 + 127) / 128, 2); + stride = ALIGN_UP(temp * 16, alignWidth); + size = stride * height; + } else if (compr == V3_COMPR_FRAME) { + size = ALIGN_UP(height * width * bitWidth * 1000UL / + (cmpRatioFrame * 8), alignWidth); + } + + return size; +} + +inline static unsigned int v3_buffer_calculate_venc(short width, short height, v3_common_pixfmt pixFmt, + unsigned int alignWidth) +{ + unsigned int bufSize = CEILING_2_POWER(width, alignWidth) * + CEILING_2_POWER(height, alignWidth) * + (pixFmt == V3_PIXFMT_YUV422SP ? 2 : 1.5); + unsigned int headSize = 16 * height; + if (pixFmt == V3_PIXFMT_YUV422SP || pixFmt >= V3_PIXFMT_RGB_BAYER_8BPP) + headSize *= 2; + else if (pixFmt == V3_PIXFMT_YUV420SP) + headSize *= 3; + headSize >>= 1; + return bufSize + headSize; +} \ No newline at end of file diff --git a/src/hal/hisi/v3_venc.h b/src/hal/hisi/v3_venc.h new file mode 100644 index 0000000..a56cda0 --- /dev/null +++ b/src/hal/hisi/v3_venc.h @@ -0,0 +1,475 @@ +#pragma once + +#include "v3_common.h" + +#define V3_VENC_CHN_NUM 16 + +typedef enum { + V3_VENC_CODEC_JPEGE = 26, + V3_VENC_CODEC_H264 = 96, + V3_VENC_CODEC_H265 = 265, + V3_VENC_CODEC_MJPG = 1002, + V3_VENC_CODEC_END +} v3_venc_codec; + +typedef enum { + V3_VENC_GOPMODE_NORMALP, + V3_VENC_GOPMODE_DUALP, + V3_VENC_GOPMODE_SMARTP, + V3_VENC_GOPMODE_BIPREDB, + V3_VENC_GOPMODE_LOWDELAYB, + V3_VENC_GOPMODE_END +} v3_venc_gopmode; + +typedef enum { + V3_VENC_NALU_H264_BSLICE, + V3_VENC_NALU_H264_PSLICE, + V3_VENC_NALU_H264_ISLICE, + V3_VENC_NALU_H264_IDRSLICE = 5, + V3_VENC_NALU_H264_SEI, + V3_VENC_NALU_H264_SPS, + V3_VENC_NALU_H264_PPS, + V3_VENC_NALU_H264_END +} v3_venc_nalu_h264; + +typedef enum { + V3_VENC_NALU_H265_BSLICE, + V3_VENC_NALU_H265_PSLICE, + V3_VENC_NALU_H265_ISLICE, + V3_VENC_NALU_H265_IDRSLICE = 19, + V3_VENC_NALU_H265_VPS = 32, + V3_VENC_NALU_H265_SPS, + V3_VENC_NALU_H265_PPS, + V3_VENC_NALU_H265_SEI = 39, + V3_VENC_NALU_H265_END +} v3_venc_nalu_h265; + +typedef enum { + V3_VENC_NALU_MJPG_ECS = 5, + V3_VENC_NALU_MJPG_APP, + V3_VENC_NALU_MJPG_VDO, + V3_VENC_NALU_MJPG_PIC, + V3_VENC_NALU_MJPG_END +} v3_venc_nalu_mjpg; + +typedef enum { + V3_VENC_RATEMODE_H264CBR = 1, + V3_VENC_RATEMODE_H264VBR, + V3_VENC_RATEMODE_H264AVBR, + V3_VENC_RATEMODE_H264QVBR, + V3_VENC_RATEMODE_H264QP, + V3_VENC_RATEMODE_H264QPMAP, + V3_VENC_RATEMODE_MJPGCBR, + V3_VENC_RATEMODE_MJPGVBR, + V3_VENC_RATEMODE_MJPGQP, + V3_VENC_RATEMODE_H265CBR, + V3_VENC_RATEMODE_H265VBR, + V3_VENC_RATEMODE_H265AVBR, + V3_VENC_RATEMODE_H265QVBR, + V3_VENC_RATEMODE_H265QP, + V3_VENC_RATEMODE_H265QPMAP, + V3_VENC_RATEMODE_END +} v3_venc_ratemode; + +typedef struct { + v3_common_dim maxPic; + unsigned int bufSize; + unsigned int profile; + int byFrame; + v3_common_dim pic; +} v3_venc_attr_h26x; + +typedef struct { + v3_common_dim maxPic; + unsigned int bufSize; + int byFrame; + v3_common_dim pic; +} v3_venc_attr_mjpg; + +typedef struct { + v3_common_dim maxPic; + unsigned int bufSize; + int byFrame; + v3_common_dim pic; + int dcfThumbs; +} v3_venc_attr_jpg; + +typedef struct { + v3_venc_codec codec; + union { + v3_venc_attr_h26x h264; + v3_venc_attr_mjpg mjpg; + v3_venc_attr_jpg jpg; + v3_venc_attr_h26x h265; + }; +} v3_venc_attrib; + +typedef struct { + unsigned int gop; + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + unsigned int bitrate; + unsigned int avgLvl; +} v3_venc_rate_h26xcbr; + +typedef struct { + unsigned int gop; + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + unsigned int maxBitrate; + unsigned int maxQual; + unsigned int minQual; + unsigned int minIQual; +} v3_venc_rate_h26xvbr; + +typedef struct { + unsigned int gop; + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + unsigned int bitrate; +} v3_venc_rate_h26xxvbr; + +typedef struct { + unsigned int gop; + unsigned int srcFps; + unsigned int dstFps; + unsigned int interQual; + unsigned int predQual; + unsigned int bipredQual; +} v3_venc_rate_h26xqp; + +typedef struct { + unsigned int gop; + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + // Accepts values from 0-2 (mean QP, min QP, max QP) + unsigned int qpMapMode; + unsigned int predQual; + unsigned int bipredQual; +} v3_venc_rate_h26xqpmap; + +typedef struct { + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + unsigned int bitrate; + unsigned int avgLvl; +} v3_venc_rate_mjpgcbr; + +typedef struct { + unsigned int statTime; + unsigned int srcFps; + unsigned int dstFps; + unsigned int maxBitrate; + unsigned int maxQual; + unsigned int minQual; +} v3_venc_rate_mjpgvbr; + +typedef struct { + unsigned int srcFps; + unsigned int dstFps; + unsigned int quality; +} v3_venc_rate_mjpgqp; +typedef struct { + v3_venc_ratemode mode; + union { + v3_venc_rate_h26xcbr h264Cbr; + v3_venc_rate_h26xvbr h264Vbr; + v3_venc_rate_h26xxvbr h264Avbr; + v3_venc_rate_h26xxvbr h264Qvbr; + v3_venc_rate_h26xqp h264Qp; + v3_venc_rate_h26xqpmap h264QpMap; + v3_venc_rate_mjpgcbr mjpgCbr; + v3_venc_rate_mjpgvbr mjpgVbr; + v3_venc_rate_mjpgqp mjpgQp; + v3_venc_rate_h26xcbr h265Cbr; + v3_venc_rate_h26xvbr h265Vbr; + v3_venc_rate_h26xxvbr h265Avbr; + v3_venc_rate_h26xxvbr h265Qvbr; + v3_venc_rate_h26xqp h265Qp; + v3_venc_rate_h26xqpmap h265QpMap; + }; + void *extend; +} v3_venc_rate; + +typedef struct { + int ipQualDelta; +} v3_venc_gop_normalp; + +typedef struct { + unsigned int spInterv; + int spQualDelta; + int ipQualDelta; +} v3_venc_gop_dualp; + +typedef struct { + unsigned int bgInterv; + int bgQualDelta; + int viQualDelta; +} v3_venc_gop_smartp; + +typedef struct { + unsigned int bFrameNum; + int bgQualDelta; + int ipQualDelta; +} v3_venc_gop_bipredb; + +typedef struct { + v3_venc_gopmode mode; + union { + v3_venc_gop_normalp normalP; + v3_venc_gop_dualp dualP; + v3_venc_gop_smartp smartP; + v3_venc_gop_bipredb bipredB; + }; +} v3_venc_gop; + +typedef struct { + v3_venc_attrib attrib; + v3_venc_rate rate; + v3_venc_gop gop; +} v3_venc_chn; + +typedef struct { + unsigned int quality; + unsigned char qtLuma[64]; + unsigned char qtChromaBlue[64]; + unsigned char qtChromaRed[64]; + unsigned int mcuPerEcs; +} v3_venc_jpg; + +typedef union { + v3_venc_nalu_h264 h264Nalu; + v3_venc_nalu_mjpg mjpgNalu; + v3_venc_nalu_h265 h265Nalu; +} v3_venc_nalu; + +typedef struct { + v3_venc_nalu packType; + unsigned int offset; + unsigned int length; +} v3_venc_packinfo; + +typedef struct { + unsigned int addr; + unsigned char *data; + unsigned int length; + unsigned long long timestamp; + int endFrame; + v3_venc_nalu naluType; + unsigned int offset; + unsigned int packNum; + v3_venc_packinfo packetInfo[8]; +} v3_venc_pack; + +typedef struct { + unsigned int leftPics; + unsigned int leftBytes; + unsigned int leftFrames; + unsigned int curPacks; + unsigned int leftRecvPics; + unsigned int leftEncPics; +} v3_venc_stat; + +typedef struct { + unsigned int size; + unsigned int iMb16x16; + unsigned int iMb8x8; + unsigned int pMb16; + unsigned int pMb8; + unsigned int pMb4; + unsigned int refSliceType; + unsigned int refType; + unsigned int updAttrCnt; + unsigned int startQual; + unsigned int meanQual; + int pSkip; +} v3_venc_strminfo_h264; + +typedef struct { + unsigned int size; + unsigned int iCu64x64; + unsigned int iCu32x32; + unsigned int iCu16x16; + unsigned int iCu8x8; + unsigned int pCu32x32; + unsigned int pCu16x16; + unsigned int pCu8x8; + unsigned int pCu4x4; + unsigned int refType; + unsigned int updAttrCnt; + unsigned int startQual; + unsigned int meanQual; + int pSkip; +} v3_venc_strminfo_h265; + +typedef struct { + unsigned int size; + unsigned int updAttrCnt; + unsigned int quality; +} v3_venc_strminfo_mjpg; + +typedef struct { + int sseOn; + unsigned int sseVal; +} v3_venc_sseinfo; + +typedef struct { + unsigned int residualBitNum; + unsigned int headBitNum; + unsigned int madiVal; + unsigned int madpVal; + double psnrVal; + unsigned int mseLcuCnt; + unsigned int mseSum; + v3_venc_sseinfo sseInfo[8]; + unsigned int qualHstgrm[52]; +} v3_venc_strmadvinfo_h26x; + +typedef struct { + unsigned int reserved; +} v3_venc_strmadvinfo_mjpg; + +typedef struct { + v3_venc_pack *packet; + unsigned int count; + unsigned int sequence; + union { + v3_venc_strminfo_h264 h264Info; + v3_venc_strminfo_mjpg mjpgInfo; + v3_venc_strminfo_h265 h265Info; + }; + union { + v3_venc_strmadvinfo_h26x h264aInfo; + v3_venc_strmadvinfo_mjpg mjpgaInfo; + v3_venc_strmadvinfo_h26x h265aInfo; + }; +} v3_venc_strm; + +typedef struct { + void *handle; + + int (*fnCreateChannel)(int channel, v3_venc_chn *config); + int (*fnGetChannelConfig)(int channel, v3_venc_chn *config); + int (*fnDestroyChannel)(int channel); + int (*fnResetChannel)(int channel); + int (*fnSetChannelConfig)(int channel, v3_venc_chn *config); + int (*fnSetColorToGray)(int channel, int *active); + + int (*fnFreeDescriptor)(int channel); + int (*fnGetDescriptor)(int channel); + + int (*fnGetJpegParam)(int channel, v3_venc_jpg *param); + int (*fnSetJpegParam)(int channel, v3_venc_jpg *param); + + int (*fnFreeStream)(int channel, v3_venc_strm *stream); + int (*fnGetStream)(int channel, v3_venc_strm *stream, unsigned int timeout); + + int (*fnQuery)(int channel, v3_venc_stat* stats); + + int (*fnStartReceivingEx)(int channel, int *count); + int (*fnStopReceiving)(int channel); +} v3_venc_impl; + +static int v3_venc_load(v3_venc_impl *venc_lib) { + if (!(venc_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_venc] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnCreateChannel = (int(*)(int channel, v3_venc_chn *config)) + dlsym(venc_lib->handle, "HI_MPI_VENC_CreateChn"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_CreateChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnDestroyChannel = (int(*)(int channel)) + dlsym(venc_lib->handle, "HI_MPI_VENC_DestroyChn"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_DestroyChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetChannelConfig = (int(*)(int channel, v3_venc_chn *config)) + dlsym(venc_lib->handle, "HI_MPI_VENC_GetChnAttr"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_GetChnAttr!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnResetChannel = (int(*)(int channel)) + dlsym(venc_lib->handle, "HI_MPI_VENC_ResetChn"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_ResetChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnSetChannelConfig = (int(*)(int channel, v3_venc_chn *config)) + dlsym(venc_lib->handle, "HI_MPI_VENC_SetChnAttr"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_SetChnAttr!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnFreeDescriptor = (int(*)(int channel)) + dlsym(venc_lib->handle, "HI_MPI_VENC_CloseFd"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_CloseFd!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetDescriptor = (int(*)(int channel)) + dlsym(venc_lib->handle, "HI_MPI_VENC_GetFd"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_GetFd!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetJpegParam = (int(*)(int channel, v3_venc_jpg *param)) + dlsym(venc_lib->handle, "HI_MPI_VENC_GetJpegParam"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_GetJpegParam!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnSetJpegParam = (int(*)(int channel, v3_venc_jpg *param)) + dlsym(venc_lib->handle, "HI_MPI_VENC_SetJpegParam"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_SetJpegParam!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnFreeStream = (int(*)(int channel, v3_venc_strm *stream)) + dlsym(venc_lib->handle, "HI_MPI_VENC_ReleaseStream"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_ReleaseStream!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetStream = (int(*)(int channel, v3_venc_strm *stream, unsigned int timeout)) + dlsym(venc_lib->handle, "HI_MPI_VENC_GetStream"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_GetStream!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnQuery = (int(*)(int channel, v3_venc_stat *stats)) + dlsym(venc_lib->handle, "HI_MPI_VENC_QueryStatus"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_QueryStatus!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnStartReceivingEx = (int(*)(int channel, int *count)) + dlsym(venc_lib->handle, "HI_MPI_VENC_StartRecvFrame"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_StartRecvFrame!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnStopReceiving = (int(*)(int channel)) + dlsym(venc_lib->handle, "HI_MPI_VENC_StopRecvFrame"))) { + fprintf(stderr, "[v3_venc] Failed to acquire symbol HI_MPI_VENC_StopRecvPic!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_venc_unload(v3_venc_impl *venc_lib) { + if (venc_lib->handle) dlclose(venc_lib->handle); + venc_lib->handle = NULL; + memset(venc_lib, 0, sizeof(*venc_lib)); +} \ No newline at end of file diff --git a/src/hal/hisi/v3_vi.h b/src/hal/hisi/v3_vi.h new file mode 100644 index 0000000..c9b9ead --- /dev/null +++ b/src/hal/hisi/v3_vi.h @@ -0,0 +1,159 @@ +#pragma once + +#include "v3_common.h" + +typedef enum { + V3_VI_INTF_BT656, + V3_VI_INTF_BT601, + V3_VI_INTF_DIGITAL_CAMERA, + V3_VI_INTF_BT1120_STANDARD, + V3_VI_INTF_BT1120_INTERLEAVED, + V3_VI_INTF_MIPI, + V3_VI_INTF_LVDS, + V3_VI_INTF_HISPI, + V3_VI_INTF_END +} v3_vi_intf; + +typedef enum { + V3_VI_REPHASE_NONE, + V3_VI_REPHASE_SKIP1_2, + V3_VI_REPHASE_SKIP1_3, + V3_VI_REPHASE_BINNING1_2, + V3_VI_REPHASE_BINNING1_3, + V3_VI_REPHASE_END +} v3_vi_rephase; + +typedef enum { + V3_VI_SEQ_VUVU, + V3_VI_SEQ_UVUV, + V3_VI_SEQ_UYVY, + V3_VI_SEQ_VYUY, + V3_VI_SEQ_YUYV, + V3_VI_SEQ_YVYU, + V3_VI_SEQ_END +} v3_vi_seq; + +typedef enum { + V3_VI_WORK_1MULTIPLEX, + V3_VI_WORK_2MULTIPLEX, + V3_VI_WORK_4MULTIPLEX +} v3_vi_work; + +typedef struct { + v3_common_rect capt; + v3_common_dim dest; + // Accepts values from 0-2 (top, bottom, both) + int field; + v3_common_pixfmt pixFmt; + v3_common_compr compress; + int mirror; + int flip; + int srcFps; + int dstFps; +} v3_vi_chn; + +typedef struct { + unsigned int hsyncFront; + unsigned int hsyncWidth; + unsigned int hsyncBack; + unsigned int vsyncFront; + unsigned int vsyncWidth; + unsigned int vsyncBack; + // Next three are valid on interlace mode + // and define even-frame timings + unsigned int vsyncIntrlFront; + unsigned int vsyncIntrlWidth; + unsigned int vsyncIntrlBack; +} v3_vi_timing; + +typedef struct { + int vsyncPulse; + int vsyncInv; + int hsyncPulse; + int hsyncInv; + int vsyncValid; + int vsyncValidInv; + v3_vi_timing timing; +} v3_vi_sync; + +typedef struct { + v3_vi_intf intf; + v3_vi_work work; + unsigned int cmpntMask[2]; + int progressiveOn; + int adChn[4]; + v3_vi_seq seq; + v3_vi_sync sync; + // Accepts values from 0-2 (bypass, isp, raw) + int dataPath; + int rgbModeOn; + int dataRevOn; + v3_common_rect rect; + v3_common_dim bayerSize; + int bayerComprOn; + v3_vi_rephase hsyncBayerReph; + v3_vi_rephase vsyncBayerReph; +} v3_vi_dev; + +typedef struct { + void *handle; + + int (*fnDisableDevice)(int device); + int (*fnEnableDevice)(int device); + int (*fnSetDeviceConfig)(int device, v3_vi_dev *config); + + int (*fnDisableChannel)(int channel); + int (*fnEnableChannel)(int channel); + int (*fnSetChannelConfig)(int channel, v3_vi_chn *config); +} v3_vi_impl; + +static int v3_vi_load(v3_vi_impl *vi_lib) { + if (!(vi_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_vi] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnDisableDevice = (int(*)(int device)) + dlsym(vi_lib->handle, "HI_MPI_VI_DisableDev"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_DisableDev!\n"); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnEnableDevice = (int(*)(int device)) + dlsym(vi_lib->handle, "HI_MPI_VI_EnableDev"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_EnableDev!\n"); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnSetDeviceConfig = (int(*)(int device, v3_vi_dev *config)) + dlsym(vi_lib->handle, "HI_MPI_VI_SetDevAttr"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_SetDevAttr!\n"); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnDisableChannel = (int(*)(int channel)) + dlsym(vi_lib->handle, "HI_MPI_VI_DisableChn"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_DisableChn!\n"); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnEnableChannel = (int(*)(int channel)) + dlsym(vi_lib->handle, "HI_MPI_VI_EnableChn"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_EnableChn!\n"); + return EXIT_FAILURE; + } + + if (!(vi_lib->fnSetChannelConfig = (int(*)(int channel, v3_vi_chn *config)) + dlsym(vi_lib->handle, "HI_MPI_VI_SetChnAttr"))) { + fprintf(stderr, "[v3_vi] Failed to acquire symbol HI_MPI_VI_SetChnAttr!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_vi_unload(v3_vi_impl *vi_lib) { + if (vi_lib->handle) dlclose(vi_lib->handle); + vi_lib->handle = NULL; + memset(vi_lib, 0, sizeof(*vi_lib)); +} \ No newline at end of file diff --git a/src/hal/hisi/v3_vpss.h b/src/hal/hisi/v3_vpss.h new file mode 100644 index 0000000..aa1297b --- /dev/null +++ b/src/hal/hisi/v3_vpss.h @@ -0,0 +1,112 @@ +#pragma once + +#include "v3_common.h" + +#define V3_VPSS_CHN_NUM 11 +#define V3_VPSS_GRP_NUM 32 + +typedef struct { + int sharpOn; + int borderEn; + int mirror; + int flip; + int srcFps; + int dstFps; + v3_common_bord border; +} v3_vpss_chn; + +typedef struct { + v3_common_dim dest; + v3_common_pixfmt pixFmt; + int enhOn; + int dciOn; + int nredOn; + int histEn; + // Accepts values from 0-2 (auto, off, on) + int interlMode; + int sharpOn; +} v3_vpss_grp; + +typedef struct { + void *handle; + + int (*fnCreateGroup)(int group, v3_vpss_grp *config); + int (*fnDestroyGroup)(int group); + int (*fnResetGroup)(int group); + int (*fnSetGroupConfig)(int channel, v3_vpss_grp *config); + int (*fnStartGroup)(int group); + int (*fnStopGroup)(int group); + + int (*fnDisableChannel)(int group, int channel); + int (*fnEnableChannel)(int group, int channel); + int (*fnSetChannelConfig)(int group, int channel, v3_vpss_chn *config); +} v3_vpss_impl; + +static int v3_vpss_load(v3_vpss_impl *vpss_lib) { + if (!(vpss_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[v3_vpss] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnCreateGroup = (int(*)(int group, v3_vpss_grp *config)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_CreateGrp"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_CreateGrp!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnDestroyGroup = (int(*)(int group)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_DestroyGrp"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_DestroyGrp!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnResetGroup = (int(*)(int group)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_ResetGrp"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_ResetGrp!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnSetGroupConfig = (int(*)(int group, v3_vpss_grp *config)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_SetGrpAttr"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_SetGrpAttr!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnStartGroup = (int(*)(int group)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_StartGrp"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_StartGrp!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnStopGroup = (int(*)(int group)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_StopGrp"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_StopGrp!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnDisableChannel = (int(*)(int group, int channel)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_DisableChn"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_DisableChn!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnEnableChannel = (int(*)(int group, int channel)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_EnableChn"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_EnableChn!\n"); + return EXIT_FAILURE; + } + + if (!(vpss_lib->fnSetChannelConfig = (int(*)(int group, int channel, v3_vpss_chn *config)) + dlsym(vpss_lib->handle, "HI_MPI_VPSS_SetChnAttr"))) { + fprintf(stderr, "[v3_vpss] Failed to acquire symbol HI_MPI_VPSS_SetChnAttr!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void v3_vpss_unload(v3_vpss_impl *vpss_lib) { + if (vpss_lib->handle) dlclose(vpss_lib->handle); + vpss_lib->handle = NULL; + memset(vpss_lib, 0, sizeof(*vpss_lib)); +} diff --git a/src/hal/hisi/v4_snr.h b/src/hal/hisi/v4_snr.h index 8a6eb07..628e4ca 100644 --- a/src/hal/hisi/v4_snr.h +++ b/src/hal/hisi/v4_snr.h @@ -94,7 +94,7 @@ typedef struct { int dataBeOn; int syncBeOn; // Value -1 signifies a lane is disabled - short laneId[4]; + short laneId[V4_SNR_LVDS_LANE_NUM]; /* Each lane has two virtual channel, each has four params If syncSavOn is false: SOF, EOF, SOL, EOL If syncSavOn is true: invalid sav, invalid eav, valid sav, valid eav */ @@ -105,9 +105,9 @@ typedef struct { v4_common_prec prec; v4_snr_mwdr mode; // Value -1 signifies a lane is disabled - short laneId[4]; + short laneId[V4_SNR_MIPI_LANE_NUM]; union { - short wdrVcType[2]; + short wdrVcType[V4_SNR_WDR_VC_NUM]; }; } v4_snr_mipi; diff --git a/src/hal/hisi/v4_sys.h b/src/hal/hisi/v4_sys.h index cfc0813..cd4eba5 100644 --- a/src/hal/hisi/v4_sys.h +++ b/src/hal/hisi/v4_sys.h @@ -14,11 +14,11 @@ typedef enum { V4_SYS_MOD_GROUP, V4_SYS_MOD_VPSS, V4_SYS_MOD_VENC, - V4_SYS_MOD_VDA, + V4_SYS_MOD_SVP, V4_SYS_MOD_H264E, V4_SYS_MOD_JPEGE, V4_SYS_MOD_MPEG4E, - V4_SYS_MOD_H264D, + V4_SYS_MOD_H265E, V4_SYS_MOD_JPEGD, V4_SYS_MOD_VOU, V4_SYS_MOD_VIU, @@ -35,28 +35,38 @@ typedef enum { V4_SYS_MOD_PCIVFMW, V4_SYS_MOD_ISP, V4_SYS_MOD_IVE, - V4_SYS_MOD_DCCM = 31, + V4_SYS_MOD_USER, + V4_SYS_MOD_DCCM, V4_SYS_MOD_DCCS, V4_SYS_MOD_PROC, V4_SYS_MOD_LOG, - V4_SYS_MOD_MST_LOG, - V4_SYS_MOD_VD, - V4_SYS_MOD_VCMP = 38, + V4_SYS_MOD_VFMW, + V4_SYS_MOD_H264D, + V4_SYS_MOD_GDC, + V4_SYS_MOD_PHOTO, V4_SYS_MOD_FB, V4_SYS_MOD_HDMI, V4_SYS_MOD_VOIE, V4_SYS_MOD_TDE, - V4_SYS_MOD_USR, - V4_SYS_MOD_VEDU, + V4_SYS_MOD_HDR, + V4_SYS_MOD_PRORES, V4_SYS_MOD_VGS, - V4_SYS_MOD_H265E, - V4_SYS_MOD_FD, + V4_SYS_MOD_FD = 47, V4_SYS_MOD_ODT, V4_SYS_MOD_VQA, V4_SYS_MOD_LPR, - V4_SYS_MOD_FISHEYE, - V4_SYS_MOD_PHOTO, - V4_SYS_MOD_EXTAO, + V4_SYS_MOD_SVP_NNIE, + V4_SYS_MOD_SVP_DSP, + V4_SYS_MOD_DPU_RECT, + V4_SYS_MOD_DPU_MATCH, + V4_SYS_MOD_MOTSNS, + V4_SYS_MOD_MOTFUS, + V4_SYS_MOD_GYRODIS, + V4_SYS_MOD_PM, + V4_SYS_MOD_SVP_ALG, + V4_SYS_MOD_IVP, + V4_SYS_MOD_MCF, + V4_SYS_MOD_QR, V4_SYS_MOD_END } v4_sys_mod; diff --git a/src/hal/hisi/v4_vi.h b/src/hal/hisi/v4_vi.h index 3935be4..b6e0e2b 100644 --- a/src/hal/hisi/v4_vi.h +++ b/src/hal/hisi/v4_vi.h @@ -179,19 +179,19 @@ static int v4_vi_load(v4_vi_impl *vi_lib) { return EXIT_FAILURE; } - if (!(vi_lib->fnDisableChannel = (int(*)(int pipe, int device)) + if (!(vi_lib->fnDisableChannel = (int(*)(int pipe, int channel)) dlsym(vi_lib->handle, "HI_MPI_VI_DisableChn"))) { fprintf(stderr, "[v4_vi] Failed to acquire symbol HI_MPI_VI_DisableChn!\n"); return EXIT_FAILURE; } - if (!(vi_lib->fnEnableChannel = (int(*)(int pipe, int device)) + if (!(vi_lib->fnEnableChannel = (int(*)(int pipe, int channel)) dlsym(vi_lib->handle, "HI_MPI_VI_EnableChn"))) { fprintf(stderr, "[v4_vi] Failed to acquire symbol HI_MPI_VI_EnableChn!\n"); return EXIT_FAILURE; } - if (!(vi_lib->fnSetChannelConfig = (int(*)(int pipe, int device, v4_vi_chn *config)) + if (!(vi_lib->fnSetChannelConfig = (int(*)(int pipe, int channel, v4_vi_chn *config)) dlsym(vi_lib->handle, "HI_MPI_VI_SetChnAttr"))) { fprintf(stderr, "[v4_vi] Failed to acquire symbol HI_MPI_VI_SetChnAttr!\n"); return EXIT_FAILURE;