diff --git a/src/hal/inge/tx_hal.c b/src/hal/inge/tx_hal.c index 1304bc5..7e6d6ec 100644 --- a/src/hal/inge/tx_hal.c +++ b/src/hal/inge/tx_hal.c @@ -16,6 +16,7 @@ char _tx_aud_chn = 0; char _tx_aud_dev = 0; char _tx_fs_chn = 0; char _tx_osd_grp = 0; +char _tx_venc_grp = 0; void tx_hal_deinit(void) { @@ -83,7 +84,7 @@ int tx_audio_init(void) return EXIT_SUCCESS; } -int tx_pipeline_create(short width, short height, char framerate) +int tx_pipeline_create(short width, short height, char framerate, char regionOn) { int ret; @@ -97,10 +98,62 @@ int tx_pipeline_create(short width, short height, char framerate) if (ret = tx_fs.fnCreateChannel(_tx_fs_chn, &channel)) return ret; } + + if (ret = tx_venc.fnCreateGroup(_tx_venc_grp)) + return ret; + + if (regionOn) { + { + tx_sys_bind source = { .device = TX_SYS_DEV_FS, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_OSD, .group = 0, .port = 0 }; + if (ret = tx_sys.fnBind(&source, &dest)) + return ret; + } + + { + tx_sys_bind source = { .device = TX_SYS_DEV_OSD, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_ENC, .group = 0, .port = 0 }; + if (ret = tx_sys.fnBind(&source, &dest)) + return ret; + } + + } else { + tx_sys_bind source = { .device = TX_SYS_DEV_FS, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_ENC, .group = 0, .port = 0 }; + if (ret = tx_sys.fnBind(&source, &dest)) + return ret; + } + + if (ret = tx_fs.fnEnableChannel(_tx_fs_chn)) + return ret; + + return EXIT_SUCCESS; } -void tx_pipeline_destroy() +void tx_pipeline_destroy(char regionOn) { + tx_fs.fnDisableChannel(_tx_fs_chn); + + if (regionOn) { + { + tx_sys_bind source = { .device = TX_SYS_DEV_OSD, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_ENC, .group = 0, .port = 0 }; + tx_sys.fnUnbind(&source, &dest); + } + + { + tx_sys_bind source = { .device = TX_SYS_DEV_FS, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_OSD, .group = 0, .port = 0 }; + tx_sys.fnUnbind(&source, &dest); + } + } else { + tx_sys_bind source = { .device = TX_SYS_DEV_FS, .group = 0, .port = 0 }; + tx_sys_bind dest = { .device = TX_SYS_DEV_ENC, .group = 0, .port = 0 }; + tx_sys.fnUnbind(&source, &dest); + } + + tx_venc.fnDestroyGroup(_tx_venc_grp); + tx_fs.fnDestroyChannel(_tx_fs_chn); } @@ -167,6 +220,99 @@ int tx_region_setbitmap(int *handle, hal_bitmap *bitmap) return tx_osd.fnSetRegionConfig(*handle, ®ion); } +int tx_video_create(char index, hal_vidconfig *config) +{ + int ret; + tx_venc_chn channel; + memset(&channel, 0, sizeof(channel)); + channel.gop.mode = TX_VENC_GOPMODE_NORMAL; + channel.gop.length = config->gop / config->framerate; + channel.rate.fpsDen = config->framerate; + channel.rate.fpsNum = 1; + switch (config->codec) { + case HAL_VIDCODEC_JPG: + channel.attrib.profile = TX_VENC_PROF_MJPG; + break; + case HAL_VIDCODEC_MJPG: + channel.attrib.profile = TX_VENC_PROF_MJPG; + break; + case HAL_VIDCODEC_H265: + channel.attrib.profile = TX_VENC_PROF_H265_MAIN; + break; + case HAL_VIDCODEC_H264: + switch (config->profile) { + case HAL_VIDPROFILE_BASELINE: channel.attrib.profile = TX_VENC_PROF_H264_BASE; break; + case HAL_VIDPROFILE_MAIN: channel.attrib.profile = TX_VENC_PROF_H264_MAIN; break; + default: channel.attrib.profile = TX_VENC_PROF_H264_HIGH; break; + } + break; + default: TX_ERROR("This codec is not supported by the hardware!"); + + } + switch (config->mode) { + case HAL_VIDMODE_CBR: + channel.rate.mode = TX_VENC_RATEMODE_CBR; + channel.rate.cbr = (tx_venc_rate_cbr){ .tgtBitrate = config->bitrate }; break; + case HAL_VIDMODE_VBR: + channel.rate.mode = TX_VENC_RATEMODE_VBR; + channel.rate.vbr = (tx_venc_rate_vbr){ .maxBitrate = MAX(config->bitrate, + config->maxBitrate) }; break; + case HAL_VIDMODE_QP: + channel.rate.mode = TX_VENC_RATEMODE_QP; + channel.rate.qpModeQual = config->maxQual; break; + case HAL_VIDMODE_AVBR: + channel.rate.mode = TX_VENC_RATEMODE_AVBR; + channel.rate.avbr = (tx_venc_rate_xvbr){ .maxBitrate = config->bitrate }; break; + default: + TX_ERROR("Video encoder does not support this mode!"); + } + channel.attrib.width = config->width; + channel.attrib.height = config->height; + channel.attrib.picFmt = (config->codec == HAL_VIDCODEC_JPG || config->codec == HAL_VIDCODEC_MJPG) ? + TX_VENC_PICFMT_422_8BPP : TX_VENC_PICFMT_420_8BPP; + + if (ret = tx_venc.fnCreateChannel(index, &channel)) + return ret; + + { + int count = -1; + if (config->codec != HAL_VIDCODEC_JPG && + (ret = tx_venc.fnStartReceiving(index))) + return ret; + } + + tx_state[index].payload = config->codec; + + return EXIT_SUCCESS; +} + +int tx_video_destroy(char index) +{ + int ret; + + tx_state[index].payload = HAL_VIDCODEC_UNSPEC; + + if (ret = tx_venc.fnStopReceiving(index)) + return ret; + + if (ret = tx_venc.fnDestroyChannel(index)) + return ret; + + return EXIT_SUCCESS; +} + +int tx_video_destroy_all(void) +{ + int ret; + + for (char i = 0; i < TX_VENC_CHN_NUM; i++) + if (tx_state[i].enable) + if (ret = tx_video_destroy(i)) + return ret; + + return EXIT_SUCCESS; +} + void *tx_video_thread(void) { diff --git a/src/hal/inge/tx_hal.h b/src/hal/inge/tx_hal.h index bfa5b7e..b4433f8 100644 --- a/src/hal/inge/tx_hal.h +++ b/src/hal/inge/tx_hal.h @@ -21,13 +21,17 @@ int tx_hal_init(void); void tx_audio_deinit(void); int tx_audio_init(void); -int tx_pipeline_create(short width, short height, char framerate); -void tx_pipeline_destroy(void); +int tx_pipeline_create(short width, short height, char framerate, + char regionOn); +void tx_pipeline_destroy(char regionOn); int tx_region_create(int *handle, char group, hal_rect rect); void tx_region_destroy(int *handle, char group); int tx_region_setbitmap(int *handle, hal_bitmap *bitmap); +int tx_video_create(char index, hal_vidconfig *config); +int tx_video_destroy(char index); +int tx_video_destroy_all(void); void *tx_video_thread(void); void tx_system_deinit(void); diff --git a/src/hal/support.c b/src/hal/support.c index e81306d..6d29440 100644 --- a/src/hal/support.c +++ b/src/hal/support.c @@ -89,20 +89,20 @@ void hal_identify(void) { return; } else if (!access("/proc/jz", 0) && - hal_registry(0x1300002C, &val, OP_READ)) - switch ((val >> 12) & 0xFF) { - case 0x21: - case 0x31: + hal_registry(0x1300002C, &val, OP_READ)) { + char gen = (val >> 12) & 0xFF; + switch (gen) { + case 0x21: + case 0x30: case 0x31: + case 0x40: case 0x41: plat = HAL_PLATFORM_TX; - strcpy(series, - ((val >> 12) & 0xFF) == 0x21 ? "T21" : - ((val >> 12) & 0xFF) == 0x31 ? "T31" : - "unknown"); + sprintf(series, "T%X", gen); chnCount = TX_VENC_CHN_NUM; chnState = (hal_chnstate*)tx_state; venc_thread = tx_video_thread; return; } + } if (file = fopen("/proc/iomem", "r")) while (fgets(line, 200, file)) diff --git a/src/video.c b/src/video.c index e176771..3f424c1 100644 --- a/src/video.c +++ b/src/video.c @@ -192,7 +192,7 @@ int start_sdk() { case HAL_PLATFORM_I6F: ret = i6f_pipeline_create(0, width, height, framerate); break; case HAL_PLATFORM_TX: ret = tx_pipeline_create(width, - height, framerate); break; + height, framerate, app_config.osd_enable); break; case HAL_PLATFORM_V4: ret = v4_pipeline_create(); break; } if (ret) { @@ -248,6 +248,7 @@ int start_sdk() { case HAL_PLATFORM_I6: ret = i6_video_create(index, &config); break; case HAL_PLATFORM_I6C: ret = i6c_video_create(index, &config); break; case HAL_PLATFORM_I6F: ret = i6f_video_create(index, &config); break; + case HAL_PLATFORM_TX: ret = tx_video_create(index, &config); break; case HAL_PLATFORM_V4: ret = v4_video_create(index, &config); break; } @@ -291,6 +292,7 @@ int start_sdk() { case HAL_PLATFORM_I6: ret = i6_video_create(index, &config); break; case HAL_PLATFORM_I6C: ret = i6c_video_create(index, &config); break; case HAL_PLATFORM_I6F: ret = i6f_video_create(index, &config); break; + case HAL_PLATFORM_TX: ret = tx_video_create(index, &config); break; case HAL_PLATFORM_V4: ret = v4_video_create(index, &config); break; } @@ -360,6 +362,7 @@ int stop_sdk() { case HAL_PLATFORM_I6: i6_video_destroy_all(); break; case HAL_PLATFORM_I6C: i6c_video_destroy_all(); break; case HAL_PLATFORM_I6F: i6f_video_destroy_all(); break; + case HAL_PLATFORM_TX: tx_video_destroy_all(); break; case HAL_PLATFORM_V4: v4_video_destroy_all(); break; } @@ -367,7 +370,7 @@ int stop_sdk() { case HAL_PLATFORM_I6: i6_pipeline_destroy(); break; case HAL_PLATFORM_I6C: i6c_pipeline_destroy(); break; case HAL_PLATFORM_I6F: i6f_pipeline_destroy(); break; - case HAL_PLATFORM_TX: tx_pipeline_destroy(); break; + case HAL_PLATFORM_TX: tx_pipeline_destroy(app_config.osd_enable); break; case HAL_PLATFORM_V4: v4_pipeline_destroy(); break; }