# 3516cv610_app **Repository Path**: yangdev89/3516cv610_app ## Basic Information - **Project Name**: 3516cv610_app - **Description**: demo for 3516cv610 - **Primary Language**: C/C++ - **License**: GPL-3.0 - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 25 - **Created**: 2025-03-11 - **Last Updated**: 2025-03-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 3516cv610_app #### 介绍 基于海思Hi3516CV610 SDK 010 musl 版本的IPC摄像头demo 1. H264/H265 rtsp服务 2. H264 rtmp服务 3. OSD(时间)功能 4. 海思图像自适应 5. Mp4文件保存 6. aidetect 7. yolov8(只支持20s上运行,且无法和aidetect同时运行) 8. jpg抓拍 当前支持的sensor为: 1. SC4336P #### 流程图 ``` |vpss chn(2)--------->aidetect(1024x576)/yolov8(640x640)------------>rtsp stream3 | |vpss chn(1)--------->venc sub(固定720 x 480)-------->rtsp stream2 | (和vi相同分辨率) (和vi相同分辨率) mipi/vi-------->vpss grp(0)-------->vpss chn(0)---------->venc main(分辨率大小由venc.json中指定,例如1920x1080)--------->rtsp stream1 | | | |-------->mp4保存 | | |------>jpg保存 ``` #### 设置合理的os内存和MMZ内存 1. 10B DDR大小为64M,其中默认OS=32M,MMZ=32M 2. 20S DDR大小为128M,其中默认OS=32M,MMZ=96M 3. ss_mpi_vb_set_cfg设置公用vb块,确保cat /proc/umap/vb中pool_type=common,owner=common的vb块中min_free=0,且当min_free=0时候,cat /dev/logmpp无获取不到vb报错信息 4. 应用程序开启,所有功能开启(保证应用程序用到了所有模块的mmz),cat /proc/umap/media-mem 查看最后一行,看remain=XXXXXKB,remain一行是MMZ剩余的内存,可以将这些内存给OS使用,例如remain=9000KB,则可以将多余的8M给os(OS=40M,MMZ=24M) 5. 修改uboot参数设置合理的os大小,修改load脚本中mmz_start,mmz_size,和os大小匹配 #### 推荐的设置 1. vi vpss mode设置为OT_VI_ONLIE_VPSS_ONLINE ``` vi_vpss_mode.mode[0] = OT_VI_ONLINE_VPSS_ONLINE; ret = ss_mpi_sys_set_vi_vpss_mode(&vi_vpss_mode); ``` 2. vpss chn0 compress_mode设置为OT_COMPRESS_MODE_SEG_COMPACT ``` m_vpss_chn0_attr.compress_mode = OT_COMPRESS_MODE_SEG_COMPACT; ``` 3. vi 3dnr compress_mode设置为OT_COMPRESS_MODE_FRAME ``` nr_attr.compress_mode = OT_COMPRESS_MODE_FRAME; ret = ss_mpi_vi_set_pipe_3dnr_attr(m_pipes[0],&nr_attr); ``` 4. vpss ch0启用绕卷,vpss ch1 启用low delay ``` ot_vpss_chn_buf_wrap_attr wrap_attr; wrap_attr.enable = TD_TRUE; wrap_attr.buf_line = buf_line; wrap_attr.buf_size = wrap_buf_size; DEV_WRITE_LOG_INFO("WRAP INFO:enalbe=%d,buf_line:%d,buf_size:%d",wrap_attr.enable,wrap_attr.buf_line,wrap_attr.buf_size); ret = ss_mpi_vpss_set_chn_buf_wrap(m_vpss_grp,m_vpss_chn,&wrap_attr); .... .... ot_vpss_chn vpss_chn1 = 1; ret = ss_mpi_vpss_set_chn_attr(m_vpss_grp, vpss_chn1, &m_vpss_chn1_attr); ``` 5. 主码流绑定到vpss chn0,子码流绑定到vpss chn1 6. h264/h265编码参数rcn_ref_share_buf_en 设置为true ``` m_venc_chn_attr.venc_attr.h265_attr.rcn_ref_share_buf_en = TD_TRUE; ``` 7. ss_mpi_vb_set_cfg()参考dev_sys.cpp #### 10B资源情况 1. 按照推荐配置,以sc4336p为例,在主码流h265编码2560x1440@30p,子码流h265编码720x480@30,两个osd区域,开启scene_auto的情况下,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=32768KB(32MB),used=17020KB(16MB + 636KB),remain=15748KB(15MB + 388KB),zone_number=1,block_number=49 ``` 2. 在1的基础上加入jpg抓拍,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=32768KB(32MB),used=24248KB(23MB + 696KB),remain=8520KB(8MB + 328KB),zone_number=1,block_number=51 ``` 3. 在1的基础上加入aidetect,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=32768KB(32MB),used=21264KB(20MB + 784KB),remain=11504KB(11MB + 240KB),zone_number=1,block_number=63 ``` 4. 在1的基础上加入aidetect 检测视频,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=32768KB(32MB),used=23428KB(22MB + 900KB),remain=9340KB(9MB + 124KB),zone_number=1,block_number=68 ``` #### 20S资源情况 1. 按照推荐配置,以sc4336p为例,在主码流h265编码2560x1440@30p,子码流h265编码720x480@30,两个osd区域,开启scene_auto的情况下,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=98304KB(96MB),used=16752KB(16MB + 368KB),remain=81552KB(79MB + 656KB),zone_number=1,block_number=49 ``` 2. 在1的基础上加入jpg抓拍,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=98304KB(96MB),used=23964KB(23MB + 412KB),remain=74340KB(72MB + 612KB),zone_number=1,block_number=51 ``` 3. 在1的基础上加入aidetect 检测视频,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=98304KB(96MB),used=23160KB(22MB + 632KB),remain=75144KB(73MB + 392KB),zone_number=1,block_number=68 ``` 4. 在1的基础上加入yolov8 检测视频,mmz使用情况(cat /proc/umap/median-mem)如下: ``` total size=98304KB(96MB),used=41220KB(40MB + 260KB),remain=57084KB(55MB + 764KB),zone_number=1,block_number=69 ``` #### 编译方法 1. 按照Hi3516CV610_SDK_V1.0.0.1/smp/a7_linux/source/bsp/readme_cn.txt文档编译SDK 2. 修改Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/out/include/ot_buffer_detail.h 615,675行,修改如下: ```` //line 615 pme_share_en = (attr->share_buf_en && (attr->svc_version != OT_VENC_SVC_V2)) ? TD_TRUE : TD_FALSE; //line 675 pme_share_en = (attr->share_buf_en && (attr->svc_version != OT_VENC_SVC_V2)) ? TD_TRUE : TD_FALSE; ```` 3. 修改Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/out/include/ot_buffer.h 258行,修改如下: ``` //line 258 pme_share_en = ((attr->share_buf_en == TD_TRUE) && (attr->svc_version != OT_VENC_SVC_V2)) ? TD_TRUE : TD_FALSE; ``` 4. 按照如下命令,编译app ``` cd Hi3516CV610_SDK_V1.0.0.1/smp/a7_linux/source/mpp/sample git clone https://gitee.com/shumjj/3516cv610_app.git cd 3516cv610_app make ``` #### 运行 ``` //加载ko,10b请加载相应的脚本 cd /opt/ceanic/ko/load3516cv610/ ./load3516cv610_20s_debug -i //如果要运行yolov(20s上支持),需要将libsvp_aicpu.so放到环境变量 export LD_LIBRARY_PATH=/opt/ceanic/lib:$LD_LIBRARY_PATH cd /opt/ceanic/bin ./ceanic_app ``` #### 目录结构 ``` ├── app_std.h //app头文件 ├── device //海思设备相关 ├── doc //doc ├── json //json库 ├── log //log库 ├── main.cpp ├── Makefile ├── README.md ├── rootfs //SDK rootfs修改部分 ├── rtmp //rtmp 实现 ├── rtsp //rtsp 实现 ├── thirdlibrary //第三方库 └── util //通用头文件 ``` #### 配置文件说明 ##### vi.json ``` //sample for sc4336p { "sensor1" : { "name" : "SC4336P" } } ``` | 类型 | 说明 | | ---- | ---- | | name | sensor类型,当前支持"SC4336P" | ##### venc.json ``` { "venc1" : { "bitrate" : 4000, "fr" : 30, "h" : 1080, "name" : "H264_CBR", "w" : 1920 } } ``` | 类型 | 说明 | | ---- | ---- | | bitrate | 编码码率(kbps),当前支持CBR(平均码率),AVBR(最大码率) | | fr | 编码帧率 | | h | 编码视频高 | | name | 编码类型,当前支持"H264_CBR","H264_AVBR","H265_CBR","H265_AVBR" | | w | 编码视频宽 | ##### net_service.json ``` { "net_service" : { "rtmp" : { "enable" : 1, "main_url" : "rtmp://192.168.10.97/live/stream1", "sub_url" : "rtmp://192.168.10.97/live/stream2" }, "rtsp" : { "port" : 554 } } } ``` | 类型 | 说明 | | ---- | ---- | | rtsp:port | RTSP 侦听端口,默认554 | | rtmp:enable | 0:不启用rtmp 1:启用rtmp | | rtmp:main_url | rtmp 主编码数据url | | rtmp:sub_url | rtmp 子编码数据url | ##### scene.json ``` { "scene" : { "dir_path" : "/opt/ceanic/scene/param/sensor_sc4336p", "enable" : 1, "mode" : 0 } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | dir_path | scene使用的配置目录路径 | | mode | scene mode序号(见config_scenemode.ini) | ##### mp4_save.json ``` { "mp4_save" : { "file" : "/mnt/test.mp4", "enable" : 0, } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | file | mp4保存路径 | ##### aidetect.json ``` { "aidetect" : { "enable" : 0, "model_file" : "/opt/ceanic/aidetect/det_hvf_normal.bin" } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | model_file | 模型文件路径 | ##### yolov8.json ``` { "yolov8" : { "enable" : 0, "model_file" : "/opt/ceanic/yolov8/yolov8.om" "cfg_file" : "/opt/ceanic/yolov8/acl.json" } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | model_file | 模型文件路径 | | cfg_file | 模型配置文件 | ##### jpg_save.json ``` { "jpg_save" : { "enable" : 0, "quality" : 90, "interval" : 60, "dir_path" : "/mnt/", } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | quality | JPG图像质量[1,99] | | interval | 抓拍间隔(秒) | | dir_path | 保存目录路径 | #### RTSP ##### RTSP URL url为: ``` //main stream rtsp://192.168.10.98/stream1 //sub stream rtsp://192.168.10.98/stream2 //yolov8 stream(需要配置文件中开启yolov8) //因为性能限制,yolov8的帧率在8-12之间,如果使用vlc连接yolov8视频,需要开大vlc缓存(建议开到2000ms) rtsp://192.168.10.98/stream3 ``` ##### VLC连接RTSP vlc连接方法:媒体->打开网络串流->输入RTSP URL ![avatar](doc/rtsp_open.jpg) #### RTMP rtmp默认不开启,需要修改/opt/ceanic/etc/net_service.json文件 ##### RTMP测试服务器(nginx)搭建(ubuntu20.04) 1. 按照如下命令编译nginx,需要注意的是运行nginx, -C 后面的参赛需要是全路径 ``` wget http://nginx.org/download/nginx-1.21.6.tar.gz wget https://github.com/arut/nginx-rtmp-module/archive/master.zip tar -xf nginx-1.21.6.tar.gz unzip master.zip cd nginx-1.21.6/ ./configure --prefix=`pwd`/mybuild --with-http_ssl_module --add-module=../nginx-rtmp-module-master make && make install cd mybuild/sbin sudo ./nginx -c /home/mjj/work/nginx-1.21.6/mybuild/sbin/nginx_rtmp.conf ``` 2. nginx_rtmp.conf见rtmp目录 3. 查看nginx rtmp服务是否开启 ``` ~/work/nginx-1.21.6/mybuild/sbin$ sudo netstat -na | grep 1935 tcp 0 0 0.0.0.0:1935 0.0.0.0:* LISTEN ``` 4. 查看rtmp 日志 错误日志如下 ``` mjj@mjj-VirtualBox:~/work/nginx-1.21.6/mybuild/sbin$ tail ../logs/error.log 024/01/09 15:59:54 [info] 16432#0: *100 disconnect, client: 192.168.10.200, server: 0.0.0.0:1935 2024/01/09 15:59:54 [info] 16432#0: *100 deleteStream, client: 192.168.10.200, server: 0.0.0.0:1935 2024/01/09 16:03:57 [info] 16432#0: *98 disconnect, client: 192.168.10.98, server: 0.0.0.0:1935 2024/01/09 16:03:57 [info] 16432#0: *98 deleteStream, client: 192.168.10.98, server: 0.0.0.0:1935 2024/01/09 16:03:57 [info] 16432#0: *97 disconnect, client: 192.168.10.98, server: 0.0.0.0:1935 2024/01/09 16:03:57 [info] 16432#0: *97 deleteStream, client: 192.168.10.98, server: 0.0.0.0:1935 ``` 连接日志如下 ``` tail ../logs/access.log 192.168.10.200 [09/Jan/2024:15:34:32 +0800] PLAY "live" "stream2" "" - 478 31874328 "" "LNX 9,0,124,2" (4m 8s) 192.168.10.98 [09/Jan/2024:15:49:24 +0800] PUBLISH "live" "stream2" "" - 151203194 409 "" "" (19m 27s) 192.168.10.98 [09/Jan/2024:15:49:24 +0800] PUBLISH "live" "stream1" "" - 603082173 409 "" "" (19m 27s) 192.168.10.200 [09/Jan/2024:15:53:48 +0800] PLAY "live" "stream1" "" - 1549 453211948 "" "LNX 9,0,124,2" (19m 8s) 192.168.10.98 [09/Jan/2024:15:58:50 +0800] PUBLISH "live" "stream2" "" - 4021860 409 "" "" (32s) 192.168.10.98 [09/Jan/2024:15:58:50 +0800] PUBLISH "live" "stream1" "" - 16027268 409 "" "" (32s) 192.168.10.200 [09/Jan/2024:15:59:41 +0800] PLAY "live" "stream1" "" - 411 11245160 "" "LNX 9,0,124,2" (26s) 192.168.10.200 [09/Jan/2024:15:59:54 +0800] PLAY "live" "stream2" "" - 378 1600363 "" "LNX 9,0,124,2" (13s) 192.168.10.98 [09/Jan/2024:16:03:57 +0800] PUBLISH "live" "stream2" "" - 37391403 409 "" "" (4m 50s) 192.168.10.98 [09/Jan/2024:16:03:57 +0800] PUBLISH "live" "stream1" "" - 149073600 409 "" "" (4m 50s) ``` 5. nginx 开启/关闭 ``` //开启命令 ~/work/nginx-1.21.6/mybuild/sbin$sudo ./nginx -c /home/mjj/work/nginx-1.21.6/mybuild/sbin/nginx_rtmp.conf //关闭命令 ~/work/nginx-1.21.6/mybuild/sbin$sudo ./nginx -s stop ``` ##### VLC连接nginx 1. 先根据[RTMP测试服务器搭建](#####RTMP测试服务器(nginx)搭建(ubuntu20.04))章节搭建好nginx 服务器 2. 根据[RTMP配置文件说明](#####RTMP配置文件说明)中说明获取到RTMP URL 3. 打开vlc->媒体->打开网络串流->输入RTMP URL ![avatar](doc/rtmp_open.jpg) #### thirdlibrary ##### freetype-2.7.1交叉编译 ``` ./configure --prefix=`pwd`/mybuild_arm_v01c02_linux_musleabi --host=arm-v01c02-linux-musleabi --with-zlib=no CPPFLAGS=-fPIC make && make install ``` ##### libevent-2.0.18-stable交叉编译 ``` //修改evutil.c 427行 //struct _timeb tb; struct timeb tb; //修改evutil.c 440行 //_ftime(&tb); ftime(&tb); ./configure --prefix=`pwd`/mybuild_arm_v01c02_linux_musleabi --host=arm-v01c02-linux-musleabi CFLAGS=-fPIC make && make install ``` ##### lob4cpp交叉编译 ``` /configure --prefix=`pwd`/mybuild_arm_v01c02_linux_muslabi --host=arm-v01c02-linux-musleabi CXXFLAGS=-fPIC make && make install ``` ##### rtmpdump交叉编译 ``` make prefix=./mybuild_arm_v01c02_linux_musleabi SYS=posix CROSS_COMPILE=arm-v01c02-linux-musleabi- XDEF=-DNO_SSL CRYPTO= //修改Makefile和librtmp/Makefile中的prefix定义(调用上述命令未修改prefix中的值,手动修改 prefix=./mybuild_arm_v01c02_linux_musleabi make && make install ``` #### 调试记录 1. ss_mpi_vgs_add_cover_task()的参数的坐标必须为2的倍速,否则返回失败,如下代码用ROUND_DOWN,ROUND_UP保证为2的倍速 ```` vgs_add_cover.rect_attr.rect.x = ROUND_DOWN(result->object_class[i].objects[j].detect_rect.x,2); vgs_add_cover.rect_attr.rect.y = ROUND_DOWN(result->object_class[i].objects[j].detect_rect.y,2); vgs_add_cover.rect_attr.rect.width = ROUND_UP(result->object_class[i].objects[j].detect_rect.width,2); vgs_add_cover.rect_attr.rect.height = ROUND_UP(result->object_class[i].objects[j].detect_rect.height,2); ss_mpi_vgs_add_cover_task(vgs_handle, &vgs_task, &vgs_add_cover, 1); ```` 2. ss_mpi_vgs_end_job()必须判断返回值,如果返回值失败,需要调用ss_mpi_vgs_cancel_job(),否则会导致资源泄漏 ```` ret = ss_mpi_vgs_end_job(vgs_handle); if(ret != TD_SUCCESS) { ss_mpi_vgs_cancel_job(vgs_handle); } ```` 3. sdk下用yolov5测试,每帧的处理时间约200ms,改成yolov8后,每帧处理约90ms 4. sdk下的yolov8.om运行起来,remain为55M,用SVP_NNN_PC_V5.0.0.21下atc生成作出来的yolov8.om,remain为60M,建议用atc生成的,MMZ可以省5M ``` //使用sdk sample下的yolov8.om(sample/svp/svp_npu/data/model/yolov8.om),mmz资源如下: total size=98304KB(96MB),used=41220KB(40MB + 260KB),remain=57084KB(55MB + 764KB),zone_number=1,block_number=69 //使用atc生成的yolov8,mmz资源如下: //atc --dump_data=0 --input_shape="images:1,3,640,640" --input_type="images:UINT8" --log_level=0 --online_model_type=0 --batch_num=1 --input_format=NCHW --output="./model/yolov8" --soc_version=Hi3516CV610 --insert_op_conf=./insert_op_yvu.cfg --framework=5 --compile_mode=0 --model="./onnx_model/yolov8n.onnx" --image_list="images:./data/image_ref_list.txt" total size=98304KB(96MB),used=36216KB(35MB + 376KB),remain=62088KB(60MB + 648KB),zone_number=1,block_number=68 ``` 5. 新增一路jpg编码做jpg抓拍,多7M左右mmz。 6. aidetect编码(1024x576)会导致/dev/logmpp下报miss_start,ring_back,ring_buf_full等错误,需要加大wrap buf,方式如下: ``` //dev_sys.cpp中修改 vb_cfg.common_pool[3].blk_size = ot_comm_get_vpss_venc_wrap_buf_size(&buf_attr, 256);//原来的128太小,改成256 //dev_vi_isp.cpp中修改 td_u32 buf_line = 256; ot_vpss_chn_buf_wrap_attr wrap_attr; wrap_attr.enable = TD_TRUE; wrap_attr.buf_line = buf_line;//256 wrap_attr.buf_size = wrap_buf_size; ``` 7. 主码流延时在67ms(2560x1440@30,vi_onlie_vpss_online),vpss grp0,chn0无法在wrap情况下开启lowdelay 8. mp4录像需要足够的内存,当前默认os 32M情况下,mp4录像会有outof memory错误,导致程序被kernel kill调,应该是SS_MP4_WriteFrame对内存的要求较高。注释调SS_MP4_WriteFrame()就正常,后续需要提高os内存,确定多少内存才能mp4录像。 9. 当启用wrapbuf的时候,vpss chn0的分辨率必须和venc主码流分辨率一致,否则会有如下报错: ``` <3>[ venc] [Func]:venc_check_vpss_ring_info [Line]:732 [Info]:venc 0: video info err. <3>[ venc] [Func]:venc_check_ring_scene [Line]:615 [Info]:venc 0, ring frame width: 2560, height 1440, venc width: 1920, height 1080 ``` #### 合作交流 联系方式: 深圳思尼克技术有限公司 jiajun.ma@ceanic.com 马佳君