diff --git a/vendor/.gitkeep b/vendor/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/Makefile b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/Makefile
new file mode 100755
index 0000000000000000000000000000000000000000..5c0d0b328341f5ab30d765ceaea25a4d8476f267
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/Makefile
@@ -0,0 +1,44 @@
+# 编译所需的公共文件
+include ../mk.param
+
+# 编译后生成的可执行文件名
+TARGET := main
+
+# 编译此工程需要包含的头文件
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/
+CFLAGS += -I$(SDK_SAMPLE_COMMON_DIR)/
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/svp_npu
+
+# 编译此工程需要依赖的.c或.cpp文件
+SMP_SRCS := $(SDK_SAMPLE_COMMON_DIR)/sample_comm_sys.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_ipc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_isp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vi.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vo.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_mipi_tx.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vpss.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/loadbmp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vdec.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_venc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_init.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_exit.c
+SMP_SRCS += $(wildcard $(SVP_COMMON_DIR)/*.c)
+SMP_SRCS += $(FACE_DETECTION_SAMPLE_DIR)/face_detection.c
+
+# 编译此工程需要包含的库和宏
+CFLAGS += -O3 -g -Wall -DUSE_USB_CAMERA
+CFLAGS += -fstack-protector-strong
+
+# 根据实际的类型设置,可以用set_sensor脚本设置
+SENSOR0_TYPE = -DSENSOR0_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR1_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR2_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR3_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+
+CFLAGS += $(SENSOR0_TYPE)
+CFLAGS += $(SENSOR1_TYPE)
+CFLAGS += $(SENSOR2_TYPE)
+CFLAGS += $(SENSOR3_TYPE)
+# 编译工程所需的mk文件
+
+include ../sdk_linux.mk
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/README.md b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..b9c21e3af9f691dce28e010a8e0a26fc3754ae87
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/README.md
@@ -0,0 +1,128 @@
+## 2.5、face_detection 操作指导
+
+### 2.5.1、face_detection 程序简介
+
+* face_detection sample基于SS928V100平台开发,以EulerPi套件为例,face_detection sample是通过USB Camera,将采集到的图片送到人脸检测模型中进行推理,当检测到人脸时,会在人脸区域画出矩形框,并通过外接HDMI线实时的显示在外接显示屏上。
+* face_detection 案例主要是使用pytorch框架,基于YoloV8网络,使用widerface、FDDB、UFDD等开源数据集,共1.3万多张训练出来在强光、逆光、暗光下的人脸检测模型。
+
+
+
+### 2.5.2、目录
+
+```shell
+pegasus/vendor/cust/demo/face_detection
+|── data # 模型文件
+|── Makefile # 编译脚本
+└── face_detection.c # face_detection sample业务代码
+```
+
+
+
+### 2.5.3、编译
+
+* **注意:在编译cust的demo之前,请确保你已经按照[patch介绍中的步骤](../../README.md#4patch介绍)把补丁打入海思SDK的sample目录下了**。
+
+* 步骤1:先根据自己选择的操作系统,进入到对应的Pegasus所在目录下。
+
+* 步骤2:使用Makefile的方式进行单编
+
+* 在Ubuntu的命令行终端,分步执行下面的命令,单编 face_detection sample
+
+ ```
+ cd pegasus/vendor/cust/demo/face_detection
+
+ make clean && make
+ ```
+
+ 
+
+ * 在face_detection目录下,生成一个名为 face_detection 的 可执行文件,如下图所示:
+
+ 
+
+### 2.5.4、拷贝可执行程序和依赖文件至开发板的mnt目录下
+
+**方式一:使用SD卡进行资料文件的拷贝**
+
+* 首先需要自己准备一张Micro sd卡(16G 左右即可),还得有一个Micro sd卡的读卡器。
+
+
+
+* 步骤1:将编译后生成的可执行文件拷贝到SD卡中。
+
+
+
+* 步骤2:可执行文件拷贝成功后,将内存卡插入开发板的SD卡槽中,可通过挂载的方式挂载到板端,可选择SD卡 mount指令进行挂载。
+
+
+
+* 在开发板的终端,执行下面的命令进行SD卡的挂载
+ * 如果挂载失败,可以参考[这个issue尝试解决](https://gitee.com/HiSpark/HiSpark_NICU2022/issues/I54932?from=project-issue)
+
+
+```shell
+mount -t vfat /dev/mmcblk1p1 /mnt
+# 其中/dev/mmcblk1p1需要根据实际块设备号修改
+```
+
+* 挂载成功后,如下图所示:
+
+
+
+**方式二:使用NFS挂载的方式进行资料文件的拷贝**
+
+* 首先需要自己准备一根网线
+* 步骤1:参考[博客链接](https://blog.csdn.net/Wu_GuiMing/article/details/115872995?spm=1001.2014.3001.5501)中的内容,进行nfs的环境搭建
+* 步骤2:将编译后生成的可执行文件拷贝到Windows的nfs共享路径下
+
+
+
+* 步骤3:在开发板的终端执行下面的命令,将Windows的nfs共享路径挂载至开发板的mnt目录下
+ * 注意:这里IP地址请根据你开发板和电脑主机的实际IP地址进行填写
+
+
+```
+ifconfig eth0 192.168.100.100
+mount -o nolock,addr=192.168.100.10 -t nfs 192.168.100.10:/d/nfs /mnt
+```
+
+
+
+### 2.5.5、硬件连接
+
+* 准备一个外接显示器和HDMI数据线,将HDMI的一头接在开发板的HDMI输出口,将HDMI的另外一头接在外接显示器的HDMI输入口。
+
+
+
+* 将USB 摄像头接在EulerPi开发板的USB接口上。
+
+
+
+### 2.5.6、功能验证
+
+* 在开发板的终端执行下面的命令,运行可执行文件
+
+```
+cd /mnt
+
+chmod +x face_detection
+
+./face_detection
+```
+
+
+
+* 此时,在HDMI的外接显示屏上即可出现实时码流,如下图所示:
+
+
+
+* 如果您看到的现象和下图现象不一致,可以确认一下USB涉嫌头是否插入到开发板的USB口,并且在开发板的/dev目录下能够看到video0 和 video1两个设备节点。如果没有这两个设备节点,请确保镜像烧录正常。
+
+
+
+* 正常情况下,我们会在外接显示屏上看到人脸的区域被框出来,且在比较黑暗或者强逆光条件下,也能比较好的检测到人脸。
+
+* 敲两下回车即可关闭程序
+
+
+
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/data/model/face_detection.om b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/data/model/face_detection.om
new file mode 100755
index 0000000000000000000000000000000000000000..4765828d501e8d424ae023e6cedff0bb4cf24a5e
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/data/model/face_detection.om differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/face_detection.c b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/face_detection.c
new file mode 100755
index 0000000000000000000000000000000000000000..44779cbca233b4d0c63fb2f5551a0de4c535458e
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/face_detection.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "securec.h"
+#include "svp_acl.h"
+#include "svp_acl_rt.h"
+#include "svp_acl_ext.h"
+#include "sdk_module_init.h"
+#include "sample_common_svp.h"
+#include "sample_common_svp_npu.h"
+#include "sample_common_svp_npu_model.h"
+
+/* 新增v4l2相关头文件 */
+#include // 文件控制
+#include // 错误处理
+#include // POSIX API
+#include // IO控制
+#include // 内存映射
+#include // select复用
+#include // v4l2核心
+
+#define SAMPLE_SVP_NPU_RESNET50_INPUT_FILE_NUM 1
+#define SAMPLE_SVP_NPU_LSTM_INPUT_FILE_NUM 4
+#define SAMPLE_SVP_NPU_SHAERD_WORK_BUF_NUM 1
+#define SAMPLE_SVP_NPU_YOLO_TYPE_NUM 12
+#define SAMPLE_SVP_NPU_YOLO_THRESHOLD_NUM 1
+
+#define SAMPLE_SVP_NPU_PATH_LEN 0x100
+static td_bool g_svp_npu_terminate_signal = TD_FALSE;
+static td_s32 g_svp_npu_dev_id = 0;
+static sample_svp_npu_task_info g_svp_npu_task[SAMPLE_SVP_NPU_MAX_TASK_NUM] = {0};
+static sample_svp_npu_shared_work_buf g_svp_npu_shared_work_buf[SAMPLE_SVP_NPU_SHAERD_WORK_BUF_NUM] = {0};
+
+static sample_svp_npu_threshold g_svp_npu_yolo_threshold[SAMPLE_SVP_NPU_YOLO_TYPE_NUM] = {
+ {0.9, 0.15, 1.0, 1.0, "rpn_data"}, // yolov8
+};
+
+static sample_svp_npu_roi_info g_svp_npu_yolo_roi_info[SAMPLE_SVP_NPU_YOLO_TYPE_NUM] = {
+ {"output0", "output0_"}, // yolov8
+};
+
+static ot_sample_svp_rect_info g_svp_npu_rect_info = {0};
+static td_bool g_svp_npu_thread_stop = TD_FALSE;
+static pthread_t g_svp_npu_thread = 0;
+static sample_vo_cfg g_svp_npu_vo_cfg = { 0 };
+static pthread_t g_svp_npu_vdec_thread = 0;
+static ot_vb_pool_info g_svp_npu_vb_pool_info;
+static td_void *g_svp_npu_vb_virt_addr = TD_NULL;
+
+static ot_sample_svp_media_cfg g_svp_npu_media_cfg = {
+ .svp_switch = {TD_FALSE, TD_TRUE},
+ .pic_type = {PIC_1080P, PIC_CIF},
+ .chn_num = OT_SVP_MAX_VPSS_CHN_NUM,
+};
+
+static sample_vdec_attr g_svp_npu_vdec_cfg = {
+ .type = OT_PT_MJPEG,
+ .mode = OT_VDEC_SEND_MODE_FRAME,
+ .width = FHD_WIDTH,
+ .height = FHD_HEIGHT,
+ .sample_vdec_picture.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420, /* 420:pixel_format */
+ .sample_vdec_picture.alpha = 0, /* 0:alpha */
+ .display_frame_num = 2, /* 2:display_frame_num */
+ .frame_buf_cnt = 5, /* 5:2+2+1 */
+};
+
+static vdec_thread_param g_svp_npu_vdec_param = {
+ .chn_id = 0,
+
+ .v4l2_device = "/dev/video0", // 摄像头设备
+ .width = FHD_WIDTH, // 采集分辨率宽
+ .height = FHD_HEIGHT, // 采集分辨率高
+ .pixel_format = V4L2_PIX_FMT_MJPEG, // MJPEG格式
+
+ .type = OT_PT_MJPEG,
+ .stream_mode = OT_VDEC_SEND_MODE_FRAME,
+ .interval_time = 1000, /* 1000:interval_time */
+ .pts_init = 0,
+ .pts_increase = 0,
+ .e_thread_ctrl = THREAD_CTRL_START,
+ .circle_send = TD_TRUE,
+ .milli_sec = 0,
+ .min_buf_size = (FHD_WIDTH * FHD_HEIGHT * 3) >> 1, /* 3:chn_size */
+ .fps = 30,
+};
+
+static td_void sample_svp_npu_acl_terminate(td_void)
+{
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
+ }
+}
+
+/* function : svp npu signal handle */
+td_void sample_svp_npu_acl_handle_sig(td_void)
+{
+ g_svp_npu_terminate_signal = TD_TRUE;
+}
+
+static td_void sample_svp_npu_acl_deinit(td_void)
+{
+ svp_acl_error ret;
+
+ ret = svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("reset device fail\n");
+ }
+ sample_svp_trace_info("end to reset device is %d\n", g_svp_npu_dev_id);
+
+ ret = svp_acl_finalize();
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("finalize acl fail\n");
+ }
+ sample_svp_trace_info("end to finalize acl\n");
+ (td_void)sample_common_svp_check_sys_exit();
+}
+
+static td_s32 sample_svp_npu_acl_init(const td_char *acl_config_path, td_bool vi_en)
+{
+ /* svp acl init */
+ svp_acl_rt_run_mode run_mode;
+ svp_acl_error ret;
+ td_bool is_mpi_init;
+
+ is_mpi_init = sample_common_svp_check_sys_init(vi_en);
+ sample_svp_check_exps_return(is_mpi_init != TD_TRUE, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "mpi init failed!\n");
+
+ ret = svp_acl_init(acl_config_path);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "acl init failed!\n");
+
+ sample_svp_trace_info("svp acl init success!\n");
+
+ /* open device */
+ ret = svp_acl_rt_set_device(g_svp_npu_dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ (td_void)svp_acl_finalize();
+ sample_svp_trace_err("svp acl open device %d failed!\n", g_svp_npu_dev_id);
+ return TD_FAILURE;
+ }
+ sample_svp_trace_info("open device %d success!\n", g_svp_npu_dev_id);
+
+ /* get run mode */
+ ret = svp_acl_rt_get_run_mode(&run_mode);
+ if ((ret != SVP_ACL_SUCCESS) || (run_mode != SVP_ACL_DEVICE)) {
+ (td_void)svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ (td_void)svp_acl_finalize();
+ sample_svp_trace_err("acl get run mode failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_trace_info("get run mode success!\n");
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_acl_dataset_init(td_u32 task_idx)
+{
+ td_s32 ret = sample_common_svp_npu_create_input(&g_svp_npu_task[task_idx]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "create input failed!\n");
+
+ ret = sample_common_svp_npu_create_output(&g_svp_npu_task[task_idx]);
+ if (ret != TD_SUCCESS) {
+ sample_common_svp_npu_destroy_input(&g_svp_npu_task[task_idx]);
+ sample_svp_trace_err("execute create output fail.\n");
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS;
+}
+
+static td_void sample_svp_npu_acl_dataset_deinit(td_u32 task_idx)
+{
+ (td_void)sample_common_svp_npu_destroy_input(&g_svp_npu_task[task_idx]);
+ (td_void)sample_common_svp_npu_destroy_output(&g_svp_npu_task[task_idx]);
+}
+
+static td_void sample_svp_npu_acl_deinit_task(td_u32 task_num, td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ (td_void)sample_common_svp_npu_destroy_work_buf(&g_svp_npu_task[task_idx]);
+ (td_void)sample_common_svp_npu_destroy_task_buf(&g_svp_npu_task[task_idx]);
+ (td_void)sample_svp_npu_acl_dataset_deinit(task_idx);
+ (td_void)memset_s(&g_svp_npu_task[task_idx], sizeof(sample_svp_npu_task_cfg), 0,
+ sizeof(sample_svp_npu_task_cfg));
+ }
+ if (g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr != TD_NULL) {
+ (td_void)svp_acl_rt_free(g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr);
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr = TD_NULL;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size = 0;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_stride = 0;
+ }
+}
+
+static td_s32 sample_svp_npu_acl_create_shared_work_buf(td_u32 task_num, td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+ td_u32 work_buf_size;
+ td_u32 work_buf_stride;
+ td_s32 ret;
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ ret = sample_common_svp_npu_get_work_buf_info(&g_svp_npu_task[task_idx], &work_buf_size, &work_buf_stride);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th task work buf info failed!\n", task_idx);
+
+ if (g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size < work_buf_size) {
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size = work_buf_size;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_stride = work_buf_stride;
+ }
+ }
+ ret = svp_acl_rt_malloc_cached(&g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr,
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "malloc %u-th shared work buf failed!\n", shared_work_buf_idx);
+
+ (td_void)svp_acl_rt_mem_flush(g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr,
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size);
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_acl_init_task(td_u32 task_num, td_bool is_share_work_buf,
+ td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+ td_s32 ret;
+
+ if (is_share_work_buf == TD_TRUE) {
+ ret = sample_svp_npu_acl_create_shared_work_buf(task_num, shared_work_buf_idx);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create shared work buf failed!\n");
+ }
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ ret = sample_svp_npu_acl_dataset_init(task_idx);
+ if (ret != TD_SUCCESS) {
+ goto task_init_end_0;
+ }
+ ret = sample_common_svp_npu_create_task_buf(&g_svp_npu_task[task_idx]);
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("create task buf failed.\n");
+ goto task_init_end_0;
+ }
+ if (is_share_work_buf == TD_FALSE) {
+ ret = sample_common_svp_npu_create_work_buf(&g_svp_npu_task[task_idx]);
+ } else {
+ /* if all tasks are on the same stream, work buf can be shared */
+ ret = sample_common_svp_npu_share_work_buf(&g_svp_npu_shared_work_buf[shared_work_buf_idx],
+ &g_svp_npu_task[task_idx]);
+ }
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("create work buf failed.\n");
+ goto task_init_end_0;
+ }
+ }
+ return TD_SUCCESS;
+
+task_init_end_0:
+ (td_void)sample_svp_npu_acl_deinit_task(task_num, shared_work_buf_idx);
+ return ret;
+}
+
+static td_s32 sample_svp_npu_acl_frame_proc(const ot_video_frame_info *ext_frame,
+ const ot_video_frame_info *base_frame, td_void *args)
+{
+ td_s32 ret;
+ td_void *virt_addr = TD_NULL;
+ sample_svp_npu_detection_info *detection_info = TD_NULL;
+ sample_svp_npu_thread_args *thread_args = (sample_svp_npu_thread_args *)args;
+ td_u32 size = (td_u32)(ext_frame->video_frame.height * ext_frame->video_frame.stride[0] *
+ SAMPLE_SVP_NPU_IMG_THREE_CHN / SAMPLE_SVP_NPU_DOUBLE);
+
+ virt_addr = g_svp_npu_vb_virt_addr +
+ (ext_frame->video_frame.phys_addr[0] - g_svp_npu_vb_pool_info.pool_phy_addr);
+ ret = sample_common_svp_npu_update_input_data_buffer_info(virt_addr, size,
+ ext_frame->video_frame.stride[0], 0, &g_svp_npu_task[0]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "update data buffer failed!\n");
+
+ ret = sample_common_svp_npu_model_execute(&g_svp_npu_task[0]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "model execute failed!\n");
+
+ if (thread_args->model_name == SAMPLE_SVP_NPU_RFCN || thread_args->model_name == SAMPLE_SVP_NPU_YOLO) {
+ detection_info = thread_args->detection_info;
+ if (detection_info->is_cpu_rpn == TD_FALSE) {
+ ret = sample_common_svp_npu_roi_to_rect(&g_svp_npu_task[0], detection_info, ext_frame, base_frame,
+ &g_svp_npu_rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "roi to rect failed!\n");
+ } else {
+ ret = sample_common_svp_npu_roi_to_rect_cpu(&g_svp_npu_task[0], detection_info, ext_frame, base_frame,
+ &g_svp_npu_rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "roi to rect failed!\n");
+ }
+ ret = sample_common_svp_vgs_fill_rect(base_frame, &g_svp_npu_rect_info, SAMPLE_SVP_NPU_RECT_COLOR);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vgs fill rect failed!\n");
+ for (int i = 0; i < g_svp_npu_rect_info.num; i++) {
+ printf("score:%lf, class_id:%d\r\n", g_svp_npu_rect_info.rect[i].score,
+ g_svp_npu_rect_info.rect[i].class_id);
+ }
+ }
+ return ret;
+}
+
+static td_s32 sample_svp_npu_acl_vb_map(td_u32 vb_pool_idx)
+{
+ td_s32 ret;
+
+ if (g_svp_npu_vb_virt_addr == TD_NULL) {
+ ret = ss_mpi_vb_get_pool_info(g_svp_npu_media_cfg.vb_pool[vb_pool_idx], &g_svp_npu_vb_pool_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get pool info failed!\n");
+ g_svp_npu_vb_virt_addr = ss_mpi_sys_mmap(g_svp_npu_vb_pool_info.pool_phy_addr,
+ g_svp_npu_vb_pool_info.pool_size);
+ sample_svp_check_exps_return(g_svp_npu_vb_virt_addr == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "map vb pool failed!\n");
+ }
+ return TD_SUCCESS;
+}
+
+static td_void *sample_svp_npu_acl_vdec_to_vo(td_void *args)
+{
+ td_s32 ret;
+ ot_video_frame_info base_frame;
+ ot_video_frame_info ext_frame;
+ const td_s32 milli_sec = SAMPLE_SVP_NPU_MILLIC_SEC;
+ const ot_vo_layer vo_layer = 0;
+ const ot_vo_chn vo_chn = 0;
+ const td_s32 vpss_grp = 0;
+ td_s32 vpss_chn[] = { OT_VPSS_CHN0, OT_VPSS_CHN1 };
+ td_u32 size;
+ td_u32 stride;
+ td_u8 *data = TD_NULL;
+
+ (td_void)prctl(PR_SET_NAME, "svp_npu_vdec_to_vo", 0, 0, 0);
+
+ ret = svp_acl_rt_set_device(g_svp_npu_dev_id);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "open device failed!\n");
+
+ ret = sample_svp_npu_acl_vb_map(OT_VPSS_CHN1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "map vb pool failed!\n");
+
+ ret = sample_common_svp_npu_get_input_data_buffer_info(&g_svp_npu_task[0], 0, &data, &size, &stride);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),get_input_data_buffer_info failed!\n", ret);
+
+ while (g_svp_npu_thread_stop == TD_FALSE) {
+ ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[1], &ext_frame, milli_sec);
+ sample_svp_check_exps_continue(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_vpss_get_chn_frame failed, vpss_grp(%d), vpss_chn(%d)!\n", ret, vpss_grp, vpss_chn[1]);
+
+ ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[0], &base_frame, milli_sec);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, ext_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_vpss_get_chn_frame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", ret, vpss_grp, vpss_chn[0]);
+
+ ret = sample_svp_npu_acl_frame_proc(&ext_frame, &base_frame, args);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, base_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_svp_npu_acl_frame_proc failed!\n", ret);
+
+ ret = sample_common_svp_venc_vo_send_stream(&g_svp_npu_media_cfg.svp_switch, 0, vo_layer, vo_chn, &base_frame);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, base_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_venc_vo_send_stream failed!\n", ret);
+base_release:
+ ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[0], &base_frame);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[0]);
+ext_release:
+ ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[1], &ext_frame);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[1]);
+ }
+ ret = sample_common_svp_npu_update_input_data_buffer_info(data, size, stride, 0, &g_svp_npu_task[0]);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "update buffer failed!\n");
+fail_1:
+ (td_void)ss_mpi_sys_munmap(g_svp_npu_vb_virt_addr, g_svp_npu_vb_pool_info.pool_size);
+fail_0:
+ (td_void)svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ return TD_NULL;
+}
+
+static td_void sample_svp_npu_acl_pause(td_void)
+{
+ printf("---------------press Enter key to exit!---------------\n");
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ return;
+ }
+ (td_void)getchar();
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ return;
+ }
+}
+
+static td_void sample_svp_npu_acl_set_task_info(td_u32 model_idx)
+{
+ g_svp_npu_task[0].cfg.max_batch_num = 1;
+ g_svp_npu_task[0].cfg.dynamic_batch_num = 1;
+ g_svp_npu_task[0].cfg.total_t = 0;
+ g_svp_npu_task[0].cfg.is_cached = TD_TRUE;
+ g_svp_npu_task[0].cfg.model_idx = model_idx;
+}
+
+static td_void sample_svp_npu_acl_set_detection_info(sample_svp_npu_detection_info *detection_info, td_u32 index,
+ td_bool is_cpu_rpn)
+{
+ detection_info->num_name = g_svp_npu_yolo_roi_info[index].roi_num_name;
+ detection_info->roi_name = g_svp_npu_yolo_roi_info[index].roi_class_name;
+ detection_info->has_background = TD_FALSE;
+ detection_info->is_cpu_rpn = is_cpu_rpn;
+ detection_info->idx = index;
+ /* use PIC_BUTT to be a flag, get the input resolution form om */
+ g_svp_npu_media_cfg.pic_type[1] = PIC_BUTT;
+ g_svp_npu_terminate_signal = TD_FALSE;
+}
+
+/* function : show the sample of yolo. RPN processed by npu */
+td_void sample_face_detection(void)
+{
+ td_s32 ret;
+ const td_u32 model_idx = 0;
+ const td_char *om_model_path = "./data/model/face_detection.om";
+ sample_svp_npu_detection_info detection_info = {0};
+ sample_svp_npu_thread_args args = {SAMPLE_SVP_NPU_YOLO, &detection_info};
+
+ sample_svp_npu_acl_set_detection_info(&detection_info, 0, TD_FALSE);
+
+ if (g_svp_npu_terminate_signal == TD_FALSE) {
+ /* init acl */
+ ret = sample_svp_npu_acl_init(TD_NULL, TD_FALSE);
+ sample_svp_check_exps_return_void(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "init failed!\n");
+
+ /* load model */
+ ret = sample_common_svp_npu_load_model(om_model_path, model_idx, TD_FALSE);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "load model failed!\n");
+
+ /* get input resolution */
+ ret = sample_common_svp_npu_get_input_resolution(model_idx, 0, &g_svp_npu_media_cfg.pic_size[1]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "load model failed!\n");
+
+ /* start vdec vpss venc vo */
+ ret = sample_common_svp_create_vb_start_vdec_vpss_vo(&g_svp_npu_vdec_cfg, &g_svp_npu_vdec_param,
+ &g_svp_npu_vdec_thread, &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end1, SAMPLE_SVP_ERR_LEVEL_DEBUG,
+ "init media failed!\n");
+
+ /* set cfg */
+ sample_svp_npu_acl_set_task_info(model_idx);
+
+ ret = sample_svp_npu_acl_init_task(1, TD_FALSE, 0);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end2, SAMPLE_SVP_ERR_LEVEL_ERROR, "init task failed!\n");
+ }
+ /* process */
+ if (g_svp_npu_terminate_signal == TD_FALSE) {
+ ret = sample_common_svp_npu_set_threshold(&g_svp_npu_yolo_threshold[0], SAMPLE_SVP_NPU_YOLO_THRESHOLD_NUM,
+ &g_svp_npu_task[0]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end3, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "set threshold failed!\n");
+
+ g_svp_npu_thread_stop = TD_FALSE;
+ ret = pthread_create(&g_svp_npu_thread, 0, sample_svp_npu_acl_vdec_to_vo, (td_void*)&args);
+
+ sample_svp_check_exps_goto(ret != 0, process_end3, SAMPLE_SVP_ERR_LEVEL_ERROR, "create thread failed!\n");
+
+ (td_void)sample_svp_npu_acl_pause();
+
+ g_svp_npu_thread_stop = TD_TRUE;
+ pthread_join(g_svp_npu_thread, TD_NULL);
+ }
+
+process_end3:
+ (td_void)sample_svp_npu_acl_deinit_task(1, 0);
+process_end2:
+ (td_void)sample_common_svp_destroy_vb_stop_vdec_vpss_vo(&g_svp_npu_vdec_param, &g_svp_npu_vdec_thread,
+ &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+process_end1:
+ (td_void)sample_common_svp_npu_unload_model(model_idx);
+process_end0:
+ (td_void)sample_svp_npu_acl_deinit();
+ (td_void)sample_svp_npu_acl_terminate();
+}
+
+int main(void)
+{
+#ifdef CONFIG_USER_SPACE
+ SDK_init();
+#endif
+
+ sample_face_detection();
+
+#ifdef CONFIG_USER_SPACE
+ SDK_exit();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20221114150205685.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20221114150205685.png
new file mode 100755
index 0000000000000000000000000000000000000000..4dc4215c962c57ba0e31548fb98c29c789f149d9
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20221114150205685.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210161601541.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210161601541.png
new file mode 100755
index 0000000000000000000000000000000000000000..80845ece8131933a4cd56ae3bd6119c38e0abd26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210161601541.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210170027454.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210170027454.png
new file mode 100755
index 0000000000000000000000000000000000000000..c06081fc2c963af4d1fa8af506804beedefe1b0b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250210170027454.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250213112932380.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250213112932380.png
new file mode 100755
index 0000000000000000000000000000000000000000..8b591b3437544859f4ec76b9ca03867cc401078c
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250213112932380.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919144926220.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919144926220.png
new file mode 100755
index 0000000000000000000000000000000000000000..ce52c2e8b435b703f1dcec3eccaa917d4dcd189a
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919144926220.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145314492.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145314492.png
new file mode 100755
index 0000000000000000000000000000000000000000..b6380f00ccd5350fffdf2c135185c3d3b4774648
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145314492.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145335685.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145335685.png
new file mode 100755
index 0000000000000000000000000000000000000000..3ff54534be7a6d7c18317982e37b206d5eff09d6
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145335685.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145846452.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145846452.png
new file mode 100755
index 0000000000000000000000000000000000000000..951425ca5364e2d246378265ecb864da4df46725
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919145846452.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150059493.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150059493.png
new file mode 100755
index 0000000000000000000000000000000000000000..3dd1d411dbd27dd4ae2b212af6e20fbb5ca9bada
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150059493.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150131086.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150131086.png
new file mode 100755
index 0000000000000000000000000000000000000000..a2b0ce4802b9c9531b59f8a0599e607594aae646
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150131086.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150233049.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150233049.png
new file mode 100755
index 0000000000000000000000000000000000000000..e6ee8810f1894fefb4db96404f952bf8f9bc85a6
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150233049.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150630870.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150630870.png
new file mode 100755
index 0000000000000000000000000000000000000000..2d661646429af7ee314241ca3f86556060d7911e
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150630870.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150812107.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150812107.png
new file mode 100755
index 0000000000000000000000000000000000000000..eaa958ef14096749ee02592c5790736a131c2141
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919150812107.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151018659.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151018659.png
new file mode 100755
index 0000000000000000000000000000000000000000..9b09507893b65d2142be49e6461daa31a81855c4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151018659.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151519310.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151519310.png
new file mode 100755
index 0000000000000000000000000000000000000000..7f6d881a5d0e6d3f72b7a43d089b5c5a75d7f048
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151519310.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151605632.png b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151605632.png
new file mode 100755
index 0000000000000000000000000000000000000000..c6aa9aad5685495d6bad5ba5d4e0c09e31ed3c7a
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/face_detection/pic/image-20250919151605632.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/Makefile b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/Makefile
new file mode 100755
index 0000000000000000000000000000000000000000..655332a1e534facf1e535f30523f129824e25f72
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/Makefile
@@ -0,0 +1,59 @@
+# 编译所需的公共文件
+include ../mk.param
+
+# 编译后生成的可执行文件名
+TARGET := main
+
+# 编译此工程需要包含的头文件
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/
+CFLAGS += -I$(SDK_SAMPLE_COMMON_DIR)/
+CFLAGS += -I$(AUDIO_SAMPLE)/adp/
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/svp_npu
+CFLAGS += -I$(FRUIT_IDENTIFY_SAMPLE_DIR)/
+CFLAGS += -I$(FRUIT_IDENTIFY_SAMPLE_DIR)/common/
+CFLAGS += -I$(THIRD_PARTY_DIR)/xvp_osd/include/
+
+# 编译此工程需要依赖的.c或.cpp文件
+SMP_SRCS := $(AUDIO_SAMPLE)/adp/audio_aac_adp.c
+SMP_SRCS += $(AUDIO_SAMPLE)/adp/audio_dl_adp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_sys.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_audio.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_ipc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_isp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vi.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vo.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_mipi_tx.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vpss.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/loadbmp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vdec.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_venc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_init.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_exit.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/fruit_identify.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/sample_audio.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/common/sample_common_svp_npu_model.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/common/sample_common_svp_npu.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/common/sample_common_svp_osd.c
+SMP_SRCS += $(FRUIT_IDENTIFY_SAMPLE_DIR)/common/sample_common_svp.c
+
+# 编译此工程需要包含的库和宏
+CFLAGS += -O3 -g -Wall -DUSE_USB_CAMERA
+CFLAGS += -fstack-protector-strong
+MPI_LIBS += $(THIRD_PARTY_DIR)/xvp_osd/lib/libxvp_osd.a
+
+# 根据实际的类型设置,可以用set_sensor脚本设置
+SENSOR0_TYPE = -DSENSOR0_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR1_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR2_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR3_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+
+CFLAGS += $(SENSOR0_TYPE)
+CFLAGS += $(SENSOR1_TYPE)
+CFLAGS += $(SENSOR2_TYPE)
+CFLAGS += $(SENSOR3_TYPE)
+
+# 编译工程所需的mk文件
+
+include ../sdk_linux.mk
+
+
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/README.md b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..8919851eb8da9eff1f4aaefb95c1070bdc55a0f0
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/README.md
@@ -0,0 +1,131 @@
+## 2.3、fruit_identify操作指导
+
+### 2.3.1、fruit_identify程序简介
+
+* fruit_identify sample基于SS928V100平台开发,以EulerPi套件为例,fruit_identify sample是通过USB Camera,将采集到的图片送到水果检测模型中进行推理,当检测到特定水果时,会通过外接显示屏实时显示水果的种类以及执行度,并框住水果的具体位置,并通过耳机播放出此时识别到的水果类别。
+* fruit_identify案例主要是使用pytorch框架,基于YoloV8网络,使用自行标注的水果数据集训练出来的水果分类模型。
+
+### 2.3.2、目录
+
+```shell
+pegasus/vendor/cust/demo/fruit_identify
+|── common # 基于海思mpp/sample中的svp/common/目录下修改的代码,新增了OSD部分的内容
+|── data # 模型文件和汉字库
+|── fruit_audio # 不同水果的音频文件
+|── Makefile # 编译脚本
+|── fruit_identify.c # fruit_identif sample业务代码
+|── sample_audio.c # 音频播放的业务代码
+└── sample_audio.h # 音频播放的头文件
+```
+
+
+
+### 2.3.3、编译
+
+* **注意:在编译cust的demo之前,请确保你已经按照[patch介绍中的步骤](../../README.md#4patch介绍)把补丁打入海思SDK的sample目录下了**。
+
+* 步骤1:先根据自己选择的操作系统,进入到对应的Pegasus所在目录下。
+
+* 步骤2:使用Makefile的方式进行单编
+
+* 在Ubuntu的命令行终端,分步执行下面的命令,单编 fruit_identify sample
+
+ ```
+ cd pegasus/vendor/cust/demo/fruit_identify
+
+ make clean && make
+ ```
+
+ 
+
+ * 在fruit_identify目录下,生成一个名为fruit_identify的 可执行文件,如下图所示:
+
+ 
+
+### 2.3.4、拷贝可执行程序和依赖文件至开发板的mnt目录下
+
+**方式一:使用SD卡进行资料文件的拷贝**
+
+* 首先需要自己准备一张Micro sd卡(16G 左右即可),还得有一个Micro sd卡的读卡器。
+
+
+
+* 步骤1:将编译后生成的可执行文件、data目录(里面有模型和字库),音频文件都拷贝到SD卡中。
+
+
+
+* 步骤2:可执行文件拷贝成功后,将内存卡插入开发板的SD卡槽中,可通过挂载的方式挂载到板端,可选择SD卡 mount指令进行挂载。
+
+
+
+* 在开发板的终端,执行下面的命令进行SD卡的挂载
+ * 如果挂载失败,可以参考[这个issue尝试解决](https://gitee.com/HiSpark/HiSpark_NICU2022/issues/I54932?from=project-issue)
+
+
+```shell
+mount -t vfat /dev/mmcblk1p1 /mnt
+# 其中/dev/mmcblk1p1需要根据实际块设备号修改
+```
+
+* 挂载成功后,如下图所示:
+
+
+
+**方式二:使用NFS挂载的方式进行资料文件的拷贝**
+
+* 首先需要自己准备一根网线
+* 步骤1:参考[博客链接](https://blog.csdn.net/Wu_GuiMing/article/details/115872995?spm=1001.2014.3001.5501)中的内容,进行nfs的环境搭建
+* 步骤2:将编译后生成的可执行文件、data目录(里面有模型和字库),音频文件都拷贝到Windows的nfs共享路径下
+
+
+
+* 步骤3:在开发板的终端执行下面的命令,将Windows的nfs共享路径挂载至开发板的mnt目录下
+ * 注意:这里IP地址请根据你开发板和电脑主机的实际IP地址进行填写
+
+
+```
+ifconfig eth0 192.168.100.100
+mount -o nolock,addr=192.168.100.10 -t nfs 192.168.100.10:/d/nfs /mnt
+```
+
+
+
+### 2.3.5、硬件连接
+
+* 准备一个外接显示器和HDMI数据线,将HDMI的一头接在开发板的HDMI输出口,将HDMI的另外一头接在外接显示器的HDMI输入口。
+
+
+
+* 将USB 摄像头接在EulerPi开发板的USB接口上。
+
+
+
+### 2.3.6、功能验证
+
+* 在开发板的终端执行下面的命令,运行可执行文件
+
+```
+cd /mnt
+
+chmod +x fruit_identify
+
+./fruit_identify
+```
+
+
+
+* 此时,在HDMI的外接显示屏上即可出现实时码流,如下图所示:
+
+
+
+* 如果您看到的现象和下图现象不一致,可以确认一下USB涉嫌头是否插入到开发板的USB口,并且在开发板的/dev目录下能够看到video0 和 video1两个设备节点。如果没有这两个设备节点,请确保镜像烧录正常。
+
+
+
+* 正常情况下,我们会在外接显示屏上看到有水果的区域被框出来。且在框框的左上角显示水果的种类和置信度,并且你可以在开发板上面接上耳机,可以听到检测到的水果的具体语音播报。
+
+
+
+* 敲两下回车即可关闭程序
+
+
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.c
new file mode 100755
index 0000000000000000000000000000000000000000..79778ec97254e1250f4ea6820348267955f8df4d
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.c
@@ -0,0 +1,1036 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "sample_common_svp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "ot_common.h"
+#include "ot_common_video.h"
+#include "ot_common_sys.h"
+#include "ot_common_svp.h"
+#include "ss_mpi_vb.h"
+#include "sample_comm.h"
+
+#define OT_VPSS_CHN_NUM 2
+#define OT_SAMPLE_IVE_MAX_POOL_CNT 128
+#define OT_SAMPLE_IVE_DRAW_THICK 2
+
+#define SAMPLE_SVP_BLK_CNT 16
+#define SMAPLE_SVP_DISPLAY_BUF_LEN 3
+#define SAMPLE_SVP_VI_CHN_INTERVAL 4
+#define SAMPLE_SVP_VDEC_CHN_0 0
+#define SAMPLE_SVP_VDEC_CHN_NUM 1
+#define SAMPLE_SVP_VPSS_BORDER_WIDTH 2
+#define SAMPLE_SVP_VO_DIS_BUF_LEN 3
+#define SAMPLE_SVP_MAX_WIDTH 32768
+#define SAMPLE_SVP_NUM_TWO 2
+#define SAMPLE_SVP_DSP_BIN_NUM_PER 4
+#define SAMPLE_SVP_DSP_MEM_TYPE_SYS_DDR 0
+#define SAMPLE_SVP_DSP_MEM_TYPE_IRAM 1
+#define SAMPLE_SVP_DSP_MEM_TYPE_DRAM_0 2
+#define SAMPLE_SVP_DSP_MEM_TYPE_DRAM_1 3
+
+static td_bool g_sample_svp_init_flag = TD_FALSE;
+
+static td_s32 sample_common_svp_get_pic_type_by_sns_type(sample_sns_type sns_type, ot_pic_size size[], td_u32 num)
+{
+ sample_svp_check_exps_return(num > OT_VPSS_CHN_NUM, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "num(%u) can't be larger than (%u)\n", num, OT_VPSS_CHN_NUM);
+ switch (sns_type) {
+ case HY_S0603_MIPI_8M_30FPS_12BIT:
+ case HY_S0603_MIPI_8M_30FPS_10BIT_WDR2TO1:
+ size[0] = PIC_3840X2160;
+ break;
+ default:
+ size[0] = PIC_3840X2160;
+ break;
+ }
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_comm_svp_get_pic_size(ot_pic_size pic_type, td_u64 *size)
+{
+ td_s32 ret;
+ ot_pic_buf_attr pic_buf_attr = {0};
+ ot_size pic_size = {0};
+
+ ret = sample_comm_sys_get_pic_size(pic_type, &pic_size);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
+ pic_buf_attr.width = pic_size.width;
+ pic_buf_attr.height = pic_size.height;
+ pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
+ pic_buf_attr.align = OT_DEFAULT_ALIGN;
+ pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
+ pic_buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
+ *size = ot_common_get_pic_buf_size(&pic_buf_attr);
+ return TD_SUCCESS;
+}
+
+/* System init */
+static td_s32 sample_comm_svp_sys_init(td_bool vi_en)
+{
+ td_s32 ret;
+ ot_vb_cfg vb_cfg;
+ ot_pic_size pic_type;
+ td_u64 size = 0;
+ sample_sns_type sns_type = SENSOR0_TYPE;
+
+ ret = ss_mpi_sys_exit();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_sys_exit failed!\n", ret);
+ ret = ss_mpi_vb_exit();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_vb_exit failed!\n", ret);
+
+ (td_void)memset_s(&vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
+
+ if (vi_en == TD_FALSE) {
+ vb_cfg.max_pool_cnt = SAMPLE_SVP_VB_POOL_NUM;
+ vb_cfg.common_pool[1].blk_size = SAMPLE_SVP_D1_PAL_WIDTH * SAMPLE_SVP_D1_PAL_HEIGHT * SAMPLE_SVP_VB_POOL_NUM;
+ vb_cfg.common_pool[1].blk_cnt = 1;
+ } else {
+ ret = sample_common_svp_get_pic_type_by_sns_type(sns_type, &pic_type, OT_SVP_MAX_VPSS_CHN_NUM);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_common_svp_get_pic_type_by_sns_type failed!\n");
+ ret = sample_comm_svp_get_pic_size(pic_type, &size);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):sample_common_svp_npu_get_pic_size failed!\n", ret);
+ vb_cfg.max_pool_cnt = SAMPLE_SVP_VB_POOL_NUM;
+ vb_cfg.common_pool[1].blk_size = size;
+ vb_cfg.common_pool[1].blk_cnt = SAMPLE_SVP_BLK_CNT;
+ }
+
+ ret = ss_mpi_vb_set_cfg((const ot_vb_cfg *)&vb_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_vb_set_config failed!\n", ret);
+
+ ret = ss_mpi_vb_init();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_vb_init failed!\n", ret);
+
+ ret = ss_mpi_sys_init();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_sys_init failed!\n", ret);
+
+ return ret;
+}
+
+/* System exit */
+static td_s32 sample_comm_svp_sys_exit(td_void)
+{
+ td_s32 ret;
+
+ ret = ss_mpi_sys_exit();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_sys_exit failed!\n", ret);
+
+ ret = ss_mpi_vb_exit();
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_vb_exit failed!\n", ret);
+
+ return TD_SUCCESS;
+}
+
+/* System init */
+td_s32 sample_common_svp_check_sys_init(td_bool vi_en)
+{
+ if (g_sample_svp_init_flag == TD_FALSE) {
+ if (sample_comm_svp_sys_init(vi_en) != TD_SUCCESS) {
+ sample_svp_trace_err("Svp mpi init failed!\n");
+ return TD_FALSE;
+ }
+ g_sample_svp_init_flag = TD_TRUE;
+ }
+
+ sample_svp_trace_info("Svp mpi init ok!\n");
+ return TD_TRUE;
+}
+
+/* System exit */
+td_void sample_common_svp_check_sys_exit(td_void)
+{
+ td_s32 ret;
+
+ if (g_sample_svp_init_flag == TD_TRUE) {
+ ret = sample_comm_svp_sys_exit();
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("svp mpi exit failed!\n");
+ }
+ }
+ g_sample_svp_init_flag = TD_FALSE;
+ sample_svp_trace_info("Svp mpi exit ok!\n");
+}
+
+/* Align */
+td_u32 sample_common_svp_align(td_u32 size, td_u16 align)
+{
+ td_u32 stride;
+
+ sample_svp_check_exps_return(align == 0, 0, SAMPLE_SVP_ERR_LEVEL_ERROR, "align can't be zero!\n");
+ sample_svp_check_exps_return((size < 1) || (size > SAMPLE_SVP_MAX_WIDTH), 0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "size(%u) must be [1, %u]\n", size, SAMPLE_SVP_MAX_WIDTH);
+ stride = size + (align - size % align) % align;
+ return stride;
+}
+
+/* Create mem info */
+td_s32 sample_common_svp_create_mem_info(ot_svp_mem_info *mem_info, td_u32 size, td_u32 addr_offset)
+{
+ td_s32 ret = TD_FAILURE;
+ td_u32 size_tmp;
+
+ sample_svp_check_exps_return(mem_info == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "mem_info can't be zero\n");
+
+ size_tmp = size + addr_offset;
+ mem_info->size = size;
+ ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)(&mem_info->phys_addr),
+ (void **)&mem_info->virt_addr, TD_NULL, TD_NULL, size_tmp);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):ss_mpi_sys_alloc failed!\n", ret);
+
+ mem_info->phys_addr += addr_offset;
+ mem_info->virt_addr += addr_offset;
+
+ return ret;
+}
+
+/* Destory mem info */
+td_void sample_common_svp_destroy_mem_info(ot_svp_mem_info *mem_info, td_u32 addr_offset)
+{
+ sample_svp_check_exps_return_void(mem_info == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "mem_info can't be zero\n");
+
+ if ((mem_info->virt_addr != 0) && (mem_info->phys_addr != 0)) {
+ (td_void)ss_mpi_sys_mmz_free(mem_info->phys_addr - addr_offset,
+ sample_svp_convert_addr_to_ptr(void, (mem_info->virt_addr - addr_offset)));
+ }
+ (td_void)memset_s(mem_info, sizeof(*mem_info), 0, sizeof(*mem_info));
+}
+/* Malloc memory */
+td_s32 sample_common_svp_malloc_mem(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
+ td_void **virt_addr, td_u32 size)
+{
+ td_s32 ret = TD_FAILURE;
+
+ sample_svp_check_exps_return(phys_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "phys_addr can't be null\n");
+ sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
+ ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)phys_addr, virt_addr, mmb, zone, size);
+
+ return ret;
+}
+
+/* Malloc memory with cached */
+td_s32 sample_common_svp_malloc_cached(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
+ td_void **virt_addr, td_u32 size)
+{
+ td_s32 ret = TD_FAILURE;
+
+ sample_svp_check_exps_return(phys_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "phys_addr can't be null\n");
+ sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
+ ret = ss_mpi_sys_mmz_alloc_cached((td_phys_addr_t *)phys_addr, virt_addr, mmb, zone, size);
+
+ return ret;
+}
+
+/* Fulsh cached */
+td_s32 sample_common_svp_flush_cache(td_phys_addr_t phys_addr, td_void *virt_addr, td_u32 size)
+{
+ td_s32 ret = TD_FAILURE;
+
+ sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
+ ret = ss_mpi_sys_flush_cache((td_phys_addr_t)phys_addr, virt_addr, size);
+ return ret;
+}
+
+/*
+ * function : Init Vb
+ */
+static td_s32 sample_common_svp_vb_init(ot_pic_size *pic_type, ot_size *pic_size,
+ td_u32 vpss_chn_num)
+{
+ td_s32 ret;
+ td_u32 i;
+ ot_vb_cfg vb_cfg = {0};
+ ot_pic_buf_attr pic_buf_attr;
+ ot_vb_calc_cfg calc_cfg;
+ ot_vi_vpss_mode_type mode_type = OT_VI_ONLINE_VPSS_OFFLINE;
+ ot_vi_video_mode video_mode = OT_VI_VIDEO_MODE_NORM;
+
+ vb_cfg.max_pool_cnt = OT_SAMPLE_IVE_MAX_POOL_CNT;
+
+ ret = sample_comm_sys_get_pic_size(pic_type[0], &pic_size[0]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
+ pic_buf_attr.width = pic_size[0].width;
+ pic_buf_attr.height = pic_size[0].height;
+ pic_buf_attr.align = OT_DEFAULT_ALIGN;
+ pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
+ pic_buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
+ pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
+
+ ot_common_get_pic_buf_cfg(&pic_buf_attr, &calc_cfg);
+
+ vb_cfg.common_pool[0].blk_size = calc_cfg.vb_size;
+ vb_cfg.common_pool[0].blk_cnt = SAMPLE_SVP_BLK_CNT;
+
+ for (i = 1; (i < vpss_chn_num) && (i < OT_VB_MAX_COMMON_POOLS); i++) {
+ ret = sample_comm_sys_get_pic_size(pic_type[i], &pic_size[i]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
+ pic_buf_attr.width = pic_size[i].width;
+ pic_buf_attr.height = pic_size[i].height;
+ pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
+ pic_buf_attr.align = OT_DEFAULT_ALIGN;
+
+ ot_common_get_pic_buf_cfg(&pic_buf_attr, &calc_cfg);
+
+ /* comm video buffer */
+ vb_cfg.common_pool[i].blk_size = calc_cfg.vb_size;
+ vb_cfg.common_pool[i].blk_cnt = SAMPLE_SVP_BLK_CNT;
+ }
+
+ ret = sample_comm_sys_init_with_vb_supplement(&vb_cfg, OT_VB_SUPPLEMENT_BNR_MOT_MASK);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_init failed,Error(%#x)!\n", ret);
+
+ ret = sample_comm_vi_set_vi_vpss_mode(mode_type, video_mode);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_vi_set_vi_vpss_mode failed!\n");
+ return ret;
+vb_fail_1:
+ sample_comm_sys_exit();
+vb_fail_0:
+ return ret;
+}
+
+td_s32 sample_common_svp_vgs_fill_rect(const ot_video_frame_info *frame_info,
+ ot_sample_svp_rect_info *rect, td_u32 color)
+{
+ ot_vgs_handle vgs_handle = -1;
+ td_s32 ret = TD_FAILURE;
+ td_u16 i;
+ ot_vgs_task_attr vgs_task;
+ ot_cover vgs_add_cover;
+
+ sample_svp_check_exps_return(frame_info == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "frame_info can't be null\n");
+ sample_svp_check_exps_return(rect == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "rect can't be null\n");
+ sample_svp_check_exps_return(rect->num > OT_SVP_RECT_NUM, ret,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "rect->num can't lager than %u\n", OT_SVP_RECT_NUM);
+ if (rect->num == 0) {
+ return TD_SUCCESS;
+ }
+
+ ret = ss_mpi_vgs_begin_job(&vgs_handle);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Vgs begin job fail,Error(%#x)\n", ret);
+
+ ret = memcpy_s(&vgs_task.img_in, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
+ sample_svp_check_exps_goto(ret != EOK, fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "get img_in failed\n");
+ ret = memcpy_s(&vgs_task.img_out, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
+ sample_svp_check_exps_goto(ret != EOK, fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "get img_out failed\n");
+
+ vgs_add_cover.type = OT_COVER_QUAD;
+ vgs_add_cover.color = color;
+ for (i = 0; i < rect->num; i++) {
+ vgs_add_cover.quad.is_solid = TD_FALSE;
+ vgs_add_cover.quad.thick = OT_SAMPLE_IVE_DRAW_THICK;
+ ret = memcpy_s(vgs_add_cover.quad.point, sizeof(rect->rect[i].point),
+ rect->rect[i].point, sizeof(rect->rect[i].point));
+ sample_svp_check_exps_goto(ret != EOK, fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "get point failed\n");
+ ret = ss_mpi_vgs_add_cover_task(vgs_handle, &vgs_task, &vgs_add_cover, 1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "ss_mpi_vgs_add_cover_task fail,Error(%#x)\n", ret);
+ }
+ ret = ss_mpi_vgs_end_job(vgs_handle);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "ss_mpi_vgs_end_job fail,Error(%#x)\n", ret);
+ return ret;
+fail:
+ ss_mpi_vgs_cancel_job(vgs_handle);
+ return ret;
+}
+
+/* function : Start Vpss */
+static td_s32 sample_common_svp_start_vpss(td_s32 vpss_grp_cnt, ot_size *pic_size, td_u32 vpss_chn_num)
+{
+ td_u32 i;
+ ot_vpss_chn_attr vpss_chn_attr[OT_VPSS_MAX_CHN_NUM];
+ ot_vpss_grp_attr vpss_grp_attr;
+ td_bool chn_enable[OT_VPSS_MAX_CHN_NUM] = { TD_TRUE, TD_TRUE, TD_FALSE, TD_FALSE };
+ ot_vpss_grp vpss_grp;
+ td_s32 ret;
+
+ (td_void)memset_s(&vpss_grp_attr, sizeof(ot_vpss_grp_attr), 0, sizeof(ot_vpss_grp_attr));
+ sample_comm_vpss_get_default_grp_attr(&vpss_grp_attr);
+ vpss_grp_attr.max_width = pic_size[0].width;
+ vpss_grp_attr.max_height = pic_size[0].height;
+ vpss_grp_attr.nr_attr.compress_mode = OT_COMPRESS_MODE_NONE;
+ /* VPSS only onle channel0 support compress seg mode */
+ sample_comm_vpss_get_default_chn_attr(&vpss_chn_attr[0]);
+ vpss_chn_attr[0].width = pic_size[0].width;
+ vpss_chn_attr[0].height = pic_size[0].height;
+ vpss_chn_attr[0].compress_mode = OT_COMPRESS_MODE_NONE;
+ vpss_chn_attr[0].depth = 1;
+
+ for (i = 1; i < vpss_chn_num; i++) {
+ (td_void)memset_s(&vpss_chn_attr[i], sizeof(ot_vpss_chn_attr), 0, sizeof(ot_vpss_chn_attr));
+ sample_comm_vpss_get_default_chn_attr(&vpss_chn_attr[i]);
+ vpss_chn_attr[i].width = pic_size[i].width;
+ vpss_chn_attr[i].height = pic_size[i].height;
+ vpss_chn_attr[i].compress_mode = OT_COMPRESS_MODE_NONE;
+ vpss_chn_attr[i].depth = 1;
+ }
+
+ for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) {
+ ret = sample_common_vpss_start(vpss_grp, chn_enable, &vpss_grp_attr, vpss_chn_attr, OT_VPSS_MAX_CHN_NUM);
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("failed with %#x!\n", ret);
+ return TD_FAILURE;
+ }
+ }
+ return TD_SUCCESS;
+}
+
+/* function : Stop Vpss */
+static td_void sample_common_svp_stop_vpss(td_s32 vpss_grp_cnt, td_u32 vpss_chn_num)
+{
+ ot_vpss_grp vpss_grp = 0;
+ td_bool chn_enable[OT_VPSS_MAX_CHN_NUM] = { TD_FALSE, TD_FALSE, TD_FALSE, TD_FALSE };
+ td_s32 i;
+ for (i = 0; (i < vpss_chn_num) && (i < OT_VPSS_MAX_CHN_NUM); i++) {
+ chn_enable[i] = TD_TRUE;
+ }
+ for (i = 0; (i < vpss_grp_cnt) && (i < OT_VPSS_MAX_CHN_NUM); i++) {
+ sample_common_vpss_stop(vpss_grp, chn_enable, OT_VPSS_MAX_CHN_NUM);
+ vpss_grp++;
+ }
+}
+
+static td_s32 sample_common_svp_get_def_vo_cfg(sample_vo_cfg *vo_cfg)
+{
+ ot_rect def_disp_rect = {0, 0, 1920, 1080};
+ ot_size def_img_size = {1920, 1080};
+
+ if (vo_cfg == TD_NULL) {
+ sample_svp_trace_err("error:argument can not be TD_NULL\n");
+ return TD_FAILURE;
+ }
+
+ vo_cfg->vo_dev = SAMPLE_VO_DEV_UHD;
+
+ vo_cfg->vo_intf_type = OT_VO_INTF_HDMI;
+ vo_cfg->intf_sync = OT_VO_OUT_1080P60;
+ vo_cfg->bg_color = COLOR_RGB_BLACK;
+ vo_cfg->pix_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ vo_cfg->disp_rect = def_disp_rect;
+ vo_cfg->image_size = def_img_size;
+ vo_cfg->vo_part_mode = OT_VO_PARTITION_MODE_SINGLE;
+ vo_cfg->dis_buf_len = 3; /* 3: def buf len for single */
+ vo_cfg->dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8;
+ vo_cfg->vo_mode = VO_MODE_1MUX;
+ vo_cfg->compress_mode = OT_COMPRESS_MODE_NONE;
+
+ return TD_SUCCESS;
+}
+
+/*
+ * function : Start Vo
+ */
+static td_s32 sample_common_svp_start_vo(const ot_sample_svp_switch *vo_venc_switch, sample_vo_cfg *vo_cfg)
+{
+ td_s32 ret;
+ sample_svp_check_exps_return(vo_venc_switch == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "vo_venc_switch can't be null\n");
+ sample_svp_check_exps_return(vo_cfg == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "vo_cfg can't be null\n");
+
+ if (vo_venc_switch->is_vo_open == TD_FALSE) {
+ return TD_SUCCESS;
+ }
+ ret = sample_common_svp_get_def_vo_cfg(vo_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_get_def_vo_cfg failed!\n", ret);
+ ret = sample_comm_vo_start_vo(vo_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_vo_start_vo failed!\n", ret);
+ return ret;
+}
+
+/*
+ * function : Stop Vo
+ */
+static td_void sample_common_svp_stop_vo(const ot_sample_svp_switch *vo_venc_switch, sample_vo_cfg *vo_cfg)
+{
+ sample_svp_check_exps_return_void(vo_venc_switch == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "vo_venc_switch can't be null\n");
+ sample_svp_check_exps_return_void(vo_cfg == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "vo_cfg can't be null\n");
+
+ if (vo_venc_switch->is_vo_open == TD_FALSE) {
+ return;
+ }
+ (td_void)sample_comm_vo_stop_vo(vo_cfg);
+}
+
+static td_s32 sample_common_svp_vi_bind_multi_vpss(td_s32 vpss_grp_cnt, td_s32 vi_chn_cnt,
+ td_s32 vi_chn_interval)
+{
+ td_s32 ret;
+ td_s32 loop;
+ ot_vi_chn vi_chn;
+ ot_vpss_grp vpss_grp = 0;
+
+ for (loop = 0; loop < vi_chn_cnt && vpss_grp < vpss_grp_cnt; loop++) {
+ vi_chn = loop * vi_chn_interval;
+ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0);
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("vi bind vpss failed!\n");
+ return ret;
+ }
+ vpss_grp++;
+ }
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_common_svp_vi_unbind_multi_vpss(td_s32 vpss_grp_cnt, td_s32 vi_chn_cnt,
+ td_s32 vi_chn_interval)
+{
+ td_s32 ret;
+ td_s32 loop;
+ ot_vi_chn vi_chn;
+ ot_vpss_grp vpss_grp = 0;
+
+ for (loop = 0; loop < vi_chn_cnt && vpss_grp < vpss_grp_cnt; loop++) {
+ vi_chn = loop * vi_chn_interval;
+ ret = sample_comm_vi_un_bind_vpss(0, vi_chn, vpss_grp, 0);
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("vi bind vpss failed!\n");
+ return ret;
+ }
+
+ vpss_grp++;
+ }
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_common_svp_set_vi_cfg(sample_vi_cfg *vi_cfg, ot_pic_size *pic_type,
+ td_u32 pic_type_len, ot_pic_size *ext_pic_size_type, sample_sns_type sns_type)
+{
+ sample_comm_vi_get_default_vi_cfg(sns_type, vi_cfg);
+ sample_svp_check_exps_return(pic_type_len < OT_VPSS_CHN_NUM,
+ TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "pic_type_len is illegal!\n");
+ pic_type[1] = *ext_pic_size_type;
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_common_svp_start_venc(const ot_sample_svp_switch *switch_ptr,
+ sample_vo_cfg *vo_cfg, ot_pic_size *pic_type, td_u32 chn_num)
+{
+ td_s32 ret = TD_SUCCESS;
+ ot_venc_chn h264_chn = 0;
+ sample_comm_venc_chn_param chn_param;
+ ot_size ven_size = {1920, 1080};
+
+ sample_svp_check_exps_goto(chn_num == 0, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error(%#x),chn_num(%u) can't be 0!\n",
+ ret, chn_num);
+ if (switch_ptr->is_venc_open == TD_TRUE) {
+ ret = sample_comm_venc_get_gop_attr(OT_VENC_GOP_MODE_NORMAL_P, &chn_param.gop_attr);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_venc_get_gop_attr failed!\n", ret);
+ chn_param.frame_rate = 30; /* 30 is a number */
+ chn_param.stats_time = 1; /* 1 is a number */
+ chn_param.gop = 30; /* 30 is a number */
+ chn_param.venc_size = ven_size;
+ chn_param.size = pic_type[0];
+ chn_param.profile = 0;
+ chn_param.is_rcn_ref_share_buf = TD_TRUE;
+
+ chn_param.type = OT_PT_H264;
+ chn_param.rc_mode = SAMPLE_RC_CBR;
+
+ ret = sample_comm_venc_start(h264_chn, &chn_param);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_venc_start failed!\n", ret);
+
+ ret = sample_comm_venc_start_get_stream(&h264_chn, 1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_venc_start_get_stream failed!\n", ret);
+ }
+ return ret;
+
+end_1:
+ if (switch_ptr->is_venc_open == TD_TRUE) {
+ sample_comm_venc_stop(h264_chn);
+ }
+end_0:
+ sample_common_svp_stop_vo(switch_ptr, vo_cfg);
+ return ret;
+}
+
+/*
+ * function : Start Vi/Vpss/Venc/Vo
+ */
+td_s32 sample_common_svp_start_vi_vpss_venc_vo(sample_vi_cfg *vi_cfg,
+ ot_sample_svp_switch *switch_ptr, ot_pic_size *ext_pic_size_type)
+{
+ ot_size pic_size[OT_VPSS_CHN_NUM];
+ ot_pic_size pic_type[OT_VPSS_CHN_NUM];
+ sample_vo_cfg vo_cfg;
+ ot_pic_size venc_pic_type[SAMPLE_SVP_VDEC_CHN_NUM] = {PIC_1080P};
+
+ const td_s32 vpss_grp_cnt = 1;
+ td_s32 ret = TD_FAILURE;
+ sample_sns_type sns_type = SENSOR0_TYPE;
+
+ sample_svp_check_exps_return(vi_cfg == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_cfg can't be null\n");
+ sample_svp_check_exps_return(switch_ptr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "switch_ptr can't be null\n");
+ sample_svp_check_exps_return(ext_pic_size_type == TD_NULL, ret,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "ext_pic_size_type can't be null\n");
+
+ ret = sample_common_svp_get_pic_type_by_sns_type(sns_type, pic_type, OT_VPSS_CHN_NUM);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_common_svp_get_pic_type_by_sns_type failed!\n");
+ ret = sample_common_svp_set_vi_cfg(vi_cfg, pic_type, OT_VPSS_CHN_NUM, ext_pic_size_type, sns_type);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_common_svp_set_vi_cfg failed,Error:%#x\n", ret);
+
+ /* step 1: Init vb */
+ ret = sample_common_svp_vb_init(pic_type, pic_size, OT_VPSS_CHN_NUM);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_vb_init failed!\n", ret);
+
+ /* step 2: Start vi */
+ ret = sample_comm_vi_start_vi(vi_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_vi_start_vi failed!\n", ret);
+
+ /* step 3: Bind vpss to vi */
+ ret = sample_common_svp_vi_bind_multi_vpss(vpss_grp_cnt, 1, 1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_2, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_vi_bind_multi_vpss failed!\n", ret);
+
+ /* step 4: Start vpss */
+ ret = sample_common_svp_start_vpss(vpss_grp_cnt, pic_size, OT_VPSS_CHN_NUM);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_3, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
+
+ /* step 5: Set vi frame, Start Vo */
+ ret = sample_common_svp_start_vo(switch_ptr, &vo_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_set_vi_frame failed!\n", ret);
+
+ /* step 6: Start Venc */
+ ret = sample_common_svp_start_venc(switch_ptr, &vo_cfg, venc_pic_type, SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vencb failed!\n", ret);
+
+ return TD_SUCCESS;
+end_init_4:
+ sample_common_svp_stop_vpss(vpss_grp_cnt, OT_VPSS_CHN_NUM);
+end_init_3:
+ ret = sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, 1, 1);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "svp_vi_unbind_multi_vpss failed!\n");
+end_init_2:
+ sample_comm_vi_stop_vi(vi_cfg);
+end_init_1: /* system exit */
+ sample_comm_sys_exit();
+ (td_void)memset_s(vi_cfg, sizeof(sample_vi_cfg), 0, sizeof(sample_vi_cfg));
+ return ret;
+}
+static td_void sample_common_svp_stop_venc(const ot_sample_svp_switch *vo_venc_switch)
+{
+ if (vo_venc_switch->is_venc_open == TD_TRUE) {
+ sample_comm_venc_stop_get_stream(1);
+ sample_comm_venc_stop(0);
+ }
+}
+/*
+ * function : Stop Vi/Vpss/Venc/Vo
+ */
+td_void sample_common_svp_stop_vi_vpss_venc_vo(sample_vi_cfg *vi_cfg,
+ ot_sample_svp_switch *switch_ptr)
+{
+ sample_vo_cfg vo_cfg = {0};
+ td_s32 ret;
+ const td_s32 vpss_grp_cnt = 1;
+
+ sample_svp_check_exps_return_void(vi_cfg == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_cfg can't be null\n");
+ sample_svp_check_exps_return_void(switch_ptr == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "switch_ptr can't be null\n");
+
+ sample_common_svp_stop_venc(switch_ptr);
+
+ if (switch_ptr->is_vo_open == TD_TRUE) {
+ (td_void)sample_common_svp_get_def_vo_cfg(&vo_cfg);
+ sample_common_svp_stop_vo(switch_ptr, &vo_cfg);
+ }
+
+ ret = sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, 1, 1);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_common_svp_vi_unbind_multi_vpss failed\n");
+ sample_common_svp_stop_vpss(vpss_grp_cnt, OT_VPSS_CHN_NUM);
+ sample_comm_vi_stop_vi(vi_cfg);
+ sample_comm_sys_exit();
+
+ (td_void)memset_s(vi_cfg, sizeof(sample_vi_cfg), 0, sizeof(sample_vi_cfg));
+}
+
+static td_s32 sample_common_svp_start_vdec(td_u32 chn_num, sample_vdec_attr *vdec_attr, td_u32 arr_len)
+{
+ td_s32 ret;
+ ret = sample_comm_vdec_init_vb_pool(chn_num, vdec_attr, arr_len);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_vdec_init_vb_pool failed!\n", ret);
+
+ ret = sample_comm_vdec_start(chn_num, vdec_attr, arr_len);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x), sample_comm_vdec_start failed!\n", ret);
+
+ ret = ss_mpi_vdec_set_display_mode(SAMPLE_SVP_VDEC_CHN_0, OT_VIDEO_DISPLAY_MODE_PREVIEW);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x), sample_comm_vdec_start failed!\n", ret);
+
+ return ret;
+end_1:
+ sample_comm_vdec_exit_vb_pool();
+ return ret;
+}
+
+static td_void sample_common_svp_stop_vdec(td_u32 chn_num)
+{
+ td_s32 ret;
+ ret = sample_comm_vdec_stop(chn_num);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "sample_comm_vdec_stop failed\n");
+ sample_comm_vdec_exit_vb_pool();
+}
+
+static td_s32 sample_common_svp_vpss_bind_vdec(td_s32 vpss_grp_cnt, td_s32 vdec_chn)
+{
+ td_s32 i;
+ td_s32 j;
+ td_s32 ret;
+ for (i = 0; i < vpss_grp_cnt; i++) {
+ ret = sample_comm_vdec_bind_vpss(vdec_chn, i);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x), sample_comm_vdec_bind_vpss failed!\n", ret);
+ }
+ return ret;
+end_1:
+ for (j = 0; j < i; j++) {
+ sample_comm_vdec_un_bind_vpss(vdec_chn, j);
+ }
+ return ret;
+}
+
+static td_void sample_common_svp_vpss_unbind_vdec(td_s32 vpss_grp_cnt, td_s32 vdec_chn)
+{
+ td_s32 i;
+ for (i = 0; i < vpss_grp_cnt; i++) {
+ sample_comm_vdec_un_bind_vpss(vdec_chn, i);
+ }
+}
+
+static td_s32 sample_common_svp_create_vb(ot_sample_svp_media_cfg *media_cfg)
+{
+ td_s32 ret = OT_INVALID_VALUE;
+ td_u32 i;
+ td_u32 j;
+ td_u64 blk_size;
+ ot_vb_pool_cfg vb_pool_cfg = { 0 };
+ ot_pic_buf_attr pic_buf_attr = {0};
+
+ sample_svp_check_exps_return(media_cfg == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg is NULL!\n");
+
+ sample_svp_check_exps_return((media_cfg->chn_num == 0) || (media_cfg->chn_num > OT_SVP_MAX_VPSS_CHN_NUM), ret,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg->chn_num must be [1, %d],Error(%#x)!\n", OT_SVP_MAX_VPSS_CHN_NUM, ret);
+
+ for (i = 0; i < media_cfg->chn_num; i++) {
+ if (media_cfg->pic_type[i] != PIC_BUTT) {
+ ret = sample_comm_sys_get_pic_size(media_cfg->pic_type[i], &media_cfg->pic_size[i]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
+ }
+ pic_buf_attr.width = media_cfg->pic_size[i].width;
+ pic_buf_attr.height = media_cfg->pic_size[i].height;
+ pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
+ pic_buf_attr.align = OT_DEFAULT_ALIGN;
+ pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
+ pic_buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
+ blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
+ vb_pool_cfg.blk_size = blk_size;
+ vb_pool_cfg.blk_cnt = SAMPLE_SVP_BLK_CNT;
+ media_cfg->vb_pool[i] = ss_mpi_vb_create_pool(&vb_pool_cfg);
+ }
+ return TD_SUCCESS;
+vb_fail_0:
+ for (j = 0; j < i; j++) {
+ (td_void)ss_mpi_vb_destroy_pool(media_cfg->vb_pool[j]);
+ }
+ return TD_FAILURE;
+}
+
+static td_void sample_common_svp_destroy_vb(ot_sample_svp_media_cfg *media_cfg)
+{
+ td_u32 i;
+ for (i = 0; i < media_cfg->chn_num; i++) {
+ (td_void)ss_mpi_vb_destroy_pool(media_cfg->vb_pool[i]);
+ }
+}
+static td_s32 sample_common_svp_vpss_attach_vb(ot_sample_svp_media_cfg *media_cfg, td_s32 vpss_grp_cnt)
+{
+ ot_vpss_grp grp;
+ ot_vpss_grp grp_tmp;
+ ot_vpss_chn chn;
+ ot_vpss_grp chn_tmp;
+ td_s32 ret;
+
+ for (grp = 0; grp < vpss_grp_cnt; grp++) {
+ for (chn = 0; chn < media_cfg->chn_num; chn++) {
+ ret = ss_mpi_vpss_attach_vb_pool(grp, chn, media_cfg->vb_pool[chn]);
+ if (ret == TD_SUCCESS) {
+ continue;
+ }
+ for (chn_tmp = 0; chn_tmp < chn; chn_tmp++) {
+ (td_void)ss_mpi_vpss_detach_vb_pool(grp, chn_tmp);
+ }
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x), ss_mpi_vpss_attach_vb_pool failed!\n", ret);
+ }
+ }
+ return ret;
+end_0:
+ for (grp_tmp = 0; grp_tmp < grp; grp_tmp++) {
+ for (chn_tmp = 0; chn_tmp < media_cfg->chn_num; chn_tmp++) {
+ (td_void)ss_mpi_vpss_detach_vb_pool(grp_tmp, chn_tmp);
+ }
+ }
+ return ret;
+}
+
+static td_void sample_common_svp_vpss_detach_vb(ot_sample_svp_media_cfg *media_cfg, td_s32 vpss_grp_cnt)
+{
+ ot_vpss_grp grp;
+ ot_vpss_chn chn;
+
+ for (grp = 0; grp < vpss_grp_cnt; grp++) {
+ for (chn = 0; chn < media_cfg->chn_num; chn++) {
+ (td_void)ss_mpi_vpss_detach_vb_pool(grp, chn);
+ }
+ }
+}
+
+td_s32 sample_common_svp_create_vb_start_vdec_vpss_vo(sample_vdec_attr *vdec_attr, vdec_thread_param *vdec_send,
+ pthread_t *vdec_thread, ot_sample_svp_media_cfg *media_cfg, sample_vo_cfg *vo_cfg)
+{
+ const td_s32 vpss_grp_cnt = 1;
+ td_s32 ret;
+ /* step 1: Init vb */
+ ret = sample_common_svp_create_vb(media_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_create_vb failed!\n", ret);
+ /* step 2: start vdec */
+ ret = sample_common_svp_start_vdec(SAMPLE_SVP_VDEC_CHN_NUM, vdec_attr, SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x), sample_common_svp_start_vdec failed!\n", ret);
+ /* step 3: Start vpss */
+ ret = sample_common_svp_start_vpss(vpss_grp_cnt, media_cfg->pic_size, media_cfg->chn_num);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_2, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
+
+ ret = sample_common_svp_vpss_attach_vb(media_cfg, vpss_grp_cnt);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_3, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
+
+ /* step 4: Bind vpss to vdec */
+ ret = sample_common_svp_vpss_bind_vdec(vpss_grp_cnt, SAMPLE_SVP_VDEC_CHN_0);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_vdec_bind_vpss failed!\n", ret);
+
+ /* step 5: Start vo */
+ ret = sample_common_svp_start_vo(&(media_cfg->svp_switch), vo_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_5, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vo failed!\n", ret);
+
+ /* step 5: Start Send thread */
+ sample_comm_vdec_start_send_stream(SAMPLE_SVP_VDEC_CHN_NUM, vdec_send, vdec_thread, SAMPLE_SVP_VDEC_CHN_NUM,
+ SAMPLE_SVP_VDEC_CHN_NUM);
+
+ /* step 6: Start Venc */
+ ret = sample_common_svp_start_venc(&(media_cfg->svp_switch), vo_cfg, media_cfg->pic_type,
+ SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_6, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_venc failed!\n", ret);
+
+ return ret;
+end_init_6:
+ sample_comm_vdec_stop_send_stream(SAMPLE_SVP_VDEC_CHN_NUM, vdec_send, vdec_thread, SAMPLE_SVP_VDEC_CHN_NUM,
+ SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_common_svp_stop_vo(&(media_cfg->svp_switch), vo_cfg);
+end_init_5:
+ sample_common_svp_vpss_unbind_vdec(vpss_grp_cnt, SAMPLE_SVP_VDEC_CHN_0);
+end_init_4:
+ sample_common_svp_vpss_detach_vb(media_cfg, vpss_grp_cnt);
+end_init_3:
+ sample_common_svp_stop_vpss(vpss_grp_cnt, media_cfg->chn_num);
+end_init_2:
+ sample_common_svp_stop_vdec(SAMPLE_SVP_VDEC_CHN_NUM);
+end_init_1:
+ sample_common_svp_destroy_vb(media_cfg);
+ return ret;
+}
+
+td_void sample_common_svp_destroy_vb_stop_vdec_vpss_vo(vdec_thread_param *vdec_send, pthread_t *vdec_thread,
+ ot_sample_svp_media_cfg *media_cfg, sample_vo_cfg *vo_cfg)
+{
+ const td_s32 vpss_grp_cnt = 1;
+
+ sample_svp_check_exps_return_void(media_cfg == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg is NULL!\n");
+
+ sample_svp_check_exps_return_void((media_cfg->chn_num == 0) || (media_cfg->chn_num > OT_SVP_MAX_VPSS_CHN_NUM),
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg->chn_num must be [1, %u]!\n", OT_SVP_MAX_VPSS_CHN_NUM);
+
+ sample_common_svp_stop_venc(&(media_cfg->svp_switch));
+
+ sample_comm_vdec_stop_send_stream(SAMPLE_SVP_VDEC_CHN_NUM, vdec_send, vdec_thread, SAMPLE_SVP_VDEC_CHN_NUM,
+ SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_common_svp_stop_vo(&(media_cfg->svp_switch), vo_cfg);
+ sample_common_svp_vpss_unbind_vdec(vpss_grp_cnt, SAMPLE_SVP_VDEC_CHN_0);
+ sample_common_svp_vpss_detach_vb(media_cfg, vpss_grp_cnt);
+ sample_common_svp_stop_vpss(vpss_grp_cnt, media_cfg->chn_num);
+ sample_common_svp_stop_vdec(SAMPLE_SVP_VDEC_CHN_NUM);
+ sample_common_svp_destroy_vb(media_cfg);
+}
+
+td_s32 sample_common_svp_venc_vo_send_stream(const ot_sample_svp_switch *vo_venc_switch, ot_venc_chn venc_chn,
+ ot_vo_layer vo_layer, ot_vo_chn vo_chn, const ot_video_frame_info *frame)
+{
+ td_s32 ret = OT_INVALID_VALUE;
+
+ sample_svp_check_exps_return((vo_venc_switch == TD_NULL || frame == TD_NULL), ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "vo_venc_switch is NULL!\n");
+ if (vo_venc_switch->is_venc_open) {
+ ret = ss_mpi_venc_send_frame(venc_chn, frame, OT_SVP_TIMEOUT);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_venc_send_frame failed!\n", ret);
+ }
+ if (vo_venc_switch->is_vo_open) {
+ ret = ss_mpi_vo_send_frame(vo_layer, vo_chn, frame, OT_SVP_TIMEOUT);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_vo_send_frame failed!\n", ret);
+ }
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_common_svp_npu_get_pic_size(ot_sample_svp_media_cfg *media_cfg)
+{
+ td_s32 ret;
+ ret = sample_comm_sys_get_pic_size(media_cfg->pic_type[0], &media_cfg->pic_size[0]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
+ return TD_SUCCESS;
+}
+
+/*
+ * function : Start Vi/Vpss/Vo
+ */
+td_s32 sample_common_svp_npu_start_vi_vpss_vo(sample_vi_cfg *vi_cfg, ot_sample_svp_media_cfg *media_cfg,
+ sample_vo_cfg *vo_cfg)
+{
+ td_s32 ret;
+ const td_s32 vpss_grp_cnt = 1;
+ sample_sns_type sns_type = SENSOR0_TYPE;
+
+ ret = sample_common_svp_get_pic_type_by_sns_type(sns_type, media_cfg->pic_type, OT_SVP_MAX_VPSS_CHN_NUM);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "sample_common_svp_get_pic_type_by_sns_type failed!\n");
+ sample_comm_vi_get_default_vi_cfg(sns_type, vi_cfg);
+
+ ret = sample_common_svp_npu_get_pic_size(media_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x):sample_common_svp_npu_get_pic_size failed!\n", ret);
+
+ /* step 1: Init vb */
+ ret = sample_common_svp_create_vb(media_cfg);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_create_vb failed!\n", ret);
+
+ /* step 2: Start vi */
+ ret = sample_comm_vi_start_vi(vi_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_comm_vi_start_vi failed!\n", ret);
+
+ /* step 3: Bind vpss to vi */
+ ret = sample_common_svp_vi_bind_multi_vpss(vpss_grp_cnt, 1, 1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_2, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_vi_bind_multi_vpss failed!\n", ret);
+
+ /* step 4: Start vpss */
+ ret = sample_common_svp_start_vpss(vpss_grp_cnt, media_cfg->pic_size, media_cfg->chn_num);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_3, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
+
+ /* step 5: attach vb */
+ ret = sample_common_svp_vpss_attach_vb(media_cfg, vpss_grp_cnt);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
+
+ /* step 6: Start vo */
+ ret = sample_common_svp_start_vo(&(media_cfg->svp_switch), vo_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_5, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_start_vo failed!\n", ret);
+
+ return ret;
+
+end_init_5:
+ sample_common_svp_vpss_detach_vb(media_cfg, vpss_grp_cnt);
+end_init_4:
+ sample_common_svp_stop_vpss(vpss_grp_cnt, media_cfg->chn_num);
+end_init_3:
+ sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, 1, 1);
+end_init_2:
+ sample_comm_vi_stop_vi(vi_cfg);
+end_init_1:
+ sample_common_svp_destroy_vb(media_cfg);
+ return ret;
+}
+
+td_void sample_common_svp_destroy_vb_stop_vi_vpss_vo(sample_vi_cfg *vi_cfg, ot_sample_svp_media_cfg *media_cfg,
+ sample_vo_cfg *vo_cfg)
+{
+ const td_s32 vpss_grp_cnt = 1;
+
+ sample_svp_check_exps_return_void(media_cfg == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg is NULL!\n");
+
+ sample_svp_check_exps_return_void((media_cfg->chn_num == 0) || (media_cfg->chn_num > OT_SVP_MAX_VPSS_CHN_NUM),
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "media_cfg->chn_num must be [1, %u]!\n", OT_SVP_MAX_VPSS_CHN_NUM);
+
+ sample_common_svp_stop_vo(&(media_cfg->svp_switch), vo_cfg);
+ sample_common_svp_vpss_detach_vb(media_cfg, vpss_grp_cnt);
+ sample_common_svp_stop_vpss(vpss_grp_cnt, media_cfg->chn_num);
+ sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, 1, 1);
+ sample_comm_vi_stop_vi(vi_cfg);
+ sample_common_svp_destroy_vb(media_cfg);
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.h b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.h
new file mode 100755
index 0000000000000000000000000000000000000000..4ba556b17669a3b834ffea68f50343a60fc6d3ea
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp.h
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SAMPLE_COMMON_SVP_H
+#define SAMPLE_COMMON_SVP_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ss_mpi_sys.h"
+#include "ot_common.h"
+#include "ot_common_svp.h"
+#include "sample_comm.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C"{
+#endif
+#endif /* __cplusplus */
+
+#define OT_SVP_RECT_NUM 64
+#define OT_POINT_NUM 4
+#define OT_SVP_MAX_VPSS_CHN_NUM 2
+#define OT_SVP_TIMEOUT 2000
+
+typedef enum {
+ SAMPLE_SVP_ERR_LEVEL_DEBUG = 0x0, /* debug-level */
+ SAMPLE_SVP_ERR_LEVEL_INFO = 0x1, /* informational */
+ SAMPLE_SVP_ERR_LEVEL_NOTICE = 0x2, /* normal but significant condition */
+ SAMPLE_SVP_ERR_LEVEL_WARNING = 0x3, /* warning conditions */
+ SAMPLE_SVP_ERR_LEVEL_ERROR = 0x4, /* error conditions */
+ SAMPLE_SVP_ERR_LEVEL_CRIT = 0x5, /* critical conditions */
+ SAMPLE_SVP_ERR_LEVEL_ALERT = 0x6, /* action must be taken immediately */
+ SAMPLE_SVP_ERR_LEVEL_FATAL = 0x7, /* just for compatibility with previous version */
+
+ SAMPLE_SVP_ERR_LEVEL_BUTT
+} sample_svp_err_level;
+
+typedef struct {
+ ot_point point[OT_POINT_NUM];
+ td_float score;
+ td_u16 class_id;
+} ot_sample_svp_rect;
+
+typedef struct {
+ td_u16 num;
+ ot_sample_svp_rect rect[OT_SVP_RECT_NUM];
+} ot_sample_svp_rect_info;
+
+typedef struct {
+ td_bool is_venc_open;
+ td_bool is_vo_open;
+} ot_sample_svp_switch;
+
+typedef struct {
+ ot_sample_svp_switch svp_switch;
+ ot_size pic_size[OT_SVP_MAX_VPSS_CHN_NUM];
+ ot_pic_size pic_type[OT_SVP_MAX_VPSS_CHN_NUM];
+ ot_vb_pool vb_pool[OT_SVP_MAX_VPSS_CHN_NUM];
+ td_u32 chn_num;
+} ot_sample_svp_media_cfg;
+
+#define sample_svp_printf(level_str, msg, ...) \
+do { \
+ fprintf(stderr, "[level]:%s,[func]:%s [line]:%d [info]:"msg, level_str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+} while (0)
+
+#define sample_svp_printf_red(level_str, msg, ...) \
+do { \
+ fprintf(stderr, "\033[0;31m [level]:%s,[func]:%s [line]:%d [info]:"msg"\033[0;39m\n", level_str, __FUNCTION__, \
+ __LINE__, ##__VA_ARGS__); \
+} while (0)
+/* system is unusable */
+#define sample_svp_trace_fatal(msg, ...) sample_svp_printf_red("Fatal", msg, ##__VA_ARGS__)
+/* action must be taken immediately */
+#define sample_svp_trace_alert(msg, ...) sample_svp_printf_red("Alert", msg, ##__VA_ARGS__)
+/* critical conditions */
+#define sample_svp_trace_critical(msg, ...) sample_svp_printf_red("Critical", msg, ##__VA_ARGS__)
+/* error conditions */
+#define sample_svp_trace_err(msg, ...) sample_svp_printf_red("Error", msg, ##__VA_ARGS__)
+/* warning conditions */
+#define sample_svp_trace_warning(msg, ...) sample_svp_printf("Warning", msg, ##__VA_ARGS__)
+/* normal but significant condition */
+#define sample_svp_trace_notic(msg, ...) sample_svp_printf("Notice", msg, ##__VA_ARGS__)
+/* informational */
+#define sample_svp_trace_info(msg, ...) sample_svp_printf("Info", msg, ##__VA_ARGS__)
+/* debug-level messages */
+#define sample_svp_trace_debug(msg, ...) sample_svp_printf("Debug", msg, ##__VA_ARGS__)
+
+/* exps is true, goto */
+#define sample_svp_check_exps_goto(exps, label, level, msg, ...) \
+do { \
+ if ((exps)) { \
+ sample_svp_trace_err(msg, ## __VA_ARGS__); \
+ goto label; \
+ } \
+} while (0)
+/* exps is true, return td_void */
+#define sample_svp_check_exps_return_void(exps, level, msg, ...) \
+do { \
+ if ((exps)) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ return; \
+ } \
+} while (0)
+/* exps is true, return ret */
+#define sample_svp_check_exps_return(exps, ret, level, msg, ...) \
+do { \
+ if ((exps)) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ return (ret); \
+ } \
+} while (0) \
+/* exps is true, trace */
+#define sample_svp_check_exps_trace(exps, level, msg, ...) \
+do { \
+ if ((exps)) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#define sample_svp_check_exps_continue(exps, level, msg, ...) \
+do { \
+ if ((exps)) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ continue; \
+ } \
+} while (0) \
+
+/* exps is not success, trace */
+#define sample_svp_check_failed_trace(exps, level, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+/* exps is not success, goto */
+#define sample_svp_check_failed_goto(exps, label, level, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ## __VA_ARGS__); \
+ goto label; \
+ } \
+} while (0) \
+
+/* exps is not sucecss, return */
+#define sample_svp_check_failed_return(exps, ret, level, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ return (ret); \
+ } \
+} while (0)
+
+/* exps is not equal to success, goto with level SAMPLE_SVP_ERR_LEVEL_ERROR */
+#define sample_svp_check_failed_err_level_goto(exps, label, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ## __VA_ARGS__); \
+ goto label; \
+ } \
+} while (0)
+
+/* exps is not equal to success, return with level SAMPLE_SVP_ERR_LEVEL_ERROR */
+#define sample_svp_check_failed_err_level_return(exps, ret, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ## __VA_ARGS__); \
+ return (ret); \
+ } \
+} while (0)
+
+/* exps is not equal success, trace with level SAMPLE_SVP_ERR_LEVEL_ERROR */
+#define sample_svp_check_failed_err_level_trace(exps, msg, ...) \
+do { \
+ if ((exps) != TD_SUCCESS) { \
+ sample_svp_trace_err(msg, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#define sample_svp_pause() \
+do { \
+ printf("---------------press Enter key to exit!---------------\n"); \
+ (void)getchar(); \
+} while (0)
+
+#define SAMPLE_SVP_VB_POOL_NUM 2
+#define SAMPLE_SVP_ALIGN_16 16
+#define SAMPLE_SVP_ALIGN_32 32
+#define SAMPLE_SVP_D1_PAL_HEIGHT 576
+#define SAMPLE_SVP_D1_PAL_WIDTH 704
+#define sample_svp_convert_addr_to_ptr(type, addr) ((type *)(td_uintptr_t)(addr))
+#define sample_svp_convert_ptr_to_addr(type, addr) ((type)(td_uintptr_t)(addr))
+
+/* free mmz */
+#define sample_svp_mmz_free(phys, virt) \
+do { \
+ if (((phys) != 0) && ((virt) != 0)) { \
+ ss_mpi_sys_mmz_free((td_phys_addr_t)(phys), (td_void*)(td_uintptr_t)(virt)); \
+ (phys) = 0; \
+ (virt) = 0; \
+ } \
+} while (0)
+
+#define sample_svp_close_file(fp) \
+do { \
+ if ((fp) != TD_NULL) { \
+ fclose((fp)); \
+ (fp) = TD_NULL; \
+ } \
+} while (0)
+
+/* System init */
+td_s32 sample_common_svp_check_sys_init(td_bool vi_en);
+
+/* System exit */
+td_void sample_common_svp_check_sys_exit(td_void);
+
+/* Align */
+td_u32 sample_common_svp_align(td_u32 size, td_u16 align);
+
+/* Create mem info */
+td_s32 sample_common_svp_create_mem_info(ot_svp_mem_info *mem_info, td_u32 size, td_u32 addr_offsset);
+
+/* Destory mem info */
+td_void sample_common_svp_destroy_mem_info(ot_svp_mem_info *mem_info, td_u32 addr_offsset);
+
+/* Malloc memory */
+td_s32 sample_common_svp_malloc_mem(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
+ td_void **virt_addr, td_u32 size);
+
+/* Malloc memory with cached */
+td_s32 sample_common_svp_malloc_cached(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
+ td_void **virt_addr, td_u32 size);
+
+/* Fulsh cached */
+td_s32 sample_common_svp_flush_cache(td_phys_addr_t phys_addr, td_void *virt_addr, td_u32 size);
+
+/* function : Call vgs to fill rect */
+td_s32 sample_common_svp_vgs_fill_rect(const ot_video_frame_info *frame_info,
+ ot_sample_svp_rect_info *rect, td_u32 color);
+
+/* function : Start Vi/Vpss/Venc/Vo */
+td_s32 sample_common_svp_start_vi_vpss_venc_vo(sample_vi_cfg *vi_config,
+ ot_sample_svp_switch *switch_ptr, ot_pic_size *ext_pic_size_type);
+
+/* function : Stop Vi/Vpss/Venc/Vo */
+td_void sample_common_svp_stop_vi_vpss_venc_vo(sample_vi_cfg *vi_config,
+ ot_sample_svp_switch *switch_ptr);
+
+/*
+ * Start Vdec/Vpss/Vo
+ */
+td_s32 sample_common_svp_create_vb_start_vdec_vpss_vo(sample_vdec_attr *vdec_attr,
+ vdec_thread_param *vdec_send, pthread_t *vdec_thread, ot_sample_svp_media_cfg *media_cfg,
+ sample_vo_cfg *vo_cfg);
+/*
+ * Stop Vdec/Vpss/Vo
+ */
+td_void sample_common_svp_destroy_vb_stop_vdec_vpss_vo(vdec_thread_param *vdec_send,
+ pthread_t *vdec_thread, ot_sample_svp_media_cfg *media_cfg, sample_vo_cfg *vo_cfg);
+/*
+ * Send stream to venc/vo
+ */
+td_s32 sample_common_svp_venc_vo_send_stream(const ot_sample_svp_switch *vo_venc_switch,
+ ot_venc_chn venc_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn, const ot_video_frame_info *frame);
+
+td_s32 sample_common_svp_npu_start_vi_vpss_vo(sample_vi_cfg *vi_cfg, ot_sample_svp_media_cfg *media_cfg,
+ sample_vo_cfg *vo_cfg);
+
+td_void sample_common_svp_destroy_vb_stop_vi_vpss_vo(sample_vi_cfg *vi_cfg, ot_sample_svp_media_cfg *media_cfg,
+ sample_vo_cfg *vo_cfg);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+#endif /* SAMPLE_COMMON_SVP_H */
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.c
new file mode 100755
index 0000000000000000000000000000000000000000..64ae73c394907fe461c04bc7611bcce526affccf
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "sample_common_svp_npu.h"
+#include "ot_common.h"
+#include "ot_common_svp.h"
+#include "sample_comm.h"
+#include "sample_common_svp.h"
+
+/* acl init */
+ td_s32 sample_common_svp_npu_acl_init(const td_char *acl_config_path, td_s32 dev_id)
+{
+ svp_acl_rt_run_mode run_mode;
+ svp_acl_error ret;
+ /* svp acl init */
+ ret = svp_acl_init(acl_config_path);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "acl init failed!\n");
+ sample_svp_trace_info("svp acl init success!\n");
+ /* open device */
+ ret = svp_acl_rt_set_device(dev_id);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "svp acl open device %d failed!\n", dev_id);
+
+ sample_svp_trace_info("open device %d success!\n", dev_id);
+ /* get run mode */
+ ret = svp_acl_rt_get_run_mode(&run_mode);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "acl get run mode failed!\n");
+ sample_svp_check_exps_goto(run_mode != SVP_ACL_DEVICE, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "run mode(%d) is not equal to %d!\n", run_mode, SVP_ACL_DEVICE);
+
+ sample_svp_trace_info("get run mode success!\n");
+ return TD_SUCCESS;
+end_1:
+ (td_void)svp_acl_rt_reset_device(dev_id);
+end_0:
+ (td_void)svp_acl_finalize();
+ return TD_FAILURE;
+}
+
+/* acl deinit */
+td_void sample_common_svp_npu_acl_deinit(td_s32 dev_id)
+{
+ svp_acl_error ret;
+
+ ret = svp_acl_rt_reset_device(dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("reset device fail\n");
+ }
+ sample_svp_trace_info("end to reset device is %d\n", dev_id);
+
+ ret = svp_acl_finalize();
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("finalize acl fail\n");
+ }
+ sample_svp_trace_info("end to finalize acl\n");
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.h b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.h
new file mode 100755
index 0000000000000000000000000000000000000000..79c1e54cf7bdc1f99e3b78d8719b1a8d79b97138
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SAMPLE_COMMON_SVP_NPU_H
+#define SAMPLE_COMMON_SVP_NPU_H
+#include "ot_type.h"
+#include "svp_acl.h"
+#include "svp_acl_mdl.h"
+#include "xvp_common_osd.h"
+
+#define SAMPLE_SVP_NPU_MAX_THREAD_NUM 16
+#define SAMPLE_SVP_NPU_MAX_TASK_NUM 16
+#define SAMPLE_SVP_NPU_MAX_MODEL_NUM 1
+#define SAMPLE_SVP_NPU_EXTRA_INPUT_NUM 2
+#define SAMPLE_SVP_NPU_BYTE_BIT_NUM 8
+#define SAMPLE_SVP_NPU_SHOW_TOP_NUM 5
+#define SAMPLE_SVP_NPU_MAX_NAME_LEN 32
+#define SAMPLE_SVP_NPU_MAX_MEM_SIZE 0xFFFFFFFF
+#define SAMPLE_SVP_NPU_RECT_LEFT_TOP 0
+#define SAMPLE_SVP_NPU_RECT_RIGHT_TOP 1
+#define SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM 2
+#define SAMPLE_SVP_NPU_RECT_LEFT_BOTTOM 3
+#define SAMPLE_SVP_NPU_THRESHOLD_NUM 4
+
+#define SAMPLE_SVP_NPU_RFCN_THRESHOLD_NUM 2
+#define SAMPLE_SVP_NPU_AICPU_WAIT_TIME 1000
+#define SAMPLE_SVP_NPU_RECT_COLOR 0x0000FF00
+#define SAMPLE_SVP_NPU_MILLIC_SEC 20000
+#define SAMPLE_SVP_NPU_IMG_THREE_CHN 3
+#define SAMPLE_SVP_NPU_DOUBLE 2
+#define SAMPLE_SVP_NPU_YOLO_CLASS_NUM 80
+#define SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM 3
+#define SAMPLE_SVP_NPU_YOLO_SCALE_SIZE 3
+#define SAMPLE_SVP_NPU_YOLO_OUT_PARM_NUM 85
+#define SAMPLE_SVP_NPU_YOLO_CLASS_MEMBER_NUM 6
+#define SAMPLE_SVP_NPU_YOLO_SCORE_THRESHOLE 0.5
+
+typedef struct {
+ td_u32 model_id;
+ td_bool is_load_flag;
+ td_ulong model_mem_size;
+ td_void *model_mem_ptr;
+ svp_acl_mdl_desc *model_desc;
+ size_t input_num;
+ size_t output_num;
+ size_t dynamic_batch_idx;
+} sample_svp_npu_model_info;
+
+typedef struct {
+ td_u32 max_batch_num;
+ td_u32 dynamic_batch_num;
+ td_u32 total_t;
+ td_bool is_cached;
+ td_u32 model_idx;
+} sample_svp_npu_task_cfg;
+
+typedef struct {
+ sample_svp_npu_task_cfg cfg;
+ svp_acl_mdl_dataset *input_dataset;
+ svp_acl_mdl_dataset *output_dataset;
+ td_void *task_buf_ptr;
+ size_t task_buf_size;
+ size_t task_buf_stride;
+ td_void *work_buf_ptr;
+ size_t work_buf_size;
+ size_t work_buf_stride;
+} sample_svp_npu_task_info;
+
+typedef struct {
+ td_void *work_buf_ptr;
+ size_t work_buf_size;
+ size_t work_buf_stride;
+} sample_svp_npu_shared_work_buf;
+
+typedef struct {
+ td_float score;
+ td_u32 class_id;
+} sample_svp_npu_top_n_result;
+
+typedef struct {
+ td_char *num_name;
+ td_char *roi_name;
+ td_bool has_background;
+ td_u32 roi_offset;
+ td_bool is_cpu_rpn;
+ td_u32 idx;
+} sample_svp_npu_detection_info;
+
+typedef enum {
+ SAMPLE_SVP_NPU_RFCN = 0,
+ SAMPLE_SVP_NPU_YOLO = 1,
+ SAMPLE_SVP_NPU_HRNET = 2,
+ SAMPLE_SVP_NPU_MODEL_NAME_BUTT,
+} svp_npu_model_name;
+
+typedef struct {
+ svp_npu_model_name model_name;
+ sample_svp_npu_detection_info *detection_info;
+ sample_mpp_osd_info mpp_osd_info;
+} sample_svp_npu_thread_args;
+
+typedef struct {
+ td_char roi_num_name[SAMPLE_SVP_NPU_MAX_NAME_LEN];
+ td_char roi_class_name[SAMPLE_SVP_NPU_MAX_NAME_LEN];
+} sample_svp_npu_roi_info;
+
+typedef struct {
+ td_float nms_threshold;
+ td_float score_threshold;
+ td_float min_height;
+ td_float min_width;
+ td_char *name;
+} sample_svp_npu_threshold;
+
+typedef struct {
+ td_float score;
+ td_float xcenter;
+ td_float ycenter;
+ td_float w;
+ td_float h;
+ td_float class_id;
+} sample_svp_npu_valid_box;
+
+typedef struct {
+ td_float lx;
+ td_float ly;
+ td_float rx;
+ td_float ry;
+ td_float score;
+ td_float class_id;
+ td_float area;
+} sample_svp_npu_roi_box;
+
+typedef struct {
+ td_float *out_data;
+ size_t idx;
+ size_t w_stride_offset;
+ td_float score_thr;
+ td_u32 out_width;
+ td_u32 chn_step;
+ td_u32 out_height_idx;
+ td_u32 obj_score_offset;
+} sample_svp_npu_detection_inner_param;
+
+/* acl init */
+td_s32 sample_common_svp_npu_acl_init(const td_char *acl_config_path, td_s32 dev_id);
+/* acl deinit */
+td_void sample_common_svp_npu_acl_deinit(td_s32 dev_id);
+
+#endif
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.c
new file mode 100755
index 0000000000000000000000000000000000000000..73f0ec1cddf77a0415a7e0453398548dd110cb51
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.c
@@ -0,0 +1,1500 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include "svp_acl_rt.h"
+#include "svp_acl_ext.h"
+#include "sample_common_svp.h"
+#include "sample_common_svp_npu_model.h"
+
+#define SAMPLE_SVP_NPU_H_DIM_IDX 2
+#define SAMPLE_SVP_NPU_W_DIM_IDX 3
+#define SAMPLE_SVP_NPU_DIM_NUM 4
+static sample_svp_npu_model_info g_svp_npu_model[SAMPLE_SVP_NPU_MAX_MODEL_NUM] = {0};
+
+static td_s32 sample_svp_npu_get_model_base_info(td_u32 model_index)
+{
+ svp_acl_error ret;
+
+ g_svp_npu_model[model_index].input_num = svp_acl_mdl_get_num_inputs(g_svp_npu_model[model_index].model_desc);
+ sample_svp_check_exps_return(g_svp_npu_model[model_index].input_num < SAMPLE_SVP_NPU_EXTRA_INPUT_NUM + 1,
+ TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get input num failed!\n");
+
+ g_svp_npu_model[model_index].output_num = svp_acl_mdl_get_num_outputs(g_svp_npu_model[model_index].model_desc);
+ sample_svp_check_exps_return(g_svp_npu_model[model_index].output_num < 1,
+ TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get output num failed!\n");
+
+ ret = svp_acl_mdl_get_input_index_by_name(g_svp_npu_model[model_index].model_desc,
+ SVP_ACL_DYNAMIC_TENSOR_NAME, &g_svp_npu_model[model_index].dynamic_batch_idx);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get dynamic batch idx failed, model id is %u, error code is %d!\n", model_index, ret);
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_get_line_num_and_line_byte_num(const sample_svp_npu_task_info *task, td_u32 idx,
+ td_bool is_input, td_u32 *total_line_num, td_u32 *line_byte_num)
+{
+ td_s32 ret;
+ td_u32 i;
+ svp_acl_mdl_io_dims dims;
+ svp_acl_data_type data_type;
+ size_t data_size;
+
+ if (is_input == TD_TRUE) {
+ ret = svp_acl_mdl_get_input_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, idx, &dims);
+ } else {
+ ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, idx, &dims);
+ }
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th input/output dims failed!\n", idx);
+
+ if (is_input == TD_TRUE) {
+ data_type = svp_acl_mdl_get_input_data_type(g_svp_npu_model[task->cfg.model_idx].model_desc, idx);
+ } else {
+ data_type = svp_acl_mdl_get_output_data_type(g_svp_npu_model[task->cfg.model_idx].model_desc, idx);
+ }
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th input/output data type failed!\n", idx);
+
+ data_size = svp_acl_data_type_size(data_type);
+ sample_svp_check_exps_return(data_size == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get data size failed!\n");
+
+ *line_byte_num = dims.dims[dims.dim_count - 1] *
+ ((data_size + SAMPLE_SVP_NPU_BYTE_BIT_NUM - 1) / SAMPLE_SVP_NPU_BYTE_BIT_NUM);
+
+ *total_line_num = 1;
+ for (i = 0; i < dims.dim_count - 1; i++) {
+ *total_line_num *= dims.dims[i];
+ }
+ /* lstm xt line num */
+ if ((task->cfg.total_t != 0) && (idx == 0)) {
+ sample_svp_check_exps_return(task->cfg.total_t > dims.dims[0], TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "total t(%u) can't be greater than max total t(%ld)!\n", task->cfg.total_t, dims.dims[0]);
+ *total_line_num /= dims.dims[0];
+ *total_line_num *= task->cfg.total_t;
+ }
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_check_task_cfg(const sample_svp_npu_task_info *task)
+{
+ sample_svp_check_exps_return(task == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "task is NULL!\n");
+
+ sample_svp_check_exps_return(task->cfg.max_batch_num == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "max_batch_num(%u) is 0!\n", task->cfg.max_batch_num);
+
+ sample_svp_check_exps_return(task->cfg.dynamic_batch_num == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "dynamic_batch_num(%u) is 0!\n", task->cfg.dynamic_batch_num);
+
+ sample_svp_check_exps_return(task->cfg.total_t != 0 && task->cfg.dynamic_batch_num != 1, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "dynamic_batch_num(%u) should be 1 when total_t(%u) is not 0!\n",
+ task->cfg.dynamic_batch_num, task->cfg.total_t);
+
+ sample_svp_check_exps_return((task->cfg.is_cached != TD_TRUE && task->cfg.is_cached != TD_FALSE), TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "is_cached(%u) should be [%u, %u]!\n", task->cfg.is_cached, TD_FALSE, TD_TRUE);
+
+ sample_svp_check_exps_return(task->cfg.model_idx >= SAMPLE_SVP_NPU_MAX_MODEL_NUM, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "model_idx(%u) should be less than %u!\n",
+ task->cfg.model_idx, SAMPLE_SVP_NPU_MAX_MODEL_NUM);
+
+ sample_svp_check_exps_return(g_svp_npu_model[task->cfg.model_idx].model_desc == TD_NULL, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "%u-th model_desc is NULL!\n", task->cfg.model_idx);
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_get_input_data(const td_char *src[], td_u32 file_num,
+ const sample_svp_npu_task_info *task)
+{
+ td_s32 ret;
+ td_u32 i;
+ td_u32 line;
+ td_u32 total_line_num;
+ td_u32 line_byte_num;
+ td_char path[PATH_MAX] = { 0 };
+ size_t stride;
+ size_t size;
+ size_t input_num;
+ FILE *fp = TD_NULL;
+ td_void *data = TD_NULL;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(src == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "src is NULL!\n");
+
+ input_num = g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM;
+ sample_svp_check_exps_return(input_num != file_num, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "input file num(%u) should be equal to %lu!\n", file_num, input_num);
+
+ for (i = 0; i < file_num; i++) {
+ sample_svp_check_exps_return(realpath(src[i], path) == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Invalid file!\n");
+
+ fp = fopen(path, "rb");
+ sample_svp_check_exps_return(fp == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "open file failed!\n");
+
+ ret = sample_svp_npu_get_line_num_and_line_byte_num(task, i, TD_TRUE, &total_line_num, &line_byte_num);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, end, SAMPLE_SVP_ERR_LEVEL_ERROR, "get line num failed!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, i);
+ sample_svp_check_exps_goto(data_buffer == TD_NULL, end, SAMPLE_SVP_ERR_LEVEL_ERROR, "get data buffer NULL!\n");
+
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_goto(data == TD_NULL, end, SAMPLE_SVP_ERR_LEVEL_ERROR, "get data addr NULL!\n");
+
+ stride = svp_acl_get_data_buffer_stride(data_buffer);
+ sample_svp_check_exps_goto(stride == 0, end, SAMPLE_SVP_ERR_LEVEL_ERROR, "get data stride failed!\n");
+
+ size = svp_acl_get_data_buffer_size(data_buffer);
+ sample_svp_check_exps_goto(size < (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride, end,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "%u-th data buffer size(%lu) is less than needed(%llu)!\n",
+ i, size, (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride);
+
+ for (line = 0; line < task->cfg.dynamic_batch_num * total_line_num; line++) {
+ ret = fread(data + line * stride, line_byte_num, 1, fp);
+ sample_svp_check_exps_goto(ret != 1, end, SAMPLE_SVP_ERR_LEVEL_ERROR, "Read file failed!\n");
+ }
+ if (task->cfg.is_cached == TD_TRUE) {
+ (td_void)svp_acl_rt_mem_flush(data, task->cfg.dynamic_batch_num * total_line_num * stride);
+ }
+ (td_void)fclose(fp);
+ }
+ return TD_SUCCESS;
+
+end:
+ if (fp != TD_NULL) {
+ (td_void)fclose(fp);
+ }
+ return TD_FAILURE;
+}
+
+static td_s32 sample_svp_npu_read_model(const td_char *model_path, td_u32 model_index, td_bool is_cached)
+{
+ FILE *fp = TD_NULL;
+ td_s32 ret;
+
+ /* Get model file size */
+ fp = fopen(model_path, "rb");
+ sample_svp_check_exps_return(fp == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "open model file failed, model file is %s!\n", model_path);
+
+ ret = fseek(fp, 0L, SEEK_END);
+ sample_svp_check_exps_goto(ret == -1, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "fseek failed!\n");
+
+ g_svp_npu_model[model_index].model_mem_size = ftell(fp);
+ sample_svp_check_exps_goto(g_svp_npu_model[model_index].model_mem_size <= 0, end_0,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "ftell failed!\n");
+
+ ret = fseek(fp, 0L, SEEK_SET);
+ sample_svp_check_exps_goto(ret == -1, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "fseek failed!\n");
+
+ /* malloc model file mem */
+ if (is_cached == TD_TRUE) {
+ ret = svp_acl_rt_malloc_cached(&g_svp_npu_model[model_index].model_mem_ptr,
+ g_svp_npu_model[model_index].model_mem_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ } else {
+ ret = svp_acl_rt_malloc(&g_svp_npu_model[model_index].model_mem_ptr,
+ g_svp_npu_model[model_index].model_mem_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ }
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "malloc mem failed, erroe code %d!\n", ret);
+
+ ret = fread(g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size, 1, fp);
+ sample_svp_check_exps_goto(ret != 1, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR, "read model file failed!\n");
+
+ if (is_cached == TD_TRUE) {
+ ret = svp_acl_rt_mem_flush(g_svp_npu_model[model_index].model_mem_ptr,
+ g_svp_npu_model[model_index].model_mem_size);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "flush mem failed!, error code is %d\n", ret);
+ }
+ (td_void)fclose(fp);
+ return TD_SUCCESS;
+end_1:
+ (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr);
+end_0:
+ (td_void)fclose(fp);
+ return TD_FAILURE;
+}
+
+static td_s32 sample_svp_npu_create_desc(td_u32 model_index)
+{
+ svp_acl_error ret;
+
+ g_svp_npu_model[model_index].model_desc = svp_acl_mdl_create_desc();
+ sample_svp_check_exps_return(g_svp_npu_model[model_index].model_desc == TD_NULL, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "create model description failed!\n");
+
+ ret = svp_acl_mdl_get_desc(g_svp_npu_model[model_index].model_desc, g_svp_npu_model[model_index].model_id);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "get model description failed, error code is %d!\n", ret);
+
+ sample_svp_trace_info("create model description success!\n");
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_load_model(const td_char *model_path, td_u32 model_index, td_bool is_cached)
+{
+ td_s32 ret;
+
+ sample_svp_check_exps_return(g_svp_npu_model[model_index].is_load_flag == TD_TRUE, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "%u-th node has already loaded a model!\n", model_index);
+
+ ret = sample_svp_npu_read_model(model_path, model_index, is_cached);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "query model failed, model file is %s!\n", model_path);
+
+ ret = svp_acl_mdl_load_from_mem(g_svp_npu_model[model_index].model_mem_ptr,
+ g_svp_npu_model[model_index].model_mem_size, &g_svp_npu_model[model_index].model_id);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "load model from mem failed, error code is %d!\n", ret);
+
+ ret = sample_svp_npu_create_desc(model_index);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "create desc failed, model file is %s!\n", model_path);
+
+ ret = sample_svp_npu_get_model_base_info(model_index);
+ sample_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_1,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "get model base info failed, model file is %s!\n", model_path);
+
+ sample_svp_trace_info("load mem_size:%lu, id:%d!\n", g_svp_npu_model[model_index].model_mem_size,
+ g_svp_npu_model[model_index].model_id);
+
+ g_svp_npu_model[model_index].is_load_flag = TD_TRUE;
+ sample_svp_trace_info("load model %s success!\n", model_path);
+
+ return TD_SUCCESS;
+end_1:
+ (td_void)svp_acl_mdl_destroy_desc(g_svp_npu_model[model_index].model_desc);
+ g_svp_npu_model[model_index].model_desc = TD_NULL;
+end_0:
+ (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr);
+ g_svp_npu_model[model_index].model_mem_ptr = TD_NULL;
+ g_svp_npu_model[model_index].model_mem_size = 0;
+ return TD_FAILURE;
+}
+
+td_void sample_common_svp_npu_unload_model(td_u32 model_index)
+{
+ svp_acl_error ret;
+
+ sample_svp_check_exps_return_void(g_svp_npu_model[model_index].is_load_flag != TD_TRUE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "%u-th node has not loaded a model!\n", model_index);
+
+ ret = svp_acl_mdl_unload(g_svp_npu_model[model_index].model_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("unload model failed, model_id is %u, error code is %d!\n",
+ g_svp_npu_model[model_index].model_id, ret);
+ }
+
+ if (g_svp_npu_model[model_index].model_desc != TD_NULL) {
+ (td_void)svp_acl_mdl_destroy_desc(g_svp_npu_model[model_index].model_desc);
+ g_svp_npu_model[model_index].model_desc = TD_NULL;
+ }
+
+ if (g_svp_npu_model[model_index].model_mem_ptr != TD_NULL) {
+ (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr);
+ g_svp_npu_model[model_index].model_mem_ptr = TD_NULL;
+ g_svp_npu_model[model_index].model_mem_size = 0;
+ }
+
+ g_svp_npu_model[model_index].is_load_flag = TD_FALSE;
+ sample_svp_trace_info("unload model SUCCESS, model id is %u!\n", g_svp_npu_model[model_index].model_id);
+}
+
+static td_s32 sample_svp_npu_malloc_mem(td_void **buffer, td_u32 buffer_size, td_bool is_cached)
+{
+ svp_acl_error ret;
+
+ if (is_cached == TD_TRUE) {
+ ret = svp_acl_rt_malloc_cached(buffer, buffer_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ } else {
+ ret = svp_acl_rt_malloc(buffer, buffer_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ }
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "can't malloc buffer, size is %u, error code is %d!\n", buffer_size, ret);
+
+ (td_void)memset_s(*buffer, buffer_size, 0, buffer_size);
+ if (is_cached == TD_TRUE) {
+ (td_void)svp_acl_rt_mem_flush(*buffer, buffer_size);
+ }
+ return ret;
+}
+
+static td_void sample_svp_npu_destroy_data_buffer(svp_acl_data_buffer *input_data)
+{
+ td_void *data = svp_acl_get_data_buffer_addr(input_data);
+ (td_void)svp_acl_rt_free(data);
+ (td_void)svp_acl_destroy_data_buffer(input_data);
+}
+
+static svp_acl_data_buffer *sample_common_svp_npu_create_input_data_buffer(sample_svp_npu_task_info *task, td_u32 idx)
+{
+ size_t buffer_size;
+ size_t stride;
+ td_void *input_buffer = TD_NULL;
+ svp_acl_data_buffer *input_data = TD_NULL;
+
+ stride = svp_acl_mdl_get_input_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, idx);
+ sample_svp_check_exps_return(stride == 0, input_data, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th input stride failed!\n", idx);
+
+ buffer_size = svp_acl_mdl_get_input_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc, idx) *
+ (td_u64)task->cfg.max_batch_num;
+ sample_svp_check_exps_return((buffer_size == 0 || buffer_size > SAMPLE_SVP_NPU_MAX_MEM_SIZE), input_data,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "buffer_size(%lu) can't be 0 and should be less than %u!\n",
+ buffer_size, SAMPLE_SVP_NPU_MAX_MEM_SIZE);
+
+ if (sample_svp_npu_malloc_mem(&input_buffer, (td_u32)buffer_size, task->cfg.is_cached) != TD_SUCCESS) {
+ sample_svp_trace_err("%u-th input malloc mem failed!\n", idx);
+ return input_data;
+ }
+
+ input_data = svp_acl_create_data_buffer(input_buffer, buffer_size, stride);
+ if (input_data == TD_NULL) {
+ sample_svp_trace_err("can't create %u-th input data buffer!\n", idx);
+ (td_void)svp_acl_rt_free(input_buffer);
+ return input_data;
+ }
+ if (idx == g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM) {
+ task->task_buf_ptr = input_buffer;
+ task->task_buf_size = buffer_size;
+ task->task_buf_stride = stride;
+ } else if (idx == g_svp_npu_model[task->cfg.model_idx].input_num - 1) {
+ task->work_buf_ptr = input_buffer;
+ task->work_buf_size = buffer_size;
+ task->work_buf_stride = stride;
+ }
+ return input_data;
+}
+
+static svp_acl_data_buffer *sample_common_svp_npu_create_output_data_buffer(const sample_svp_npu_task_info *task,
+ td_u32 idx)
+{
+ size_t buffer_size;
+ size_t stride;
+ td_void *output_buffer = TD_NULL;
+ svp_acl_data_buffer *output_data = TD_NULL;
+
+ stride = svp_acl_mdl_get_output_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, idx);
+ sample_svp_check_exps_return(stride == 0, output_data, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th output stride failed!\n", idx);
+
+ buffer_size = svp_acl_mdl_get_output_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc, idx) *
+ (td_u64)task->cfg.max_batch_num;
+ sample_svp_check_exps_return((buffer_size == 0 || buffer_size > SAMPLE_SVP_NPU_MAX_MEM_SIZE), output_data,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "buffer_size(%lu) can't be 0 and should be less than %u!\n",
+ buffer_size, SAMPLE_SVP_NPU_MAX_MEM_SIZE);
+
+ if (sample_svp_npu_malloc_mem(&output_buffer, buffer_size, task->cfg.is_cached) != TD_SUCCESS) {
+ sample_svp_trace_err("%u-th output malloc mem failed!\n", idx);
+ return output_data;
+ }
+
+ output_data = svp_acl_create_data_buffer(output_buffer, buffer_size, stride);
+ if (output_data == TD_NULL) {
+ sample_svp_trace_err("can't create %u-th output data buffer!\n", idx);
+ (td_void)svp_acl_rt_free(output_buffer);
+ return output_data;
+ }
+ return output_data;
+}
+
+td_s32 sample_common_svp_npu_create_input(sample_svp_npu_task_info *task)
+{
+ svp_acl_error ret;
+ td_u32 i;
+ svp_acl_data_buffer *input_data = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ task->input_dataset = svp_acl_mdl_create_dataset();
+ sample_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create input dataset failed!\n");
+
+ for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM; i++) {
+ input_data = sample_common_svp_npu_create_input_data_buffer(task, i);
+ if (input_data == TD_NULL) {
+ sample_svp_trace_err("create %u-th input data buffer failed!\n", i);
+ (td_void)sample_common_svp_npu_destroy_input(task);
+ return TD_FAILURE;
+ }
+
+ ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, input_data);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("add %u-th input data buffer failed!\n", i);
+ (td_void)sample_svp_npu_destroy_data_buffer(input_data);
+ (td_void)sample_common_svp_npu_destroy_input(task);
+ return TD_FAILURE;
+ }
+ }
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_create_output(sample_svp_npu_task_info *task)
+{
+ svp_acl_error ret;
+ td_u32 i;
+ svp_acl_data_buffer *output_data = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ task->output_dataset = svp_acl_mdl_create_dataset();
+ sample_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create output dataset failed!\n");
+
+ for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].output_num; i++) {
+ output_data = sample_common_svp_npu_create_output_data_buffer(task, i);
+ if (output_data == TD_NULL) {
+ sample_svp_trace_err("create %u-th output data buffer failed!\n", i);
+ (td_void)sample_common_svp_npu_destroy_input(task);
+ return TD_FAILURE;
+ }
+ ret = svp_acl_mdl_add_dataset_buffer(task->output_dataset, output_data);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("add %u-th output data buffer failed!\n", i);
+ (td_void)sample_svp_npu_destroy_data_buffer(output_data);
+ (td_void)sample_common_svp_npu_destroy_output(task);
+ return TD_FAILURE;
+ }
+ }
+
+ return TD_SUCCESS;
+}
+
+td_void sample_common_svp_npu_destroy_input(sample_svp_npu_task_info *task)
+{
+ td_u32 i;
+ size_t input_num;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_void *data = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ if (task->input_dataset == TD_NULL) {
+ return;
+ }
+
+ input_num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset);
+ for (i = 0; i < input_num; i++) {
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, i);
+ if (i < g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM) {
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ (td_void)svp_acl_rt_free(data);
+ }
+ (td_void)svp_acl_destroy_data_buffer(data_buffer);
+ }
+ (td_void)svp_acl_mdl_destroy_dataset(task->input_dataset);
+ task->input_dataset = TD_NULL;
+}
+
+td_void sample_common_svp_npu_destroy_output(sample_svp_npu_task_info *task)
+{
+ td_u32 i;
+ size_t output_num;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_void *data = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ if (task->output_dataset == TD_NULL) {
+ return;
+ }
+
+ output_num = svp_acl_mdl_get_dataset_num_buffers(task->output_dataset);
+
+ for (i = 0; i < output_num; i++) {
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i);
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ (td_void)svp_acl_rt_free(data);
+ (td_void)svp_acl_destroy_data_buffer(data_buffer);
+ }
+
+ (td_void)svp_acl_mdl_destroy_dataset(task->output_dataset);
+ task->output_dataset = TD_NULL;
+}
+
+td_void sample_common_svp_npu_destroy_task_buf(sample_svp_npu_task_info *task)
+{
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ if (task->task_buf_ptr == TD_NULL) {
+ return;
+ }
+ (td_void)svp_acl_rt_free(task->task_buf_ptr);
+ task->task_buf_ptr = TD_NULL;
+ task->task_buf_stride = 0;
+ task->task_buf_size = 0;
+}
+
+td_void sample_common_svp_npu_destroy_work_buf(sample_svp_npu_task_info *task)
+{
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ if (task->work_buf_ptr == TD_NULL) {
+ return;
+ }
+ (td_void)svp_acl_rt_free(task->work_buf_ptr);
+ task->work_buf_ptr = TD_NULL;
+ task->work_buf_stride = 0;
+ task->work_buf_size = 0;
+}
+
+td_s32 sample_common_svp_npu_create_task_buf(sample_svp_npu_task_info *task)
+{
+ size_t num;
+ svp_acl_data_buffer *task_buf = TD_NULL;
+ svp_acl_error ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "input_dataset is NULL!\n");
+
+ num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset);
+ sample_svp_check_exps_return(num != g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM,
+ TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "num of data buffer(%lu) should be %lu when create task buf!\n",
+ num, g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM);
+
+ task_buf = sample_common_svp_npu_create_input_data_buffer(task,
+ g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM);
+ sample_svp_check_exps_return(task_buf == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create task buf failed!\n");
+
+ ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, task_buf);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("add task buf failed!\n");
+ (td_void)sample_svp_npu_destroy_data_buffer(task_buf);
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_create_work_buf(sample_svp_npu_task_info *task)
+{
+ size_t num;
+ svp_acl_data_buffer *work_buf = TD_NULL;
+ svp_acl_error ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ sample_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "input_dataset is NULL!\n");
+
+ num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset);
+ sample_svp_check_exps_return(num != g_svp_npu_model[task->cfg.model_idx].input_num - 1,
+ TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "num of data buffer(%lu) should be %lu when create work buf!\n",
+ num, g_svp_npu_model[task->cfg.model_idx].input_num - 1);
+
+ work_buf = sample_common_svp_npu_create_input_data_buffer(task, g_svp_npu_model[task->cfg.model_idx].input_num - 1);
+ sample_svp_check_exps_return(work_buf == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create work buf failed!\n");
+
+ ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, work_buf);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("add work buf failed!\n");
+ (td_void)sample_svp_npu_destroy_data_buffer(work_buf);
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_get_work_buf_info(const sample_svp_npu_task_info *task,
+ td_u32 *work_buf_size, td_u32 *work_buf_stride)
+{
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ *work_buf_stride = (td_u32)svp_acl_mdl_get_input_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc,
+ g_svp_npu_model[task->cfg.model_idx].input_num - 1);
+ if (*work_buf_stride == 0) {
+ sample_svp_trace_err("get work buf stride failed!\n");
+ return TD_FAILURE;
+ }
+
+ *work_buf_size = (td_u32)svp_acl_mdl_get_input_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc,
+ g_svp_npu_model[task->cfg.model_idx].input_num - 1);
+ if (*work_buf_size == 0) {
+ sample_svp_trace_err("get work buf size failed!\n");
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_share_work_buf(const sample_svp_npu_shared_work_buf *shared_work_buf,
+ const sample_svp_npu_task_info *task)
+{
+ svp_acl_error ret;
+ svp_acl_data_buffer *work_buf = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ sample_svp_check_exps_return(shared_work_buf == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "shared_work_buf is NULL!\n");
+
+ sample_svp_check_exps_return(shared_work_buf->work_buf_ptr == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "work_buf_ptr is NULL!\n");
+
+ sample_svp_check_exps_return(task->work_buf_ptr != TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "task has created work buf!\n");
+
+ work_buf = svp_acl_create_data_buffer(shared_work_buf->work_buf_ptr, shared_work_buf->work_buf_size,
+ shared_work_buf->work_buf_stride);
+ sample_svp_check_exps_return(work_buf == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create work buf failed!\n");
+
+ ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, work_buf);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("add work buf failed!\n");
+ (td_void)svp_acl_destroy_data_buffer(work_buf);
+ return TD_FAILURE;
+ }
+
+ return TD_SUCCESS;
+}
+
+/* print the top n confidence values with indexes */
+static td_void sample_svp_npu_sort_output_result(const td_float *src, td_u32 src_len,
+ sample_svp_npu_top_n_result *dst, td_u32 dst_len)
+{
+ td_u32 i;
+ td_u32 j;
+ td_u32 index;
+ td_bool charge;
+
+ for (i = 0; i < src_len; i++) {
+ charge = TD_FALSE;
+
+ for (j = 0; j < dst_len; j++) {
+ if (src[i] > dst[j].score) {
+ index = j;
+ charge = TD_TRUE;
+ break;
+ }
+ }
+
+ if (charge == TD_TRUE) {
+ for (j = dst_len - 1; j > index; j--) {
+ dst[j].score = dst[j - 1].score;
+ dst[j].class_id = dst[j - 1].class_id;
+ }
+ dst[index].score = src[i];
+ dst[index].class_id = i;
+ }
+ }
+}
+
+td_void sample_common_svp_npu_output_classification_result(const sample_svp_npu_task_info *task)
+{
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_void *data = TD_NULL;
+ td_u32 i;
+ td_u32 j;
+ td_u32 n;
+ svp_acl_error ret;
+ size_t stride;
+ svp_acl_mdl_io_dims dims;
+ sample_svp_npu_top_n_result top[SAMPLE_SVP_NPU_SHOW_TOP_NUM] = { 0 };
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ sample_svp_check_exps_return_void(task->output_dataset == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "task->output_dataset is NULL!\n");
+
+ for (i = 0; i < svp_acl_mdl_get_dataset_num_buffers(task->output_dataset); i++) {
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i);
+ sample_svp_check_exps_return_void(data_buffer == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data buffer is NULL!\n", i);
+
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return_void(data == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data addr is NULL!\n", i);
+
+ stride = svp_acl_get_data_buffer_stride(data_buffer);
+ sample_svp_check_exps_return_void(data == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data stride is 0!\n", i);
+
+ ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, i, &dims);
+ sample_svp_check_exps_return_void(data == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th output dims failed, error code is %d!\n", i, ret);
+
+ for (n = 0; n < task->cfg.dynamic_batch_num; n++) {
+ (td_void)sample_svp_npu_sort_output_result(data, (td_u32)dims.dims[dims.dim_count - 1],
+ top, SAMPLE_SVP_NPU_SHOW_TOP_NUM);
+ sample_svp_trace_info("%u-th batch result:\n", n);
+ for (j = 0; j < SAMPLE_SVP_NPU_SHOW_TOP_NUM; j++) {
+ sample_svp_trace_info("top %d: value[%lf], class_id[%u]!\n", j, top[j].score, top[j].class_id);
+ }
+ data += stride;
+ (td_void)memset_s(top, sizeof(top), 0, sizeof(top));
+ }
+ }
+
+ sample_svp_trace_info("output data success!\n");
+}
+
+td_s32 sample_common_svp_npu_set_dynamic_batch(const sample_svp_npu_task_info *task)
+{
+ svp_acl_error ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ ret = svp_acl_mdl_set_dynamic_batch_size(g_svp_npu_model[task->cfg.model_idx].model_id,
+ task->input_dataset, g_svp_npu_model[task->cfg.model_idx].dynamic_batch_idx, task->cfg.dynamic_batch_num);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "set dynamic batch size failed, model id is %u, error code is %d!\n",
+ g_svp_npu_model[task->cfg.model_idx].model_id, ret);
+
+ if (task->cfg.total_t != 0) {
+ ret = svp_acl_mdl_set_total_t(g_svp_npu_model[task->cfg.model_idx].model_id,
+ task->input_dataset, task->cfg.total_t);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "set total_t failed, model id is %u, error code is %d!\n",
+ g_svp_npu_model[task->cfg.model_idx].model_id, ret);
+ }
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_model_execute(const sample_svp_npu_task_info *task)
+{
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_void *data = TD_NULL;
+ size_t size;
+ td_u32 i;
+ svp_acl_error ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+
+ ret = svp_acl_mdl_execute(g_svp_npu_model[task->cfg.model_idx].model_id, task->input_dataset, task->output_dataset);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "svp_acl_mdl_execute failed, model_id is %u, error code is %d!\n",
+ g_svp_npu_model[task->cfg.model_idx].model_id, ret);
+
+ if (task->cfg.is_cached == TD_TRUE) {
+ for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].output_num; i++) {
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th output data_buffer is NULL!\n", i);
+
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return(data == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th output data is NULL!\n", i);
+
+ size = svp_acl_get_data_buffer_size(data_buffer) / task->cfg.max_batch_num * task->cfg.dynamic_batch_num;
+ sample_svp_check_exps_return(size == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th output data size is 0!\n", i);
+
+ ret = svp_acl_rt_mem_flush(data, size);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "flush %u-th output data failed, error code is %d!\n", i, ret);
+ }
+ }
+ return ret;
+}
+
+static td_void sample_svp_npu_dump_dataset(const sample_svp_npu_task_info *task, const td_char *file_name,
+ td_bool is_input)
+{
+ td_u32 i;
+ td_u32 line;
+ td_u32 total_line_num;
+ td_u32 line_byte_num;
+ td_u32 data_num;
+ svp_acl_error ret;
+ size_t size;
+ size_t stride;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ svp_acl_mdl_dataset *dataset = TD_NULL;
+ td_void *data = TD_NULL;
+ FILE *fp = TD_NULL;
+ td_char name[SAMPLE_SVP_NPU_MAX_NAME_LEN] = {'\0'};
+
+ data_num = is_input == TD_TRUE ? g_svp_npu_model[task->cfg.model_idx].input_num - SAMPLE_SVP_NPU_EXTRA_INPUT_NUM :
+ g_svp_npu_model[task->cfg.model_idx].output_num;
+ dataset = is_input == TD_TRUE ? task->input_dataset : task->output_dataset;
+
+ for (i = 0; i < data_num; i++) {
+ ret = sample_svp_npu_get_line_num_and_line_byte_num(task, i, is_input, &total_line_num, &line_byte_num);
+ sample_svp_check_exps_return_void(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get line num and line byte num failed!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(dataset, i);
+ sample_svp_check_exps_return_void(data_buffer == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data_buffer failed!\n", i);
+
+ data = svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return_void(data == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data addr failed!\n", i);
+
+ stride = svp_acl_get_data_buffer_stride(data_buffer);
+ sample_svp_check_exps_return_void(stride == 0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data stride failed!\n", i);
+
+ size = svp_acl_get_data_buffer_size(data_buffer);
+ sample_svp_check_exps_return_void(size == 0, SAMPLE_SVP_ERR_LEVEL_ERROR, "get %u-th data size failed!\n", i);
+
+ sample_svp_check_exps_return_void(size < (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "%u-th data buffer size(%lu) is less than needed(%llu)!\n",
+ i, size, (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride);
+
+ ret = snprintf_s(name, SAMPLE_SVP_NPU_MAX_NAME_LEN - 1, SAMPLE_SVP_NPU_MAX_NAME_LEN - 1, file_name, i);
+ sample_svp_check_exps_return_void(ret < 0, SAMPLE_SVP_ERR_LEVEL_ERROR, "create file name failed!\n");
+
+ fp = fopen(name, "wb");
+ sample_svp_check_exps_return_void(fp == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "open file failed!\n");
+
+ for (line = 0; line < task->cfg.dynamic_batch_num * total_line_num; line++) {
+ ret = fwrite(data, line_byte_num, 1, fp);
+ if (ret != 1) {
+ fclose(fp);
+ sample_svp_check_exps_return_void(ret != 1, SAMPLE_SVP_ERR_LEVEL_ERROR, "write file failed!\n");
+ }
+ data += stride;
+ }
+ (td_void)fclose(fp);
+ }
+}
+
+td_void sample_common_svp_npu_dump_task_data(const sample_svp_npu_task_info *task)
+{
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return;
+ }
+
+ sample_svp_check_exps_return_void(task->input_dataset == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "task->input_dataset is NULL!\n");
+ sample_svp_check_exps_return_void(task->output_dataset == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "task->input_dataset is NULL!\n");
+
+ (td_void)sample_svp_npu_dump_dataset(task, "input_%u.bin", TD_TRUE);
+ (td_void)sample_svp_npu_dump_dataset(task, "output_%u.bin", TD_FALSE);
+}
+
+td_s32 sample_common_svp_npu_update_input_data_buffer_info(td_u8 *virt_addr, td_u32 size, td_u32 stride, td_u32 idx,
+ const sample_svp_npu_task_info *task)
+{
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ svp_acl_error ret;
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th data_buffer failed!\n", idx);
+ ret = svp_acl_update_data_buffer(data_buffer, (td_void *)virt_addr, size, stride);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "update data buffer failed!\n");
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_get_input_data_buffer_info(const sample_svp_npu_task_info *task, td_u32 idx,
+ td_u8 **virt_addr, td_u32 *size, td_u32 *stride)
+{
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(virt_addr == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr is NULL!\n");
+ sample_svp_check_exps_return(size == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "size is NULL!\n");
+ sample_svp_check_exps_return(stride == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "size is NULL!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get 0-th data_buffer failed!\n");
+ *size = (td_u32)svp_acl_get_data_buffer_size(data_buffer);
+ *stride = (td_u32)svp_acl_get_data_buffer_stride(data_buffer);
+ *virt_addr = (td_u8 *)svp_acl_get_data_buffer_addr(data_buffer);
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_get_roi_num(const sample_svp_npu_task_info *task, sample_svp_npu_detection_info *info,
+ ot_sample_svp_rect_info *rect_info)
+{
+ svp_acl_error ret;
+ size_t num_idx;
+ svp_acl_mdl_io_dims dims;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_float *data = TD_NULL;
+ td_float total_num = 0.0;
+ td_u32 start = 0;
+ td_u32 i;
+
+ ret = svp_acl_mdl_get_output_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc,
+ info->num_name, &num_idx);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get num idx failed!\n");
+
+ ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, num_idx, &dims);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get num dims failed!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, num_idx);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get num data_buffer is NULL!\n");
+
+ data = (td_float *)svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return(data == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get num data is NULL!\n");
+
+ if (info->has_background == TD_TRUE) {
+ info->roi_offset = (td_u32)(*data);
+ start++;
+ }
+
+ for (i = start; i < dims.dims[dims.dim_count - 1]; i++) {
+ total_num += *(data + i);
+ }
+ rect_info->num = (td_u32)total_num;
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_get_roi(const sample_svp_npu_task_info *task, const sample_svp_npu_detection_info *info,
+ const ot_video_frame_info *proc_frame, const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info)
+{
+ svp_acl_error ret;
+ size_t roi_idx;
+ size_t stride;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_float *x_min = TD_NULL;
+ td_float *y_min = TD_NULL;
+ td_float *x_max = TD_NULL;
+ td_float *y_max = TD_NULL;
+ td_float *score = TD_NULL;
+ td_float *class_id = TD_NULL;
+ td_u32 roi_offset = info->roi_offset;
+ td_u32 i;
+
+ ret = svp_acl_mdl_get_output_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc,
+ info->roi_name, &roi_idx);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi idx failed!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, roi_idx);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi data_buffer is NULL!\n");
+
+ stride = svp_acl_get_data_buffer_stride(data_buffer);
+ sample_svp_check_exps_return(stride == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get roi stride is 0!\n");
+
+ x_min = (td_float *)svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return(x_min == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "get roi data is NULL!\n");
+ y_min = x_min + stride / sizeof(td_float);
+ x_max = y_min + stride / sizeof(td_float);
+ y_max = x_max + stride / sizeof(td_float);
+ score = y_max + stride / sizeof(td_float);
+ class_id = score + stride / sizeof(td_float);
+
+ for (i = 0; i < rect_info->num; i++) {
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].x = (td_u32)((td_float)x_min[roi_offset] /
+ proc_frame->video_frame.width * show_frame->video_frame.width) & (~1);
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].y = (td_u32)((td_float)y_min[roi_offset] /
+ proc_frame->video_frame.height * show_frame->video_frame.height) & (~1);
+
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].x = (td_u32)((td_float)x_max[roi_offset] /
+ proc_frame->video_frame.width * show_frame->video_frame.width) & (~1);
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].y =
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].y;
+
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].x =
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].x;
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].y = (td_u32)((td_float)y_max[roi_offset] /
+ proc_frame->video_frame.height * show_frame->video_frame.height) & (~1);
+
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_BOTTOM].x =
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].x;
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_LEFT_BOTTOM].y =
+ rect_info->rect[i].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].y;
+
+ rect_info->rect[i].score = (td_float)((td_float)score[roi_offset]);
+ rect_info->rect[i].class_id = (td_u16)((td_float)class_id[roi_offset]);
+
+ roi_offset++;
+ }
+ return TD_SUCCESS;
+}
+
+static td_float sample_svp_npu_calc_iou(const sample_svp_npu_roi_box* box1, const sample_svp_npu_roi_box* box2)
+{
+ td_float area1 = box1->area;
+ td_float area2 = box2->area;
+ td_float xx1 = (box1->lx > box2->lx) ? box1->lx : box2->lx;
+ td_float yy1 = (box1->ly > box2->ly) ? box1->ly : box2->ly;
+ td_float xx2 = (box1->rx < box2->rx) ? box1->rx : box2->rx;
+ td_float yy2 = (box1->ry < box2->ry) ? box1->ry : box2->ry;
+ td_float w = (0.0f > (xx2 - xx1 + 1)) ? 0.0f : (xx2 - xx1 + 1);
+ td_float h = (0.0f > (yy2 - yy1 + 1)) ? 0.0f : (yy2 - yy1 + 1);
+ td_float inter = w * h;
+ td_float ovr = inter /(area1 + area2 - inter);
+ return ovr;
+}
+
+static td_void sample_svp_npu_multiclass_nms(sample_svp_npu_roi_box *roi_box, td_u32 *roi_box_num,
+ sample_svp_npu_valid_box* valid_box, td_u32 valid_box_num)
+{
+ float nms_thr = 0.45; /* 0.45: threshold of ROI */
+ for (td_u32 i = 0; i < valid_box_num; i++) {
+ sample_svp_npu_valid_box *item = &valid_box[i];
+ td_float box_x_center = item->xcenter;
+ td_float box_y_center = item->ycenter;
+ td_float box_width = item->w;
+ td_float box_height = item->h;
+
+ td_float x1 = (box_x_center - box_width / 2);
+ td_float y1 = (box_y_center - box_height / 2);
+ td_float x2 = (box_x_center + box_width / 2);
+ td_float y2 = (box_y_center + box_height / 2);
+ td_float area = (x2 - x1 + 1) * (y2 - y1 + 1);
+ td_bool keep = TD_TRUE;
+ /* lx, ly, rx, ry, score, class id, area */
+ sample_svp_npu_roi_box box = {x1, y1, x2, y2, item->score, item->class_id, area};
+ for (td_u32 j = 0; j < *roi_box_num; j++) {
+ if (sample_svp_npu_calc_iou(&box, &roi_box[j]) > nms_thr) {
+ keep = TD_FALSE;
+ break;
+ }
+ }
+ if (keep) {
+ if (*roi_box_num >= OT_SVP_RECT_NUM) {
+ sample_svp_trace_err("roi_box_num [%u] is large than %u!\n", *roi_box_num, OT_SVP_RECT_NUM);
+ return;
+ }
+ roi_box[*roi_box_num].lx = box.lx;
+ roi_box[*roi_box_num].ly = box.ly;
+ roi_box[*roi_box_num].rx = box.rx;
+ roi_box[*roi_box_num].ry = box.ry;
+ roi_box[*roi_box_num].score = box.score;
+ roi_box[*roi_box_num].class_id = box.class_id;
+ roi_box[*roi_box_num].area = box.area;
+ *roi_box_num = *roi_box_num + 1;
+ }
+ }
+}
+
+inline static td_float sample_svp_npu_sig_mod(td_float a)
+{
+ return 1.0f / (1.0f + exp(-a));
+}
+
+static td_void sample_svp_npu_get_max_score_and_idx(td_u32 obj_score_idx, td_u32 chn_step, const td_float* out_data,
+ td_float *max_cls_score, td_u32 *max_cls_id)
+{
+ td_u32 cls_score_idx = obj_score_idx + chn_step;
+ for (td_u32 c = 0; c < SAMPLE_SVP_NPU_YOLO_CLASS_NUM; c++) {
+ td_float cls_score_val = out_data[cls_score_idx];
+ if (cls_score_val > *max_cls_score) {
+ *max_cls_score = cls_score_val;
+ *max_cls_id = c;
+ }
+ cls_score_idx += chn_step;
+ }
+}
+static td_u32 g_sample_svp_npu_anchor_grids[SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM][SAMPLE_SVP_NPU_YOLO_CLASS_MEMBER_NUM] = {
+ {116, 90, 156, 198, 373, 326},
+ {30, 61, 62, 45, 59, 119},
+ {10, 13, 16, 30, 33, 23}
+};
+
+static td_void sample_svp_npu_process_per_dectection_inner(const sample_svp_npu_detection_inner_param *inner_param,
+ td_float *grids_x, td_float *grids_y, sample_svp_npu_valid_box* valid_box, td_u32 *valid_box_num)
+{
+ td_float box_hieght;
+ td_u32 expanded_strides[SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM] = { 32, 16, 8 };
+ td_u32 out_height_idx = inner_param->out_height_idx;
+ td_u32 chn_step = inner_param->chn_step;
+ td_float score_thr = inner_param->score_thr;
+ td_float *out_data = inner_param->out_data;
+ size_t w_stride_offset = inner_param->w_stride_offset;
+ td_u32 obj_score_offset = inner_param->obj_score_offset;
+ td_u32 offset = out_height_idx * inner_param->w_stride_offset;
+ for (td_u32 j = 0; j < inner_param->out_width; j++) {
+ for (td_u32 k = 0; k < SAMPLE_SVP_NPU_YOLO_SCALE_SIZE; k++) {
+ offset = j + out_height_idx * w_stride_offset + k * chn_step * SAMPLE_SVP_NPU_YOLO_OUT_PARM_NUM;
+ td_u32 obj_score_idx = offset + obj_score_offset;
+ td_float obj_score_val = sample_svp_npu_sig_mod(out_data[obj_score_idx]);
+ if (obj_score_val <= score_thr) {
+ continue;
+ }
+ if (*valid_box_num >= OT_SVP_RECT_NUM) {
+ sample_svp_trace_err("valid_box_num [%u] is large than %u!\n", *valid_box_num, OT_SVP_RECT_NUM);
+ return;
+ }
+ /* max score */
+ td_float max_cls_score = 0.0f;
+ td_u32 max_cls_id = 0;
+ sample_svp_npu_get_max_score_and_idx(obj_score_idx, chn_step, out_data, &max_cls_score, &max_cls_id);
+
+ td_float confidence_score = sample_svp_npu_sig_mod(max_cls_score) * obj_score_val;
+ if (confidence_score > score_thr) {
+ /* gen box info */
+ td_u32 x_center_idx = offset;
+ td_u32 y_center_idx = x_center_idx + chn_step;
+ td_u32 box_width_idx = y_center_idx + chn_step;
+ td_u32 box_height_idx = box_width_idx + chn_step;
+ td_float x_center = (sample_svp_npu_sig_mod(out_data[x_center_idx]) * SAMPLE_SVP_NPU_DOUBLE +
+ grids_x[j]) * expanded_strides[inner_param->idx];
+ td_float y_center = (sample_svp_npu_sig_mod(out_data[y_center_idx]) * SAMPLE_SVP_NPU_DOUBLE +
+ grids_y[out_height_idx]) * expanded_strides[inner_param->idx];
+ td_float tmp_value = sample_svp_npu_sig_mod(out_data[box_width_idx]) * SAMPLE_SVP_NPU_DOUBLE;
+ td_float box_width = tmp_value * tmp_value * g_sample_svp_npu_anchor_grids[inner_param->idx][(k << 1)];
+ tmp_value = sample_svp_npu_sig_mod(out_data[box_height_idx]) * SAMPLE_SVP_NPU_DOUBLE;
+ box_hieght = tmp_value * tmp_value * g_sample_svp_npu_anchor_grids[inner_param->idx][(k << 1) +1];
+ valid_box[*valid_box_num].score = confidence_score;
+ valid_box[*valid_box_num].xcenter = x_center;
+ valid_box[*valid_box_num].ycenter = y_center;
+ valid_box[*valid_box_num].w = box_width;
+ valid_box[*valid_box_num].h = box_hieght;
+ valid_box[*valid_box_num].class_id = (td_float)max_cls_id;
+ *valid_box_num = *valid_box_num + 1;
+ }
+ }
+ }
+}
+
+static td_void sample_svp_npu_process_per_dectection(const sample_svp_npu_task_info *task, td_u32 idx,
+ sample_svp_npu_valid_box* valid_box, td_u32 *valid_box_num)
+{
+ td_u32 out_height;
+ svp_acl_mdl_io_dims out_dims;
+ sample_svp_npu_detection_inner_param inner_param;
+ svp_acl_data_buffer* data_buffer = TD_NULL;
+ td_u32 h_sizes[SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM] = { 20, 40, 80 };
+ td_u32 w_sizes[SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM] = { 20, 40, 80 };
+ /* gen grids */
+ td_float grids_x[SAMPLE_SVP_NPU_YOLO_CLASS_NUM] = {0};
+ td_float grids_y[SAMPLE_SVP_NPU_YOLO_CLASS_NUM] = {0};
+
+ svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, idx, &out_dims);
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, idx);
+ out_height = out_dims.dims[out_dims.dim_count - SAMPLE_SVP_NPU_DOUBLE];
+ inner_param.out_width = out_dims.dims[out_dims.dim_count - 1];
+ if (out_height > SAMPLE_SVP_NPU_YOLO_CLASS_NUM || inner_param.out_width > SAMPLE_SVP_NPU_YOLO_CLASS_NUM) {
+ sample_svp_trace_err("out_width[%u] or out_width[%u] is large than %u!\n",
+ out_height, inner_param.out_width, SAMPLE_SVP_NPU_YOLO_CLASS_NUM);
+ return;
+ }
+
+ inner_param.score_thr = SAMPLE_SVP_NPU_YOLO_SCORE_THRESHOLE;
+ inner_param.idx = idx;
+ inner_param.out_data = (td_float *)svp_acl_get_data_buffer_addr(data_buffer);
+ inner_param.w_stride_offset =
+ svp_acl_mdl_get_output_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, idx) / sizeof(td_float);
+ inner_param.chn_step = out_height * inner_param.w_stride_offset;
+
+ for (td_u32 i = 0; i < h_sizes[idx]; i++) {
+ grids_y[i] = i - SAMPLE_SVP_NPU_YOLO_SCORE_THRESHOLE;
+ }
+ for (td_u32 i = 0; i < w_sizes[idx]; i++) {
+ grids_x[i] = i - SAMPLE_SVP_NPU_YOLO_SCORE_THRESHOLE;
+ }
+ inner_param.obj_score_offset = sizeof(td_float) * inner_param.chn_step;
+ for (td_u32 i = 0; i < out_height; i++) {
+ inner_param.out_height_idx = i;
+ sample_svp_npu_process_per_dectection_inner(&inner_param, grids_x, grids_y, valid_box, valid_box_num);
+ }
+}
+
+static td_void sample_svp_npu_filter_yolo_box(const sample_svp_npu_task_info *task,
+ sample_svp_npu_valid_box* valid_box, td_u32 *valid_box_num)
+{
+ td_u32 out_num = svp_acl_mdl_get_num_outputs(g_svp_npu_model[task->cfg.model_idx].model_desc);
+ if (out_num > SAMPLE_SVP_NPU_YOLO_CPU_OUT_NUM) {
+ sample_svp_trace_err("output num [%u] is large than 3!\n", out_num);
+ return;
+ }
+
+ /* gen box */
+ for (td_u32 n = 0; n < out_num; n++) {
+ sample_svp_npu_process_per_dectection(task, n, valid_box, valid_box_num);
+ }
+}
+
+static td_void sample_svp_npu_fill_rect_info(const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, const sample_svp_npu_roi_box *roi_box,
+ td_u32 roi_box_num, ot_sample_svp_rect_info *rect_info)
+{
+ td_u32 rect_num = 0;
+ td_float w_multiples = (td_float)show_frame->video_frame.width / (td_float)proc_frame->video_frame.width;
+ td_float h_multiples = (td_float)show_frame->video_frame.height / (td_float)proc_frame->video_frame.height;
+ for (td_u32 i = 0; i < roi_box_num; i++) {
+ if (roi_box[i].score > 1.0f || roi_box[i].score < 0.0f) {
+ continue;
+ }
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].x = (td_u32)(roi_box[i].lx * w_multiples) & (~1);
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].y = (td_u32)(roi_box[i].ly * h_multiples) & (~1);
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].x = (td_u32)(roi_box[i].rx * w_multiples) & (~1);
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].y =
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].y;
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].x =
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_TOP].x;
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].y =
+ (td_u32)(roi_box[i].ry * h_multiples) & (~1);
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_BOTTOM].x =
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_TOP].x;
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_LEFT_BOTTOM].y =
+ rect_info->rect[rect_num].point[SAMPLE_SVP_NPU_RECT_RIGHT_BOTTOM].y;
+ rect_num++;
+ }
+ rect_info->num = rect_num;
+}
+
+static td_s32 cmp_valid_box(const void *item1, const void *item2)
+{
+ sample_svp_npu_valid_box *box1 = (sample_svp_npu_valid_box *)item1;
+ sample_svp_npu_valid_box *box2 = (sample_svp_npu_valid_box *)item2;
+ if (box1->score > box2->score) {
+ return 1;
+ }
+ return 0;
+}
+
+static td_s32 cmp_roi_box(const void *item1, const void *item2)
+{
+ sample_svp_npu_roi_box *box1 = (sample_svp_npu_roi_box *)item1;
+ sample_svp_npu_roi_box *box2 = (sample_svp_npu_roi_box *)item2;
+ if (box1->class_id < box2->class_id) {
+ return 1;
+ } else if (box1->class_id == box2->class_id) {
+ return box1->score > box2->score;
+ }
+ return 0;
+}
+
+static td_s32 sample_svp_npu_get_roi_by_cpu(const sample_svp_npu_task_info *task,
+ const sample_svp_npu_detection_info *info, const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info)
+{
+ td_u32 valid_box_num = 0;
+ td_u32 roi_box_num = 0;
+ sample_svp_npu_valid_box valid_box[OT_SVP_RECT_NUM] = {0};
+ sample_svp_npu_roi_box roi_box[OT_SVP_RECT_NUM] = {0};
+
+ sample_svp_npu_filter_yolo_box(task, valid_box, &valid_box_num);
+ qsort((td_void *)valid_box, valid_box_num, sizeof(sample_svp_npu_valid_box), cmp_valid_box);
+
+ sample_svp_npu_multiclass_nms(roi_box, &roi_box_num, valid_box, valid_box_num);
+ if (roi_box_num == 0) {
+ sample_svp_trace_info("No target object is detected !!!\n");
+ return TD_SUCCESS;
+ }
+ qsort((td_void *)roi_box, roi_box_num, sizeof(sample_svp_npu_roi_box), cmp_roi_box);
+ sample_svp_npu_fill_rect_info(proc_frame, show_frame, roi_box, roi_box_num, rect_info);
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_roi_to_rect(const sample_svp_npu_task_info *task,
+ sample_svp_npu_detection_info *detection_info, const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info)
+{
+ td_s32 ret;
+ td_u32 i;
+ td_float max_confidence = 0.0f;
+ td_u32 max_index = 0;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(detection_info == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "detection_info is NULL!\n");
+ sample_svp_check_exps_return(proc_frame == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "proc_frame is NULL!\n");
+ sample_svp_check_exps_return(show_frame == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "show_frame is NULL!\n");
+ sample_svp_check_exps_return(rect_info == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "rect_info is NULL!\n");
+
+ detection_info->roi_offset = 0;
+ ret = sample_svp_npu_get_roi_num(task, detection_info, rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi num failed!\n");
+
+ ret = sample_svp_npu_get_roi(task, detection_info, proc_frame, show_frame, rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi failed!\n");
+
+ // 新增部分:筛选置信度最高的矩形框
+ if (rect_info->num > 0) {
+ // 1. 查找置信度最高的矩形框
+ for (i = 0; i < rect_info->num; i++) {
+ if (rect_info->rect[i].score > max_confidence) {
+ max_confidence = rect_info->rect[i].score;
+ max_index = i;
+ }
+ }
+
+ // 2. 只保留置信度最高的矩形框
+ if (rect_info->num > 1) {
+ rect_info->rect[0] = rect_info->rect[max_index];
+ rect_info->num = 1;
+ }
+ }
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_roi_to_rect_cpu(const sample_svp_npu_task_info *task,
+ sample_svp_npu_detection_info *detection_info, const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info)
+{
+ td_s32 ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(detection_info == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "detection_info is NULL!\n");
+ sample_svp_check_exps_return(proc_frame == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "proc_frame is NULL!\n");
+ sample_svp_check_exps_return(show_frame == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "show_frame is NULL!\n");
+ sample_svp_check_exps_return(rect_info == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "rect_info is NULL!\n");
+
+ ret = sample_svp_npu_get_roi_by_cpu(task, detection_info, proc_frame, show_frame, rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi failed!\n");
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_set_threshold(sample_svp_npu_threshold threshold[], td_u32 threshold_num,
+ const sample_svp_npu_task_info *task)
+{
+ td_u32 i;
+ td_u32 n;
+ svp_acl_error ret;
+ svp_acl_data_buffer *data_buffer = TD_NULL;
+ td_float *data = TD_NULL;
+ size_t idx;
+ size_t size;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(threshold == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "threshold is NULL!\n");
+ sample_svp_check_exps_return(threshold_num == 0, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "threshold_num is 0!\n");
+
+ for (i = 0; i < threshold_num; i++) {
+ ret = svp_acl_mdl_get_input_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc,
+ threshold[i].name, &idx);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi idx failed!\n");
+
+ data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx);
+ sample_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi data_buffer is NULL!\n");
+
+ size = svp_acl_get_data_buffer_size(data_buffer);
+ sample_svp_check_exps_return(size < SAMPLE_SVP_NPU_THRESHOLD_NUM * sizeof(td_float), TD_FAILURE,
+ SAMPLE_SVP_ERR_LEVEL_ERROR, "get size(%lu) is less than %lu!\n",
+ size, SAMPLE_SVP_NPU_THRESHOLD_NUM * sizeof(td_float));
+
+ data = (td_float *)svp_acl_get_data_buffer_addr(data_buffer);
+ sample_svp_check_exps_return(data == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get roi data is NULL!\n");
+ n = 0;
+ data[n++] = threshold[i].nms_threshold;
+ data[n++] = threshold[i].score_threshold;
+ data[n++] = threshold[i].min_height;
+ data[n++] = threshold[i].min_width;
+ }
+ return TD_SUCCESS;
+}
+
+td_s32 sample_common_svp_npu_check_has_aicpu_task(const sample_svp_npu_task_info *task, td_bool *has_aicpu_task)
+{
+ td_u32 aicpu_task_num;
+ svp_acl_error ret;
+
+ if (sample_svp_check_task_cfg(task) != TD_SUCCESS) {
+ sample_svp_trace_err("check task cfg failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_check_exps_return(has_aicpu_task == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "has_aicpu_task is NULL!\n");
+
+ ret = svp_acl_ext_get_mdl_aicpu_task_num(g_svp_npu_model[task->cfg.model_idx].model_id, &aicpu_task_num);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get aicpu task num failed, error code is %d!\n", ret);
+
+ *has_aicpu_task = (aicpu_task_num == 0) ? TD_FALSE : TD_TRUE;
+ return TD_SUCCESS;
+}
+
+sample_svp_npu_model_info* sample_common_svp_npu_get_model_info(td_u32 model_idx)
+{
+ sample_svp_check_exps_return(model_idx >= SAMPLE_SVP_NPU_MAX_MODEL_NUM, NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "model_idx(%u) must be [0, %u)!\n", model_idx, SAMPLE_SVP_NPU_MAX_MODEL_NUM);
+ return &g_svp_npu_model[model_idx];
+}
+
+td_s32 sample_common_svp_npu_get_input_resolution(td_u32 model_idx, td_u32 input_idx,
+ ot_size *pic_size)
+{
+ svp_acl_error ret;
+ svp_acl_mdl_io_dims dims = {0};
+
+ ret = svp_acl_mdl_get_input_dims(g_svp_npu_model[model_idx].model_desc, input_idx, &dims);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get num dims failed!\n");
+ pic_size->height = dims.dims[dims.dim_count - SAMPLE_SVP_NPU_H_DIM_IDX]; // NCHW
+ pic_size->width = dims.dims[dims.dim_count - 1]; // NCHW
+ return TD_SUCCESS;
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.h b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.h
new file mode 100755
index 0000000000000000000000000000000000000000..18ff9e359a4c3cf2345f9c98d1821a1dcc2b5e93
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_npu_model.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SAMPLE_COMMON_SVP_NPU_MODEL_H
+#define SAMPLE_COMMON_SVP_NPU_MODEL_H
+#include "ot_type.h"
+#include "svp_acl_mdl.h"
+#include "sample_common_svp.h"
+#include "sample_common_svp_npu.h"
+
+td_s32 sample_common_svp_npu_get_input_data(const td_char *src[], td_u32 file_num,
+ const sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_load_model(const td_char *model_path, td_u32 model_index, td_bool is_cached);
+td_void sample_common_svp_npu_unload_model(td_u32 model_index);
+
+td_s32 sample_common_svp_npu_create_input(sample_svp_npu_task_info *task);
+td_s32 sample_common_svp_npu_create_output(sample_svp_npu_task_info *task);
+td_void sample_common_svp_npu_destroy_input(sample_svp_npu_task_info *task);
+td_void sample_common_svp_npu_destroy_output(sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_create_task_buf(sample_svp_npu_task_info *task);
+td_s32 sample_common_svp_npu_create_work_buf(sample_svp_npu_task_info *task);
+td_void sample_common_svp_npu_destroy_task_buf(sample_svp_npu_task_info *task);
+td_void sample_common_svp_npu_destroy_work_buf(sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_get_work_buf_info(const sample_svp_npu_task_info *task,
+ td_u32 *work_buf_size, td_u32 *work_buf_stride);
+td_s32 sample_common_svp_npu_share_work_buf(const sample_svp_npu_shared_work_buf *shared_work_buf,
+ const sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_set_dynamic_batch(const sample_svp_npu_task_info *task);
+td_s32 sample_common_svp_npu_model_execute(const sample_svp_npu_task_info *task);
+td_void sample_common_svp_npu_output_classification_result(const sample_svp_npu_task_info *task);
+
+td_void sample_common_svp_npu_dump_task_data(const sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_set_threshold(sample_svp_npu_threshold threshold[], td_u32 threshold_num,
+ const sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_roi_to_rect(const sample_svp_npu_task_info *task,
+ sample_svp_npu_detection_info *detection_info, const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info);
+
+td_s32 sample_common_svp_npu_roi_to_rect_cpu(const sample_svp_npu_task_info *task,
+ sample_svp_npu_detection_info *detection_info, const ot_video_frame_info *proc_frame,
+ const ot_video_frame_info *show_frame, ot_sample_svp_rect_info *rect_info);
+
+td_s32 sample_common_svp_npu_update_input_data_buffer_info(td_u8 *virt_addr, td_u32 size, td_u32 stride, td_u32 idx,
+ const sample_svp_npu_task_info *task);
+
+td_s32 sample_common_svp_npu_get_input_data_buffer_info(const sample_svp_npu_task_info *task, td_u32 idx,
+ td_u8 **virt_addr, td_u32 *size, td_u32 *stride);
+
+td_s32 sample_common_svp_npu_check_has_aicpu_task(const sample_svp_npu_task_info *task, td_bool *has_aicpu_task);
+
+sample_svp_npu_model_info* sample_common_svp_npu_get_model_info(td_u32 model_idx);
+
+td_s32 sample_common_svp_npu_get_input_resolution(td_u32 model_idx, td_u32 input_idx,
+ ot_size *pic_size);
+#endif
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.c
new file mode 100755
index 0000000000000000000000000000000000000000..cc1def3677c282f89006400bbc6b86793b0ce252
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.c
@@ -0,0 +1,193 @@
+/*
+ Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sample_comm.h"
+#include "easy_log.h"
+#include "xvp_common_osd.h"
+#include "sample_common_svp_npu.h"
+
+#define OVERLAY_MIN_HANDLE 20
+#define BUFFER_SIZE 16
+#define CLASS_BUFFER_SIZE 10
+#define DOUBLE_OF_SIZE 2
+#define BACKGROUND_ALPHA 255
+#define OSD_BUFFER_SIZE 32
+#define WIDTH_OF_MIN 1920
+#define HEIGHT_OF_MIN 1080
+#define WIDTH_OF_MAX 2560
+#define HEIGHT_OF_MAX 1440
+
+void sample_osd_region_init(ot_rgn_attr *region, ot_size img_size)
+{
+ td_s32 i;
+ region->type = OT_RGN_OVERLAYEX;
+ region->attr.overlay.canvas_num = 2; /* 2: canvas num */
+
+ for (i = 0; i < OT_RGN_CLUT_NUM; i++) {
+ region->attr.overlay.clut[i] = (td_u32)(0x000fff0f * (i + 1) * (i + 1));
+ region->attr.overlay.clut[i] |= 0xff000000;
+ }
+ region->attr.overlay.pixel_format = OT_PIXEL_FORMAT_ARGB_1555;
+ region->attr.overlay.size.width = img_size.width * DOUBLE_OF_SIZE;
+ region->attr.overlay.size.height = img_size.height * DOUBLE_OF_SIZE;
+ region->attr.overlay.bg_color = 0xffff;
+}
+
+void sample_osd_chn_attr_init(ot_rgn_chn_attr *chn_attr)
+{
+ chn_attr->type = OT_RGN_OVERLAYEX;
+ chn_attr->is_show = TD_TRUE;
+ chn_attr->attr.overlay_chn.bg_alpha = BACKGROUND_ALPHA;
+ chn_attr->attr.overlay_chn.fg_alpha = BACKGROUND_ALPHA;
+ chn_attr->attr.overlay_chn.qp_info.enable = TD_FALSE;
+ chn_attr->attr.overlay_chn.qp_info.is_abs_qp = TD_FALSE;
+ chn_attr->attr.overlay_chn.qp_info.qp_val = 0;
+ chn_attr->attr.overlay_chn.dst = OT_RGN_ATTACH_JPEG_MAIN;
+ chn_attr->attr.overlay_chn.layer = 0;
+}
+
+void sample_osd_info_init(xvp_osd_info *osd_info, ot_rgn_attr region)
+{
+ osd_info->border_color = 0x0;
+ osd_info->font_color = SAMPLE_SVP_NPU_RECT_COLOR;
+ osd_info->factor = 2; /* 2: factor of osd info */
+ osd_info->width = region.attr.overlay.size.width;
+ osd_info->height = region.attr.overlay.size.height;
+ osd_info->stride = region.attr.overlay.size.width;
+}
+
+int sample_osd_init(sample_mpp_osd_info *mpp_osd_info)
+{
+ printf("sample_osd_init ...\r\n");
+ td_s32 ret;
+ ot_rgn_attr region = {0};
+ ot_mpp_chn chn = {0};
+ ot_rgn_chn_attr chn_attr = {0};
+ xvp_osd_info osd_info = {0};
+ char osd_str[BUFFER_SIZE] = "scissors 0.00";
+ unsigned char gb_str[BUFFER_SIZE] = {0};
+ ot_size img_size = {BUFFER_SIZE};
+
+ chn.mod_id = OT_ID_VPSS;
+ chn.dev_id = 0;
+ chn.chn_id = 0;
+
+ xvp_common_osd_utf8_to_gb2312((unsigned char *)osd_str, strlen(osd_str), gb_str);
+ xvp_common_osd_calculate_canvas_size(gb_str, 1, &img_size.width, &img_size.height);
+ printf("%s-%d l:%d w:%u h:%u\n", __func__, __LINE__, strlen(gb_str), img_size.width, img_size.height);
+
+ sample_osd_region_init(®ion, img_size);
+
+ ret = ss_mpi_rgn_create(mpp_osd_info->handle, ®ion);
+ if (ret != TD_SUCCESS) {
+ LOGE("ss_mpi_rgn_create failed with %#x!", ret);
+ }
+
+ sample_osd_chn_attr_init(&chn_attr);
+ ret = ss_mpi_rgn_attach_to_chn(mpp_osd_info->handle, &chn, &chn_attr);
+ if (ret != TD_SUCCESS) {
+ LOGE("ss_mpi_rgn_attach_to_chn failed with %#x!", ret);
+ }
+
+ sample_osd_info_init(&osd_info, region);
+ mpp_osd_info->chn = chn;
+ mpp_osd_info->chn_attr = chn_attr;
+ mpp_osd_info->osd_info = osd_info;
+
+ xvp_common_osd_init(NULL);
+
+ return 0;
+}
+
+int sample_osd_exit(sample_mpp_osd_info *mpp_osd_info)
+{
+ printf("sample_osd_exit ...\r\n");
+ td_s32 ret;
+ xvp_common_osd_exit();
+
+ ret = ss_mpi_rgn_detach_from_chn(mpp_osd_info->handle, &mpp_osd_info->chn);
+ if (ret != TD_SUCCESS) {
+ LOGE("ss_mpi_rgn_detach_from_chn failed with %#x!", ret);
+ }
+
+ ret = ss_mpi_rgn_destroy(mpp_osd_info->handle);
+ if (ret != TD_SUCCESS) {
+ LOGE("ss_mpi_rgn_destroy failed with %#x!", ret);
+ }
+
+ return 0;
+}
+
+int sample_osd_draw_text(td_float score, td_u16 class_id, td_u16 x, td_u16 y,
+ sample_mpp_osd_info mpp_osd_info)
+{
+ printf("sample_osd_draw_text ...\r\n");
+ td_s32 ret;
+ const char classes[][CLASS_BUFFER_SIZE] = {"梨子", "西瓜", "橙子", "香蕉", "苹果"};
+ char osd_str[OSD_BUFFER_SIZE] = "西瓜 0.00";
+ unsigned char gb_str[OSD_BUFFER_SIZE] = {0};
+ ot_size img_size = {0};
+ ot_bmp bitmap = {0};
+
+ bitmap.width = mpp_osd_info.osd_info.width;
+ bitmap.height = mpp_osd_info.osd_info.height;
+ bitmap.pixel_format = OT_PIXEL_FORMAT_ARGB_1555;
+ bitmap.data = (td_void*)malloc(bitmap.width * bitmap.height * DOUBLE_OF_SIZE);
+
+ ret = snprintf(osd_str, sizeof(osd_str), "%s %0.2f", classes[class_id], score);
+ if (ret < 0) {
+ printf("%s:snprintf failed, ret:0x%x.\n", __FUNCTION__, ret);
+ }
+ memset_sp(bitmap.data, bitmap.width * bitmap.height * DOUBLE_OF_SIZE, 0x0,
+ bitmap.width * bitmap.height * DOUBLE_OF_SIZE);
+ memset_sp(gb_str, sizeof(gb_str), 0, sizeof(gb_str));
+ xvp_common_osd_utf8_to_gb2312((unsigned char *)osd_str, strlen(osd_str), gb_str);
+
+ xvp_common_osd_draw_text((unsigned char *)bitmap.data, gb_str, 0, 0, &mpp_osd_info.osd_info);
+ ret = ss_mpi_rgn_set_bmp(mpp_osd_info.handle, &bitmap);
+ if (ret != TD_SUCCESS) {
+ LOGE("ss_mpi_rgn_set_bmp failed with %#x!", ret);
+ }
+ int min_x = (int)(x * WIDTH_OF_MIN / WIDTH_OF_MAX);
+ int min_y = (int)(y * HEIGHT_OF_MIN / HEIGHT_OF_MAX);
+
+ if ((min_x % DOUBLE_OF_SIZE) != 0) {
+ min_x = min_x + 1;
+ }
+ if ((min_y % DOUBLE_OF_SIZE) != 0) {
+ min_y = min_y + 1;
+ }
+ printf("min_x:%d, min_y:%d\r\n", min_x, min_y);
+ mpp_osd_info.chn_attr.attr.overlay_chn.point.x = min_x;
+ mpp_osd_info.chn_attr.attr.overlay_chn.point.y = min_y;
+ mpp_osd_info.chn_attr.is_show = TD_TRUE;
+ ss_mpi_rgn_set_display_attr(mpp_osd_info.handle, &mpp_osd_info.chn, &mpp_osd_info.chn_attr);
+
+ if (bitmap.data != NULL) {
+ free(bitmap.data);
+ bitmap.data = NULL;
+ }
+
+ return 0;
+}
+
+int sample_osd_clean_text(sample_mpp_osd_info mpp_osd_info)
+{
+ ss_mpi_rgn_set_display_attr(mpp_osd_info.handle, &mpp_osd_info.chn, &mpp_osd_info.chn_attr);
+}
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.h b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.h
new file mode 100755
index 0000000000000000000000000000000000000000..3399494a4b8d190dc485a8503819fc845e798148
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/common/sample_common_svp_osd.h
@@ -0,0 +1,18 @@
+#ifndef SAMPLE_COMMON_SVP_OSD_H
+#define SAMPLE_COMMON_SVP_OSD_H
+#include "xvp_common_osd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sample_osd_init(sample_mpp_osd_info *mpp_osd_info);
+int sample_osd_exit(sample_mpp_osd_info *mpp_osd_info);
+int sample_osd_draw_text(td_float score, td_u16 class_id, td_u16 x, td_u16 y, sample_mpp_osd_info mpp_osd_info);
+int sample_osd_clean_text(sample_mpp_osd_info mpp_osd_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SAMPLE_COMMON_SVP_OSD_H
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/hzk/hzk16 b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/hzk/hzk16
new file mode 100755
index 0000000000000000000000000000000000000000..460e0550372c3317fe0b901b14e84ce65ddc9e50
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/hzk/hzk16 differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/model/fruit_identify.om b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/model/fruit_identify.om
new file mode 100755
index 0000000000000000000000000000000000000000..c8bda4529527724097744a302b5c311f530ccdb2
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/data/model/fruit_identify.om differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/apple/audio_chn0.aac b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/apple/audio_chn0.aac
new file mode 100755
index 0000000000000000000000000000000000000000..be17a8c4b7dc63b33b3ec46196db5cedb1ab7a25
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/apple/audio_chn0.aac differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/banana/audio_chn0.aac b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/banana/audio_chn0.aac
new file mode 100755
index 0000000000000000000000000000000000000000..f7f529304bd73f4de175ba167ae501075c852b00
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/banana/audio_chn0.aac differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/orange/audio_chn0.aac b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/orange/audio_chn0.aac
new file mode 100755
index 0000000000000000000000000000000000000000..41d79b4688bcaba26971ff36e7bbd3bf42f47fbc
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/orange/audio_chn0.aac differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/pear/audio_chn0.aac b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/pear/audio_chn0.aac
new file mode 100755
index 0000000000000000000000000000000000000000..cf40ce599eda4aaad8d6bc75465fd1117cd0d8ac
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/pear/audio_chn0.aac differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/watermelon/audio_chn0.aac b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/watermelon/audio_chn0.aac
new file mode 100755
index 0000000000000000000000000000000000000000..7a13293d952ff025530b18bb49670a522013da11
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_audio/watermelon/audio_chn0.aac differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_identify.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_identify.c
new file mode 100755
index 0000000000000000000000000000000000000000..db0faaed36d1dae9735ce4b38dbf040c4c7d7308
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/fruit_identify.c
@@ -0,0 +1,706 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+/* 新增v4l2相关头文件 */
+#include // 文件控制
+#include // 错误处理
+#include // POSIX API
+#include // 字符串操作
+#include // 内存映射
+#include // IO控制
+#include // select复用
+#include // v4l2核心
+
+#include "svp_acl_rt.h"
+#include "svp_acl.h"
+#include "svp_acl_ext.h"
+#include "sample_audio.h" // 包含音频文件
+#include "audio_aac_adp.h"
+#include "sdk_module_init.h"
+#include "common/sample_common_svp_osd.h" // osd头文件
+#include "common/sample_common_svp.h"
+#include "common/sample_common_svp_npu.h"
+#include "common/sample_common_svp_npu_model.h"
+
+#define SAMPLE_SVP_NPU_SHAERD_WORK_BUF_NUM 1
+#define SAMPLE_SVP_NPU_YOLO_TYPE_NUM 12
+#define SAMPLE_SVP_NPU_YOLO_THRESHOLD_NUM 1
+#define SAMPLE_SVP_NPU_PATH_LEN 0x100
+
+static int g_last_played_class_id = -1;
+static td_bool g_svp_npu_terminate_signal = TD_FALSE;
+static td_s32 g_svp_npu_dev_id = 0;
+static sample_svp_npu_task_info g_svp_npu_task[SAMPLE_SVP_NPU_MAX_TASK_NUM] = {0};
+static sample_svp_npu_shared_work_buf g_svp_npu_shared_work_buf[SAMPLE_SVP_NPU_SHAERD_WORK_BUF_NUM] = {0};
+
+static sample_svp_npu_threshold g_svp_npu_rfcn_threshold[SAMPLE_SVP_NPU_RFCN_THRESHOLD_NUM] = {
+ {0.7, 0.0, 16.0, 16.0, "rpn_data"}, {0.3, 0.9, 16.0, 16.0, "rpn_data1"}
+};
+
+static sample_svp_npu_threshold g_svp_npu_yolo_threshold[SAMPLE_SVP_NPU_YOLO_TYPE_NUM] = {
+ {0.9, 0.15, 1.0, 1.0, "rpn_data"}, // yolov8
+};
+
+static sample_svp_npu_roi_info g_svp_npu_yolo_roi_info[SAMPLE_SVP_NPU_YOLO_TYPE_NUM] = {
+ {"output0", "output0_"}, // yolov8
+};
+
+static sample_vi_cfg g_vi_config;
+static ot_sample_svp_rect_info g_svp_npu_rect_info = {0};
+static td_bool g_svp_npu_thread_stop = TD_FALSE;
+static pthread_t g_svp_npu_thread = 0;
+static sample_vo_cfg g_svp_npu_vo_cfg = { 0 };
+static pthread_t g_svp_npu_vdec_thread = 0;
+static ot_vb_pool_info g_svp_npu_vb_pool_info;
+static td_void *g_svp_npu_vb_virt_addr = TD_NULL;
+
+static ot_sample_svp_media_cfg g_svp_npu_media_cfg = {
+ .svp_switch = {TD_FALSE, TD_TRUE},
+ .pic_type = {PIC_1080P, PIC_CIF},
+ .chn_num = OT_SVP_MAX_VPSS_CHN_NUM,
+};
+
+static sample_vdec_attr g_svp_npu_vdec_cfg = {
+ .type = OT_PT_MJPEG,
+ .mode = OT_VDEC_SEND_MODE_FRAME,
+ .width = FHD_WIDTH,
+ .height = FHD_HEIGHT,
+ .sample_vdec_picture.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420, /* 420:pixel_format */
+ .sample_vdec_picture.alpha = 0, /* 0:alpha */
+ .display_frame_num = 2, /* 2:display_frame_num */
+ .frame_buf_cnt = 5, /* 5:2+2+1 */
+};
+
+static vdec_thread_param g_svp_npu_vdec_param = {
+ .chn_id = 0,
+
+ .v4l2_device = "/dev/video0", // 摄像头设备
+ .width = FHD_WIDTH, // 采集分辨率宽
+ .height = FHD_HEIGHT, // 采集分辨率高
+ .pixel_format = V4L2_PIX_FMT_MJPEG, // MJPEG格式
+
+ .type = OT_PT_MJPEG,
+ .stream_mode = OT_VDEC_SEND_MODE_FRAME,
+ .interval_time = 1000, /* 1000:interval_time */
+ .pts_init = 0,
+ .pts_increase = 0,
+ .e_thread_ctrl = THREAD_CTRL_START,
+ .circle_send = TD_TRUE,
+ .milli_sec = 0,
+ .min_buf_size = (FHD_WIDTH * FHD_HEIGHT * 3) >> 1, /* 3:chn_size */
+ .fps = 30,
+};
+
+// 音频线程
+typedef struct {
+ int class_id;
+} audio_play_param;
+
+void* audio_play_thread(void* arg)
+{
+ audio_play_param* param = (audio_play_param*)arg;
+ td_s32 audio_ret = TD_SUCCESS;
+
+ switch (param->class_id) {
+ case 0:
+ audio_ret = sample_audio_adec_ao("fruit_audio", "pear");
+ break;
+ case 1:
+ audio_ret = sample_audio_adec_ao("fruit_audio", "watermelon");
+ break;
+ case 2: /* 2: case of orange */
+ audio_ret = sample_audio_adec_ao("fruit_audio", "orange");
+ break;
+ case 3: /* 3: case of banana */
+ audio_ret = sample_audio_adec_ao("fruit_audio", "banana");
+ break;
+ case 4: /* 4: case of apple */
+ audio_ret = sample_audio_adec_ao("fruit_audio", "apple");
+ break;
+ default:
+ audio_ret = TD_SUCCESS;
+ break;
+ }
+
+ if (audio_ret != TD_SUCCESS) {
+ sample_svp_trace_err("play audio failed!\n");
+ } else {
+ sample_svp_trace_info("play audio success!\n");
+ }
+
+ free(param); // 释放参数
+ return NULL;
+}
+
+static td_void sample_svp_npu_acl_terminate(td_void)
+{
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
+ }
+}
+
+/* function : svp npu signal handle */
+td_void sample_svp_npu_acl_handle_sig(td_void)
+{
+ g_svp_npu_terminate_signal = TD_TRUE;
+}
+
+static td_void sample_svp_npu_acl_deinit(td_void)
+{
+ svp_acl_error ret;
+
+ ret = svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("reset device fail\n");
+ }
+ sample_svp_trace_info("end to reset device is %d\n", g_svp_npu_dev_id);
+
+ ret = svp_acl_finalize();
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("finalize acl fail\n");
+ }
+ sample_svp_trace_info("end to finalize acl\n");
+ (td_void)sample_common_svp_check_sys_exit();
+}
+
+static td_s32 sample_svp_npu_acl_init(const td_char *acl_config_path, td_bool vi_en)
+{
+ /* svp acl init */
+ svp_acl_rt_run_mode run_mode;
+ svp_acl_error ret;
+ td_bool is_mpi_init;
+
+ is_mpi_init = sample_common_svp_check_sys_init(vi_en);
+ sample_svp_check_exps_return(is_mpi_init != TD_TRUE, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "mpi init failed!\n");
+
+ ret = svp_acl_init(acl_config_path);
+ sample_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "acl init failed!\n");
+
+ sample_svp_trace_info("svp acl init success!\n");
+
+ /* open device */
+ ret = svp_acl_rt_set_device(g_svp_npu_dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ (td_void)svp_acl_finalize();
+ sample_svp_trace_err("svp acl open device %d failed!\n", g_svp_npu_dev_id);
+ return TD_FAILURE;
+ }
+ sample_svp_trace_info("open device %d success!\n", g_svp_npu_dev_id);
+
+ /* get run mode */
+ ret = svp_acl_rt_get_run_mode(&run_mode);
+ if ((ret != SVP_ACL_SUCCESS) || (run_mode != SVP_ACL_DEVICE)) {
+ (td_void)svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ (td_void)svp_acl_finalize();
+ sample_svp_trace_err("acl get run mode failed!\n");
+ return TD_FAILURE;
+ }
+ sample_svp_trace_info("get run mode success!\n");
+
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_acl_dataset_init(td_u32 task_idx)
+{
+ td_s32 ret = sample_common_svp_npu_create_input(&g_svp_npu_task[task_idx]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "create input failed!\n");
+
+ ret = sample_common_svp_npu_create_output(&g_svp_npu_task[task_idx]);
+ if (ret != TD_SUCCESS) {
+ sample_common_svp_npu_destroy_input(&g_svp_npu_task[task_idx]);
+ sample_svp_trace_err("execute create output fail.\n");
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS;
+}
+
+static td_void sample_svp_npu_acl_dataset_deinit(td_u32 task_idx)
+{
+ (td_void)sample_common_svp_npu_destroy_input(&g_svp_npu_task[task_idx]);
+ (td_void)sample_common_svp_npu_destroy_output(&g_svp_npu_task[task_idx]);
+}
+
+static td_void *sample_svp_npu_acl_thread_execute(td_void *args)
+{
+ td_s32 ret;
+ td_u32 task_idx = *(td_u32 *)args;
+
+ ret = svp_acl_rt_set_device(g_svp_npu_dev_id);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "open device %d failed!\n", g_svp_npu_dev_id);
+
+ ret = sample_common_svp_npu_model_execute(&g_svp_npu_task[task_idx]);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("execute inference failed of task[%u]!\n", task_idx);
+ }
+
+ ret = svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ if (ret != SVP_ACL_SUCCESS) {
+ sample_svp_trace_err("task[%u] reset device failed!\n", task_idx);
+ }
+ return TD_NULL;
+}
+
+static td_void sample_svp_npu_acl_model_execute_multithread()
+{
+ pthread_t execute_threads[SAMPLE_SVP_NPU_MAX_THREAD_NUM] = {0};
+ td_u32 idx[SAMPLE_SVP_NPU_MAX_THREAD_NUM] = {0};
+ td_u32 task_idx;
+
+ for (task_idx = 0; task_idx < SAMPLE_SVP_NPU_MAX_THREAD_NUM; task_idx++) {
+ idx[task_idx] = task_idx;
+ pthread_create(&execute_threads[task_idx], NULL, sample_svp_npu_acl_thread_execute, &idx[task_idx]);
+ }
+
+ td_void *waitret[SAMPLE_SVP_NPU_MAX_THREAD_NUM];
+ for (task_idx = 0; task_idx < SAMPLE_SVP_NPU_MAX_THREAD_NUM; task_idx++) {
+ pthread_join(execute_threads[task_idx], &waitret[task_idx]);
+ }
+
+ for (task_idx = 0; task_idx < SAMPLE_SVP_NPU_MAX_THREAD_NUM; task_idx++) {
+ sample_svp_trace_info("output %u-th task data\n", task_idx);
+ sample_common_svp_npu_output_classification_result(&g_svp_npu_task[task_idx]);
+ }
+}
+
+static td_void sample_svp_npu_acl_deinit_task(td_u32 task_num, td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ (td_void)sample_common_svp_npu_destroy_work_buf(&g_svp_npu_task[task_idx]);
+ (td_void)sample_common_svp_npu_destroy_task_buf(&g_svp_npu_task[task_idx]);
+ (td_void)sample_svp_npu_acl_dataset_deinit(task_idx);
+ (td_void)memset_s(&g_svp_npu_task[task_idx], sizeof(sample_svp_npu_task_cfg), 0,
+ sizeof(sample_svp_npu_task_cfg));
+ }
+ if (g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr != TD_NULL) {
+ (td_void)svp_acl_rt_free(g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr);
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr = TD_NULL;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size = 0;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_stride = 0;
+ }
+}
+
+static td_s32 sample_svp_npu_acl_create_shared_work_buf(td_u32 task_num, td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+ td_u32 work_buf_size;
+ td_u32 work_buf_stride;
+ td_s32 ret;
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ ret = sample_common_svp_npu_get_work_buf_info(&g_svp_npu_task[task_idx], &work_buf_size, &work_buf_stride);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get %u-th task work buf info failed!\n", task_idx);
+
+ if (g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size < work_buf_size) {
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size = work_buf_size;
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_stride = work_buf_stride;
+ }
+ }
+ ret = svp_acl_rt_malloc_cached(&g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr,
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "malloc %u-th shared work buf failed!\n", shared_work_buf_idx);
+
+ (td_void)svp_acl_rt_mem_flush(g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_ptr,
+ g_svp_npu_shared_work_buf[shared_work_buf_idx].work_buf_size);
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_svp_npu_acl_init_task(td_u32 task_num, td_bool is_share_work_buf,
+ td_u32 shared_work_buf_idx)
+{
+ td_u32 task_idx;
+ td_s32 ret;
+
+ if (is_share_work_buf == TD_TRUE) {
+ ret = sample_svp_npu_acl_create_shared_work_buf(task_num, shared_work_buf_idx);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "create shared work buf failed!\n");
+ }
+
+ for (task_idx = 0; task_idx < task_num; task_idx++) {
+ ret = sample_svp_npu_acl_dataset_init(task_idx);
+ if (ret != TD_SUCCESS) {
+ goto task_init_end_0;
+ }
+ ret = sample_common_svp_npu_create_task_buf(&g_svp_npu_task[task_idx]);
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("create task buf failed.\n");
+ goto task_init_end_0;
+ }
+ if (is_share_work_buf == TD_FALSE) {
+ ret = sample_common_svp_npu_create_work_buf(&g_svp_npu_task[task_idx]);
+ } else {
+ /* if all tasks are on the same stream, work buf can be shared */
+ ret = sample_common_svp_npu_share_work_buf(&g_svp_npu_shared_work_buf[shared_work_buf_idx],
+ &g_svp_npu_task[task_idx]);
+ }
+ if (ret != TD_SUCCESS) {
+ sample_svp_trace_err("create work buf failed.\n");
+ goto task_init_end_0;
+ }
+ }
+ return TD_SUCCESS;
+
+task_init_end_0:
+ (td_void)sample_svp_npu_acl_deinit_task(task_num, shared_work_buf_idx);
+ return ret;
+}
+
+// 辅助函数:根据class_id播放音频(如果类别发生变化)
+static void play_audio_if_class_changed(void)
+{
+ int max_idx = -1;
+ double max_score = 0.5;
+
+ // 检测到目标时,启动音频播放线程
+ for (int i = 0; i < g_svp_npu_rect_info.num; i++) {
+ if (g_svp_npu_rect_info.rect[i].score >= max_score) {
+ if (max_idx == -1 || g_svp_npu_rect_info.rect[i].score > g_svp_npu_rect_info.rect[max_idx].score) {
+ max_idx = i;
+ }
+ }
+ }
+ // ...existing code...
+ if (max_idx != -1) {
+ int current_class_id = g_svp_npu_rect_info.rect[max_idx].class_id;
+ if (current_class_id != g_last_played_class_id) {
+ pthread_t audio_thread;
+ audio_play_param* param = malloc(sizeof(audio_play_param));
+ if (param != NULL) {
+ param->class_id = current_class_id;
+ pthread_create(&audio_thread, NULL, audio_play_thread, param);
+ pthread_detach(audio_thread); // 不阻塞主流程
+ g_last_played_class_id = current_class_id; // 只在播放时更新
+ }
+ }
+ }
+}
+
+static void get_detection_results(void)
+{
+ // 循环打印置信度和类别ID
+ for (int i = 0; i < g_svp_npu_rect_info.num; i++) {
+ const char* class_name = NULL;
+ switch (g_svp_npu_rect_info.rect[i].class_id) {
+ case 0:
+ class_name = "梨子";
+ break;
+ case 1:
+ class_name = "西瓜";
+ break;
+ case 2: /* 2: case of orange */
+ class_name = "橘子";
+ break;
+ case 3: /* 3: case of banana */
+ class_name = "香蕉";
+ break;
+ case 4: /* 4: case of apple */
+ class_name = "苹果";
+ break;
+ default:
+ class_name = "未知";
+ break;
+ }
+ printf("score:%lf, class_id:%d, name:%s\r\n",
+ g_svp_npu_rect_info.rect[i].score,
+ g_svp_npu_rect_info.rect[i].class_id,
+ class_name);
+ }
+}
+
+static td_s32 sample_svp_npu_acl_frame_proc(const ot_video_frame_info *ext_frame,
+ const ot_video_frame_info *base_frame, td_void *args)
+{
+ td_s32 ret;
+ td_void *virt_addr = TD_NULL;
+ sample_svp_npu_detection_info *detection_info = TD_NULL;
+ sample_svp_npu_thread_args *thread_args = (sample_svp_npu_thread_args *)args;
+ td_u32 size = (td_u32)(ext_frame->video_frame.height * ext_frame->video_frame.stride[0] *
+ SAMPLE_SVP_NPU_IMG_THREE_CHN / SAMPLE_SVP_NPU_DOUBLE);
+
+ virt_addr = g_svp_npu_vb_virt_addr +
+ (ext_frame->video_frame.phys_addr[0] - g_svp_npu_vb_pool_info.pool_phy_addr);
+ ret = sample_common_svp_npu_update_input_data_buffer_info(virt_addr, size,
+ ext_frame->video_frame.stride[0], 0, &g_svp_npu_task[0]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "update data buffer failed!\n");
+
+ ret = sample_common_svp_npu_model_execute(&g_svp_npu_task[0]);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "model execute failed!\n");
+
+ play_audio_if_class_changed();
+
+ // ...existing code...
+ if (thread_args->model_name == SAMPLE_SVP_NPU_RFCN || thread_args->model_name == SAMPLE_SVP_NPU_YOLO) {
+ detection_info = thread_args->detection_info;
+ if (detection_info->is_cpu_rpn == TD_FALSE) {
+ ret = sample_common_svp_npu_roi_to_rect(&g_svp_npu_task[0], detection_info, ext_frame, base_frame,
+ &g_svp_npu_rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "roi to rect failed!\n");
+ } else {
+ ret = sample_common_svp_npu_roi_to_rect_cpu(&g_svp_npu_task[0], detection_info, ext_frame, base_frame,
+ &g_svp_npu_rect_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "roi to rect failed!\n");
+ }
+ ret = sample_common_svp_vgs_fill_rect(base_frame, &g_svp_npu_rect_info, SAMPLE_SVP_NPU_RECT_COLOR);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vgs fill rect failed!\n");
+
+ // 在屏幕上打印信息检测到的水果信息
+ int i;
+ for (i = 0; i < (g_svp_npu_rect_info.num); i++) {
+ sample_osd_draw_text(g_svp_npu_rect_info.rect[i].score, g_svp_npu_rect_info.rect[i].class_id,
+ g_svp_npu_rect_info.rect[i].point[0].x, g_svp_npu_rect_info.rect[i].point[0].y,
+ thread_args->mpp_osd_info);
+ }
+ if (g_svp_npu_rect_info.num == 0) {
+ thread_args->mpp_osd_info.chn_attr.is_show = TD_FALSE;
+ sample_osd_clean_text(thread_args->mpp_osd_info);
+ }
+ }
+ get_detection_results();
+
+ return ret;
+}
+
+static td_s32 sample_svp_npu_acl_vb_map(td_u32 vb_pool_idx)
+{
+ td_s32 ret;
+
+ if (g_svp_npu_vb_virt_addr == TD_NULL) {
+ ret = ss_mpi_vb_get_pool_info(g_svp_npu_media_cfg.vb_pool[vb_pool_idx], &g_svp_npu_vb_pool_info);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "get pool info failed!\n");
+ g_svp_npu_vb_virt_addr = ss_mpi_sys_mmap(g_svp_npu_vb_pool_info.pool_phy_addr,
+ g_svp_npu_vb_pool_info.pool_size);
+ sample_svp_check_exps_return(g_svp_npu_vb_virt_addr == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "map vb pool failed!\n");
+ }
+ return TD_SUCCESS;
+}
+
+static td_void *sample_svp_npu_acl_vdec_to_vo(td_void *args)
+{
+ td_s32 ret;
+ ot_video_frame_info base_frame;
+ ot_video_frame_info ext_frame;
+ const td_s32 milli_sec = SAMPLE_SVP_NPU_MILLIC_SEC;
+ const ot_vo_layer vo_layer = 0;
+ const ot_vo_chn vo_chn = 0;
+ const td_s32 vpss_grp = 0;
+ td_s32 vpss_chn[] = { OT_VPSS_CHN0, OT_VPSS_CHN1 };
+ td_u32 size;
+ td_u32 stride;
+ td_u8 *data = TD_NULL;
+
+ (td_void)prctl(PR_SET_NAME, "svp_npu_vdec_to_vo", 0, 0, 0);
+
+ ret = svp_acl_rt_set_device(g_svp_npu_dev_id);
+ sample_svp_check_exps_return(ret != TD_SUCCESS, TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "open device failed!\n");
+
+ ret = sample_svp_npu_acl_vb_map(OT_VPSS_CHN1);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "map vb pool failed!\n");
+
+ ret = sample_common_svp_npu_get_input_data_buffer_info(&g_svp_npu_task[0], 0, &data, &size, &stride);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),get_input_data_buffer_info failed!\n", ret);
+
+ while (g_svp_npu_thread_stop == TD_FALSE) {
+ ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[1], &ext_frame, milli_sec);
+ sample_svp_check_exps_continue(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_vpss_get_chn_frame failed, vpss_grp(%d), vpss_chn(%d)!\n", ret, vpss_grp, vpss_chn[1]);
+
+ ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[0], &base_frame, milli_sec);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, ext_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),ss_mpi_vpss_get_chn_frame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", ret, vpss_grp, vpss_chn[0]);
+
+ ret = sample_svp_npu_acl_frame_proc(&ext_frame, &base_frame, args);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, base_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_svp_npu_acl_frame_proc failed!\n", ret);
+
+ ret = sample_common_svp_venc_vo_send_stream(&g_svp_npu_media_cfg.svp_switch, 0, vo_layer, vo_chn, &base_frame);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, base_release, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),sample_common_svp_venc_vo_send_stream failed!\n", ret);
+base_release:
+ ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[0], &base_frame);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[0]);
+ext_release:
+ ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[1], &ext_frame);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "Error(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[1]);
+ }
+ ret = sample_common_svp_npu_update_input_data_buffer_info(data, size, stride, 0, &g_svp_npu_task[0]);
+ sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "update buffer failed!\n");
+fail_1:
+ (td_void)ss_mpi_sys_munmap(g_svp_npu_vb_virt_addr, g_svp_npu_vb_pool_info.pool_size);
+fail_0:
+ (td_void)svp_acl_rt_reset_device(g_svp_npu_dev_id);
+ return TD_NULL;
+}
+
+static td_void sample_svp_npu_acl_pause(td_void)
+{
+ printf("---------------press Enter key to exit!---------------\n");
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ return;
+ }
+ (td_void)getchar();
+ if (g_svp_npu_terminate_signal == TD_TRUE) {
+ return;
+ }
+}
+
+static td_void sample_svp_npu_acl_set_task_info(td_u32 model_idx)
+{
+ g_svp_npu_task[0].cfg.max_batch_num = 1;
+ g_svp_npu_task[0].cfg.dynamic_batch_num = 1;
+ g_svp_npu_task[0].cfg.total_t = 0;
+ g_svp_npu_task[0].cfg.is_cached = TD_TRUE;
+ g_svp_npu_task[0].cfg.model_idx = model_idx;
+}
+
+static td_void sample_svp_npu_acl_set_detection_info(sample_svp_npu_detection_info *detection_info, td_u32 index,
+ td_bool is_cpu_rpn)
+{
+ detection_info->num_name = g_svp_npu_yolo_roi_info[index].roi_num_name;
+ detection_info->roi_name = g_svp_npu_yolo_roi_info[index].roi_class_name;
+ detection_info->has_background = TD_FALSE;
+ detection_info->is_cpu_rpn = is_cpu_rpn;
+ detection_info->idx = index;
+ /* use PIC_BUTT to be a flag, get the input resolution form om */
+ g_svp_npu_media_cfg.pic_type[1] = PIC_BUTT;
+ g_svp_npu_terminate_signal = TD_FALSE;
+}
+
+static void sample_svp_audio_init()
+{
+ // 初始化音频编解码器
+ ss_mpi_aenc_aac_init();
+ ss_mpi_adec_aac_init();
+}
+
+static void sample_svp_audio_exit()
+{
+ // 反初始化音频
+ ss_mpi_aenc_aac_deinit();
+ ss_mpi_adec_aac_deinit();
+}
+
+/* 处理线程管理模块 */
+static td_s32 start_processing_thread(sample_svp_npu_thread_args *args)
+{
+ td_s32 ret;
+
+ ret = sample_common_svp_npu_set_threshold(&g_svp_npu_yolo_threshold[0],
+ SAMPLE_SVP_NPU_YOLO_THRESHOLD_NUM, &g_svp_npu_task[0]);
+
+ sample_svp_audio_init();
+ g_svp_npu_thread_stop = TD_FALSE;
+
+ ret = pthread_create(&g_svp_npu_thread, 0, sample_svp_npu_acl_vdec_to_vo, (td_void*)args);
+
+ return TD_SUCCESS;
+}
+
+/* function : show the sample of yolo. RPN processed by npu */
+td_void sample_svp_npu_acl_yolo_npu(void)
+{
+ td_s32 ret;
+ ot_mpp_chn chn;
+ td_s32 handle;
+ const td_u32 model_idx = 0;
+ const td_char *om_model_path = "./data/model/fruit_identify.om";
+ sample_svp_npu_detection_info detection_info = {0};
+ sample_svp_npu_thread_args args = {SAMPLE_SVP_NPU_YOLO, &detection_info};
+
+ sample_svp_npu_acl_set_detection_info(&detection_info, 0, TD_FALSE);
+
+ if (g_svp_npu_terminate_signal == TD_FALSE) {
+ /* init acl */
+ ret = sample_svp_npu_acl_init(TD_NULL, TD_FALSE);
+ sample_svp_check_exps_return_void(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "init failed!\n");
+
+ /* load model */
+ ret = sample_common_svp_npu_load_model(om_model_path, model_idx, TD_FALSE);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end0, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "load model failed!\n");
+
+ /* get input resolution */
+ ret = sample_common_svp_npu_get_input_resolution(model_idx, 0, &g_svp_npu_media_cfg.pic_size[1]);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end1, SAMPLE_SVP_ERR_LEVEL_ERROR,
+ "load model failed!\n");
+
+ /* start vdec vpss venc vo */
+ ret = sample_common_svp_create_vb_start_vdec_vpss_vo(&g_svp_npu_vdec_cfg, &g_svp_npu_vdec_param,
+ &g_svp_npu_vdec_thread, &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end1, SAMPLE_SVP_ERR_LEVEL_DEBUG,
+ "init media failed!\n");
+
+ // osd init
+ sample_osd_init(&args.mpp_osd_info);
+
+ /* set cfg */
+ sample_svp_npu_acl_set_task_info(model_idx);
+
+ ret = sample_svp_npu_acl_init_task(1, TD_FALSE, 0);
+ sample_svp_check_exps_goto(ret != TD_SUCCESS, process_end2, SAMPLE_SVP_ERR_LEVEL_ERROR, "init task failed!\n");
+ }
+ /* process */
+ if (g_svp_npu_terminate_signal == TD_FALSE) {
+ // 处理线程启动
+ ret = start_processing_thread(&args);
+ sample_svp_check_exps_goto(ret != 0, process_end3, SAMPLE_SVP_ERR_LEVEL_ERROR, "create thread failed!\n");
+
+ (td_void)sample_svp_npu_acl_pause();
+
+ g_svp_npu_thread_stop = TD_TRUE;
+ pthread_join(g_svp_npu_thread, TD_NULL);
+ }
+
+process_end3:
+ (td_void)sample_svp_npu_acl_deinit_task(1, 0);
+process_end2:
+ sample_osd_exit(&args.mpp_osd_info);
+ (td_void)sample_common_svp_destroy_vb_stop_vdec_vpss_vo(&g_svp_npu_vdec_param, &g_svp_npu_vdec_thread,
+ &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+process_end1:
+ (td_void)sample_common_svp_npu_unload_model(model_idx);
+process_end0:
+ (td_void)sample_svp_npu_acl_deinit();
+ (td_void)sample_svp_npu_acl_terminate();
+ sample_svp_audio_exit();
+}
+
+int main(void)
+{
+#ifdef CONFIG_USER_SPACE
+ SDK_init();
+#endif
+ sample_svp_npu_acl_yolo_npu();
+#ifdef CONFIG_USER_SPACE
+ SDK_exit();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20221114150205685.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20221114150205685.png
new file mode 100755
index 0000000000000000000000000000000000000000..4dc4215c962c57ba0e31548fb98c29c789f149d9
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20221114150205685.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210161601541.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210161601541.png
new file mode 100755
index 0000000000000000000000000000000000000000..80845ece8131933a4cd56ae3bd6119c38e0abd26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210161601541.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210170027454.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210170027454.png
new file mode 100755
index 0000000000000000000000000000000000000000..c06081fc2c963af4d1fa8af506804beedefe1b0b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250210170027454.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250213112932380.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250213112932380.png
new file mode 100755
index 0000000000000000000000000000000000000000..8b591b3437544859f4ec76b9ca03867cc401078c
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250213112932380.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919150630870.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919150630870.png
new file mode 100755
index 0000000000000000000000000000000000000000..91f881e85b3292118336ce2c3d81968e4aee8c26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919150630870.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151018659.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151018659.png
new file mode 100755
index 0000000000000000000000000000000000000000..9b09507893b65d2142be49e6461daa31a81855c4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151018659.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151519310.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151519310.png
new file mode 100755
index 0000000000000000000000000000000000000000..7f6d881a5d0e6d3f72b7a43d089b5c5a75d7f048
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919151519310.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173612332.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173612332.png
new file mode 100755
index 0000000000000000000000000000000000000000..d6b77aee440df447f0a4abcade34334be11c9580
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173612332.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173833285.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173833285.png
new file mode 100755
index 0000000000000000000000000000000000000000..0bf4e22357955f8390868050e0f3b4b8ad97376a
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173833285.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173911326.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173911326.png
new file mode 100755
index 0000000000000000000000000000000000000000..93af51cb4cfcbc2adfb866c035b592efee9354d0
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919173911326.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174107506.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174107506.png
new file mode 100755
index 0000000000000000000000000000000000000000..912fdccc2333688a45f928e9fd267f11284fa6a3
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174107506.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174301632.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174301632.png
new file mode 100755
index 0000000000000000000000000000000000000000..2fe2ad3ac92f9cce99d64199c81d4383514b5e1f
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919174301632.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175651286.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175651286.png
new file mode 100755
index 0000000000000000000000000000000000000000..787594f96e048545d9ffc2e872993994c04f1042
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175651286.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175810259.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175810259.png
new file mode 100755
index 0000000000000000000000000000000000000000..e6dbb6ee26c07a5a97528a7726027cdc471c5961
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175810259.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175946122.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175946122.png
new file mode 100755
index 0000000000000000000000000000000000000000..89d008483b60abd625c51183c61196c97a79b363
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919175946122.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919180706355.png b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919180706355.png
new file mode 100755
index 0000000000000000000000000000000000000000..ba4971e35c5cdaaf64386cebfa6a896383e61c7d
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/pic/image-20250919180706355.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.c b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.c
new file mode 100755
index 0000000000000000000000000000000000000000..22d334818f0b025fb71e80c4ec8196f06ea0bc8e
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sample_comm.h"
+#include "audio_aac_adp.h"
+#include "audio_dl_adp.h"
+#include "ot_resample.h"
+
+#include "sample_audio.h"
+
+static ot_payload_type g_payload_type = OT_PT_AAC;
+static td_bool g_aio_resample = TD_FALSE;
+static ot_audio_sample_rate g_in_sample_rate = OT_AUDIO_SAMPLE_RATE_BUTT;
+static ot_audio_sample_rate g_out_sample_rate = OT_AUDIO_SAMPLE_RATE_BUTT;
+
+#define sample_dbg(ret) \
+ do { \
+ printf("ret = %#x, fuc:%s, line:%d\n", ret, __FUNCTION__, __LINE__); \
+ } while (0)
+
+#define sample_res_check_null_ptr(ptr) \
+ do { \
+ if ((td_u8*)(ptr) == TD_NULL) { \
+ printf("ptr is TD_NULL,fuc:%s,line:%d\n", __FUNCTION__, __LINE__); \
+ return TD_FAILURE; \
+ } \
+ } while (0)
+
+/* function : PT number to string */
+static char *sample_audio_pt2_str(ot_payload_type type)
+{
+ if (type == OT_PT_G711A) {
+ return "g711a";
+ } else if (type == OT_PT_G711U) {
+ return "g711u";
+ } else if (type == OT_PT_ADPCMA) {
+ return "adpcm";
+ } else if (type == OT_PT_G726) {
+ return "g726";
+ } else if (type == OT_PT_LPCM) {
+ return "pcm";
+ } else if (type == OT_PT_AAC) {
+ return "aac";
+ } else {
+ return "data";
+ }
+}
+
+/* function : open adec file */
+static FILE *sample_audio_open_adec_file(ot_adec_chn ad_chn, ot_payload_type type,
+ const td_char *file_name1, const td_char *file_name2)
+{
+ FILE *fd = TD_NULL;
+ td_char asz_file_name[FILE_NAME_LEN] = {0};
+ td_s32 ret;
+ td_char path[PATH_MAX] = {0};
+
+ /* create file for save stream */
+#ifdef __LITEOS__
+ ret = snprintf_s(asz_file_name, FILE_NAME_LEN, FILE_NAME_LEN - 1,
+ "/sharefs/audio_chn%d.%s", ad_chn, sample_audio_pt2_str(type));
+#else
+ ret = snprintf_s(asz_file_name, FILE_NAME_LEN, FILE_NAME_LEN - 1,
+ "%s/%s/audio_chn%d.%s", file_name1, file_name2, ad_chn, sample_audio_pt2_str(type));
+#endif
+ if (ret < 0) {
+ printf("[func]:%s [line]:%d [info]:%s\n", __FUNCTION__, __LINE__, "get adec file name failed");
+ return TD_NULL;
+ }
+
+ if (asz_file_name[0] == '\0') {
+ printf("[func]:%s [line]:%d [info]:%s\n", __FUNCTION__, __LINE__, "adec file name is NULL");
+ return TD_NULL;
+ }
+
+ if (strlen(asz_file_name) > (FILE_NAME_LEN - 1)) {
+ printf("[func]:%s [line]:%d [info]:%s\n", __FUNCTION__, __LINE__, "adec file name extra long");
+ return TD_NULL;
+ }
+
+ if (realpath(asz_file_name, path) == TD_NULL) {
+ printf("[func]:%s [line]:%d [info]:%s\n", __FUNCTION__, __LINE__, "adec file name realpath fail");
+ return TD_NULL;
+ }
+
+ fd = fopen(path, "rb");
+ if (fd == NULL) {
+ printf("%s: open file %s failed\n", __FUNCTION__, asz_file_name);
+ return NULL;
+ }
+ printf("open stream file:\"%s\" for adec ok\n", asz_file_name);
+ return fd;
+}
+
+static td_void sample_audio_adec_ao_init_param(ot_aio_attr *aio_attr, ot_audio_dev *ao_dev)
+{
+ aio_attr->sample_rate = OT_AUDIO_SAMPLE_RATE_48000;
+ aio_attr->bit_width = OT_AUDIO_BIT_WIDTH_16;
+ aio_attr->work_mode = OT_AIO_MODE_I2S_MASTER;
+ aio_attr->snd_mode = OT_AUDIO_SOUND_MODE_STEREO;
+ aio_attr->expand_flag = 0;
+ aio_attr->frame_num = 30; /* 30:frame num */
+ if (g_payload_type == OT_PT_AAC) {
+ aio_attr->point_num_per_frame = AACLC_SAMPLES_PER_FRAME;
+ } else {
+ aio_attr->point_num_per_frame = SAMPLE_AUDIO_POINT_NUM_PER_FRAME;
+ }
+ aio_attr->chn_cnt = 2; /* 2:chn num */
+#ifdef OT_ACODEC_TYPE_INNER
+ *ao_dev = SAMPLE_AUDIO_INNER_AO_DEV;
+ aio_attr->clk_share = 1;
+ aio_attr->i2s_type = OT_AIO_I2STYPE_INNERCODEC;
+#else
+ *ao_dev = SAMPLE_AUDIO_EXTERN_AO_DEV;
+ aio_attr->clk_share = 1;
+ aio_attr->i2s_type = OT_AIO_I2STYPE_EXTERN;
+#endif
+ g_aio_resample = TD_FALSE;
+ g_in_sample_rate = OT_AUDIO_SAMPLE_RATE_BUTT;
+ g_out_sample_rate = OT_AUDIO_SAMPLE_RATE_BUTT;
+}
+
+td_void sample_audio_adec_ao_inner(ot_audio_dev ao_dev, ot_ao_chn ao_chn, ot_adec_chn ad_chn,
+ const td_char *file_name1, const td_char *file_name2)
+{
+ td_s32 ret;
+ FILE *fd = NULL;
+
+ ret = sample_comm_audio_ao_bind_adec(ao_dev, ao_chn, ad_chn);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ return;
+ }
+
+ fd = sample_audio_open_adec_file(ad_chn, g_payload_type, file_name1, file_name2);
+ if (fd == TD_NULL) {
+ sample_dbg(TD_FAILURE);
+ goto adec_ao_err0;
+ }
+
+ ret = sample_comm_audio_creat_trd_file_adec(ad_chn, fd);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ fclose(fd);
+ fd = TD_NULL;
+ goto adec_ao_err0;
+ }
+
+ printf("bind adec:%d to ao(%d,%d) ok \n", ad_chn, ao_dev, ao_chn);
+
+ sleep(2); /* 2: sleep 2 seconds */
+
+ ret = sample_comm_audio_destory_trd_file_adec(ad_chn);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ }
+
+adec_ao_err0:
+ ret = sample_comm_audio_ao_unbind_adec(ao_dev, ao_chn, ad_chn);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ }
+
+ return;
+}
+
+/* function : file -> adec -> ao */
+td_s32 sample_audio_adec_ao(const td_char *file_name1, const td_char *file_name2)
+{
+ td_s32 ret;
+ td_u32 ao_chn_cnt;
+ td_u32 adec_chn_cnt;
+ ot_audio_dev ao_dev;
+ ot_aio_attr aio_attr;
+ const ot_ao_chn ao_chn = 0;
+ const ot_adec_chn ad_chn = 0;
+
+ sample_audio_adec_ao_init_param(&aio_attr, &ao_dev);
+
+ adec_chn_cnt = aio_attr.chn_cnt >> ((td_u32)aio_attr.snd_mode);
+ ret = sample_comm_audio_start_adec(adec_chn_cnt, g_payload_type);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ goto adec_ao_err3;
+ }
+
+ ao_chn_cnt = aio_attr.chn_cnt;
+ ret = sample_comm_audio_start_ao(ao_dev, ao_chn_cnt, &aio_attr, g_in_sample_rate, g_aio_resample);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ goto adec_ao_err2;
+ }
+
+ ret = sample_comm_audio_cfg_acodec(&aio_attr);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ goto adec_ao_err1;
+ }
+
+ sample_audio_adec_ao_inner(ao_dev, ao_chn, ad_chn, file_name1, file_name2);
+
+adec_ao_err1:
+ ret = sample_comm_audio_stop_ao(ao_dev, ao_chn_cnt, g_aio_resample);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ }
+
+adec_ao_err2:
+ ret = sample_comm_audio_stop_adec(ad_chn);
+ if (ret != TD_SUCCESS) {
+ sample_dbg(ret);
+ }
+
+adec_ao_err3:
+ return ret;
+}
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.h b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.h
new file mode 100755
index 0000000000000000000000000000000000000000..ebb5b5babcfbd3795ee222442abad02c792fec35
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/fruit_identify/sample_audio.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SAMPLE_AUDIO_ADEC_AO_H__
+#define __SAMPLE_AUDIO_ADEC_AO_H__
+
+#include "sample_comm.h"
+
+td_s32 sample_audio_adec_ao(const td_char *file_name1, const td_char *file_name2);
+
+
+#endif /* __SAMPLE_AUDIO_ADEC_AO_H__ */
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/mk.param b/vendor/ZhongShanKuangShi_CUST/demo/mk.param
new file mode 100755
index 0000000000000000000000000000000000000000..7e3dfab53c4002c11ded8c0362fb0d96785a1188
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/mk.param
@@ -0,0 +1,42 @@
+# 各模块makefile均应在前面include此文件
+export ROOT_DIR := /home/openharmony/pegasus
+export SDK_ROOT := $(ROOT_DIR)/platform/ss928v100_clang
+export CUST_ROOT := $(ROOT_DIR)/vendor/ZhongShanKuangShi_CUST/
+export THIRD_PARTY_DIR := $(ROOT_DIR)/vendor/opensource
+export MPP_DIR := $(SDK_ROOT)/smp/a55_linux/mpp
+export OUTPUT_DIR := $(CUST_ROOT)/demo/output/
+export OBJS_DIR := $(CUST_ROOT)/demo/obj/
+
+# 交叉编译器
+CLANG_PATH := /home/openharmony/pegasus/os/OpenHarmony/ohos/prebuilts/clang/ohos/linux-x86_64/llvm
+export SYSROOT_PATH := /home/openharmony/pegasus/os/OpenHarmony/ohos/out/hispark_ss928v100/ipcamera_hispark_ss928v100_linux/sysroot
+COMPILER_PATH := $(CLANG_PATH)/bin/
+export CC:=$(COMPILER_PATH)/clang --target=aarch64-linux-ohos -Wno-unused-command-line-argument --sysroot $(SYSROOT_PATH) -isystem $(SYSROOT_PATH)/usr/include
+export CXXCPP := $(COMPILER_PATH)/clang++ --target=aarch64-linux-ohos --sysroot=$(CLANG_PATH)/sysroot -nostdinc -isystem $(CLANG_PATH)/include/c++/v1 -isystem $(CLANG_PATH)/lib/clang/15.0.4/include -isystem $(SYSROOT_PATH)/usr/include/aarch64-linux-ohos -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=2 -D__ARM_NEON=1 -D__ARM_NEON__=1 -mfpu=neon -resource-dir=$(CLANG_PATH)/lib/clang/15.0.4
+CC += -fuse-ld=lld -rtlib=compiler-rt
+
+# 编译所依赖的库目录
+export SDK_LINUX_OUT_LIB := $(MPP_DIR)/out/lib
+export SDK_LINUX_OUT_SVP_NPU_LIB := $(SDK_LINUX_OUT_LIB)/svp_npu
+
+# 编译所依赖的头文件和源文件目录
+export SDK_LINUX_INCLUDE_DIR := $(MPP_DIR)/out/include
+export SDK_SAMPLE_COMMON_DIR := $(MPP_DIR)/sample/common
+export SVP_COMMON_DIR := $(MPP_DIR)/sample/svp/common
+
+# 第三方软件的库和头文件
+export OPENCV_LIB := $(THIRD_PARTY_DIR)/opencv/lib
+export OPENCV_INCLUDE := $(THIRD_PARTY_DIR)/opencv/include/opencv4
+
+# target输出的存储目录
+export TARGET_ROOT := ./
+export TARGET_DIR := $(TARGET_ROOT)/out/
+
+export AUDIO_SAMPLE := $(MPP_DIR)/sample/audio/
+# cust 项目子模块目录
+export FACE_DETECTION_SAMPLE_DIR := $(CUST_ROOT)/demo/face_detection
+export FRUIT_IDENTIFY_SAMPLE_DIR := $(CUST_ROOT)/demo/fruit_identify
+export HNR_AUTO_SAMPLE_DIR := $(CUST_ROOT)/demo/hnr_auto
+export KCF_TRACK_SAMPLE_DIR := $(CUST_ROOT)/demo/sample_kcf_track
+export OPENCV_DNN_SAMPLE_DIR := $(CUST_ROOT)/demo/opencv_dnn
+
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/Makefile b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/Makefile
new file mode 100755
index 0000000000000000000000000000000000000000..14ead07993fed2e673e88a02d595ed919dc0d5d9
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/Makefile
@@ -0,0 +1,54 @@
+# 编译所需的公共文件
+include ../mk.param
+
+# 编译后生成的可执行文件名
+TARGET := main
+
+# 编译此工程需要包含的头文件
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/
+CFLAGS += -I$(SDK_SAMPLE_COMMON_DIR)/
+CFLAGS += -Wno-psabi -I$(OPENCV_INCLUDE)/
+CFLAGS += -I$(OPENCV_DNN_SAMPLE_DIR)/
+
+
+# 编译此工程需要依赖的.c文件
+SMP_SRCS := $(SDK_SAMPLE_COMMON_DIR)/sample_comm_sys.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_ipc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_isp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vi.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vo.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_mipi_tx.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vpss.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/loadbmp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vdec.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_venc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_exit.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_init.c
+SMP_SRCS += $(OPENCV_DNN_SAMPLE_DIR)/host_uvc.c
+SMP_SRCS += $(OPENCV_DNN_SAMPLE_DIR)/media_vdec.c
+
+# 编译此工程需要依赖的.cpp文件
+CPP_SRCS += $(OPENCV_DNN_SAMPLE_DIR)/main.cpp
+
+# 编译此工程需要包含的库和宏
+CFLAGS += -O3 -g -Wall -DSAMPLE_HNR_SUPPORT
+CFLAGS += -fstack-protector-strong
+MPI_LIBS += -L$(OPENCV_LIB)/
+MPI_LIBS += -lopencv_videoio -lopencv_calib3d -lopencv_dnn -lopencv_core -lopencv_video
+MPI_LIBS += -lopencv_flann -lopencv_features2d -lopencv_highgui -lopencv_imgcodecs
+MPI_LIBS += -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching
+
+# 根据实际的类型设置,可以用set_sensor脚本设置
+SENSOR0_TYPE = -DSENSOR0_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR1_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR2_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR3_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+
+CFLAGS += $(SENSOR0_TYPE)
+CFLAGS += $(SENSOR1_TYPE)
+CFLAGS += $(SENSOR2_TYPE)
+CFLAGS += $(SENSOR3_TYPE)
+# 编译工程所需的mk文件
+
+include ../sdk_linux.mk
+
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/README.md b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..3318b331348d8dc62397031abb50a14f2d9df294
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/README.md
@@ -0,0 +1,134 @@
+## 2.1、opencv_dnn操作指导
+
+### 2.1.1、opencv_dnn程序简介
+
+* opencv_dnn sample基于SS928V100平台开发,以EulerPi套件为例,opencv_dnn sample是通过USB camera采集到的图片送到人脸检测模型进行推理,将得到的结果通过HDMI,显示在外接显示屏上面。
+* opencv_dnn案例,模型推理是在CPU上实现了,没有调用svp_npu的接口,都是调用opencv的接口来实现。
+
+### 2.1.2、目录
+
+```shell
+pegasus/vendor/cust/demo/opencv_dnn
+|── onnx # 模型文件和汉字库
+|── media_vdec.c # 主要是将推理的结果在HDMI外接显示器上显示
+|── media_vdec.h
+|── Makefile # 编译脚本
+|── main.cpp # opencv_dnn sample业务代码
+|── host_uvc.c #参考海思SDK的host_uvc代码
+└── host_uvc.h
+```
+
+
+
+### 2.1.3、编译
+
+* **注意:在编译cust的demo之前,请确保你已经按照[patch介绍中的步骤](../../README.md#4patch介绍)把补丁打入海思SDK的sample目录下了**。
+
+* 步骤1:先根据自己选择的操作系统,进入到对应的Pegasus所在目录下。
+
+* 步骤2:使用Makefile的方式进行单编
+
+* 在Ubuntu的命令行终端,分步执行下面的命令,单编 opencv_dnn sample
+
+ ```
+ cd pegasus/vendor/cust/demo/opencv_dnn
+
+ make clean && make
+ ```
+
+ 
+
+ * 在opencv_dnn目录下,生成一个名为opencv_dnn的 可执行文件,如下图所示:
+
+ 
+
+### 2.1.4、拷贝可执行程序和依赖文件至开发板的mnt目录下
+
+**方式一:使用SD卡进行资料文件的拷贝**
+
+* 首先需要自己准备一张Micro sd卡(16G 左右即可),还得有一个Micro sd卡的读卡器。
+
+
+
+* 步骤1:将编译后生成的可执行文件、onnx模型文件都拷贝到SD卡中。
+
+
+
+* 步骤2:可执行文件拷贝成功后,将内存卡插入开发板的SD卡槽中,可通过挂载的方式挂载到板端,可选择SD卡 mount指令进行挂载。
+
+
+
+* 在开发板的终端,执行下面的命令进行SD卡的挂载
+ * 如果挂载失败,可以参考[这个issue尝试解决](https://gitee.com/HiSpark/HiSpark_NICU2022/issues/I54932?from=project-issue)
+
+
+```shell
+mount -t vfat /dev/mmcblk1p1 /mnt
+# 其中/dev/mmcblk1p1需要根据实际块设备号修改
+```
+
+* 挂载成功后,如下图所示:
+
+
+
+**方式二:使用NFS挂载的方式进行资料文件的拷贝**
+
+* 首先需要自己准备一根网线
+* 步骤1:参考[博客链接](https://blog.csdn.net/Wu_GuiMing/article/details/115872995?spm=1001.2014.3001.5501)中的内容,进行nfs的环境搭建
+* 步骤2:将编译后生成的可执行文件、onnx模型文件、opencv库(在pegasus/vendor/opensource/opencv/lib目录下)都拷贝到Windows的nfs共享路径下
+
+
+
+* 步骤3:在开发板的终端执行下面的命令,将Windows的nfs共享路径挂载至开发板的mnt目录下
+ * 注意:这里IP地址请根据你开发板和电脑主机的实际IP地址进行填写
+
+
+```
+ifconfig eth0 192.168.100.100
+mount -o nolock,addr=192.168.100.10 -t nfs 192.168.100.10:/d/nfs /mnt
+```
+
+
+
+### 2.1.5、硬件连接
+
+* 准备一个外接显示器和HDMI数据线,将HDMI的一头接在开发板的HDMI输出口,将HDMI的另外一头接在外接显示器的HDMI输入口。
+
+
+
+* 将USB 摄像头接在EulerPi开发板的USB接口上。
+
+
+
+### 2.1.6、功能验证
+
+* 在开发板的终端执行下面的命令,运行可执行文件
+
+```c
+# 把opencv的库添加到环境变量中
+export LD_LIBRARY_PATH=/mnt/lib:$LD_LIBRARY_PATH
+
+cd /mnt
+
+chmod +x opencv_dnn
+
+./opencv_dnn /dev/media0 -fMJPEG -s1920x1080 -Ftest.mjpg
+```
+
+
+
+* 此时,在HDMI的外接显示屏上即可出现实时码流,如下图所示:
+
+
+
+* 如果您看到的现象和下图现象不一致,可以确认一下USB涉嫌头是否插入到开发板的USB口,并且在开发板的/dev目录下能够看到video0 和 video1两个设备节点。如果没有这两个设备节点,请确保镜像烧录正常。
+
+
+
+* 正常情况下,我们会在外接显示屏上看到有人脸的区域被框出来,且在框框的左上角显示置信度。
+
+
+
+* Ctrl + C,然后回车即可关闭程序
+
+
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.c b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.c
new file mode 100755
index 0000000000000000000000000000000000000000..603450806508bff1a59a66b8f875a711ca49f965
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "host_uvc.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+#define array_size(a) (sizeof(a) / sizeof((a)[0]))
+
+format_info g_pixel_formats[] = {
+ { "YUYV", V4L2_PIX_FMT_YUYV, 1 },
+ { "MJPEG", V4L2_PIX_FMT_MJPEG, 1 },
+ { "H264", V4L2_PIX_FMT_H264, 1 },
+ { "H265", V4L2_PIX_FMT_H265, 1 },
+ { "NV12", V4L2_PIX_FMT_NV12, 1 },
+ { "NV21", V4L2_PIX_FMT_NV21, 1 },
+};
+
+static struct option g_opts[] = {
+ {"file", 2, 0, 'F'}, /* 2 is a number */
+ {"format", 1, 0, 'f'},
+ {"help", 0, 0, 'h'},
+ {"size", 1, 0, 's'},
+ {0, 0, 0, 0}
+};
+
+static const format_info *sample_uvc_v4l2_format_by_fourcc(td_u32 fourcc)
+{
+ td_u32 i;
+
+ for (i = 0; i < array_size(g_pixel_formats); ++i) {
+ if (g_pixel_formats[i].fourcc == fourcc) {
+ return &g_pixel_formats[i];
+ }
+ }
+ return TD_NULL;
+}
+
+static td_void sample_uvc_usage(const td_char *argv0)
+{
+ printf("sample_uvc_usage: %s device [options]\n", argv0);
+ printf("supported options:\n");
+ printf("-f, --format format set the video format\n");
+ printf("-F, --file[=name] write file\n");
+ printf("-h, --help show help info\n");
+ printf("-s, --size WxH set the frame size (eg. 1920x1080)\n\n");
+ printf("inquire USB device format: ./sample_uvc --enum-formats\n\n");
+ printf("example of setting USB device format:\n");
+ printf(" ./opencv_dnn /dev/media0 -fH264 -s1920x1080 -Ftest.h264\n");
+ printf(" ./opencv_dnn /dev/media0 -fH265 -s1920x1080 -Ftest.h265\n");
+ printf(" ./opencv_dnn /dev/media0 -fMJPEG -s1920x1080 -Ftest.mjpg\n");
+ printf(" ./opencv_dnn /dev/media0 -fYUYV -s1920x1080 -Ftest.yuv\n");
+ printf(" ./opencv_dnn /dev/media0 -fNV21 -s640x360 -Ftest.yuv\n\n");
+ printf("note: set macro MEDIA_WORK to 0 to write file on disk.\n\n");
+}
+
+static const format_info *sample_uvc_v4l2_format_by_name(const td_char *name)
+{
+ td_u32 i;
+ for (i = 0; i < array_size(g_pixel_formats); ++i) {
+ if (!strcmp(g_pixel_formats[i].name, name)) {
+ return &g_pixel_formats[i];
+ }
+ }
+ return TD_NULL;
+}
+
+static td_void sample_uvc_list_formats(td_void)
+{
+ td_u32 i;
+ for (i = 0; i < array_size(g_pixel_formats); i++) {
+ sample_print("%s (\"%c%c%c%c\", %u planes)\n", g_pixel_formats[i].name, g_pixel_formats[i].fourcc & 0xff,
+ (g_pixel_formats[i].fourcc >> 8) & 0xff, (g_pixel_formats[i].fourcc >> 16) & 0xff, /* 8,16:shift */
+ (g_pixel_formats[i].fourcc >> 24) & 0xff, g_pixel_formats[i].n_planes); /* 24:shift */
+ }
+}
+
+static td_s32 sample_uvc_get_opt(td_s32 argc, td_char *argv[], uvc_ctrl_info *ctrl_info)
+{
+ td_s32 c;
+ const format_info *info;
+ td_char *endptr;
+
+ while ((c = getopt_long(argc, argv, "B:c::Cd:f:F::hi:Iln:p::q:r:R::s:t:uw:x:", g_opts, TD_NULL)) != -1) {
+ switch (c) {
+ case 'f':
+ if (!strcmp("help", optarg)) {
+ sample_uvc_list_formats();
+ return TD_FAILURE;
+ }
+ ctrl_info->do_set_format = 1;
+ info = sample_uvc_v4l2_format_by_name(optarg);
+ if (info == TD_NULL) {
+ sample_print("Unsupported video format '%s'\n", optarg);
+ return TD_FAILURE;
+ }
+ ctrl_info->pixelformat = info->fourcc;
+ break;
+ case 'F':
+ ctrl_info->do_file = 1;
+ if (optarg) {
+ ctrl_info->pattern = optarg;
+ }
+ break;
+ case 'h':
+ sample_uvc_usage(argv[0]);
+ return TD_FAILURE;
+ case 's':
+ ctrl_info->do_capture = 1;
+ ctrl_info->do_set_format = 1;
+ ctrl_info->width = strtol(optarg, &endptr, 10); /* 10:base */
+ if (*endptr != 'x' || endptr == optarg) {
+ sample_print("Invalid size '%s'\n", optarg);
+ return TD_FAILURE;
+ }
+ ctrl_info->height = strtol(endptr + 1, &endptr, 10); /* 10:base */
+ if (*endptr != 0) {
+ sample_print("Invalid size '%s'\n", optarg);
+ return TD_FAILURE;
+ }
+ break;
+ default:
+ sample_print("Run %s -h for help.\n", argv[0]);
+ return TD_FAILURE;
+ }
+ }
+ return TD_SUCCESS;
+}
+
+static td_void sample_uvc_ctrl_info_init(uvc_ctrl_info *ctrl_info)
+{
+ ctrl_info->pattern = "frame-#.bin";
+ ctrl_info->width = 640; /* 640:width */
+ ctrl_info->height = 480; /* 480:height */
+ ctrl_info->pixelformat = V4L2_PIX_FMT_YUYV;
+}
+
+const td_char *sample_uvc_v4l2_format_name(td_u32 fourcc)
+{
+ const format_info *format;
+ static td_char format_name[5]; /* 5: array len */
+ td_u32 i;
+ format = sample_uvc_v4l2_format_by_fourcc(fourcc);
+ if (format) {
+ return format->name;
+ }
+
+ for (i = 0; i < 4; ++i) { /* 4: format */
+ format_name[i] = fourcc & 0xff;
+ fourcc >>= 8; /* 8: shift */
+ }
+
+ format_name[4] = '\0'; /* 4: end */
+ return format_name;
+}
+
+td_s32 sample_host_uvc(td_s32 argc, td_char *argv[], uvc_ctrl_info *ctrl_info)
+{
+ int ret;
+ sample_uvc_ctrl_info_init(ctrl_info);
+ ret = sample_uvc_get_opt(argc, argv, ctrl_info);
+ if (ret != TD_SUCCESS) {
+ return TD_FAILURE;
+ }
+ if (optind >= argc) {
+ sample_uvc_usage(argv[0]);
+ return TD_FAILURE;
+ }
+ return TD_SUCCESS ;
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* End of #ifdef __cplusplus */
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.h b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.h
new file mode 100755
index 0000000000000000000000000000000000000000..2260d03101ecb6a09ad12f938aca663b297f8059
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/host_uvc.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __HOST_UVC_H__
+#define __HOST_UVC_H__
+
+#include
+#include
+#include
+#include "sample_comm.h"
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+#ifndef V4L2_PIX_FMT_H265
+#define V4L2_PIX_FMT_H265 v4l2_fourcc('H', '2', '6', '5') /* H.265 aka HEVC */
+#endif
+
+typedef struct {
+ const td_char *name;
+ td_u32 fourcc;
+ td_char n_planes;
+} format_info;
+
+typedef struct {
+ const td_char *pattern;
+ const td_char *type_name;
+ td_s32 do_capture;
+ td_s32 do_set_format;
+ td_u32 pixelformat;
+ td_s32 do_file;
+ td_u32 input;
+ td_u32 width;
+ td_u32 height;
+} uvc_ctrl_info;
+
+td_s32 sample_host_uvc(td_s32 argc, td_char *argv[], uvc_ctrl_info *ctrl_info);
+const td_char *sample_uvc_v4l2_format_name(td_u32 fourcc);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* End of #ifdef __cplusplus */
+
+#endif /* end of #ifndef __HOST_UVC_H__ */
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/main.cpp b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/main.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..f7a639decea635484fce719becd28e1b99832511
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/main.cpp
@@ -0,0 +1,285 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include "host_uvc.h"
+#include "media_vdec.h"
+#include "sdk_module_init.h"
+
+using namespace cv;
+using namespace std;
+using namespace std::chrono;
+
+td_bool g_uvc_exit = TD_FALSE;
+
+// 优化内存管理类
+class MemoryManager {
+public:
+ static void optimizeMemory()
+ {
+ cv::setUseOptimized(true);
+ cv::setNumThreads(4); /* 4: Number of CPU cores */
+ }
+};
+
+static void sample_uvc_exit_signal_handler(int signal)
+{
+ printf("收到退出信号,准备退出...\n");
+ g_uvc_exit = TD_TRUE;
+}
+
+int main(int argc, char** argv)
+{
+ // 优化内存使用
+ MemoryManager::optimizeMemory();
+
+ int ret;
+ uvc_ctrl_info ctrl_info = {0};
+ struct sigaction sig_exit;
+ sig_exit.sa_handler = sample_uvc_exit_signal_handler;
+ sigaction(SIGINT, &sig_exit, nullptr);
+ sigaction(SIGTERM, &sig_exit, nullptr);
+ ret = sample_host_uvc(argc, argv, &ctrl_info);
+ if (ret != TD_SUCCESS) {
+ return TD_FAILURE;
+ }
+#ifdef CONFIG_USER_SPACE
+ SDK_init();
+#endif
+ // OpenCV V4L2 video capture
+ VideoCapture cap(0, cv::CAP_V4L2);
+ if (!cap.isOpened()) {
+ printf("Error: Failed to open camera device!\n");
+ return -1;
+ }
+
+ int width = ctrl_info.width;
+ int height = ctrl_info.height;
+ int fps = 30;
+
+ // 设置摄像头参数
+ cap.set(CAP_PROP_FRAME_WIDTH, width);
+ cap.set(CAP_PROP_FRAME_HEIGHT, height);
+ cap.set(CAP_PROP_FPS, fps);
+ cap.set(CAP_PROP_BUFFERSIZE, 4); /* 4: Increase buffer size */
+
+ // 根据格式设置摄像头参数
+ const char* type_name = sample_uvc_v4l2_format_name(ctrl_info.pixelformat);
+ if (strcmp(type_name, "MJPEG") == 0) {
+ cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));
+ } else if (strcmp(type_name, "YUYV") == 0) {
+ cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('Y', 'U', 'Y', 'V'));
+ } else {
+ std::cerr << "只支持 YUYV 或 MJPEG 格式,请用 -fYUYV 或 -fMJPEG 参数启动!" << std::endl;
+ return -1;
+ }
+
+ // 验证设置是否成功
+ int actual_width = cap.get(CAP_PROP_FRAME_WIDTH);
+ int actual_height = cap.get(CAP_PROP_FRAME_HEIGHT);
+ double actual_fps = cap.get(CAP_PROP_FPS);
+
+ printf("Requested resolution: %dx%d @ %d fps\n", width, height, fps);
+ printf("Actual resolution: %dx%d @ %.2f fps\n", actual_width, actual_height, actual_fps);
+ printf("Using format: %s\n", type_name);
+
+ if (actual_width != width || actual_height != height) {
+ printf("Warning: Camera does not support requested resolution, using actual resolution\n");
+ width = actual_width;
+ height = actual_height;
+ }
+
+ // 初始化人脸检测器,使用更快的参数
+ const string modelPath = "./onnx/face_detection_yunet_2023mar.onnx";
+ Ptr detector = FaceDetectorYN::create(
+ /* 256 144 input width height 0.6 score_threshold 0.7 nms_threshold */
+ modelPath, "", Size(256, 144), 0.6, 0.7, 100); /* 100 top_k */
+ if (!detector) {
+ printf("Error: Failed to create face detector\n");
+ return -1;
+ }
+
+ // 初始化媒体链路
+ if (sample_uvc_media_init(type_name, width, height) != TD_SUCCESS) {
+ std::cerr << "media start failed!" << std::endl;
+ return -1;
+ }
+
+ const int MAX_RETRIES = 3; /* 3: max retries */
+ int retry_count = 0;
+ bool device_reconnected = false;
+ int empty_frame_count = 0;
+ const int MAX_EMPTY_FRAMES = 10; /* 10: max empty frames */
+
+ // 预分配Mat对象
+ Mat frame;
+ Mat faces;
+ Mat yuvFrame;
+ vector mjpeg_buffer;
+ mjpeg_buffer.reserve(width * height * 3 / 2); /* 3 / 2 YUV420 memory size */
+
+ // 创建MJPEG编码器
+ vector mjpeg_params = {
+ IMWRITE_JPEG_QUALITY, 90, /* 90: JPEG quality */
+ IMWRITE_JPEG_OPTIMIZE, 1,
+ IMWRITE_JPEG_PROGRESSIVE, 0
+ };
+
+ // 预分配VPSS缓冲区
+ ot_size pic_size;
+ pic_size.width = static_cast(width);
+ pic_size.height = static_cast(height);
+
+ if (strcmp(type_name, "YUYV") == 0) {
+ // 预分配YUYV缓冲区,每个像素2字节
+ yuvFrame.create(height, width, CV_8UC2);
+ }
+
+ // 新增:人脸检测相关变量
+ int frame_count = 0;
+ vector last_detected_faces;
+ vector last_confidence_scores;
+ const int DETECT_INTERVAL = 5; /* 5: Detect every 5 frames */
+
+ while (!g_uvc_exit) {
+ cap >> frame;
+
+ if (frame.empty()) {
+ empty_frame_count++;
+ printf("Empty frame %d/%d, attempting to reconnect...\n", empty_frame_count, MAX_EMPTY_FRAMES);
+
+ if (empty_frame_count >= MAX_EMPTY_FRAMES) {
+ if (retry_count < MAX_RETRIES) {
+ printf("Attempting to reconnect camera (attempt %d/%d)...\n", retry_count + 1, MAX_RETRIES);
+ cap.release();
+ sleep(1);
+
+ cap.open(0, cv::CAP_V4L2);
+ if (cap.isOpened()) {
+ cap.set(CAP_PROP_FRAME_WIDTH, width);
+ cap.set(CAP_PROP_FRAME_HEIGHT, height);
+ cap.set(CAP_PROP_FPS, fps);
+ cap.set(CAP_PROP_BUFFERSIZE, 4); /* 4 cap prop buffer size */
+ if (strcmp(type_name, "MJPEG") == 0) {
+ cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));
+ } else {
+ cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('Y', 'U', 'Y', 'V'));
+ }
+
+ actual_width = cap.get(CAP_PROP_FRAME_WIDTH);
+ actual_height = cap.get(CAP_PROP_FRAME_HEIGHT);
+ actual_fps = cap.get(CAP_PROP_FPS);
+
+ printf("Camera reconnected successfully\n");
+ printf("New resolution: %dx%d @ %.2f fps\n", actual_width, actual_height, actual_fps);
+
+ retry_count = 0;
+ empty_frame_count = 0;
+ device_reconnected = true;
+ continue;
+ }
+ retry_count++;
+ printf("Retry %d/%d failed\n", retry_count, MAX_RETRIES);
+ } else {
+ printf("Failed to reconnect after %d attempts\n", MAX_RETRIES);
+ break;
+ }
+ }
+ continue;
+ }
+
+ empty_frame_count = 0;
+ retry_count = 0;
+
+ if (device_reconnected) {
+ printf("Reinitializing media pipeline...\n");
+ if (sample_uvc_media_init(type_name, width, height) != TD_SUCCESS) {
+ std::cerr << "media reinit failed!" << std::endl;
+ break;
+ }
+ device_reconnected = false;
+ }
+
+ // 人脸检测逻辑
+ frame_count++;
+ bool is_detect_frame = (frame_count % DETECT_INTERVAL == 0);
+
+ if (is_detect_frame) {
+ // 预处理阶段
+ Mat small_frame;
+ resize(frame, small_frame, Size(256, 144), 0, 0, INTER_NEAREST); /* 256 144 resize width height */
+
+ // 检测阶段
+ detector->detect(small_frame, faces);
+
+ // 处理检测结果
+ const int minFaceSize = 50; /* 50 min face size */
+ last_detected_faces.clear();
+ last_confidence_scores.clear();
+
+ if (faces.rows > 0) {
+ float scale_x = static_cast(frame.cols) / small_frame.cols;
+ float scale_y = static_cast(frame.rows) / small_frame.rows;
+
+ for (int i = 0; i < faces.rows; ++i) {
+ int x = static_cast(faces.at(i, 0) * scale_x);
+ int y = static_cast(faces.at(i, 1) * scale_y);
+ int w = static_cast(faces.at(i, 2) * scale_x); /* 2 the number of width */
+ int h = static_cast(faces.at(i, 3) * scale_y); /* 3 the number of heigth */
+ float score = faces.at(i, 4); /* 4 the number of socre */
+
+ if (w >= minFaceSize && h >= minFaceSize) {
+ last_detected_faces.emplace_back(x, y, w, h);
+ last_confidence_scores.push_back(score);
+ }
+ }
+ }
+ }
+
+ // 绘制人脸框
+ for (size_t i = 0; i < last_detected_faces.size(); ++i) {
+ rectangle(frame, last_detected_faces[i], Scalar(0, 255, 0), 2); /* 0 255 0 R G B, 2 Line width */
+ char scoreText[20]; /* 20 text buffer size */
+ ret = snprintf(scoreText, sizeof(scoreText), "Conf: %.2f",
+ last_confidence_scores[i] / 100); /* 100 get the percentage */
+ if (ret < 0) {
+ printf("[func]:%s [line]:%d [info]:snprintf failed\n", __FUNCTION__, __LINE__);
+ break;
+ }
+ putText(frame, scoreText, Point(last_detected_faces[i].x,
+ last_detected_faces[i].y - 5), /* 5 pic height minus 5 */
+ /* 0.5 scaling ratio 0 255 0 R G B, 1 Line width */
+ FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
+ }
+
+ // 后续处理保持不变
+ if (strcmp(type_name, "MJPEG") == 0) {
+ imencode(".jpg", frame, mjpeg_buffer, mjpeg_params);
+ ret = sample_uvc_media_send_data(mjpeg_buffer.data(), mjpeg_buffer.size(),
+ width, &pic_size, "MJPEG");
+ } else {
+ // YUYV格式转换
+ cvtColor(frame, yuvFrame, COLOR_BGR2YUV_YUY2);
+ ret = sample_uvc_media_send_data(yuvFrame.data, yuvFrame.total() * yuvFrame.elemSize(),
+ yuvFrame.step, &pic_size, "YUYV");
+ }
+
+ if (ret != 0) {
+ ret = -errno;
+ std::cerr << "write error: " << strerror(-ret) << std::endl;
+ }
+ }
+
+ printf("--media exit...\n");
+ sample_uvc_media_stop_receive_data();
+ sample_uvc_media_exit();
+ cap.release();
+
+#ifdef CONFIG_USER_SPACE
+ SDK_exit();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.c b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.c
new file mode 100755
index 0000000000000000000000000000000000000000..8afe3e73d0b97b8fed53b74f0256273f445f1e49
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "media_vdec.h"
+#include
+
+ot_vb_src g_vdec_vb_source = OT_VB_SRC_MOD;
+
+#define REF_NUM 2
+#define DISPLAY_NUM 2
+
+static vdec_display_cfg g_vdec_display_cfg = {
+ .pic_size = PIC_1080P,
+ .intf_sync = OT_VO_OUT_1080P60,
+ .intf_type = OT_VO_INTF_HDMI,
+};
+
+static td_u32 g_input_width;
+static td_u32 g_input_height;
+static ot_size g_disp_size;
+sample_vo_cfg g_vo_config;
+static td_bool g_is_need_vdec = TD_TRUE;
+
+static td_s32 sample_uvc_init_module_vb(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, ot_payload_type type,
+ td_u32 len)
+{
+ td_u32 i;
+ td_s32 ret;
+ for (i = 0; (i < vdec_chn_num) && (i < len); i++) {
+ sample_vdec[i].type = type;
+ sample_vdec[i].width = g_input_width;
+ sample_vdec[i].height = g_input_height;
+ sample_vdec[i].mode = sample_comm_vdec_get_lowdelay_en() ? OT_VDEC_SEND_MODE_COMPAT :
+ OT_VDEC_SEND_MODE_FRAME;
+ sample_vdec[i].sample_vdec_video.dec_mode = OT_VIDEO_DEC_MODE_IP;
+ sample_vdec[i].sample_vdec_video.bit_width = OT_DATA_BIT_WIDTH_8;
+ if (type == OT_PT_JPEG) {
+ sample_vdec[i].sample_vdec_video.ref_frame_num = 0;
+ } else {
+ sample_vdec[i].sample_vdec_video.ref_frame_num = REF_NUM;
+ }
+ sample_vdec[i].display_frame_num = DISPLAY_NUM;
+ sample_vdec[i].frame_buf_cnt = (type == OT_PT_JPEG) ? (sample_vdec[i].display_frame_num + 1) :
+ (sample_vdec[i].sample_vdec_video.ref_frame_num + sample_vdec[i].display_frame_num + 1);
+ if (type == OT_PT_JPEG) {
+ sample_vdec[i].sample_vdec_picture.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ sample_vdec[i].sample_vdec_picture.alpha = 255; /* 255:pic alpha value */
+ }
+ }
+ ret = sample_comm_vdec_init_vb_pool(vdec_chn_num, &sample_vdec[0], len);
+ if (ret != TD_SUCCESS) {
+ sample_print("init mod common vb fail for %#x!\n", ret);
+ return ret;
+ }
+ return ret;
+}
+
+static td_s32 sample_uvc_init_sys_and_vb(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, ot_payload_type type,
+ td_u32 len)
+{
+ ot_vb_cfg vb_cfg;
+ ot_pic_buf_attr buf_attr = {0};
+ td_s32 ret;
+ ret = sample_comm_sys_get_pic_size(g_vdec_display_cfg.pic_size, &g_disp_size);
+ if (ret != TD_SUCCESS) {
+ sample_print("sys get pic size fail for %#x!\n", ret);
+ return ret;
+ }
+ buf_attr.align = 0;
+ buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
+ buf_attr.compress_mode = OT_COMPRESS_MODE_SEG;
+ buf_attr.height = 2160; /* 2160:height */
+ buf_attr.width = 3840; /* 3840:width */
+ buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+
+ (td_void)memset_s(&vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
+ vb_cfg.max_pool_cnt = 1;
+ vb_cfg.common_pool[0].blk_cnt = 10 * vdec_chn_num; /* 10:common vb cnt */
+ vb_cfg.common_pool[0].blk_size = ot_common_get_pic_buf_size(&buf_attr);
+ ret = sample_comm_sys_init(&vb_cfg);
+ if (ret != TD_SUCCESS) {
+ sample_print("init sys fail for %#x!\n", ret);
+ sample_comm_sys_exit();
+ return ret;
+ }
+
+ if (g_is_need_vdec == TD_TRUE) {
+ ret = sample_uvc_init_module_vb(&sample_vdec[0], vdec_chn_num, type, len);
+ if (ret != TD_SUCCESS) {
+ sample_print("init mod vb fail for %#x!\n", ret);
+ sample_comm_vdec_exit_vb_pool();
+ sample_comm_sys_exit();
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static td_s32 sample_uvc_vdec_bind_vpss(td_u32 vpss_grp_num)
+{
+ td_u32 i;
+ td_s32 ret = TD_SUCCESS;
+ for (i = 0; i < vpss_grp_num; i++) {
+ ret = sample_comm_vdec_bind_vpss(i, i);
+ if (ret != TD_SUCCESS) {
+ sample_print("vdec bind vpss fail for %#x!\n", ret);
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static td_void sample_uvc_stop_vpss(ot_vpss_grp vpss_grp, td_bool *vpss_chn_enable, td_u32 chn_array_size)
+{
+ td_s32 i;
+ for (i = vpss_grp; i >= 0; i--) {
+ vpss_grp = i;
+ sample_common_vpss_stop(vpss_grp, &vpss_chn_enable[0], chn_array_size);
+ }
+}
+
+static td_s32 sample_uvc_vdec_unbind_vpss(td_u32 vpss_grp_num)
+{
+ td_u32 i;
+ td_s32 ret = TD_SUCCESS;
+ for (i = 0; i < vpss_grp_num; i++) {
+ ret = sample_comm_vdec_un_bind_vpss(i, i);
+ if (ret != TD_SUCCESS) {
+ sample_print("vdec unbind vpss fail for %#x!\n", ret);
+ }
+ }
+ return ret;
+}
+
+static td_void sample_uvc_config_vpss_grp_attr(ot_vpss_grp_attr *vpss_grp_attr)
+{
+ vpss_grp_attr->max_width = g_input_width;
+ vpss_grp_attr->max_height = g_input_height;
+ vpss_grp_attr->frame_rate.src_frame_rate = -1;
+ vpss_grp_attr->frame_rate.dst_frame_rate = -1;
+ vpss_grp_attr->pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ vpss_grp_attr->nr_en = TD_FALSE;
+ vpss_grp_attr->ie_en = TD_FALSE;
+ vpss_grp_attr->dci_en = TD_FALSE;
+ vpss_grp_attr->dei_mode = OT_VPSS_DEI_MODE_OFF;
+ vpss_grp_attr->buf_share_en = TD_FALSE;
+}
+
+static td_void sample_uvc_stop_vdec(td_u32 vdec_chn_num)
+{
+ if (g_is_need_vdec == TD_FALSE) {
+ return;
+ }
+ sample_comm_vdec_stop(vdec_chn_num);
+ sample_comm_vdec_exit_vb_pool();
+
+ return;
+}
+
+static td_s32 sample_uvc_start_vdec(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, td_u32 len)
+{
+ td_s32 ret;
+
+ if (g_is_need_vdec == TD_FALSE) {
+ return TD_SUCCESS;
+ }
+ ret = sample_comm_vdec_start(vdec_chn_num, &sample_vdec[0], len);
+ if (ret != TD_SUCCESS) {
+ sample_print("start VDEC fail for %#x!\n", ret);
+ sample_uvc_stop_vdec(vdec_chn_num);
+ }
+
+ return ret;
+}
+
+static td_s32 sample_uvc_config_vpss_ldy_attr(td_u32 vpss_grp_num)
+{
+ td_u32 i;
+ td_s32 ret;
+ ot_low_delay_info vpss_ldy_info;
+
+ for (i = 0; i < vpss_grp_num; i++) {
+ ret = ss_mpi_vpss_get_low_delay_attr(i, 0, &vpss_ldy_info);
+ if (ret != TD_SUCCESS) {
+ sample_print("vpss get low delay attr fail for %#x!\n", ret);
+ return ret;
+ }
+ vpss_ldy_info.enable = TD_TRUE;
+ vpss_ldy_info.line_cnt = g_disp_size.height / 4 * 1; /* 1/4:lowdelay line num */
+ ret = ss_mpi_vpss_set_low_delay_attr(i, 0, &vpss_ldy_info);
+ if (ret != TD_SUCCESS) {
+ sample_print("vpss set low delay attr fail for %#x!\n", ret);
+ return ret;
+ }
+ }
+ return TD_SUCCESS;
+}
+
+static td_s32 sample_uvc_start_vpss(ot_vpss_grp *vpss_grp, td_u32 vpss_grp_num,
+ td_bool *vpss_chn_enable, td_u32 arr_len)
+{
+ td_u32 i;
+ td_s32 ret;
+ ot_vpss_chn_attr vpss_chn_attr[OT_VPSS_MAX_CHN_NUM];
+ ot_vpss_grp_attr vpss_grp_attr = {0};
+ sample_uvc_config_vpss_grp_attr(&vpss_grp_attr);
+ (td_void)memset_s(vpss_chn_enable, arr_len * sizeof(td_bool), 0, arr_len * sizeof(td_bool));
+ if (arr_len > 1) {
+ vpss_chn_enable[0] = TD_TRUE;
+ vpss_chn_attr[0].width = g_disp_size.width;
+ vpss_chn_attr[0].height = g_disp_size.height;
+ vpss_chn_attr[0].chn_mode = OT_VPSS_CHN_MODE_USER;
+ vpss_chn_attr[0].compress_mode = OT_COMPRESS_MODE_NONE;
+ vpss_chn_attr[0].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ vpss_chn_attr[0].video_format = OT_VIDEO_FORMAT_LINEAR;
+ vpss_chn_attr[0].frame_rate.src_frame_rate = -1;
+ vpss_chn_attr[0].frame_rate.dst_frame_rate = -1;
+ vpss_chn_attr[0].depth = 0;
+ vpss_chn_attr[0].mirror_en = TD_FALSE;
+ vpss_chn_attr[0].flip_en = TD_FALSE;
+ vpss_chn_attr[0].border_en = TD_FALSE;
+ vpss_chn_attr[0].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
+ }
+
+ for (i = 0; i < vpss_grp_num; i++) {
+ *vpss_grp = i;
+ ret = sample_common_vpss_start(*vpss_grp, &vpss_chn_enable[0],
+ &vpss_grp_attr, vpss_chn_attr, OT_VPSS_MAX_CHN_NUM);
+ if (ret != TD_SUCCESS) {
+ sample_print("start VPSS fail for %#x!\n", ret);
+ sample_uvc_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+ return ret;
+ }
+ }
+ ret = sample_uvc_config_vpss_ldy_attr(vpss_grp_num);
+ if (ret != TD_SUCCESS) {
+ sample_uvc_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+ return ret;
+ }
+ ret = sample_uvc_vdec_bind_vpss(vpss_grp_num);
+ if (ret != TD_SUCCESS) {
+ sample_uvc_vdec_unbind_vpss(vpss_grp_num);
+ sample_uvc_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+ }
+ return ret;
+}
+
+static td_s32 sample_uvc_vpss_bind_vo(sample_vo_cfg vo_config, td_u32 vpss_grp_num)
+{
+ td_u32 i;
+ ot_vo_layer vo_layer;
+ td_s32 ret = TD_SUCCESS;
+ vo_layer = vo_config.vo_dev;
+ for (i = 0; i < vpss_grp_num; i++) {
+ ret = sample_comm_vpss_bind_vo(i, 0, vo_layer, i);
+ if (ret != TD_SUCCESS) {
+ sample_print("vpss bind vo fail for %#x!\n", ret);
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static td_s32 sample_uvc_vpss_unbind_vo(td_u32 vpss_grp_num, sample_vo_cfg vo_config)
+{
+ td_u32 i;
+ ot_vo_layer vo_layer = vo_config.vo_dev;
+ td_s32 ret = TD_SUCCESS;
+ for (i = 0; i < vpss_grp_num; i++) {
+ ret = sample_comm_vpss_un_bind_vo(i, 0, vo_layer, i);
+ if (ret != TD_SUCCESS) {
+ sample_print("vpss unbind vo fail for %#x!\n", ret);
+ }
+ }
+ return ret;
+}
+
+static td_void sample_uvc_get_default_vo_cfg(sample_vo_cfg *vo_config)
+{
+ vo_config->vo_dev = SAMPLE_VO_DEV_UHD;
+ vo_config->vo_intf_type = g_vdec_display_cfg.intf_type;
+ vo_config->intf_sync = g_vdec_display_cfg.intf_sync;
+ vo_config->pic_size = g_vdec_display_cfg.pic_size;
+ vo_config->bg_color = COLOR_RGB_BLUE;
+ vo_config->dis_buf_len = 3; /* 3:buf length */
+ vo_config->dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8;
+ vo_config->vo_mode = VO_MODE_1MUX;
+ vo_config->pix_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ vo_config->disp_rect.x = 0;
+ vo_config->disp_rect.y = 0;
+ vo_config->disp_rect.width = g_disp_size.width;
+ vo_config->disp_rect.height = g_disp_size.height;
+ vo_config->image_size.width = g_disp_size.width;
+ vo_config->image_size.height = g_disp_size.height;
+ vo_config->vo_part_mode = OT_VO_PARTITION_MODE_SINGLE;
+ vo_config->compress_mode = OT_COMPRESS_MODE_NONE;
+}
+
+static td_s32 sample_uvc_start_vo(sample_vo_cfg *vo_config, td_u32 vpss_grp_num)
+{
+ td_s32 ret;
+ sample_uvc_get_default_vo_cfg(vo_config);
+ ret = sample_comm_vo_start_vo(vo_config);
+ if (ret != TD_SUCCESS) {
+ sample_print("start VO fail for %#x!\n", ret);
+ sample_comm_vo_stop_vo(vo_config);
+ return ret;
+ }
+ ret = sample_uvc_vpss_bind_vo(*vo_config, vpss_grp_num);
+ if (ret != TD_SUCCESS) {
+ sample_uvc_vpss_unbind_vo(vpss_grp_num, *vo_config);
+ sample_comm_vo_stop_vo(vo_config);
+ }
+
+ return ret;
+}
+
+static ot_payload_type sample_uvc_get_payload_type(const td_char *type_name)
+{
+ if (strcmp(type_name, "H264") == 0) {
+ return OT_PT_H264;
+ } else if (strcmp(type_name, "H265") == 0) {
+ return OT_PT_H265;
+ } else if (strcmp(type_name, "MJPEG") == 0) {
+ return OT_PT_JPEG;
+ } else {
+ sample_print("type name error!\n");
+ return OT_PT_BUTT;
+ }
+}
+
+static td_void sample_uvc_update_vdec_flag(const td_char *type_name)
+{
+ if ((strcmp(type_name, "H264") == 0) ||
+ (strcmp(type_name, "H265") == 0) ||
+ (strcmp(type_name, "MJPEG") == 0)) {
+ g_is_need_vdec = TD_TRUE;
+ } else {
+ g_is_need_vdec = TD_FALSE;
+ }
+}
+
+td_s32 sample_uvc_media_init(const td_char *type_name, td_u32 width, td_u32 height)
+{
+ td_s32 ret;
+ td_u32 vdec_chn_num;
+ td_u32 vpss_grp_num;
+ sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
+ td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
+ ot_vpss_grp vpss_grp;
+
+ ot_payload_type payload_type = OT_PT_H264;
+ vdec_chn_num = 1;
+ vpss_grp_num = vdec_chn_num;
+ g_input_width = width;
+ g_input_height = height;
+ sample_uvc_update_vdec_flag(type_name);
+
+ if (g_is_need_vdec == TD_TRUE) {
+ payload_type = sample_uvc_get_payload_type(type_name);
+ if (payload_type == OT_PT_BUTT) {
+ return TD_FAILURE;
+ }
+ }
+ ret = sample_uvc_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, payload_type, OT_VDEC_MAX_CHN_NUM);
+ if (ret != TD_SUCCESS) {
+ return ret;
+ }
+ ret = sample_uvc_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM);
+ if (ret != TD_SUCCESS) {
+ goto stop_sys;
+ }
+ ret = sample_uvc_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+ if (ret != TD_SUCCESS) {
+ goto stop_vdec;
+ }
+ ret = sample_uvc_start_vo(&g_vo_config, vpss_grp_num);
+ if (ret != TD_SUCCESS) {
+ goto stop_vpss;
+ }
+
+ return TD_SUCCESS;
+
+stop_vpss:
+ ret = sample_uvc_vdec_unbind_vpss(vpss_grp_num);
+ sample_uvc_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+stop_vdec:
+ sample_uvc_stop_vdec(vdec_chn_num);
+stop_sys:
+ sample_comm_sys_exit();
+
+ return TD_FAILURE;
+}
+
+td_s32 sample_uvc_media_exit(td_void)
+{
+ td_u32 vdec_chn_num = 1;
+ td_u32 vpss_grp_num = 1;
+ ot_vpss_grp vpss_grp = 0;
+ td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM] = {0};
+ vpss_chn_enable[0] = TD_TRUE;
+
+ (td_void)sample_uvc_vpss_unbind_vo(vpss_grp_num, g_vo_config);
+ sample_comm_vo_stop_vo(&g_vo_config);
+ (td_void)sample_uvc_vdec_unbind_vpss(vpss_grp_num);
+ sample_uvc_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
+ sample_uvc_stop_vdec(vdec_chn_num);
+ sample_comm_sys_exit();
+
+ return TD_SUCCESS;
+}
+
+static td_void sample_uvc_cut_stream_for_mjpeg(td_void *data, td_u32 size, td_s32 chn_id,
+ td_s32 *read_num, td_u32 *start)
+{
+ td_s32 i;
+ td_u32 len;
+ td_s32 read_len = size;
+ td_u8 *buf = data;
+ td_bool find_start = TD_FALSE;
+ for (i = 0; i < read_len - 1; i++) {
+ if (buf[i] == 0xFF && buf[i + 1] == 0xD8) { /* 0xFFD8: JPEG起始标记 */
+ *start = i;
+ find_start = TD_TRUE;
+ i = i + 2; /* 2: 跳过标记长度 */
+ break;
+ }
+ }
+
+ /* 3: 检查下一个标记头所需长度 */
+ for (; i < read_len - 3; i++) {
+ if ((buf[i] == 0xFF) && (buf[i + 1] & 0xF0) == 0xE0) {
+ len = (buf[i + 2] << 8) + buf[i + 3]; /* 2 3 index 8: 长度字段占2字节 */
+ i += 1 + len;
+ } else {
+ break;
+ }
+ }
+
+ for (; i < read_len - 1; i++) {
+ if (buf[i] == 0xFF && buf[i + 1] == 0xD9) { /* 0xFFD9: JPEG结束标记 */
+ break;
+ }
+ }
+ read_len = i + 2; /* 2: 包含结束标记 */
+
+ if (find_start == TD_FALSE) {
+ sample_print("chn %d can not find JPEG start code! read_len %d!\n", chn_id, read_len);
+ }
+
+ *read_num = read_len;
+}
+
+static td_void sample_uvc_cut_stream_for_h264(td_void *data, td_u32 size, td_s32 chn_id, td_s32 *read_num)
+{
+ td_bool find_start = TD_FALSE;
+ td_bool find_end = TD_FALSE;
+ td_s32 i;
+ td_u8 *buf = data;
+ td_s32 read_len = size;
+ for (i = 0; i < read_len - 8; i++) { /* 8: 起始码最小长度 */
+ int tmp = buf[i + 3] & 0x1F; /* 0x1F: NALU类型掩码 */
+ /* 0x5: IDR帧, 0x1: 非IDR帧 0x80: 关键帧标志 2 index */
+ if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 &&
+ (((tmp == 0x5 || tmp == 0x1) && ((buf[i + 4] & 0x80) == 0x80)) || /* 4 index */
+ (tmp == 20 && (buf[i + 7] & 0x80) == 0x80))) { /* 20 帧起始类型 7 index */
+ find_start = TD_TRUE;
+ i += 8; /* 8: 跳过起始码 */
+ break;
+ }
+ }
+
+ for (; i < read_len - 8; i++) { /* 8: 查找结束所需最小长度 */
+ int tmp = buf[i + 3] & 0x1F; /* 0x1F: NALU类型掩码 */
+ if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 2 index */
+ (tmp == 15 || tmp == 7 || tmp == 8 || tmp == 6 || /* 15 SEI 7 SPS 8 PPS 6 SEI */
+ ((tmp == 5 || tmp == 1) && ((buf[i + 4] & 0x80) == 0x80)) || /* 5 1 帧起始类型 4 index */
+ (tmp == 20 && (buf[i + 7] & 0x80) == 0x80))) { /* 20 帧起始类型 7 index */
+ find_end = TD_TRUE;
+ break;
+ }
+ }
+
+ if (i > 0) {
+ read_len = i;
+ }
+
+ if (find_start == TD_FALSE) {
+ sample_print("chn %d can not find H264 start code! read_len %d!\n", chn_id, read_len);
+ }
+
+ if (find_end == TD_FALSE) {
+ read_len = i + 8; /* 8: 包含下一帧起始码 */
+ }
+
+ *read_num = read_len;
+}
+
+static td_void sample_uvc_cut_stream_for_h265(td_void *data, td_u32 size, td_s32 chn_id, td_s32 *read_num)
+{
+ td_bool find_start = TD_FALSE;
+ td_bool find_end = TD_FALSE;
+ td_bool new_pic = TD_FALSE;
+ td_s32 i;
+ td_u8 *buf = data;
+ td_s32 read_len = size;
+ for (i = 0; i < read_len - 6; i++) { /* 6:h265 frame start code length */
+ td_u32 tmp = (buf[i + 3] & 0x7E) >> 1; /* 0x7E:frame start marker 3:index */
+ new_pic = (buf[i + 0] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
+ (tmp <= 21) && ((buf[i + 5] & 0x80) == 0x80)); /* 5:index 21 0x80:frame start marker */
+
+ if (new_pic) {
+ find_start = TD_TRUE;
+ i += 6; /* 6:h265 frame start code length */
+ break;
+ }
+ }
+
+ for (; i < read_len - 6; i++) { /* 6:h265 frame start code length */
+ td_u32 tmp = (buf[i + 3] & 0x7E) >> 1; /* 0x7E:frame start marker 3:index */
+ new_pic = (buf[i + 0] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
+ (tmp == 32 || tmp == 33 || tmp == 34 || tmp == 39 || tmp == 40 || /* 32 33 34 39 40:frame start marker */
+ ((tmp <= 21) && (buf[i + 5] & 0x80) == 0x80))); /* 5:index 21 0x80:frame start marker */
+
+ if (new_pic) {
+ find_end = TD_TRUE;
+ break;
+ }
+ }
+
+ if (i > 0) {
+ read_len = i;
+ }
+
+ if (find_start == TD_FALSE) {
+ sample_print("chn %d can not find H265 start code! read_len %d!\n", chn_id, read_len);
+ }
+
+ if (find_end == TD_FALSE) {
+ read_len = i + 6; /* 6:h265 frame start code length */
+ }
+
+ *read_num = read_len;
+}
+
+static td_s32 sample_uvc_prepare_frame_info(ot_vb_blk vb_blk, const ot_pic_buf_attr *buf_attr,
+ const ot_vb_calc_cfg *calc_cfg, ot_video_frame_info *video_frame)
+{
+ video_frame->video_frame.header_phys_addr[0] = ss_mpi_vb_handle_to_phys_addr(vb_blk);
+ if (video_frame->video_frame.header_phys_addr[0] == TD_NULL) {
+ sample_print("ss_mpi_vb_handle_to_phys_addr fail\n");
+ return TD_FAILURE;
+ }
+
+ video_frame->video_frame.header_virt_addr[0] =
+ (td_u8*)ss_mpi_sys_mmap(video_frame->video_frame.header_phys_addr[0], calc_cfg->vb_size);
+ if (video_frame->video_frame.header_virt_addr[0] == TD_NULL) {
+ sample_print("ss_mpi_sys_mmap fail\n");
+ return TD_FAILURE;
+ }
+
+ video_frame->mod_id = OT_ID_VGS;
+ video_frame->pool_id = ss_mpi_vb_handle_to_pool_id(vb_blk);
+
+ video_frame->video_frame.header_phys_addr[1] =
+ video_frame->video_frame.header_phys_addr[0] + calc_cfg->head_y_size;
+ video_frame->video_frame.header_virt_addr[1] =
+ video_frame->video_frame.header_virt_addr[0] + calc_cfg->head_y_size;
+ video_frame->video_frame.phys_addr[0] =
+ video_frame->video_frame.header_phys_addr[0] + calc_cfg->head_size;
+ video_frame->video_frame.phys_addr[1] =
+ video_frame->video_frame.phys_addr[0] + calc_cfg->main_y_size;
+ video_frame->video_frame.virt_addr[0] =
+ video_frame->video_frame.header_virt_addr[0] + calc_cfg->head_size;
+ video_frame->video_frame.virt_addr[1] =
+ video_frame->video_frame.virt_addr[0] + calc_cfg->main_y_size;
+ video_frame->video_frame.header_stride[0] = calc_cfg->head_stride;
+ video_frame->video_frame.header_stride[1] = calc_cfg->head_stride;
+ video_frame->video_frame.stride[0] = calc_cfg->main_stride;
+ video_frame->video_frame.stride[1] = calc_cfg->main_stride;
+
+ video_frame->video_frame.width = buf_attr->width;
+ video_frame->video_frame.height = buf_attr->height;
+ video_frame->video_frame.dynamic_range = OT_DYNAMIC_RANGE_SDR8;
+ video_frame->video_frame.compress_mode = OT_COMPRESS_MODE_NONE;
+ video_frame->video_frame.video_format = OT_VIDEO_FORMAT_LINEAR;
+ video_frame->video_frame.field = OT_VIDEO_FIELD_FRAME;
+ video_frame->video_frame.pixel_format = OT_PIXEL_FORMAT_YUV_SEMIPLANAR_420;
+
+ return TD_SUCCESS;
+}
+
+static td_void sample_uvc_buf_attr_init(const ot_size *pic_size, ot_pic_buf_attr *buf_attr)
+{
+ buf_attr->width = pic_size->width;
+ buf_attr->height = pic_size->height;
+ buf_attr->pixel_format = OT_PIXEL_FORMAT_YUV_SEMIPLANAR_420;
+ buf_attr->compress_mode = OT_COMPRESS_MODE_NONE;
+ buf_attr->align = 0;
+ buf_attr->bit_width = OT_DATA_BIT_WIDTH_8;
+}
+
+static td_void sample_uvc_yuyv_to_nv12(td_char *image_in, td_u32 width, td_u32 height,
+ td_u32 size, td_char *image_out)
+{
+ td_s32 pixel_num = width * height;
+ td_u32 cycle_num = size / pixel_num / 2; /* 2: YUYV格式中每个像素占2字节 */
+
+ td_char *y = image_out;
+ td_char *uv = image_out + pixel_num;
+
+ td_char *start = image_in;
+ td_u32 i = 0;
+ td_u32 j = 0;
+ td_u32 k = 0;
+
+ /* Y */
+ for (i = 0; i < cycle_num; i++) {
+ int index = 0;
+ for (j = 0; j < pixel_num * 2; j = j + 2) { /* 2: 跳过UV分量,每次取Y */
+ *(y + index) = *(start + j);
+ index++;
+ }
+ start = image_in + pixel_num * 2 * i; /* 2: 每帧YUYV数据跨度 */
+ y = y + pixel_num * 3 / 2; /* 3/2: NV12中Y+UV的总大小比例 */
+ }
+
+ /* UV */
+ start = image_in;
+ for (i = 0; i < cycle_num; i++) {
+ int uv_index = 0;
+ for (j = 0; j < height; j = j + 2) { /* 2: 隔行采样UV */
+ /* 2: YUYV宽度步进 4: 每两个像素的YUYV数据块 1: 取U分量的位置偏移 2: 取下一个V分量的偏移 */
+ for (k = j * width * 2 + 1; k < width * 2 * (j + 1); k = k + 4) {
+ *(uv + uv_index) = *(start + k); /* U分量 */
+ *(uv + uv_index + 1) = *(start + k + 2); /* 2 取下一个V分量的偏移 */
+ uv_index += 2; /* 2: UV平面存储步进 */
+ }
+ }
+ start = image_in + pixel_num * 2 * i; /* 2: 每帧YUYV数据跨度 */
+ uv = uv + pixel_num * 3 / 2; /* 3/2: NV12中Y+UV的总大小比例 */
+ }
+}
+
+static td_void sample_uvc_update_vb_cfg(ot_pixel_format pixel_format, td_u32 stride, const ot_size *pic_size,
+ ot_vb_calc_cfg *calc_cfg)
+{
+ if (pixel_format != OT_PIXEL_FORMAT_YUYV_PACKAGE_422) {
+ return;
+ }
+
+ calc_cfg->main_stride = stride >> 1;
+ calc_cfg->main_y_size = calc_cfg->main_stride * pic_size->height;
+}
+
+static td_s32 sample_uvc_send_frame_to_vpss(td_void *data, td_u32 size, td_u32 stride,
+ const ot_size *pic_size, ot_pixel_format pixel_format)
+{
+ td_s32 ret;
+ ot_vpss_grp grp = 0;
+ ot_video_frame_info frame_info = {0};
+ td_s32 milli_sec = -1;
+ ot_vb_blk vb_blk;
+ ot_pic_buf_attr buf_attr;
+ ot_vb_calc_cfg calc_cfg;
+ sample_uvc_buf_attr_init(pic_size, &buf_attr);
+ ot_common_get_pic_buf_cfg(&buf_attr, &calc_cfg);
+ sample_uvc_update_vb_cfg(pixel_format, stride, pic_size, &calc_cfg);
+ vb_blk = ss_mpi_vb_get_blk(OT_VB_INVALID_POOL_ID, calc_cfg.vb_size, TD_NULL);
+ if (vb_blk == OT_VB_INVALID_HANDLE) {
+ sample_print("get vb blk(size:%d) failed!\n", calc_cfg.vb_size);
+ return TD_FAILURE;
+ }
+ ret = sample_uvc_prepare_frame_info(vb_blk, &buf_attr, &calc_cfg, &frame_info);
+ if (ret != TD_SUCCESS) {
+ return ret;
+ }
+
+ if (pixel_format == OT_PIXEL_FORMAT_YUYV_PACKAGE_422) {
+ sample_uvc_yuyv_to_nv12(data, pic_size->width, pic_size->height, size, frame_info.video_frame.virt_addr[0]);
+ } else {
+ frame_info.video_frame.pixel_format = pixel_format;
+ (td_void)memcpy_s(frame_info.video_frame.virt_addr[0], size, data, size);
+ }
+ ret = ss_mpi_vpss_send_frame(grp, &frame_info, milli_sec);
+ if (ret != TD_SUCCESS) {
+ sample_print("send frame to vpss failed!\n");
+ }
+ ss_mpi_sys_munmap(frame_info.video_frame.virt_addr[0], calc_cfg.vb_size);
+ ret = ss_mpi_vb_release_blk(vb_blk);
+ if (ret != TD_SUCCESS) {
+ sample_print("release vb failed!\n");
+ return TD_FAILURE;
+ }
+
+ return ret;
+}
+
+static td_s32 sample_uvc_get_pixel_format(const td_char *type_name, ot_pixel_format *pixel_format)
+{
+ if (strcmp(type_name, "YUYV") == 0) {
+ *pixel_format = OT_PIXEL_FORMAT_YUYV_PACKAGE_422;
+ } else if (strcmp(type_name, "NV12") == 0) {
+ *pixel_format = OT_PIXEL_FORMAT_YUV_SEMIPLANAR_420;
+ } else if (strcmp(type_name, "NV21") == 0) {
+ *pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
+ } else {
+ sample_print("pixel format error!\n");
+ return TD_FAILURE;
+ }
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_uvc_media_send_data(td_void *data, td_u32 size, td_u32 stride,
+ const ot_size *pic_size, const td_char *type_name)
+{
+ td_bool end_of_stream = TD_FALSE;
+ td_s32 read_len = size;
+ td_u8 *buf = data;
+ ot_vdec_stream vdec_stream;
+ td_u32 start = 0;
+ td_s32 ret;
+ td_s32 chn_id = 0;
+ ot_pixel_format pixel_format;
+ td_bool send_again = TD_TRUE;
+
+ if (strcmp(type_name, "MJPEG") == 0) {
+ sample_uvc_cut_stream_for_mjpeg(data, size, chn_id, &read_len, &start);
+ } else if (strcmp(type_name, "H264") == 0) {
+ sample_uvc_cut_stream_for_h264(data, size, chn_id, &read_len);
+ } else if (strcmp(type_name, "H265") == 0) {
+ sample_uvc_cut_stream_for_h265(data, size, chn_id, &read_len);
+ } else {
+ ret = sample_uvc_get_pixel_format(type_name, &pixel_format);
+ if (ret != TD_SUCCESS) {
+ return ret;
+ }
+ return sample_uvc_send_frame_to_vpss(data, size, stride, pic_size, pixel_format);
+ }
+
+ vdec_stream.addr = buf + start;
+ vdec_stream.len = read_len;
+ vdec_stream.end_of_frame = TD_TRUE;
+ vdec_stream.end_of_stream = end_of_stream;
+ vdec_stream.need_display = 1;
+
+ while (send_again == TD_TRUE) {
+ ss_mpi_sys_get_cur_pts(&vdec_stream.pts);
+ ret = ss_mpi_vdec_send_stream(chn_id, &vdec_stream, 0);
+ if (ret != TD_SUCCESS) {
+ usleep(1000); /* 1000 sleep 1000us */
+ sample_print("send stream to vdec failed!\n");
+ continue;
+ } else {
+ end_of_stream = TD_FALSE;
+ }
+ send_again = TD_FALSE;
+ }
+ usleep(1000); /* 1000 sleep 1000us */
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_uvc_media_stop_receive_data(td_void)
+{
+ ot_vdec_stream vdec_stream = {0};
+ td_u32 vdec_chn_num = 1;
+ td_s32 chn_id = 0;
+
+ if (g_is_need_vdec == TD_FALSE) {
+ return TD_SUCCESS;
+ }
+
+ vdec_stream.end_of_stream = TD_TRUE;
+ ss_mpi_vdec_send_stream(chn_id, &vdec_stream, -1);
+ ss_mpi_vdec_stop_recv_stream(vdec_chn_num);
+
+ return TD_SUCCESS;
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* End of #ifdef __cplusplus */
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.h b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.h
new file mode 100755
index 0000000000000000000000000000000000000000..dcd6942734b98e09e5befc75a6cac348d7fa38c8
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/media_vdec.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_VDEC_H__
+#define __MEDIA_VDEC_H__
+
+#include "sample_comm.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+td_s32 sample_uvc_media_init(const td_char *type_name, td_u32 width, td_u32 height);
+td_s32 sample_uvc_media_exit(td_void);
+td_s32 sample_uvc_media_send_data(td_void *data, td_u32 data_size, td_u32 stride,
+ const ot_size *pic_size, const td_char *type_name);
+td_s32 sample_uvc_media_stop_receive_data(td_void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* End of #ifdef __cplusplus */
+
+
+#endif /* end of #ifndef __MEDIA_VDEC_H__ */
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/onnx/face_detection_yunet_2023mar.onnx b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/onnx/face_detection_yunet_2023mar.onnx
new file mode 100755
index 0000000000000000000000000000000000000000..f9beb3044f3791affe1c2f0932af31927e2e4705
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/onnx/face_detection_yunet_2023mar.onnx differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20221114150205685.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20221114150205685.png
new file mode 100755
index 0000000000000000000000000000000000000000..4dc4215c962c57ba0e31548fb98c29c789f149d9
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20221114150205685.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210161601541.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210161601541.png
new file mode 100755
index 0000000000000000000000000000000000000000..80845ece8131933a4cd56ae3bd6119c38e0abd26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210161601541.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210170027454.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210170027454.png
new file mode 100755
index 0000000000000000000000000000000000000000..c06081fc2c963af4d1fa8af506804beedefe1b0b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250210170027454.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250213112932380.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250213112932380.png
new file mode 100755
index 0000000000000000000000000000000000000000..8b591b3437544859f4ec76b9ca03867cc401078c
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250213112932380.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919150630870.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919150630870.png
new file mode 100755
index 0000000000000000000000000000000000000000..91f881e85b3292118336ce2c3d81968e4aee8c26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919150630870.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151018659.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151018659.png
new file mode 100755
index 0000000000000000000000000000000000000000..9b09507893b65d2142be49e6461daa31a81855c4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151018659.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151519310.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151519310.png
new file mode 100755
index 0000000000000000000000000000000000000000..7f6d881a5d0e6d3f72b7a43d089b5c5a75d7f048
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919151519310.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181207847.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181207847.png
new file mode 100755
index 0000000000000000000000000000000000000000..08df0f6a6eb2e5c602d2b818c18347651384099b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181207847.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181826651.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181826651.png
new file mode 100755
index 0000000000000000000000000000000000000000..aaab3c4c1e0461bcd92fe63139841fddde7f7ba0
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181826651.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181855261.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181855261.png
new file mode 100755
index 0000000000000000000000000000000000000000..b629a8f13c23348fb7267180b4f47e1aa3b065ce
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919181855261.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182525339.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182525339.png
new file mode 100755
index 0000000000000000000000000000000000000000..6c4d223c9998d82e2c72cf1d5461aa373f0ed880
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182525339.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182655395.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182655395.png
new file mode 100755
index 0000000000000000000000000000000000000000..e43e99ff241013e06a69b330ac0afdc683156472
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182655395.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182937455.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182937455.png
new file mode 100755
index 0000000000000000000000000000000000000000..1eb3de878098d1f78e8a36fd78a56d54ea197de9
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919182937455.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183224310.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183224310.png
new file mode 100755
index 0000000000000000000000000000000000000000..b539dd4175d5937062827ba614b2993165d510e4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183224310.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183401330.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183401330.png
new file mode 100755
index 0000000000000000000000000000000000000000..bea2b8acdd54f9eb7146a598b91c48da8895e0de
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183401330.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183513040.png b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183513040.png
new file mode 100755
index 0000000000000000000000000000000000000000..d31cf4f5366f15bfeca2abc2cbf1999eab8cd3f2
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/opencv_dnn/pic/image-20250919183513040.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/Makefile b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/Makefile
new file mode 100755
index 0000000000000000000000000000000000000000..3f3058a2e4d124d2bd7ecd595e454f3bf817acd4
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/Makefile
@@ -0,0 +1,48 @@
+# 编译所需的公共文件
+include ../mk.param
+
+# 编译后生成的可执行文件名
+TARGET := main
+
+# 编译此工程需要包含的头文件
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/
+CFLAGS += -I$(SDK_SAMPLE_COMMON_DIR)/
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)/svp_npu
+CFLAGS += -I$(KCF_TRACK_SAMPLE_DIR)/
+
+# 编译此工程需要依赖的.c或.cpp文件
+SMP_SRCS := $(SDK_SAMPLE_COMMON_DIR)/sample_comm_sys.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_ipc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_isp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vi.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vo.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_mipi_tx.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vpss.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/loadbmp.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_vdec.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sample_comm_venc.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_init.c
+SMP_SRCS += $(SDK_SAMPLE_COMMON_DIR)/sdk_exit.c
+SMP_SRCS += $(wildcard $(SVP_COMMON_DIR)/*.c)
+SMP_SRCS += $(KCF_TRACK_SAMPLE_DIR)/main.c
+SMP_SRCS += $(KCF_TRACK_SAMPLE_DIR)/sample_kcf_track.c
+SMP_SRCS += $(KCF_TRACK_SAMPLE_DIR)/sample_svp_npu_process.c
+
+# 编译此工程需要包含的库和宏
+CFLAGS += -O3 -g -Wall -DUSE_USB_CAMERA
+CFLAGS += -fstack-protector-strong
+
+# 根据实际的类型设置,可以用set_sensor脚本设置
+SENSOR0_TYPE = -DSENSOR0_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR1_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR2_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+SENSOR3_TYPE = -DSENSOR1_TYPE=HY_S0603_MIPI_8M_30FPS_12BIT
+
+CFLAGS += $(SENSOR0_TYPE)
+CFLAGS += $(SENSOR1_TYPE)
+CFLAGS += $(SENSOR2_TYPE)
+CFLAGS += $(SENSOR3_TYPE)
+# 编译工程所需的mk文件
+
+include ../sdk_linux.mk
+
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/README.md b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..85f586108390ebdb743bf7811af1d6f0b6c5ea4a
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/README.md
@@ -0,0 +1,140 @@
+## 2.4、sample_kcf_track操作指导
+
+### 2.4.1、sample_kcf_track程序简介
+
+* sample_kcf_track 基于SS928V100平台开发,以EulerPi套件为例,sample_kcf_track 基于KCF+Track模型,通过USB Camera,将采集到的图片送到KFC+trak模型,实现对目标的实时跟踪效果。
+
+### 2.4.2、目录
+
+```shell
+pegasus/vendor/cust/demo/sample_kcf_track
+|── main.c # sample_kcf_track的主入口
+|── Makefile # 编译脚本
+|── sample_kcf_track.c # sample_kcf_track业务代码
+|── sample_kcf_track.h # sample_kcf_track业务代码头文件
+|── sample_svp_npu_process.c # 调用SVP_NPU的业务代码
+└── sample_svp_npu_process.c # 调用SVP_NPU的头文件
+```
+
+
+
+### 2.4.3、编译
+
+* **注意:在编译cust的demo之前,请确保你已经按照[patch介绍中的步骤](../../README.md#4patch介绍)把补丁打入海思SDK的sample目录下了**。
+
+* 步骤1:先根据自己选择的操作系统,进入到对应的Pegasus所在目录下。
+
+* 步骤2:使用Makefile的方式进行单编
+
+* 在Ubuntu的命令行终端,分步执行下面的命令,单编 sample_kcf_track
+
+ ```
+ cd pegasus/vendor/cust/demo/sample_kcf_track
+
+ make clean && make
+ ```
+
+ 
+
+ * 在sample_kcf_track目录下,生成一个名为sample_kcf_track的 可执行文件,如下图所示:
+
+ 
+
+### 2.4.4、拷贝可执行程序和依赖文件至开发板的mnt目录下
+
+**方式一:使用SD卡进行资料文件的拷贝**
+
+* 首先需要自己准备一张Micro sd卡(16G 左右即可),还得有一个Micro sd卡的读卡器。
+
+
+
+* 步骤1:将编译后生成的可执行文件拷贝到SD卡中。
+
+
+
+* 步骤2:可执行文件拷贝成功后,将内存卡插入开发板的SD卡槽中,可通过挂载的方式挂载到板端,可选择SD卡 mount指令进行挂载。
+
+
+
+* 在开发板的终端,执行下面的命令进行SD卡的挂载
+ * 如果挂载失败,可以参考[这个issue尝试解决](https://gitee.com/HiSpark/HiSpark_NICU2022/issues/I54932?from=project-issue)
+
+
+```shell
+mount -t vfat /dev/mmcblk1p1 /mnt
+# 其中/dev/mmcblk1p1需要根据实际块设备号修改
+```
+
+* 挂载成功后,如下图所示:
+
+
+
+**方式二:使用NFS挂载的方式进行资料文件的拷贝**
+
+* 首先需要自己准备一根网线
+* 步骤1:参考[博客链接](https://blog.csdn.net/Wu_GuiMing/article/details/115872995?spm=1001.2014.3001.5501)中的内容,进行nfs的环境搭建
+* 步骤2:将编译后生成的可执行文件拷贝到Windows的nfs共享路径下
+
+
+
+* 步骤3:在开发板的终端执行下面的命令,将Windows的nfs共享路径挂载至开发板的mnt目录下
+ * 注意:这里IP地址请根据你开发板和电脑主机的实际IP地址进行填写
+
+
+```
+ifconfig eth0 192.168.100.100
+
+mount -o nolock,addr=192.168.100.10 -t nfs 192.168.100.10:/d/nfs /mnt
+```
+
+
+
+### 2.4.5、硬件连接
+
+* 准备一个外接显示器和HDMI数据线,将HDMI的一头接在开发板的HDMI输出口,将HDMI的另外一头接在外接显示器的HDMI输入口。
+
+
+
+* 将USB 摄像头接在EulerPi开发板的USB接口上。
+
+
+
+### 2.4.6、功能验证
+
+* 在开发板的终端执行下面的命令,运行可执行文件
+
+```
+cd /mnt
+
+chmod +x sample_kcf_track
+
+./sample_kcf_track
+```
+
+
+
+* 此时,在HDMI的外接显示屏上即可出现实时码流,如下图所示:
+
+
+
+* 如果您看到的现象和下图现象不一致,可以确认一下USB涉嫌头是否插入到开发板的USB口,并且在开发板的/dev目录下能够看到video0 和 video1两个设备节点。如果没有这两个设备节点,请确保镜像烧录正常。
+
+
+
+* 正常情况下,我们会在外接显示屏上看到USB Camera采集到的画面。
+* 步骤1:按下键盘的空格键,会在屏幕的正中间显示一个红色的框框。
+
+
+
+* 步骤2:把需要跟踪的目标放在红色框框内,然后再按一下空格键,此时红色框会变绿,如果没有变,可以重复一次。
+* 步骤3:移动需要跟踪的目标,绿色框会跟着目标一起移动。
+
+
+
+* 当目标不在sensor视野范围内,绿框会变成黄色。
+
+
+
+* 输入Q键,即可关闭程序
+
+
\ No newline at end of file
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/main.c b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/main.c
new file mode 100755
index 0000000000000000000000000000000000000000..62a2b7375f57999d236528a96dcb25fe145f8758
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/main.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sdk_module_init.h"
+#include "securec.h"
+#include "sample_svp_npu_process.h"
+
+int main(int argc, char *argv[])
+{
+ td_s32 ret;
+
+#ifdef CONFIG_USER_SPACE
+ SDK_init();
+#endif
+
+ sample_svp_npu_acl_v4l2_kcf();
+
+#ifdef CONFIG_USER_SPACE
+ SDK_exit();
+#endif
+ return 0;
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20221114150205685.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20221114150205685.png
new file mode 100755
index 0000000000000000000000000000000000000000..4dc4215c962c57ba0e31548fb98c29c789f149d9
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20221114150205685.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210161601541.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210161601541.png
new file mode 100755
index 0000000000000000000000000000000000000000..80845ece8131933a4cd56ae3bd6119c38e0abd26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210161601541.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210170027454.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210170027454.png
new file mode 100755
index 0000000000000000000000000000000000000000..c06081fc2c963af4d1fa8af506804beedefe1b0b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250210170027454.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250213112932380.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250213112932380.png
new file mode 100755
index 0000000000000000000000000000000000000000..8b591b3437544859f4ec76b9ca03867cc401078c
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250213112932380.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919150630870.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919150630870.png
new file mode 100755
index 0000000000000000000000000000000000000000..91f881e85b3292118336ce2c3d81968e4aee8c26
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919150630870.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151018659.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151018659.png
new file mode 100755
index 0000000000000000000000000000000000000000..9b09507893b65d2142be49e6461daa31a81855c4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151018659.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151519310.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151519310.png
new file mode 100755
index 0000000000000000000000000000000000000000..7f6d881a5d0e6d3f72b7a43d089b5c5a75d7f048
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919151519310.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919184816530.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919184816530.png
new file mode 100755
index 0000000000000000000000000000000000000000..d9f0932b345fcfa7c140c5f21d352e7e5cff64c4
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919184816530.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185144994.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185144994.png
new file mode 100755
index 0000000000000000000000000000000000000000..9895a2068cd586218c3a5ff02ec5d78c545ffc1c
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185144994.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185208004.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185208004.png
new file mode 100755
index 0000000000000000000000000000000000000000..c29a199bc69ee1234b567cbe69f1a38eec9901d2
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919185208004.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191208927.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191208927.png
new file mode 100755
index 0000000000000000000000000000000000000000..3e7e7ce97378be27813af2e1e785abe09c715617
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191208927.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191302486.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191302486.png
new file mode 100755
index 0000000000000000000000000000000000000000..ade82dd2219dbaebd70423a330cec800472926f3
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191302486.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191401771.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191401771.png
new file mode 100755
index 0000000000000000000000000000000000000000..7cb07614edd60c0e0277898410468468044ef390
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191401771.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191456754.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191456754.png
new file mode 100755
index 0000000000000000000000000000000000000000..b564293336921a8118b5df93841f7b0ce0431c41
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919191456754.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192137187.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192137187.png
new file mode 100755
index 0000000000000000000000000000000000000000..40ae9c3bd0c0aa31a35641ceb139f98b193505cf
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192137187.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192243361.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192243361.png
new file mode 100755
index 0000000000000000000000000000000000000000..a2231c40a1430a678ed005050c743925f2ff02e1
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192243361.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192349341.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192349341.png
new file mode 100755
index 0000000000000000000000000000000000000000..e5ba33632d982e6806c584cc20fe487bb61389d6
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192349341.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192508575.png b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192508575.png
new file mode 100755
index 0000000000000000000000000000000000000000..28ee9c1456146bda8ff4119bca992c73bd423b1b
Binary files /dev/null and b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/pic/image-20250919192508575.png differ
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.c b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.c
new file mode 100755
index 0000000000000000000000000000000000000000..45c4fb0b9522c64e816a673792583065597bfa6c
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+#include
+#include "ss_mpi_ive.h"
+#include "sample_common_svp.h"
+#include "sample_common_ive.h"
+#include "sample_kcf_track.h"
+
+#define KCF_QUEUE_LEN 4 /* 简化环形队列深度 */
+
+/* **** 新增:KCF 用到的全局结构 **** */
+static sample_yolo_kcf_info g_kcf_info = {0}; /* 资源句柄、互斥锁等 */
+static ot_sample_svp_rect_info g_new_rect; /* NPU 推过来的检测框 */
+static pthread_mutex_t g_rect_mutex = PTHREAD_MUTEX_INITIALIZER;
+static td_bool g_has_new_rect = TD_FALSE; /* 标记框是否更新 */
+static td_bool g_stop_flag = TD_FALSE;
+static pthread_t g_get_frame_thd = 0;
+static pthread_t g_track_thd = 0;
+static int g_kcf_mode = 0; // 0=只画红框, 1=跟踪
+
+// 新增:全局保存最后有效框和丢失计数(替代线程内的局部静态变量)
+static ot_sample_svp_rect_info g_last_valid_rect = {0};
+static td_s32 g_lost_count = 0;
+
+#define KCF_BOX_WIDTH 200 // 统一宽度
+#define KCF_BOX_HEIGHT 200 // 统一高度
+
+static void kcf_rect_to_roi_info(const ot_sample_svp_rect_info *rect, td_u32 base_w, td_u32 base_h)
+{
+ if (rect->num == 0) {
+ return;
+ }
+ // 只用第0个框,不做任何选择
+ g_kcf_info.roi_num = 1;
+ g_kcf_info.roi_info[0].roi_id = 0;
+ g_kcf_info.roi_info[0].roi.x = rect->rect[0].point[0].x * OT_SAMPLE_QUARTER_OF_1M;
+ g_kcf_info.roi_info[0].roi.y = rect->rect[0].point[0].y * OT_SAMPLE_QUARTER_OF_1M;
+ g_kcf_info.roi_info[0].roi.width = rect->rect[0].point[1].x - rect->rect[0].point[0].x;
+ g_kcf_info.roi_info[0].roi.height = rect->rect[0].point[2].y - rect->rect[0].point[1].y; /* 2 index */
+ // 后续宽高限制代码可保留
+ if (g_kcf_info.roi_info[0].roi.width > 684) { /* 684 pic width */
+ g_kcf_info.roi_info[0].roi.width = 684; /* 684 pic width */
+ }
+ if (g_kcf_info.roi_info[0].roi.height > 684) { /* 684 pic height */
+ g_kcf_info.roi_info[0].roi.height = 684; /* 684 pic height */
+ }
+ if (g_kcf_info.roi_info[0].roi.width < KCF_BOX_WIDTH) {
+ g_kcf_info.roi_info[0].roi.width = KCF_BOX_WIDTH;
+ }
+ if (g_kcf_info.roi_info[0].roi.height < KCF_BOX_HEIGHT) {
+ g_kcf_info.roi_info[0].roi.height = KCF_BOX_HEIGHT;
+ }
+ if ((g_kcf_info.roi_info[0].roi.x / OT_SAMPLE_QUARTER_OF_1M) + g_kcf_info.roi_info[0].roi.width > base_w) {
+ g_kcf_info.roi_info[0].roi.x = (base_w - g_kcf_info.roi_info[0].roi.width) * OT_SAMPLE_QUARTER_OF_1M;
+ }
+ if ((g_kcf_info.roi_info[0].roi.y / OT_SAMPLE_QUARTER_OF_1M) + g_kcf_info.roi_info[0].roi.height > base_h) {
+ g_kcf_info.roi_info[0].roi.y = (base_h - g_kcf_info.roi_info[0].roi.height) * OT_SAMPLE_QUARTER_OF_1M;
+ }
+ if (g_kcf_info.roi_info[0].roi.x < 0) {
+ g_kcf_info.roi_info[0].roi.x = 0;
+ }
+ if (g_kcf_info.roi_info[0].roi.y < 0) {
+ g_kcf_info.roi_info[0].roi.y = 0;
+ }
+ if (g_kcf_info.roi_info[0].roi.width & 1) {
+ g_kcf_info.roi_info[0].roi.width--;
+ }
+ if (g_kcf_info.roi_info[0].roi.height & 1) {
+ g_kcf_info.roi_info[0].roi.height--;
+ }
+}
+
+/* **** 简单把 video_frame 填到 ot_svp_img **** */
+static void kcf_fill_image(const ot_video_frame_info *frame, ot_svp_img *img)
+{
+ img->phys_addr[0] = frame->video_frame.phys_addr[0];
+ img->phys_addr[1] = frame->video_frame.phys_addr[1];
+ img->stride[0] = frame->video_frame.stride[0];
+ img->stride[1] = frame->video_frame.stride[1];
+ img->width = frame->video_frame.width;
+ img->height = frame->video_frame.height;
+
+ /* 根据 VPSS 输出像素格式决定 IVE 输入类型 */
+ switch (frame->video_frame.pixel_format) {
+ case OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420:
+ case OT_PIXEL_FORMAT_YUV_SEMIPLANAR_420:
+ img->type = OT_SVP_IMG_TYPE_YUV420SP;
+ break;
+ case OT_PIXEL_FORMAT_YVU_SEMIPLANAR_422:
+ case OT_PIXEL_FORMAT_YUV_SEMIPLANAR_422:
+ img->type = OT_SVP_IMG_TYPE_YUV422SP;
+ break;
+ default:
+ /* 回退为 420,必要时可扩展 */
+ img->type = OT_SVP_IMG_TYPE_YUV420SP;
+ break;
+ }
+}
+
+typedef struct {
+ td_s32 x;
+ td_s32 y;
+ td_s32 w;
+ td_s32 h;
+} BoxPosition;
+
+// 限制框在画面范围内
+static void clamp_box_to_frame(BoxPosition* box, const ot_video_frame_info* frame)
+{
+ const td_s32 max_w = frame->video_frame.width - 2; /* 2 pixel */
+ const td_s32 max_h = frame->video_frame.height - 2; /* 2 pixel */
+
+ // 确保最小尺寸
+ box->w = (box->w > KCF_BOX_WIDTH) ? box->w : KCF_BOX_WIDTH;
+ box->h = (box->h > KCF_BOX_HEIGHT) ? box->h : KCF_BOX_HEIGHT;
+
+ /* 4 允许超出的最大范围(框宽的1/4) */
+ const td_s32 max_overlap = box->w / 4;
+ if (box->x + box->w > max_w + max_overlap) {
+ box->x = max_w - box->w;
+ }
+ if (box->y + box->h > max_h + max_overlap) {
+ box->y = max_h - box->h;
+ }
+}
+
+// 消除位置抖动
+static void smooth_box_position(BoxPosition* current, BoxPosition* last, td_bool* is_first_frame)
+{
+ if (*is_first_frame) {
+ *last = *current;
+ *is_first_frame = TD_FALSE;
+ return;
+ }
+
+ // 微小变化时保持上一帧位置
+ if (abs(current->x - last->x) <= 2 && abs(current->y - last->y) <= 2 && /* 2 pixel */
+ abs(current->w - last->w) <= 2 && abs(current->h - last->h) <= 2) { /* 2 pixel */
+ *current = *last;
+ } else {
+ *last = *current;
+ }
+}
+
+// 确保坐标和尺寸为偶数
+static void align_to_even(BoxPosition* box)
+{
+ box->x &= ~1; // 清除最低位保证为偶数
+ box->y &= ~1;
+ box->w &= ~1;
+ box->h &= ~1;
+}
+
+// 设置矩形顶点坐标
+static void set_rect_points(ot_sample_svp_rect* rect, const BoxPosition* box)
+{
+ rect->point[0].x = box->x;
+ rect->point[0].y = box->y;
+ rect->point[1].x = box->x + box->w;
+ rect->point[1].y = box->y;
+ rect->point[2].x = box->x + box->w; /* 2 index of 2 */
+ rect->point[2].y = box->y + box->h; /* 2 index of 2 */
+ rect->point[3].x = box->x; /* 3 index of 3 */
+ rect->point[3].y = box->y + box->h; /* 3 index of 3 */
+}
+
+static void kcf_bbox_to_rect(const ot_ive_kcf_bbox bbox[], td_u32 num,
+ const ot_video_frame_info* frame, ot_sample_svp_rect_info* rect)
+{
+ rect->num = (num > 0) ? 1 : 0;
+ if (rect->num == 0) {
+ return;
+ }
+ // 初始化转换参数
+ static BoxPosition last_box = {0};
+ static td_bool first_frame = TD_TRUE;
+
+ BoxPosition current = {
+ .x = bbox[0].roi_info.roi.x / OT_SAMPLE_QUARTER_OF_1M,
+ .y = bbox[0].roi_info.roi.y / OT_SAMPLE_QUARTER_OF_1M,
+ .w = bbox[0].roi_info.roi.width,
+ .h = bbox[0].roi_info.roi.height
+ };
+
+ // 处理流程
+ clamp_box_to_frame(¤t, frame);
+ smooth_box_position(¤t, &last_box, &first_frame);
+ align_to_even(¤t);
+
+ // 设置输出矩形
+ set_rect_points(&rect->rect[0], ¤t);
+}
+/* 边界检测辅助函数 */
+static td_bool is_touching_border(const ot_sample_svp_rect *rect, td_s32 screen_w,
+ td_s32 screen_h, td_s32 threshold)
+{
+ td_s32 rect_left = rect->point[0].x;
+ td_s32 rect_top = rect->point[0].y;
+ td_s32 rect_right = rect->point[1].x;
+ td_s32 rect_bottom = rect->point[2].y;
+
+ return (rect_left <= threshold) || (rect_top <= threshold) ||
+ ((screen_w - rect_right) <= threshold) || ((screen_h - rect_bottom) <= threshold);
+}
+
+/* 绘制矩形辅助函数 */
+static void draw_tracking_rect(const ot_video_frame_info *frm,
+ const ot_sample_svp_rect_info *rect_info, td_bool is_touching_border)
+{
+ td_u32 color = is_touching_border ? 0x00FFFF00 : 0x0000FF00;
+ sample_common_svp_vgs_fill_rect(frm, rect_info, color);
+}
+
+/* KCF训练辅助函数 */
+static void train_kcf_on_new_rect(const ot_video_frame_info *frm)
+{
+ pthread_mutex_lock(&g_rect_mutex);
+ kcf_rect_to_roi_info(&g_new_rect, frm->video_frame.width, frm->video_frame.height);
+ g_has_new_rect = TD_FALSE;
+ pthread_mutex_unlock(&g_rect_mutex);
+
+ td_s32 ret = ss_mpi_ive_kcf_get_train_obj(
+ g_kcf_info.padding, g_kcf_info.roi_info,
+ g_kcf_info.roi_num, &g_kcf_info.cos_win_x,
+ &g_kcf_info.cos_win_y, &g_kcf_info.gauss_peak,
+ &g_kcf_info.obj_list);
+ if (ret != TD_SUCCESS) {
+ printf("[KCF] get_train_obj failed 0x%x, w=%u h=%u\n", ret,
+ g_kcf_info.roi_info[0].roi.width,
+ g_kcf_info.roi_info[0].roi.height);
+ } else {
+ printf("[KCF] train_obj_num=%u\n", g_kcf_info.obj_list.train_obj_num);
+ }
+}
+
+/* 处理丢失目标情况 */
+static void handle_lost_target(const ot_video_frame_info *frm)
+{
+ g_lost_count++;
+ printf("[KCF] Lost target (count=%d), keep last rect\n", g_lost_count);
+
+ if (g_last_valid_rect.num > 0) {
+ sample_common_svp_vgs_fill_rect(frm, &g_last_valid_rect, 0x00FFFF00);
+ }
+
+ if (g_lost_count >= 10 && g_last_valid_rect.num > 0) { /* 10 lost count */
+ pthread_mutex_lock(&g_rect_mutex);
+ g_new_rect = g_last_valid_rect;
+ g_has_new_rect = TD_TRUE;
+ pthread_mutex_unlock(&g_rect_mutex);
+ g_lost_count = 0;
+ }
+}
+
+static void process_kcf_tracking(const ot_video_frame_info* frm,
+ ot_sample_svp_rect_info* draw_rect)
+{
+ td_s32 ret;
+ ot_ive_handle handle = 0;
+ ot_svp_img src_img;
+
+ // 填充图像数据
+ kcf_fill_image(frm, &src_img);
+
+ // 执行KCF处理
+ ret = ss_mpi_ive_kcf_proc(&handle, &src_img, &g_kcf_info.obj_list,
+ &g_kcf_info.kcf_proc_ctrl, TD_TRUE);
+ if (ret != TD_SUCCESS) {
+ printf("[KCF] kcf_proc failed 0x%x\n", ret);
+ g_kcf_info.bbox_obj_num = 0;
+ return;
+ }
+
+ // 获取目标边界框
+ ret = ss_mpi_ive_kcf_get_obj_bbox(&g_kcf_info.obj_list, g_kcf_info.bbox,
+ &g_kcf_info.bbox_obj_num, &g_kcf_info.kcf_bbox_ctrl);
+ if (ret != TD_SUCCESS) {
+ printf("[KCF] get_obj_bbox failed 0x%x\n", ret);
+ g_kcf_info.bbox_obj_num = 0;
+ return;
+ }
+
+ // 处理有效目标
+ if (g_kcf_info.bbox_obj_num > 0) {
+ kcf_bbox_to_rect(g_kcf_info.bbox, g_kcf_info.bbox_obj_num, frm, draw_rect);
+
+ td_s32 screen_w = frm->video_frame.width - 2;
+ td_s32 screen_h = frm->video_frame.height - 2;
+ td_bool touching_border = is_touching_border(
+ &draw_rect->rect[0], screen_w, screen_h, 5);
+
+ draw_tracking_rect(frm, draw_rect, touching_border);
+ g_last_valid_rect = *draw_rect;
+ g_lost_count = 0;
+ }
+}
+
+/* 主线程函数(重构后) */
+static void *kcf_track_thread(void *args)
+{
+ (void)args;
+ td_s32 ret;
+ const ot_vo_layer vo_layer = 0;
+ const ot_vo_chn vo_chn = 0;
+ const td_s32 milli_sec = 20;
+ const td_s32 vpss_grp = 0;
+ const td_s32 vpss_chn = 0;
+ ot_sample_svp_rect_info draw_rect = {0};
+
+ while (!g_stop_flag) {
+ ot_video_frame_info frm;
+ ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn, &frm, milli_sec);
+ if (ret != TD_SUCCESS) {
+ usleep(1000); // 1000 sleep 1ms
+ continue;
+ }
+
+ // 红框模式处理
+ if (g_kcf_mode == 0) {
+ ot_ive_kcf_bbox initial_bbox[1];
+ initial_bbox[0].roi_info = g_kcf_info.roi_info[0];
+ kcf_bbox_to_rect(initial_bbox, 1, &frm, &draw_rect);
+ sample_common_svp_vgs_fill_rect(&frm, &draw_rect, 0x00FF0000);
+ g_kcf_info.bbox_obj_num = 0;
+ goto send_and_release;
+ }
+
+ // 训练模式处理
+ if (g_has_new_rect) {
+ train_kcf_on_new_rect(&frm);
+ }
+
+ // 跟踪模式处理
+ if (g_kcf_mode == 1 && (g_kcf_info.obj_list.train_obj_num != 0 ||
+ g_kcf_info.obj_list.track_obj_num != 0)) {
+ process_kcf_tracking(&frm, &draw_rect);
+ } else if (g_kcf_mode == 1) {
+ g_kcf_info.bbox_obj_num = 0;
+ }
+ // 处理丢失目标
+ if (g_kcf_mode == 1 && g_kcf_info.bbox_obj_num == 0) {
+ handle_lost_target(&frm);
+ }
+
+ send_and_release:
+ ret = sample_common_svp_venc_vo_send_stream(&g_kcf_info.svp_switch, 0,
+ vo_layer, vo_chn, &frm);
+ if (ret != TD_SUCCESS) {
+ printf("[KCF] sample_common_svp_venc_vo_send_stream failed 0x%x\n", ret);
+ }
+ (td_void)ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn, &frm);
+ usleep(8000); // 8000 sleep 8ms
+ }
+ return TD_NULL;
+}
+
+static void sample_kcf_info_init(ot_svp_mem_info total_mem, td_u32 list_mem_size)
+{
+ g_kcf_info.list_mem = total_mem;
+ g_kcf_info.list_mem.size = list_mem_size;
+
+ g_kcf_info.gauss_peak.phys_addr = g_kcf_info.list_mem.phys_addr + list_mem_size;
+ g_kcf_info.gauss_peak.virt_addr = g_kcf_info.list_mem.virt_addr + list_mem_size;
+ g_kcf_info.gauss_peak.size = SAMPLE_KCF_GAUSS_PEAK_SIZE;
+
+ g_kcf_info.cos_win_x.phys_addr = g_kcf_info.gauss_peak.phys_addr + SAMPLE_KCF_GAUSS_PEAK_SIZE;
+ g_kcf_info.cos_win_x.virt_addr = g_kcf_info.gauss_peak.virt_addr + SAMPLE_KCF_GAUSS_PEAK_SIZE;
+ g_kcf_info.cos_win_x.size = SAMPLE_KCF_COS_WIN_SIZE;
+
+ g_kcf_info.cos_win_y.phys_addr = g_kcf_info.cos_win_x.phys_addr + SAMPLE_KCF_COS_WIN_SIZE;
+ g_kcf_info.cos_win_y.virt_addr = g_kcf_info.cos_win_x.virt_addr + SAMPLE_KCF_COS_WIN_SIZE;
+ g_kcf_info.cos_win_y.size = SAMPLE_KCF_COS_WIN_SIZE;
+
+ g_kcf_info.kcf_proc_ctrl.tmp_buf.phys_addr =
+ g_kcf_info.cos_win_y.phys_addr + SAMPLE_KCF_COS_WIN_SIZE;
+ g_kcf_info.kcf_proc_ctrl.tmp_buf.virt_addr =
+ g_kcf_info.cos_win_y.virt_addr + SAMPLE_KCF_COS_WIN_SIZE;
+ g_kcf_info.kcf_proc_ctrl.tmp_buf.size = SAMPLE_KCF_TEMP_BUF_SIZE;
+}
+
+static void sample_kcf_proc_ctrl_init(void)
+{
+ g_kcf_info.kcf_proc_ctrl.csc_mode = OT_IVE_CSC_MODE_VIDEO_BT709_YUV_TO_RGB;
+ /* 0.001 learning rate 1024 Quantization scaling factor 32 Additional scaling factor */
+ g_kcf_info.kcf_proc_ctrl.interp_factor = (td_u1q15)(0.001 * 1024 * 32); /* 降低学习率,减少抖动 ≈327 */
+ g_kcf_info.kcf_proc_ctrl.lamda = 10; /* 10 lamda */
+ g_kcf_info.kcf_proc_ctrl.sigma = (td_u0q8)(0.5 * 256); /* 0.5 * 256 降低sigma,提高稳定性 ≈77 */
+ g_kcf_info.kcf_proc_ctrl.norm_trunc_alfa = (td_u4q12)(0.15 * 4096); /* 0.15 * 4096 降低截断因子 ≈614 */
+ g_kcf_info.kcf_proc_ctrl.response_threshold = 5; /* 5 提高阈值,减少误检 */
+ g_kcf_info.kcf_proc_ctrl.core_id = OT_IVE_KCF_CORE0;
+}
+
+static void sample_kcf_bbox_ctrl_init(void)
+{
+ g_kcf_info.kcf_bbox_ctrl.max_bbox_num = SAMPLE_KCF_LIST_NODE_MAX;
+ g_kcf_info.kcf_bbox_ctrl.response_threshold = 12; /* 12 threshold */
+ g_kcf_info.padding = 48; /* 48 padding */
+}
+
+static td_s32 sample_kcf_media_cfg(const ot_sample_svp_media_cfg *media_cfg)
+{
+ if (media_cfg != TD_NULL) {
+ g_kcf_info.svp_switch = media_cfg->svp_switch; /* {TD_FALSE, TD_TRUE} */
+ } else {
+ g_kcf_info.svp_switch.is_venc_open = TD_FALSE;
+ g_kcf_info.svp_switch.is_vo_open = TD_TRUE;
+ }
+
+ g_stop_flag = TD_FALSE;
+ // Removed g_get_frame_thd creation
+ if (pthread_create(&g_track_thd, NULL, kcf_track_thread, NULL) != 0) {
+ return TD_FAILURE;
+ }
+ // 在 sample_kcf_track_init 末尾添加
+ g_kcf_info.roi_num = 1;
+ g_kcf_info.roi_info[0].roi_id = 0;
+ td_u32 safe_margin = 50; /* 50 Edge safety distance */
+ td_u32 init_x = (1920 - KCF_BOX_WIDTH) / 2; /* 1920 PIC of width */
+ td_u32 init_y = (1080 - KCF_BOX_HEIGHT) / 2; /* 1080 PIC of width */
+ // 确保初始位置不靠近边缘(至少50像素缓冲)
+ if (init_x < safe_margin) init_x = safe_margin;
+ if (init_y < safe_margin) init_y = safe_margin;
+ g_kcf_info.roi_info[0].roi.x = init_x * OT_SAMPLE_QUARTER_OF_1M;
+ g_kcf_info.roi_info[0].roi.y = init_y * OT_SAMPLE_QUARTER_OF_1M;
+ g_kcf_info.roi_info[0].roi.width = KCF_BOX_WIDTH;
+ g_kcf_info.roi_info[0].roi.height = KCF_BOX_HEIGHT;
+
+ return TD_SUCCESS;
+}
+
+td_s32 sample_kcf_track_init(const ot_sample_svp_media_cfg *media_cfg, sample_vo_cfg *vo_cfg)
+{
+ memset(&g_kcf_info, 0, sizeof(g_kcf_info));
+ pthread_mutex_init(&g_kcf_info.det_mutex, NULL);
+
+ /* ---------------- KCF 内存初始化 ---------------- */
+ td_s32 ret;
+ td_u32 list_mem_size;
+ td_u32 total_size;
+
+ /* 1. 计算对象链表大小 */
+ ret = ss_mpi_ive_kcf_get_mem_size(SAMPLE_KCF_LIST_NODE_MAX, &list_mem_size);
+ if (ret != TD_SUCCESS) {
+ printf("kcf get mem size failed 0x%x\n", ret);
+ return ret;
+ }
+
+ /* 2. 申请一整块连续内存 (list + gauss + cosX + cosY + tmp) */
+ total_size = list_mem_size + SAMPLE_KCF_GAUSS_PEAK_SIZE +
+ SAMPLE_KCF_COS_WIN_SIZE * 2 + SAMPLE_KCF_TEMP_BUF_SIZE; /* 2 is a number */
+
+ ot_svp_mem_info total_mem = {0};
+ ret = sample_common_ive_create_mem_info(&total_mem, total_size);
+ if (ret != TD_SUCCESS) {
+ printf("kcf alloc total mem failed 0x%x\n", ret);
+ return ret;
+ }
+
+ /* 3. 切分子区域 */
+ sample_kcf_info_init(total_mem, list_mem_size);
+
+ /* 4. 创建对象链表 */
+ ret = ss_mpi_ive_kcf_create_obj_list(&g_kcf_info.list_mem, SAMPLE_KCF_LIST_NODE_MAX, &g_kcf_info.obj_list);
+ if (ret != TD_SUCCESS) {
+ printf("create obj list err 0x%x\n", ret);
+ return ret;
+ }
+
+ /* 5. 生成 GaussPeak / CosWin 窗口 */
+ g_kcf_info.padding = 48; /* 48 is 1.5*32 */
+ ret = ss_mpi_ive_kcf_create_gauss_peak(g_kcf_info.padding, &g_kcf_info.gauss_peak);
+ if (ret != TD_SUCCESS) {
+ printf("create gauss peak err 0x%x\n", ret);
+ return ret;
+ }
+ ret = ss_mpi_ive_kcf_create_cos_win(&g_kcf_info.cos_win_x, &g_kcf_info.cos_win_y);
+ if (ret != TD_SUCCESS) {
+ printf("create cos win err 0x%x\n", ret);
+ return ret;
+ }
+
+ /* 6. 填写 kcf_proc_ctrl 默认参数 */
+ sample_kcf_proc_ctrl_init();
+
+ /* 7. 初始化 bbox ctrl */
+ sample_kcf_bbox_ctrl_init();
+
+ /* 8. 继承媒体配置中的开关,使 KCF 线程能够把结果帧送到 VO/VENC */
+ ret = sample_kcf_media_cfg(media_cfg);
+ if (ret != TD_SUCCESS) {
+ printf("kcf media cfg err 0x%x\n", ret);
+ return ret;
+ }
+
+ return TD_SUCCESS;
+}
+
+void sample_kcf_track_deinit(void)
+{
+ g_stop_flag = TD_TRUE;
+ // Removed g_get_frame_thd join
+ if (g_track_thd) {
+ pthread_join(g_track_thd, NULL);
+ }
+ /* 释放 KCF 内存与对象链表 */
+ ss_mpi_ive_kcf_destroy_obj_list(&g_kcf_info.obj_list);
+
+ /* 仅需释放一次整块内存,避免重复 free 导致 mmb not found 警告 */
+ sample_svp_mmz_free(g_kcf_info.list_mem.phys_addr, g_kcf_info.list_mem.virt_addr);
+
+ pthread_mutex_destroy(&g_kcf_info.det_mutex);
+}
+
+// 修改 sample_kcf_set_det_rect,只在切换到跟踪模式时设置 g_has_new_rect
+void sample_kcf_set_det_rect(const ot_sample_svp_rect_info *rect, int mode)
+{
+ pthread_mutex_lock(&g_rect_mutex);
+ g_new_rect = *rect;
+ if (mode == 1) {
+ ss_mpi_ive_kcf_destroy_obj_list(&g_kcf_info.obj_list);
+ ss_mpi_ive_kcf_create_obj_list(&g_kcf_info.list_mem, SAMPLE_KCF_LIST_NODE_MAX, &g_kcf_info.obj_list);
+ g_has_new_rect = TD_TRUE;
+ // 重置上一次的黄色框信息,避免切换时残留
+ memset(&g_last_valid_rect, 0, sizeof(ot_sample_svp_rect_info));
+ g_lost_count = 0;
+ } else if (mode == 0) { // 切换到红色框模式:强制红框回到中央
+ // 计算屏幕中央坐标(基于1920x1080分辨率)
+ td_u32 center_x = (1920 - KCF_BOX_WIDTH) / 2; // 中央x坐标
+ td_u32 center_y = (1080 - KCF_BOX_HEIGHT) / 2; // 中央y坐标
+ // 重置红框的初始位置到中央(与初始化时一致)
+ g_kcf_info.roi_info[0].roi.x = center_x * OT_SAMPLE_QUARTER_OF_1M;
+ g_kcf_info.roi_info[0].roi.y = center_y * OT_SAMPLE_QUARTER_OF_1M;
+ // 保持宽高不变(KCF_BOX_WIDTH x KCF_BOX_HEIGHT)
+ g_kcf_info.roi_info[0].roi.width = KCF_BOX_WIDTH;
+ g_kcf_info.roi_info[0].roi.height = KCF_BOX_HEIGHT;
+ }
+ g_kcf_mode = mode;
+
+ if (mode == 0) {
+ g_kcf_info.obj_list.train_obj_num = 0;
+ g_kcf_info.obj_list.track_obj_num = 0;
+ g_kcf_info.bbox_obj_num = 0;
+ }
+ pthread_mutex_unlock(&g_rect_mutex);
+}
+
+td_u32 sample_kcf_get_bbox_num(void)
+{
+ return g_kcf_info.bbox_obj_num;
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.h b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.h
new file mode 100755
index 0000000000000000000000000000000000000000..9b5a4d2111c76506641612fdc6db91b31c2095ff
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_kcf_track.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SAMPLE_KCF_TRACK_H
+#define SAMPLE_KCF_TRACK_H
+
+#include
+#include "sample_comm.h"
+#include "ot_common_svp.h"
+#include "sample_common_svp.h"
+#include "sample_common_ive.h"
+
+#ifndef SAMPLE_YOLO_KCF_INFO_T
+#define SAMPLE_YOLO_KCF_INFO_T
+#define SAMPLE_KCF_MAX_OBJ 4
+
+typedef struct {
+ ot_ive_roi_info roi_info[SAMPLE_KCF_MAX_OBJ];
+ td_u32 roi_num;
+
+ /* 训练相关内存 */
+ ot_svp_mem_info cos_win_x;
+ ot_svp_mem_info cos_win_y;
+ ot_svp_mem_info gauss_peak;
+ ot_svp_mem_info list_mem; /* KCF 对象链表内存 */
+ ot_ive_kcf_obj_list obj_list;
+ ot_ive_kcf_proc_ctrl kcf_proc_ctrl;
+ ot_ive_kcf_bbox_ctrl kcf_bbox_ctrl;
+
+ /* 跟踪结果 */
+ ot_ive_kcf_bbox bbox[SAMPLE_KCF_MAX_OBJ];
+ td_u32 bbox_obj_num;
+
+ /* 帧缓存 */
+ ot_video_frame_info frame_info_arr[1];
+
+ /* 互斥 */
+ pthread_mutex_t det_mutex;
+
+ /* 其它 */
+ td_u3q5 padding; /* 调 API 需要的 padding 值 */
+ ot_sample_svp_switch svp_switch;
+ sample_vo_cfg vo_cfg; /* VO configuration */
+} sample_yolo_kcf_info;
+#endif
+
+#define SAMPLE_KCF_LIST_NODE_MAX 64
+#define SAMPLE_KCF_GAUSS_PEAK_SIZE 455680
+#define SAMPLE_KCF_COS_WIN_SIZE 832
+#define SAMPLE_KCF_TEMP_BUF_SIZE 47616
+
+/* 说明:
+ * 1. sample_kcf_track_init 内部会创建获取帧+跟踪线程并一直运行;
+ * 2. 检测线程(NPU/RFCN 或 YOLO)每获得一次新检测框,调用 sample_kcf_set_det_rect
+ * 把第一只目标的 rect 信息推送给 KCF,KCF 会在下一帧里自动训练 / 跟踪;
+ * 3. sample_kcf_track_deinit 会安全地结束线程并释放内存。
+ */
+td_s32 sample_kcf_track_init(const ot_sample_svp_media_cfg *media_cfg, sample_vo_cfg *vo_cfg);
+void sample_kcf_track_deinit(void);
+
+void sample_kcf_set_det_rect(const ot_sample_svp_rect_info *rect, int mode);
+
+td_u32 sample_kcf_get_bbox_num(void);
+
+#endif /* SAMPLE_KCF_TRACK_H */
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.c b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.c
new file mode 100755
index 0000000000000000000000000000000000000000..5f655d4a9d87cf8e6e821188b665269feedc08ec
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+#include
+#include "sample_comm.h"
+#include "sample_common_svp.h"
+#include "sample_common_svp_npu.h"
+#include "sample_common_svp_npu_model.h"
+#include "sample_kcf_track.h"
+#include "sample_svp_npu_process.h"
+
+#ifndef OT_SAMPLE_SYS_ALIGN_SIZE
+#define OT_SAMPLE_SYS_ALIGN_SIZE 64 // 常见对齐值,根据 SDK 调整
+#endif
+#ifndef CIF_WIDTH
+#define CIF_WIDTH 200
+#endif
+#ifndef CIF_HEIGHT
+#define CIF_HEIGHT 200
+#endif
+
+// getch实现放在文件顶部
+static int getch(void)
+{
+ struct termios oldt;
+ struct termios newt;
+ int ch;
+ tcgetattr(STDIN_FILENO, &oldt);
+ newt = oldt;
+ newt.c_lflag &= ~(ICANON | ECHO);
+ tcsetattr(STDIN_FILENO, TCSANOW, &newt);
+ ch = getchar();
+ tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
+ return ch;
+}
+
+td_s32 sample_common_svp_get_def_vo_cfg(sample_vo_cfg *vo_cfg);
+static td_bool g_svp_npu_terminate_signal = TD_FALSE;
+static sample_vi_cfg g_vi_config;
+
+static ot_sample_svp_rect_info g_svp_npu_rect_info = {0};
+static td_bool g_svp_npu_thread_stop = TD_FALSE;
+static pthread_t g_svp_npu_thread = 0;
+static sample_vo_cfg g_svp_npu_vo_cfg = { 0 };
+static pthread_t g_svp_npu_vdec_thread = 0;
+static ot_vb_pool_info g_svp_npu_vb_pool_info;
+static td_void *g_svp_npu_vb_virt_addr = TD_NULL;
+
+static ot_sample_svp_media_cfg g_svp_npu_media_cfg = {
+ .svp_switch = {TD_FALSE, TD_TRUE},
+ .pic_type = {PIC_1080P, PIC_CIF}, // Changed to PIC_1080P for main stream
+ .chn_num = OT_SVP_MAX_VPSS_CHN_NUM,
+};
+
+static sample_vdec_attr g_svp_npu_vdec_cfg = {
+ .type = OT_PT_MJPEG,
+ .mode = OT_VDEC_SEND_MODE_FRAME,
+ .width = FHD_WIDTH, // Changed to FHD_WIDTH
+ .height = FHD_HEIGHT, // Changed to FHD_HEIGHT
+ .sample_vdec_picture.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420, /* 420:pixel_format */
+ .sample_vdec_picture.alpha = 0, /* 0:alpha */
+ .display_frame_num = 1, /* Keep 1 */
+ .frame_buf_cnt = 3, /* Keep 3 */
+};
+
+static vdec_thread_param g_svp_npu_vdec_param = {
+ .chn_id = 0,
+
+ .v4l2_device = "/dev/video0", // 摄像头设备
+ .width = FHD_WIDTH, // Changed to FHD_WIDTH
+ .height = FHD_HEIGHT, // Changed to FHD_HEIGHT
+ .pixel_format = V4L2_PIX_FMT_MJPEG, // MJPEG格式
+
+ .type = OT_PT_MJPEG,
+ .stream_mode = OT_VDEC_SEND_MODE_FRAME,
+ .interval_time = 1000, /* 1000:interval_time */
+ .pts_init = 0,
+ .pts_increase = 0,
+ .e_thread_ctrl = THREAD_CTRL_START,
+ .circle_send = TD_TRUE,
+ .milli_sec = 0,
+ .min_buf_size = (FHD_WIDTH * FHD_HEIGHT * 3) >> 1, /* 3 Re-calculated for 1080P */
+ .fps = 30, /* 30 fps */
+};
+
+td_void sample_vb_cfg_init(ot_vb_cfg *vb_cfg, ot_size size_1080p, ot_size size_cif)
+{
+ td_u64 raw_size_1080p = 0;
+ td_u64 raw_size_cif = 0;
+
+ raw_size_1080p = (td_u64)size_1080p.width * size_1080p.height * 3 / 2; /* 3 2 YUV420: 1.5 bytes per pixel */
+ vb_cfg->max_pool_cnt = 2; /* 2 pool */
+ vb_cfg->common_pool[0].blk_size = (raw_size_1080p + OT_SAMPLE_SYS_ALIGN_SIZE - 1) & ~(OT_SAMPLE_SYS_ALIGN_SIZE - 1);
+ vb_cfg->common_pool[0].blk_cnt = 10; // 块数,根据需要调整(对于1080P,建议10-20)
+
+ raw_size_cif = (td_u64)size_cif.width * size_cif.height * 3 / 2; /* 3 2 raw size */
+ vb_cfg->common_pool[1].blk_size = (raw_size_cif + OT_SAMPLE_SYS_ALIGN_SIZE - 1) & ~(OT_SAMPLE_SYS_ALIGN_SIZE - 1);
+ vb_cfg->common_pool[1].blk_cnt = 4; /* 4 pool */
+}
+
+td_void sample_center_rect_init(ot_sample_svp_rect_info *center_rect)
+{
+ int frame_w = FHD_WIDTH;
+ int frame_h = FHD_HEIGHT; // Use FHD resolution for initial box
+ int box_w = CIF_WIDTH;
+ int box_h = CIF_HEIGHT; // A reasonable box size for FHD
+ int x = (frame_w - box_w) / 2; /* 2 half of x */
+ int y = (frame_h - box_h) / 2; /* 2 half of y */
+
+ center_rect->num = 1;
+ center_rect->rect[0].point[0].x = x;
+ center_rect->rect[0].point[0].y = y;
+ center_rect->rect[0].point[1].x = x + box_w;
+ center_rect->rect[0].point[1].y = y;
+ center_rect->rect[0].point[2].x = x + box_w; /* 2 index of 2 */
+ center_rect->rect[0].point[2].y = y + box_h; /* 2 index of 2 */
+ center_rect->rect[0].point[3].x = x; /* 3 index of 3 */
+ center_rect->rect[0].point[3].y = y + box_h; /* 3 index of 3 */
+
+ printf("[MAIN-2] Setting input rect: (%d,%d) to (%d,%d)\n",
+ center_rect->rect[0].point[0].x, center_rect->rect[0].point[0].y,
+ center_rect->rect[0].point[2].x, center_rect->rect[0].point[2].y); /* 2 index of 2 */
+}
+
+// 1. 程序启动时,推送中心红框,KCF只画红框不训练
+static td_void sample_svp_npu_kcf_tracking_loop(td_void)
+{
+ ot_sample_svp_rect_info center_rect = {0};
+ sample_center_rect_init(¢er_rect);
+ sample_kcf_set_det_rect(¢er_rect, 0); // 0=只画红框
+
+ int tracking_on = 0; // 0=红框, 1=跟踪
+ // FIX: Use non-blocking input check to avoid blocking termination signal
+ struct termios oldt;
+ struct termios newt;
+ tcgetattr(STDIN_FILENO, &oldt);
+ newt = oldt;
+ newt.c_lflag &= ~(ICANON | ECHO);
+ tcsetattr(STDIN_FILENO, TCSANOW, &newt);
+
+ while (!g_svp_npu_terminate_signal) {
+ int ch = getch();
+ if (ch == ' ') {
+ tracking_on = !tracking_on; // 切换模式
+ if (tracking_on) {
+ sample_kcf_set_det_rect(¢er_rect, 1); // 进入跟踪模式,重新训练KCF
+ printf("[MAIN] Set to tracking mode\n");
+ } else {
+ sample_kcf_set_det_rect(¢er_rect, 0); // 回到红框模式
+ printf("[MAIN] Set to red box mode\n");
+ }
+ } else if (ch == 'q') {
+ break;
+ }
+ usleep(100000); // 100000 100ms poll to reduce CPU usage
+ }
+ // Restore terminal settings
+ tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
+}
+
+td_void sample_svp_npu_acl_v4l2_kcf(td_void)
+{
+ td_s32 ret;
+ ot_vb_cfg vb_cfg = {0};
+ ot_size size_cif;
+ ot_size size_1080p;
+
+ g_svp_npu_terminate_signal = TD_FALSE; /* 清除退出标志 */
+ // 计算 1080P 的 blk_size
+ sample_comm_sys_get_pic_size(PIC_1080P, &size_1080p); // 从 SDK 获取标准分辨率 (1920x1080)
+ // 计算 CIF 的 blk_size
+ sample_comm_sys_get_pic_size(PIC_CIF, &size_cif); // 从 SDK 获取标准分辨率 (352x288)
+ sample_vb_cfg_init(&vb_cfg, size_1080p, size_cif);
+ ret = sample_comm_sys_init(&vb_cfg); // 初始化系统 VB
+ if (ret != TD_SUCCESS) {
+ printf("[SYS] init failed 0x%x\n", ret);
+ return;
+ }
+ /* ** 2. 新增:获取默认VO配置 ** */
+ ret = sample_common_svp_get_def_vo_cfg(&g_svp_npu_vo_cfg);
+ if (ret != TD_SUCCESS) {
+ printf("[VO] get default config failed 0x%x\n", ret);
+ sample_comm_sys_exit(); // **** 新增:清理系统 VB ****
+ return;
+ }
+ /* 3. 根据采集分辨率重新设定 VB 图像类型,避免无谓的 4K 内存开销 */
+ g_svp_npu_media_cfg.pic_type[0] = PIC_1080P;
+ g_svp_npu_media_cfg.pic_type[1] = PIC_CIF; /* 备用,不使用 */
+
+ /* 4. 启动 V4L2->VDEC->VPSS->VO 通路(内部自动绑定) */
+ ret = sample_common_svp_create_vb_start_vdec_vpss_vo(&g_svp_npu_vdec_cfg, &g_svp_npu_vdec_param,
+ &g_svp_npu_vdec_thread, &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ if (ret != TD_SUCCESS) {
+ printf("[PIPE] create pipeline failed 0x%x\n", ret);
+ sample_common_svp_destroy_vb_stop_vdec_vpss_vo(&g_svp_npu_vdec_param, &g_svp_npu_vdec_thread,
+ &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ return;
+ }
+ /* 4. 启动 KCF 跟踪——内部线程会从 VPSS grp0 chn0 拉帧并画框 */
+ ret = sample_kcf_track_init(&g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ if (ret != TD_SUCCESS) {
+ printf("[KCF] init failed 0x%x\n", ret);
+ sample_common_svp_destroy_vb_stop_vdec_vpss_vo(&g_svp_npu_vdec_param, &g_svp_npu_vdec_thread,
+ &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ return;
+ }
+
+ sample_svp_npu_kcf_tracking_loop();
+
+ sample_kcf_track_deinit();
+ sample_common_svp_destroy_vb_stop_vdec_vpss_vo(&g_svp_npu_vdec_param, &g_svp_npu_vdec_thread,
+ &g_svp_npu_media_cfg, &g_svp_npu_vo_cfg);
+ sample_comm_sys_exit();
+}
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.h b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.h
new file mode 100755
index 0000000000000000000000000000000000000000..09ccdb7b41a19ea2af9fc8b9f25e4184ca12d6e0
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sample_kcf_track/sample_svp_npu_process.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SAMPLE_SVP_NPU_PROCESS_H
+#define SAMPLE_SVP_NPU_PROCESS_H
+#include "ot_type.h"
+
+/* function : show the sample of v4l2 -> VDEC -> VPSS -> KCF -> VGS/VO */
+td_void sample_svp_npu_acl_v4l2_kcf(td_void);
+
+#endif
diff --git a/vendor/ZhongShanKuangShi_CUST/demo/sdk_linux.mk b/vendor/ZhongShanKuangShi_CUST/demo/sdk_linux.mk
new file mode 100755
index 0000000000000000000000000000000000000000..ae4dc7394bcf98706ce3c2d9a9e1ebcb48e8d15c
--- /dev/null
+++ b/vendor/ZhongShanKuangShi_CUST/demo/sdk_linux.mk
@@ -0,0 +1,93 @@
+#====================================================
+# SDK libs
+#====================================================
+MPI_LIBS += -L$(TARGET_DIR)
+MPI_LIBS += -L$(SDK_LINUX_OUT_LIB)
+MPI_LIBS += -L$(SYSROOT_PATH)/lib
+#MPI_LIBS += -L$(SYSROOT_PATH)/usr/lib
+#MPI_LIBS += -L$(OUT_UNSTRIPPED_LIB)
+MPI_LIBS += -lot_osal -lot_base -lot_sys -lot_chnl -lot_rgn -lot_vpp -lot_vo -lot_vgs -lot_vpss -lsecurec
+MPI_LIBS += -lot_vdec -lot_h265e -lot_h264e -lot_jpege -lot_venc -lot_vedu -lot_vi -lot_mpi_isp -lot_rc -lot_jpegd
+MPI_LIBS += -lot_sensor_i2c -lot_sensor_spi -lot_aio -lot_ai -lot_ao -lot_aenc -lot_adec -lot_acodec -lot_irq
+MPI_LIBS += -lss_mpi -lss_mau -lss_dpu_match -lss_ive -lss_dpu_rect -lss_pqp -lss_hdmi -lot_vfmw -lot_isp -lot_dis
+MPI_LIBS += -lot_gdc -lss_ae -lss_isp -lot_isp -lss_awb -lss_dehaze -lss_extend_stats -lss_drc -lss_ldci -lss_crb -lss_bnr -lss_voice_engine -lss_upvqe -lss_dnvqe
+MPI_LIBS += -lss_calcflicker -lss_ir_auto -lss_acs -lss_acs -lsns_hy_s0603
+#MPI_LIBS += -lsns_os08a20 -lsns_os05a10_2l_slave -lsns_imx347_slave -lsns_imx485 -lsns_os04a10 -lsns_os08b10
+MPI_LIBS += $(SDK_LINUX_OUT_LIB)/svp_npu/libsvp_acl.a
+MPI_LIBS += -L$(SDK_LINUX_OUT_LIB)/svp_npu -lprotobuf-c
+
+# 设置浮点运算, cpu类型, 链接器的相关设置
+CFLAGS += -Dss928v100 -DOT_XXXX -lpthread -lm -ldl -DISP_V2 -lc++ -lc -Wall -fsigned-char -mcpu=cortex-a53 -ldl -ffunction-sections -fdata-sections -O2 -fstack-protector-strong -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -fPIE -pie -s -Wall -fsigned-char -DOT_RELEASE -DVER_X=1 -DVER_Y=0 -DVER_Z=0 -DVER_P=0 -DVER_B=10 -DUSER_BIT_64 -DKERNEL_BIT_64 -Wno-date-time
+
+#====================================================
+# SDK include
+#====================================================
+CFLAGS += -I$(SDK_LINUX_INCLUDE_DIR)
+#CFLAGS += -I$(BOUNDS_CHECKING_DIR)
+CFLAGS += -I$(SDK_SAMPLE_COMMON_DIR)
+CFLAGS += -I$(SVP_COMMON_DIR)
+
+#====================================================
+# Source FileList
+#====================================================
+SOURCE_TREE := $(ROOT_DIR)
+BUILD_TREE := $(ROOT_DIR)
+
+#====================================================
+# Objects FileList
+#====================================================
+SRC_ROOT := $(SOURCE_TREE)
+OBJ_ROOT := $(OBJS_DIR)
+OBJS := $(SMP_SRCS:$(SRC_ROOT)%.c=$(OBJ_ROOT)%.o)
+OBJS := $(sort $(OBJS))
+OBJS_DIR := $(sort $(dir $(OBJS)))
+CPP_OBJS := $(CPP_SRCS:$(SRC_ROOT)%.cpp=$(OBJ_ROOT)%.o)
+OBJS_DIR += $(sort $(dir $(CPP_OBJS)))
+
+#====================================================
+# Create Directory
+#====================================================
+CreateDir = $(shell [ -d $1 ] || mkdir -p $1 || echo ":mkdir '$1' fail")
+CreateResult :=
+dummy := $(call CreateDir, $(OBJS_ROOT))
+dummy += $(foreach dir, $(OBJS_DIR), CreateResult += $(call CreateDir, $(dir)))
+ifneq ($(strip CreateDir),)
+ err = $(error $(CreateResult))
+endif
+
+#====================================================
+# Compile rules
+#====================================================
+MKDIRS := $(TARGET_DIR)
+
+.PHONY : clean all
+all: $(TARGET)
+
+$(TARGET): $(OBJS) $(CPP_OBJS) | $(MKDIRS)
+ @echo ... ld $@
+ @echo ... $(TARGET)
+ @$(CC) $(CFLAGS) $(FLAG_LD) -o $(TARGET_DIR)/$@ $^ -Wl,--start-group $(MPI_LIBS) -Wl,--end-group
+
+$(CPP_OBJS) : $(OBJ_ROOT)/%.o : $(SRC_ROOT)/%.cpp
+ @echo @@@ c++ $^
+ $(CXXCPP) $(FLAG_LD) $(CFLAGS) -c "$<" -o "$@" -w
+
+$(OBJS) : $(OBJ_ROOT)/%.o : $(SRC_ROOT)/%.c
+ @echo @@@ cc $^
+ @$(CC) $(FLAG_LD) $(CFLAGS) -c "$<" -o "$@" -w
+
+$(MKDIRS):
+ mkdir -p $@
+
+echo =========== $(TARGET) build success =================
+
+clean:
+ @rm -rf $(TARGET_DIR)
+ @rm -rf $(OBJ_ROOT)
+
+cleanstream:
+ @rm -f *.h264
+ @rm -f *.h265
+ @rm -f *.jpg
+ @rm -f *.mjp
+ @rm -f *.mp4