From ae85ecfe30a26df6db4d114f06afab61c9d1cdb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20B=C3=A9rub=C3=A9?= Date: Fri, 24 May 2024 13:39:36 -0400 Subject: [PATCH] Fixes an issue loading a ISP config file, adds early support for Ingenic T series --- README.md | 2 + src/hal/inge/tx_aud.h | 120 +++++++++++++ src/hal/inge/tx_common.h | 74 ++++++++ src/hal/inge/tx_fs.h | 115 ++++++++++++ src/hal/inge/tx_hal.c | 41 +++++ src/hal/inge/tx_hal.h | 11 ++ src/hal/inge/tx_isp.h | 97 ++++++++++ src/hal/inge/tx_osd.h | 131 ++++++++++++++ src/hal/inge/tx_sys.h | 91 ++++++++++ src/hal/inge/tx_venc.h | 379 +++++++++++++++++++++++++++++++++++++++ src/hal/support.h | 4 + src/hal/types.h | 1 + src/video.c | 2 +- 13 files changed, 1067 insertions(+), 1 deletion(-) create mode 100644 src/hal/inge/tx_aud.h create mode 100644 src/hal/inge/tx_common.h create mode 100644 src/hal/inge/tx_fs.h create mode 100644 src/hal/inge/tx_hal.c create mode 100644 src/hal/inge/tx_hal.h create mode 100644 src/hal/inge/tx_isp.h create mode 100644 src/hal/inge/tx_osd.h create mode 100644 src/hal/inge/tx_sys.h create mode 100644 src/hal/inge/tx_venc.h diff --git a/README.md b/README.md index 295f023..128ad2c 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ In spite of these design choices, Divinus boasts numerous features that cater to | infinity6e[^6] | ↻ | ✔️ | ✔️ | ✗ | ✔️ | | infinity6c[^7] | ↻ | ✔️ | ✔️ | ✗ | ✔️ | | infinity6f[^8] | ↻ | ✔️ | ✔️ | ✗ | ✔️ | +| T2X series | ↻ | ↻ | ↻ | ✗ | ↻ | +| T3X series | ↻ | ↻ | ↻ | ✗ | ↻ | _✔️ - supported, ↻ - in development, ✗ - unsupported, ⁿ/ₐ - not supported by hardware_ diff --git a/src/hal/inge/tx_aud.h b/src/hal/inge/tx_aud.h new file mode 100644 index 0000000..f680e91 --- /dev/null +++ b/src/hal/inge/tx_aud.h @@ -0,0 +1,120 @@ +#pragma once + +#include "tx_common.h" + +#define TX_AUD_CHN_NUM 2 + +typedef enum { + TX_AUD_BIT_16 +} tx_aud_bit; + +typedef enum { + TX_AUD_SND_MONO = 1, + TX_AUD_SND_STEREO = 2 +} tx_aud_snd; + +typedef struct { + // Accept industry standards from 8000 to 96000Hz + int rate; + tx_aud_bit bit; + tx_aud_snd mode; + unsigned int frmNum; + unsigned int packNumPerFrm; + unsigned int chnNum; +} tx_aud_cnf; + +typedef struct { + tx_aud_bit bit; + tx_aud_snd mode; + unsigned int addr; + unsigned int phy; + unsigned long long timestamp; + unsigned int sequence; + unsigned int length; +} tx_aud_frm; + +typedef struct { + void *handle; + + int (*fnDisableDevice)(int device); + int (*fnEnableDevice)(int device); + int (*fnSetDeviceConfig)(int device, tx_aud_cnf *config); + + int (*fnDisableChannel)(int device, int channel); + int (*fnEnableChannel)(int device, int channel); + + int (*fnSetMute)(int device, int channel, int active); + int (*fnSetVolume)(int device, int channel, int *dbLevel); + + int (*fnFreeFrame)(int device, int channel, tx_aud_frm *frame); + int (*fnGetFrame)(int device, int channel, tx_aud_frm *frame, int notBlocking); +} tx_aud_impl; + +static int tx_aud_load(tx_aud_impl *aud_lib) { + if (!(aud_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_aud] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnDisableDevice = (int(*)(int device)) + dlsym(aud_lib->handle, "IMP_AI_Disable"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_Disable!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnEnableDevice = (int(*)(int device)) + dlsym(aud_lib->handle, "IMP_AI_Enable"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_Enable!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnSetDeviceConfig = (int(*)(int device, tx_aud_cnf *config)) + dlsym(aud_lib->handle, "IMP_AI_SetPubAttr"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_SetPubAttr!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnDisableChannel = (int(*)(int device, int channel)) + dlsym(aud_lib->handle, "IMP_AI_DisableChn"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_DisableChn!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnEnableChannel = (int(*)(int device, int channel)) + dlsym(aud_lib->handle, "IMP_AI_EnableChn"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_EnableChn!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnSetMute = (int(*)(int device, int channel, int active)) + dlsym(aud_lib->handle, "IMP_AI_SetVolMute"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_SetVolMute!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnSetVolume = (int(*)(int device, int channel, int dbLevel)) + dlsym(aud_lib->handle, "IMP_AI_SetVol"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_SetVol!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnFreeFrame = (int(*)(int device, int channel, tx_aud_frm *frame)) + dlsym(aud_lib->handle, "IMP_AI_ReleaseFrame"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_ReleaseFrame!\n"); + return EXIT_FAILURE; + } + + if (!(aud_lib->fnGetFrame = (int(*)(int device, int channel, tx_aud_frm *frame, int notBlocking)) + dlsym(aud_lib->handle, "IMP_AI_GetFrame"))) { + fprintf(stderr, "[tx_aud] Failed to acquire symbol IMP_AI_GetFrame!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_aud_unload(tx_aud_impl *aud_lib) { + if (aud_lib->handle) dlclose(aud_lib->handle); + aud_lib->handle = NULL; + memset(aud_lib, 0, sizeof(*aud_lib)); +} \ No newline at end of file diff --git a/src/hal/inge/tx_common.h b/src/hal/inge/tx_common.h new file mode 100644 index 0000000..1feb563 --- /dev/null +++ b/src/hal/inge/tx_common.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "../types.h" + +#define TX_ERROR(x, ...) \ + do { \ + fprintf(stderr, "[tx_hal] \033[31m"); \ + fprintf(stderr, (x), ##__VA_ARGS__); \ + fprintf(stderr, "\033[0m"); \ + return EXIT_FAILURE; \ + } while (0) + +typedef enum { + TX_PIXFMT_YUV420P, + TX_PIXFMT_YUV422_YUYV, + TX_PIXFMT_YUV422_UYVY, + TX_PIXFMT_YUV422P, + TX_PIXFMT_YUV444P, + TX_PIXFMT_YUV410P, + TX_PIXFMT_YUV411P, + TX_PIXFMT_GRAY8, + TX_PIXFMT_MONOWHITE, + TX_PIXFMT_MONOBLACK, + TX_PIXFMT_NV12, + TX_PIXFMT_NV24, + TX_PIXFMT_RGB888, + TX_PIXFMT_BGR888, + TX_PIXFMT_ARGB8888, + TX_PIXFMT_RGBA8888, + TX_PIXFMT_ABGR8888, + TX_PIXFMT_BGRA8888, + TX_PIXFMT_RGB565BE, + TX_PIXFMT_RGB565LE, + // Following twos have their MSB set to 1 + TX_PIXFMT_RGB555BE, + TX_PIXFMT_RGB555LE, + TX_PIXFMT_BGR565BE, + TX_PIXFMT_BGR565LE, + // Following twos have their MSB set to 1 + TX_PIXFMT_BGR555BE, + TX_PIXFMT_BGR555LE, + TX_PIXFMT_0RGB8888, + TX_PIXFMT_RGB08888, + TX_PIXFMT_0BGR8888, + TX_PIXFMT_BGR08888, + TX_PIXFMT_BAYER_BGGR8, + TX_PIXFMT_BAYER_RGGB8, + TX_PIXFMT_BAYER_GBRG8, + TX_PIXFMT_BAYER_GRBG8, + TX_PIXFMT_RAW, + TX_PIXFMT_HSV888, + TX_PIXFMT_END +} tx_common_pixfmt; + +typedef struct { + int width; + int height; +} tx_common_dim; + +typedef struct { + int x; + int y; +} tx_common_pnt; + +typedef struct { + tx_common_pnt p0; + tx_common_pnt p1; +} tx_common_rect; \ No newline at end of file diff --git a/src/hal/inge/tx_fs.h b/src/hal/inge/tx_fs.h new file mode 100644 index 0000000..16bad3b --- /dev/null +++ b/src/hal/inge/tx_fs.h @@ -0,0 +1,115 @@ +#pragma once + +#include "tx_common.h" + +typedef struct { + int enable; + int left; + int top; + int width; + int height; +} tx_fs_crop; + +typedef struct { + int enable; + int width; + int height; +} tx_fs_scale; + +typedef struct { + tx_common_dim dest; + tx_common_pixfmt pixFmt; + tx_fs_crop crop; + tx_fs_scale scale; + int fpsNum; + int fpsDen; + int bufCount; + int phyOrExtChn; + tx_fs_crop frame; +} tx_fs_chn; + +typedef struct { + int index; + int poolId; + unsigned int width; + unsigned int height; + tx_common_pixfmt pixFmt; + unsigned int size; + unsigned int phyAddr; + unsigned int virtAddr; + long long timestamp; + int rotateFlag; + unsigned int priv[0]; +} tx_fs_frame; + +typedef struct { + void *handle; + + int (*fnCreateChannel)(int channel, tx_fs_chn *config); + int (*fnDestroyChannel)(int channel); + int (*fnDisableChannel)(int channel); + int (*fnEnableChannel)(int channel); + int (*fnSetChannelRotate)(int channel, char rotateMode, int width, int height); + int (*fnSetChannelSource)(int channel, int source); + + int (*fnSnapshot)(int channel, tx_common_pixfmt pixFmt, int width, int height, + void *data, tx_fs_frame *info); +} tx_fs_impl; + +static int tx_fs_load(tx_fs_impl *fs_lib) { + if (!(fs_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_fs] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnCreateChannel = (int(*)(int channel, tx_fs_chn *config)) + dlsym(fs_lib->handle, "IMP_FrameSource_CreateChn"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_CreateChn!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnDestroyChannel = (int(*)(int channel)) + dlsym(fs_lib->handle, "IMP_FrameSource_DestroyChn"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_DestroyChn!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnDisableChannel = (int(*)(int channel)) + dlsym(fs_lib->handle, "IMP_FrameSource_DisableChn"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_DisableChn!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnEnableChannel = (int(*)(int channel)) + dlsym(fs_lib->handle, "IMP_FrameSource_EnableChn"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_EnableChn!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnSetChannelRotate = (int(*)(int channel, char rotateMode, int width, int height)) + dlsym(fs_lib->handle, "IMP_FrameSource_SetChnRotate"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_SetChnRotate!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnSetChannelSource = (int(*)(int channel, int source)) + dlsym(fs_lib->handle, "IMP_FrameSource_SetSource"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_SetSource!\n"); + return EXIT_FAILURE; + } + + if (!(fs_lib->fnSnapshot = (int(*)(int channel, tx_common_pixfmt pixFmt, int width, int height, + void *data, tx_fs_frame *info)) + dlsym(fs_lib->handle, "IMP_FrameSource_SnapFrame"))) { + fprintf(stderr, "[tx_fs] Failed to acquire symbol IMP_FrameSource_SnapFrame!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_fs_unload(tx_fs_impl *fs_lib) { + if (fs_lib->handle) dlclose(fs_lib->handle); + fs_lib->handle = NULL; + memset(fs_lib, 0, sizeof(*fs_lib)); +} \ No newline at end of file diff --git a/src/hal/inge/tx_hal.c b/src/hal/inge/tx_hal.c new file mode 100644 index 0000000..206ebd0 --- /dev/null +++ b/src/hal/inge/tx_hal.c @@ -0,0 +1,41 @@ +#include "tx_hal.h" + +tx_aud_impl tx_aud; +tx_fs_impl tx_fs; +tx_isp_impl tx_isp; +tx_osd_impl tx_osd; +tx_sys_impl tx_sys; +tx_venc_impl tx_venc; + +hal_chnstate tx_state[TX_VENC_CHN_NUM] = {0}; +int (*tx_venc_cb)(char, hal_vidstream*); + +void tx_hal_deinit(void) +{ + tx_venc_unload(&tx_venc); + tx_osd_unload(&tx_osd); + tx_isp_unload(&tx_isp); + tx_fs_unload(&tx_fs); + tx_aud_unload(&tx_aud); + tx_sys_unload(&tx_sys); +} + +int tx_hal_init(void) +{ + int ret; + + if (ret = tx_sys_load(&tx_sys)) + return ret; + if (ret = tx_aud_load(&tx_aud)) + return ret; + if (ret = tx_fs_load(&tx_fs)) + return ret; + if (ret = tx_isp_load(&tx_isp)) + return ret; + if (ret = tx_osd_load(&tx_osd)) + return ret; + if (ret = tx_venc_load(&tx_venc)) + return ret; + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/hal/inge/tx_hal.h b/src/hal/inge/tx_hal.h new file mode 100644 index 0000000..217f3b0 --- /dev/null +++ b/src/hal/inge/tx_hal.h @@ -0,0 +1,11 @@ +#pragma once + +#include "tx_common.h" +#include "tx_aud.h" +#include "tx_fs.h" +#include "tx_isp.h" +#include "tx_osd.h" +#include "tx_sys.h" +#include "tx_venc.h" + +extern char keepRunning; \ No newline at end of file diff --git a/src/hal/inge/tx_isp.h b/src/hal/inge/tx_isp.h new file mode 100644 index 0000000..c1211cd --- /dev/null +++ b/src/hal/inge/tx_isp.h @@ -0,0 +1,97 @@ +#pragma once + +#include "tx_common.h" + +typedef struct { + char type[20]; + int addr; + int bus; +} tx_isp_i2c; + +typedef struct { + char alias[32]; + int bus; +} tx_isp_spi; + +typedef struct { + char name[32]; + int spiMode; + union { + tx_isp_i2c i2c; + tx_isp_spi spi; + }; + unsigned short rstPin; + unsigned short powDownPin; + unsigned short powUpPin; +} tx_isp_snr; + + +typedef struct { + void *handle; + + int (*fnExit)(void); + int (*fnInit)(void); + int (*fnLoadConfig)(char *path); + + int (*fnAddSensor)(tx_isp_snr *sensor); + int (*fnDeleteSensor)(tx_isp_snr *sensor); + int (*fnDisableSensor)(void); + int (*fnEnableSensor)(void); +} tx_isp_impl; + +static int tx_isp_load(tx_isp_impl *isp_lib) { + if (!(isp_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_isp] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnExit = (int(*)(int channel, tx_fs_chn *config)) + dlsym(isp_lib->handle, "IMP_ISP_Close"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_Close!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnInit = (int(*)(int channel)) + dlsym(isp_lib->handle, "IMP_ISP_Open"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_Open!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnLoadConfig = (int(*)(char *path)) + dlsym(isp_lib->handle, "IMP_ISP_SetDefaultBinPath"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_SetDefaultBinPath!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnAddSensor = (int(*)(tx_isp_snr *sensor)) + dlsym(isp_lib->handle, "IMP_ISP_AddSensor"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_AddSensor!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnDeleteSensor = (int(*)(tx_isp_snr *sensor)) + dlsym(isp_lib->handle, "IMP_ISP_DelSensor"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_DelSensor!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnDisableSensor = (int(*)(void)) + dlsym(isp_lib->handle, "IMP_ISP_DisableSensor"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_DisableSensor!\n"); + return EXIT_FAILURE; + } + + if (!(isp_lib->fnEnableSensor = (int(*)(void)) + dlsym(isp_lib->handle, "IMP_ISP_EnableSensor"))) { + fprintf(stderr, "[tx_isp] Failed to acquire symbol IMP_ISP_EnableSensor!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_isp_unload(tx_isp_impl *isp_lib) { + if (isp_lib->handle) dlclose(isp_lib->handle); + isp_lib->handle = NULL; + memset(isp_lib, 0, sizeof(*isp_lib)); +} \ No newline at end of file diff --git a/src/hal/inge/tx_osd.h b/src/hal/inge/tx_osd.h new file mode 100644 index 0000000..cdceeb6 --- /dev/null +++ b/src/hal/inge/tx_osd.h @@ -0,0 +1,131 @@ +#pragma once + +#include "tx_common.h" +#include "tx_sys.h" + +typedef enum { + TX_OSD_COLOR_BLACK = 0xFF000000, + TX_OSD_COLOR_BLUE = 0xFF0000FF, + TX_OSD_COLOR_GREEN = 0xFF00FF00, + TX_OSD_COLOR_RED = 0xFFFF0000, + TX_OSD_COLOR_WHITE = 0xFFFFFFFF +} tx_osd_color; + +typedef enum { + TX_OSD_TYPE_INV, + TX_OSD_TYPE_LINE, + TX_OSD_TYPE_RECT, + TX_OSD_TYPE_BITMAP, + TX_OSD_TYPE_COVER, + TX_OSD_TYPE_PIC, + TX_OSD_TYPE_PIC_RMEM, + TX_OSD_TYPE_END +} tx_osd_type; + +typedef union { + void *bitmap; + unsigned int lineParams[2]; + unsigned int coverColor; + void *picture; +} tx_osd_attr; + +typedef struct { + tx_osd_type type; + tx_common_rect rect; + tx_common_pixfmt pixFmt; + tx_osd_attr data; +} tx_osd_rgn; + +typedef struct { + int show; + tx_common_pnt pos; + float scaleX, scaleY; + int alphaOn; + int fgAlpha; + int bgAlpha; + int layer; +} tx_osd_grp; + +typedef struct { + void *handle; + + int (*fnCreateRegion)(tx_osd_rgn *config); + int (*fnDestroyRegion)(int handle); + int (*fnRegisterRegion)(int handle, int group, tx_osd_grp *config); + int (*fnSetRegionConfig)(int handle, tx_osd_rgn *config); + int (*fnUnregisterRegion)(int handle, int group); + + int (*fnAttachToGroup)(tx_sys_bind *source, tx_sys_bind *dest); + int (*fnCreateGroup)(int group); + int (*fnDestroyGroup)(int group); + int (*fnGetGroupConfig)(int handle, int group, tx_osd_grp *config); +} tx_osd_impl; + +static int tx_osd_load(tx_osd_impl *osd_lib) { + if (!(osd_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_osd] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnCreateRegion = (int(*)(tx_osd_rgn *config)) + dlsym(osd_lib->handle, "IMP_OSD_CreateRgn"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_CreateRgn!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnDestroyRegion = (int(*)(int handle)) + dlsym(osd_lib->handle, "IMP_OSD_DestroyRgn"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_DestroyRgn!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnRegisterRegion = (int(*)(int handle, int group, tx_osd_grp *config)) + dlsym(osd_lib->handle, "IMP_OSD_RegisterRgn"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_RegisterRgn!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnSetRegionConfig = (int(*)(int handle, tx_osd_rgn *config)) + dlsym(osd_lib->handle, "IMP_OSD_SetRgnAttr"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_SetRgnAttr!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnUnregisterRegion = (int(*)(int handle, int group)) + dlsym(osd_lib->handle, "IMP_OSD_UnRegisterRgn"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_UnRegisterRgn!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnAttachToGroup = (int(*)(tx_sys_bind *source, tx_sys_bind *dest)) + dlsym(osd_lib->handle, "IMP_OSD_AttachToGroup"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_AttachToGroup!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnCreateGroup = (int(*)(int group)) + dlsym(osd_lib->handle, "IMP_OSD_CreateGroup"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_CreateGroup!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnDestroyGroup = (int(*)(int group)) + dlsym(osd_lib->handle, "IMP_OSD_DestroyGroup"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_DestroyGroup!\n"); + return EXIT_FAILURE; + } + + if (!(osd_lib->fnGetGroupConfig = (int(*)(int handle, int group, tx_osd_grp *config)) + dlsym(osd_lib->handle, "IMP_OSD_GetGrpRgnAttr"))) { + fprintf(stderr, "[tx_osd] Failed to acquire symbol IMP_OSD_GetGrpRgnAttr!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_osd_unload(tx_osd_impl *osd_lib) { + if (osd_lib->handle) dlclose(osd_lib->handle); + osd_lib->handle = NULL; + memset(osd_lib, 0, sizeof(*osd_lib)); +} \ No newline at end of file diff --git a/src/hal/inge/tx_sys.h b/src/hal/inge/tx_sys.h new file mode 100644 index 0000000..02f84f1 --- /dev/null +++ b/src/hal/inge/tx_sys.h @@ -0,0 +1,91 @@ +#pragma once + +#include "tx_common.h" + +#define TX_SYS_API "1.0" + +typedef enum { + TX_SYS_DEV_FS, + TX_SYS_DEV_ENC, + TX_SYS_DEV_DEC, + TX_SYS_DEV_IVS, + TX_SYS_DEV_OSD, + TX_SYS_DEV_FG1DIRECT, + TX_SYS_DEV_RSVD, + TX_SYS_DED_RSVD_END = 23, + TX_SYS_DEV_END +} tx_sys_dev; + +typedef struct { + tx_sys_dev device; + int group; + int port; +} tx_sys_bind; + +typedef struct { + char version[64]; +} tx_sys_ver; + +typedef struct { + void *handle; + + int (*fnExit)(void); + int (*fnGetChipName)(const char *chip); + int (*fnGetVersion)(tx_sys_ver *version); + + int (*fnInit)(void); + + int (*fnBind)(tx_sys_bind *source, tx_sys_bind *dest); + int (*fnUnbind)(tx_sys_bind *source, tx_sys_bind *dest); +} tx_sys_impl; + +static int tx_sys_load(tx_sys_impl *sys_lib) { + if (!(sys_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_sys] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnExit = (int(*)(void)) + dlsym(sys_lib->handle, "IMP_System_Exit"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol IMP_System_Exit!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnGetChipName = (int(*)(const char *chip)) + dlsym(sys_lib->handle, "IMP_System_GetCPUInfo"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol IMP_System_GetCPUInfo!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnGetVersion = (int(*)(tx_sys_ver *version)) + dlsym(sys_lib->handle, "IMP_System_GetVersion"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol IMP_System_GetVersion!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnInit = (int(*)(void)) + dlsym(sys_lib->handle, "IMP_System_Init"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol IMP_System_Init!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnBind = (int(*)(tx_sys_bind *source, tx_sys_bind *dest)) + dlsym(sys_lib->handle, "HI_MPI_SYS_Bind"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol HI_MPI_SYS_Bind!\n"); + return EXIT_FAILURE; + } + + if (!(sys_lib->fnUnbind = (int(*)(tx_sys_bind *source, tx_sys_bind *dest)) + dlsym(sys_lib->handle, "HI_MPI_SYS_UnBind"))) { + fprintf(stderr, "[tx_sys] Failed to acquire symbol HI_MPI_SYS_UnBind!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_sys_unload(tx_sys_impl *sys_lib) { + 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/inge/tx_venc.h b/src/hal/inge/tx_venc.h new file mode 100644 index 0000000..9608964 --- /dev/null +++ b/src/hal/inge/tx_venc.h @@ -0,0 +1,379 @@ +#pragma once + +#include "tx_common.h" + +// To be validated +#define TX_VENC_CHN_NUM 4 + +typedef enum { + TX_VENC_CODEC_H264, + TX_VENC_CODEC_H265, + TX_VENC_CODEC_MJPG = 4 +} tx_venc_codec; + +typedef enum { + TX_VENC_GOPMODE_NORMAL = 0x02, + TX_VENC_GOPMODE_PYRAMID = 0x04, + TX_VENC_GOPMODE_SMARTP = 0xfe, + TX_VENC_GOPMODE_END +} tx_venc_gopmode; + +typedef enum { + TX_VENC_NALU_H264_PSLICE = 1, + TX_VENC_NALU_H264_DPASLICE, + TX_VENC_NALU_H264_DPBSLICE, + TX_VENC_NALU_H264_DPCSLICE, + TX_VENC_NALU_H264_IDRSLICE, + TX_VENC_NALU_H264_SEI, + TX_VENC_NALU_H264_SPS, + TX_VENC_NALU_H264_PPS, + TX_VENC_NALU_H264_AUD, + TX_VENC_NALU_H264_FILLER = 12 +} tx_venc_nalu_h264; + +typedef enum { + TX_VENC_NALU_H265_TRAILLSLICE, + TX_VENC_NALU_H265_TRAILLSLICE_REF, + TX_VENC_NALU_H265_TSASLICE, + TX_VENC_NALU_H265_TSASLICE_REF, + TX_VENC_NALU_H265_STSASLICE, + TX_VENC_NALU_H265_STSASLICE_REF, + TX_VENC_NALU_H265_RADLSLICE, + TX_VENC_NALU_H265_RADLSLICE_REF, + TX_VENC_NALU_H265_RASLSLICE, + TX_VENC_NALU_H265_RASLSLICE_REF, + TX_VENC_NALU_H265_BLASLICE_LP = 16, + TX_VENC_NALU_H265_BLASLICE_RADL, + TX_VENC_NALU_H265_BLASLICE, + TX_VENC_NALU_H265_IDRSLICE_RADL, + TX_VENC_NALU_H265_IDRSLICE, + TX_VENC_NALU_H265_CRASLICE, + TX_VENC_NALU_H265_VPS = 32, + TX_VENC_NALU_H265_SPS, + TX_VENC_NALU_H265_PPS, + TX_VENC_NALU_H265_AUD, + TX_VENC_NALU_H265_EOS, + TX_VENC_NALU_H265_EOB, + TX_VENC_NALU_H265_FILLER, + TX_VENC_NALU_H265_PREFIX_SEI, + TX_VENC_NALU_H265_SUFFIX_SEI +} tx_venc_nalu_h265; + +typedef enum { + TX_VENC_OPT_NONE, + TX_VENC_OPT_QP_TAB_RELATIVE = 0x00001, + TX_VENC_OPT_FIX_PREDICTOR = 0x00002, + TX_VENC_OPT_CUSTOM_LDA = 0x00004, + TX_VENC_OPT_ENABLE_AUTO_QP = 0x00008, + TX_VENC_OPT_ADAPT_AUTO_QP = 0x00010, + TX_VENC_OPT_COMPRESS = 0x00020, + TX_VENC_OPT_FORCE_REC = 0x00040, + TX_VENC_OPT_FORCE_MV_OUT = 0x00080, + TX_VENC_OPT_HIGH_FREQ = 0x02000, + TX_VENC_OPT_SRD = 0x08000, + TX_VENC_OPT_FORCE_MV_CLIP = 0x20000, + TX_VENC_OPT_RDO_COST_MODE = 0x40000, +} tx_venc_opt; + +typedef enum { + TX_VENC_PICFMT_400_8BPP = 0x88, + TX_VENC_PICFMT_420_8BPP = 0x188, + TX_VENC_PICFMT_422_8BPP = 0x288, +} tx_venc_picfmt; + +typedef enum { + TX_VENC_PROF_H264_BASE = (TX_VENC_CODEC_H264 << 24) | 66, + TX_VENC_PROF_H264_MAIN = (TX_VENC_CODEC_H264 << 24) | 77, + TX_VENC_PROF_H264_HIGH = (TX_VENC_CODEC_H264 << 24) | 100, + TX_VENC_PROF_H265_MAIN = (TX_VENC_CODEC_H265 << 24) | 1, + TX_VENC_PROF_MJPG = (TX_VENC_CODEC_MJPG << 24), +} tx_venc_prof; + +typedef enum { + TX_VENC_RATEMODE_QP, + TX_VENC_RATEMODE_CBR, + TX_VENC_RATEMODE_VBR, + TX_VENC_RATEMODE_CVBR, + TX_VENC_RATEMODE_AVBR +} tx_venc_ratemode; + +typedef enum { + TX_VENC_RCOPT_NONE, + TX_VENC_RCOPT_SCN_CHG_RES = 0x01, + TX_VENC_RCOPT_DELAYED = 0x02, + TX_VENC_RCOPT_STATIC_SCENE = 0x04, + TX_VENC_RCOPT_ENABLE_SKIP = 0x08, + TX_VENC_RCOPT_SC_PREVENTION = 0x10, + TX_VENC_RCOPT_END +} tx_venc_rcopt; + +typedef enum { + TX_VENC_SLICE_B, + TX_VENC_SLICE_P, + TX_VENC_SLICE_I, + TX_VENC_SLICE_GLODEN, + TX_VENC_SLICE_SP, + TX_VENC_SLICE_SI, + TX_VENC_SLICE_CONCEAL = 6, + TX_VENC_SLICE_SKIP, + TX_VENC_SLICE_REPEAT, + TX_VENC_SLICE_END +} tx_venc_slice; + +typedef enum { + TX_VENC_TOOL_WPP = 0x001, + TX_VENC_TOOL_TILE = 0x002, + TX_VENC_TOOL_LF = 0x004, + TX_VENC_TOOL_LF_X_SLICE = 0x008, + TX_VENC_TOOL_LF_X_TILE = 0x010, + TX_VENC_TOOL_SCL_LST = 0x020, + TX_VENC_TOOL_CONST_INTRA_PRED = 0x040, + TX_VENC_TOOL_TRANSFO_SKIP = 0x080, + TX_VENC_TOOL_PCM = 0x800, +} tx_venc_tool; + +typedef union { + tx_venc_nalu_h264 h264Nalu; + tx_venc_nalu_h265 h265Nalu; +} tx_venc_nalu; + +typedef struct { + unsigned int offset; + unsigned int length; + long long timestamp; + char endFrame; + tx_venc_nalu naluType; + tx_venc_slice sliceType; +} tx_venc_pack; + +typedef struct { + int size; + unsigned int intra; + unsigned int pSkip; + unsigned int pCu8x8; + unsigned int pCu16x16; + unsigned int pCu32x32; + unsigned int pCu64x64; + short sliceQual; + short minQual; + short maxQual; +} tx_venc_strminfo; + +typedef struct { + int size; + short quality; +} tx_venc_jpeginfo; + +typedef struct { + unsigned int phy; + unsigned int addr; + unsigned int length; + tx_venc_pack *packet; + unsigned int count; + unsigned int sequence; + char isVi; + union { + tx_venc_strminfo strmInfo; + tx_venc_jpeginfo jpegInfo; + }; +} tx_venc_strm; + +typedef struct { + char enable; + unsigned int x, y, width, height; +} tx_venc_crop; + +typedef struct { + tx_venc_prof profile; + unsigned char level; + unsigned char tier; + unsigned short width; + unsigned short height; + tx_venc_picfmt picFmt; + tx_venc_opt options; + tx_venc_tool tools; + tx_venc_crop crop; +} tx_venc_attrib; + +typedef struct { + unsigned int tgtBitrate; + short initQual; + short minQual; + short maxQual; + short ipDelta; + short pbDelta; + tx_venc_rcopt options; + unsigned int maxPicSize; +} tx_venc_rate_cbr; + +typedef struct { + unsigned int tgtBitrate; + unsigned int maxBitrate; + short initQual; + short minQual; + short maxQual; + short ipDelta; + short pbDelta; + tx_venc_rcopt options; + unsigned int maxPicSize; +} tx_venc_rate_vbr; + +typedef struct { + unsigned int tgtBitrate; + unsigned int maxBitrate; + short initQual; + short minQual; + short maxQual; + short ipDelta; + short pbDelta; + tx_venc_rcopt options; + unsigned int maxPicSize; + unsigned short maxPsnr; +} tx_venc_rate_xvbr; + +typedef struct { + tx_venc_ratemode mode; + union { + short qpModeQual; + tx_venc_rate_cbr cbr; + tx_venc_rate_vbr vbr; + tx_venc_rate_xvbr cvbr; + tx_venc_rate_xvbr avbr; + }; + unsigned int fpsDen; + unsigned int fpsNum; +} tx_venc_rate; + +typedef struct { + tx_venc_gopmode mode; + unsigned short length; + unsigned short notifyUserLTInter; + unsigned int maxSameSenceCnt; + char enableLT; + unsigned int freqLT; + char LTRC; +} tx_venc_gop; + +typedef struct { + tx_venc_attrib attrib; + tx_venc_rate rate; + tx_venc_gop gop; +} tx_venc_chn; + +typedef struct { + char isRegistered; + unsigned int leftPics; + unsigned int leftBytes; + unsigned int leftFrames; + unsigned int curPacks; + unsigned int workDone; +} tx_venc_stat; + +typedef struct { + void *handle; + + int (*fnCreateGroup)(int group); + int (*fnDestroyGroup)(int group); + + int (*fnCreateChannel)(int channel, tx_venc_chn *config); + int (*fnDestroyChannel)(int channel); + int (*fnRegisterChannel)(int group, int channel); + int (*fnUnregisterChannel)(int channel); + + int (*fnGetDescriptor)(int channel); + + int (*fnFreeStream)(int channel, tx_venc_strm *stream); + int (*fnGetStream)(int channel, tx_venc_strm *stream, char blockingOn); + + int (*fnQuery)(int channel, tx_venc_stat* stats); + + int (*fnStartReceiving)(int channel); + int (*fnStopReceiving)(int channel); +} tx_venc_impl; + +static int tx_venc_load(tx_venc_impl *venc_lib) { + if (!(venc_lib->handle = dlopen("libimp.so", RTLD_LAZY | RTLD_GLOBAL))) { + fprintf(stderr, "[tx_venc] Failed to load library!\nError: %s\n", dlerror()); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnCreateGroup = (int(*)(int group)) + dlsym(venc_lib->handle, "IMP_Encoder_CreateGroup"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_CreateGroup!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnDestroyGroup = (int(*)(int group)) + dlsym(venc_lib->handle, "IMP_Encoder_DestroyGroup"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_DestroyGroup!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnCreateChannel = (int(*)(int channel, tx_venc_chn *config)) + dlsym(venc_lib->handle, "IMP_Encoder_CreateChn"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_CreateChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnDestroyChannel = (int(*)(int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_DestroyChn"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_DestroyChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnRegisterChannel = (int(*)(int group, int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_RegisterChn"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_RegisterChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnUnregisterChannel = (int(*)(int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_UnRegisterChn"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_UnRegisterChn!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetDescriptor = (int(*)(int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_GetFd"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_GetFd!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnFreeStream = (int(*)(int channel, tx_venc_strm *stream)) + dlsym(venc_lib->handle, "IMP_Encoder_ReleaseStream"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_ReleaseStream!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnGetStream = (int(*)(int channel, tx_venc_strm *stream, char blockingOn)) + dlsym(venc_lib->handle, "IMP_Encoder_GetStream"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_GetStream!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnQuery = (int(*)(int channel, tx_venc_stat *stats)) + dlsym(venc_lib->handle, "IMP_Encoder_Query"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_Query!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnStartReceiving = (int(*)(int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_StartRecvPic"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_StartRecvPic!\n"); + return EXIT_FAILURE; + } + + if (!(venc_lib->fnStopReceiving = (int(*)(int channel)) + dlsym(venc_lib->handle, "IMP_Encoder_StopRecvPic"))) { + fprintf(stderr, "[tx_venc] Failed to acquire symbol IMP_Encoder_StopRecvPic!\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static void tx_venc_unload(tx_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/support.h b/src/hal/support.h index 351be15..a322b1b 100644 --- a/src/hal/support.h +++ b/src/hal/support.h @@ -1,5 +1,6 @@ #include "types.h" #include "hisi/v4_hal.h" +#include "inge/tx_hal.h" #include "sstar/i6_hal.h" #include "sstar/i6c_hal.h" #include "sstar/i6f_hal.h" @@ -19,6 +20,9 @@ extern hal_platform plat; extern void *v4_encoder_thread(void); extern hal_chnstate v4_state[V4_VENC_CHN_NUM]; +//extern void *tx_encoder_thread(void); +//extern hal_chnstate tx_state[TX_VENC_CHN_NUM]; + extern void *i6_encoder_thread(void); extern hal_chnstate i6_state[I6_VENC_CHN_NUM]; diff --git a/src/hal/types.h b/src/hal/types.h index 11480c4..ceff80e 100644 --- a/src/hal/types.h +++ b/src/hal/types.h @@ -23,6 +23,7 @@ typedef enum { HAL_PLATFORM_I6C, HAL_PLATFORM_I6E, HAL_PLATFORM_I6F, + HAL_PLATFORM_TX, HAL_PLATFORM_V4 } hal_platform; diff --git a/src/video.c b/src/video.c index f1f07fc..78f48ee 100644 --- a/src/video.c +++ b/src/video.c @@ -355,7 +355,7 @@ int start_sdk() { pthread_attr_destroy(&thread_attr); } - if (!access(app_config.sensor_config, 0) || !sleep(1)) + if (!access(app_config.sensor_config, 0) ^ sleep(1)) switch (plat) { case HAL_PLATFORM_I6: case HAL_PLATFORM_I6B0: