# ss928_app **Repository Path**: graylin2025/ss928_app ## Basic Information - **Project Name**: ss928_app - **Description**: ipc demo for ss928 - **Primary Language**: C/C++ - **License**: BSD-3-Clause - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 14 - **Created**: 2025-08-30 - **Last Updated**: 2025-08-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ss928_app #### 介绍 基于海思SS928V100_SDK_V2.0.2.2的IPC摄像头demo,支持以下功能: 1. H264/H265 rtsp服务 2. H264 rtmp服务 3. OSD(时间)功能 4. HNR 5. 图像自适应 6. yolov5 rtsp视频 当前支持的sensor为: 1. OS08A20 #### 编译方法 1. 按照/SS928V100_SDK_V2.0.2.2/osdrv/readme_cn.txt文档编译SDK 2. 按照如下命令,编译app ``` cd SS928V100_SDK_V2.0.2.2/smp/a55_linux/mpp/sample git clone https://gitee.com/shumjj/ss928_app.git cd ss928_app make ``` #### 运行 1. 烧写默认rootfs,挂载nfs,假设nfs已经挂载,nfs目录为/mnt ``` // opt见版本库rootfs下 cp /mnt/opt / -Rdp cd /opt/ceanic/ko ./load_ss928v100 -i ``` 2. 复制编译的程序到板子,并手动运行 ``` ./ss928_app ``` #### 配置文件说明 ##### vi.json ``` { "sensor1" : { "flip" : 0, "fr" : 30, "h" : 2184, "name" : "OS08A20", "w" : 3840 } } ``` | 类型 | 说明 | | ---- | ---- | | flip | 保留 | | fr | 帧率 | | h | sensor视频高 | | name | sensor类型,当前支持"OS08A20","OS08A20_WDR",WDR需要和scene中的mode相匹配 | | w | sensor视频宽 | ##### venc.json ``` { "venc1" : { "bitrate" : 8000, "fr" : 30, "h" : 2184, "name" : "H264", "w" : 3840 } } ``` | 类型 | 说明 | | ---- | ---- | | bitrate | 编码码率(kbps),当前支持CBR | | fr | 编码帧率 | | h | 编码视频高 | | name | 编码类型,当前支持"H264","H265" | | 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 | ##### aiisp.json ``` { "aiisp" : { "enable" : 1, "model_file" : "/opt/ceanic/aiisp/model/normal_hnr.bin" } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | model_file | 模型文件绝对路径,需要和mode中的类型匹配 | ##### scene.json ``` { "scene" : { "dir_path" : "/opt/ceanic/scene/param/sensor_os08a20", "enable" : 1, "mode" : 0 } } ``` | 类型 | 说明 | | ---- | ---- | | enable | 1:启用 0:启用 | | dir_path | scene使用的配置目录路径 | | mode | scene mode序号(见config_scenemode.ini) | #### RTSP ##### RTSP URL url为: rtsp://192.168.10.98/stream1 rtsp://192.168.10.98/stream2 rtsp://192.168.10.98/stream3 其中192.168.10.98需要修改为实际的板端地址,stream1为主编码(高清)码流,stream2为子编码(标清)码流,stream3为yolov5 视频(需要开启yolov5,/opt/ceanic/yolov5/yolov5.json) ##### 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) #### YOLOV5相关 1. demo中的yolov5使用svp_npu,默认022 sdk无yolov5.om,在022补丁下提供 2. 使用yolov5,需要关闭hnr,并且修改load_ss928v100脚本,修改内容如下: ``` #insmod ot_pqp.ko insmod svp_npu/ot_svp_npu.ko svp_npu_save_power=1 svp_npu_max_task_node_num=512 ``` 3. 修改/opt/ceanic/yolov5/yolov5.json ``` { "yolov5" : { "enable" : 1, "model_file" : "/mnt/ss928/yolov5.om" } } ``` 4. 板端运行ss928_app,pc端运行vlc,vlc地址为:rtsp://192.168.10.98/stream3 #### 调试总结 ##### Demo板RTC开启方法 demo板用的是Epson RX8900,需要在linux下开启驱动 1. make ARCH=arm64 CROSS_COMPILE=aarch64-mix210-linux- menuconfig 2. Device Drivers--->Real Time Clock--->Micro Crystal RV8803, Epson RX8900,按M选择模块 3. make ARCH=arm64 CROSS_COMPILE=aarch64-mix210-linux- modules 4. 生成drivers/rtc/rtc-rv8803.ko 5. 在板子上insmod后,使用date和hwclock命令修改时间 ##### uboot默认环境参赛修改 1. bootargs修改方法: 修改.config文件(该文件来源于configs目录,例如emmc版本为configs/ss928v100_emmc_defconfig) ``` CONFIG_BOOTARGS="mem=512M console=ttyAMA0,115200 clk_ignore_unused ubi.mtd=2 root=ubi0:ubifs rootfstype=ubifs rw mtdparts=nand:1M(boot),11M(kernel),32M(rootfs.ubifs)" ``` 2. bootcmd修改方法: 修改include/configs/ss928v100.h ``` #define CONFIG_BOOTCOMMAND "nand read 0x50000000 0x100000 0xb00000;bootm 0x50000000" ``` ##### initramfs 1. 参考osdrv/readme_cn.txt编译整个sdk,生成osdrv/put/rootfs_glibc_arm64文件系统 2. 参考SS928V100╱SS927V100 开发环境用户指南.pdf 6.3.4章节中的内核配置 3. 在linux目录下调用make ARCH=arm64 CROSS_COMPILE=aarch64-mix210-linux- menuconfig,在配置界面中General setup--->Initial RAM filesystem and RAM disk (initramfs/initrd) support这项按y选中后,Initramfs source file这栏中输入rootfs的路径(例如:/home/mjj/work/3403/SS928V100_SDK_V2.0.2.2/osdrv/pub/rootfs_glibc_arm64),rootfs必须是第一步中已经生成好的 4. 按照osdrv/readme_cn.txt单独编译kernel生成fip.bin,因为已经包含了rootfs,生成的fip.bin大小为13.8M左右(不含rootfs的大小在10.8M左右) 5. 烧录的时候只需要烧录uboot和fip.bin,uboot设置1M大小,fip.bin设置15M 6. uboot参赛设如下(spi nand下): ``` setenv bootcmd 'nand read 0x50000000 0x100000 0xf00000;bootm 0x50000000';sa setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/ram0 rw init=/init blkdevparts=mmcblk0:1M(boot),15M(kernel)';sa ``` ##### ramdisk ramdisk不是文件系统(ext4,vfat)的概念,是一种叫法,区别传统物理硬盘挂载。 1. 传统的挂载(例如硬盘),设备符为/dev/sda(表示这个设备指向实际物理存储设备),用fdisk分区成/dev/sda1,dev/sda2,用mkfs.ext4等工具格式化分区(mkfs.ext4 /dev/sda1),然后再挂载(mount -t ext4 /dev/sda1 /mnt) 2. ramdisk,设备符为/dev/ram0,表示这个设备指向内存,这个/dev/ram0设备地址需要在内核中制定,如下图menuconfig中 Device Drivers--->[*] Block devices---><*>RAM block device support: 其中(16)代表内核中生成/dev/ram0-/dev/ram15,一般情况下我们只需要/dev/ram0,所以可以设置该值为1就可以 其中(65536)这个值代表/dev/ram0内存中文件系统的大小(和/dev/sda1中的分区大小类似),改值单位为k,65536表示容量为64M,实际的分区大小可以小于该值 ![avatar](doc/ramdisk_device_blk.jpg) 3. 从上面这张图可以看到,内核中生成了/dev/ram0这个描述符,代表了内存中有一块64M的分区,但是还缺一个关键信息就是这块分区在内存中的地址,该值一般通过uboot bootarg参数传入,例如root=/dev/ram0 initrd=0x52000000,0x100000就向内核传递了我要把内存中0x52000000,大小为16M挂载到/dev/ram0上 4. 既然牵涉到挂载,那还需要知道这块内存区域的文件是什么格式的,用的最多的是ext2,ext4也有。常用的一些文件格式当前内核无需配置,都支持。 ###### 3403 ramdisk(ext2)制作步骤 1. 参考osdrv/readme_cn.txt编译整个sdk,生成osdrv/put/rootfs_glibc_arm64文件系统 2. 在linux目录下调用make ARCH=arm64 CROSS_COMPILE=aarch64-mix210-linux- menuconfig,在配置界面中General setup--->Initial RAM filesystem and RAM disk (initramfs/initrd) support这项按y选中后,Initramfs source file这栏为空 3. 进入rootfs_glibc_arm64,查看rootfs占用的空间,默认编译出来的占用10M,保守期间我们可以制作一个11M的ramdisk系统,实际的话根据需求,只要小于上面内核配置的64M的就可以 ``` cd rootfs_glibc_arm64/ du -h ``` 4. 使用genext2fs创建一个ext2的ramdisk,下述的11264为11x1024(11M)的计算结果 ``` genext2fs -b 11264 -d ../rootfs_glibc_arm64/ ramdisk //验证作出来的ramdisk是否正确: mkdir test sudo mount -t ext2 ramdisk ./test ls ./test sudo umount ./test ``` 5. 使用gzip压缩,生成ramdisk.gz,压缩后的大小为4M,uboot的参数initrd=addr,size中的size表示的是压缩前的大小 ``` gzip --best ramdisk ``` 6. 烧录uboot,kernel,rootfs,uboot参数设置如下: ![avatar](doc/ramdisk_ext2.jpg) ``` //nand read 0x52000000 0xC00000 0x400000,压缩后的ramdisk大小为4M,从flash中读取到0x52000000中 setenv bootcmd 'nand read 0x52000000 0xC00000 0x400000;nand read 0x50000000 0x100000 0xB00000;bootm 0x50000000';sa //initrd=0x52000000,0xB00000,0xB00000代表11M,表示的是压缩前的ramdisk大小 setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/ram0 initrd=0x52000000,0xB00000 blkdevparts=mmcblk0:1M(boot),11M(kernel),11M(rootfs.ramdisk)';sa ``` ###### 3403 ramdisk(cramfs)制作步骤 1. 参考osdrv/readme_cn.txt编译整个sdk,生成osdrv/put/rootfs_glibc_arm64文件系统 2. 在linux目录下调用make ARCH=arm64 CROSS_COMPILE=aarch64-mix210-linux- menuconfig,在配置界面中General setup--->Initial RAM filesystem and RAM disk (initramfs/initrd) support这项按y选中后,Initramfs source file这栏为空 3. 进入rootfs_glibc_arm64,查看rootfs占用的空间,默认编译出来的占用10M,保守期间我们可以制作一个11M的ramdisk系统,实际的话根据需求,只要小于上面内核配置的64M的就可以 ``` cd rootfs_glibc_arm64/ du -h ``` 4. 使用mkfs.cramfs创建一个cramfs的ramdisk ``` ../bin/pc/mkfs.cramfs ../rootfs_glibc_arm64 cramfs.ramdisk //验证作出来的ramdisk是否正确: mkdir test sudo mount -t cramfs cramfs.ramdisk ./test ls ./test sudo umount ./test ``` 5. 使用gzip压缩,生成cramfs.ramdisk.gz,压缩后的大小为4.6M,uboot的参数initrd=addr,size中的size表示的是压缩前的大小 ``` gzip --best cramfs.ramdisk ``` 6. 烧录uboot,kernel,rootfs,uboot参数设置如下: ![avatar](doc/ramdisk_cramfs.jpg) ``` //nand read 0x52000000 0xC00000 0x500000,压缩后的ramdisk大小为4.6M,从flash中读取到0x52000000中 setenv bootcmd 'nand read 0x52000000 0xC00000 0x500000;nand read 0x50000000 0x100000 0xB00000;bootm 0x50000000';sa //initrd=0x52000000,0xB00000,0xB00000代表11M,表示的是压缩前的ramdisk大小 setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/ram0 initrd=0x52000000,0xB00000 blkdevparts=mmcblk0:1M(boot),11M(kernel),11M(rootfs.ramdisk)';sa ``` ##### cramfs文件系统制作 1. 参考osdrv/readme_cn.txt编译整个sdk,生成osdrv/put/rootfs_glibc_arm64文件系统 2. 使用SDK下的kernel,无需修改 3. 调用mkfs.cramfs生成rootfs ``` mkfs.cramfs ../rootfs_glibc_arm64 cramfs.img ``` 4. 烧录uboot,kermel,rootfs ![avatar](doc/cramfs.jpg) 5. uboot bootarg和bootcmd参数如下(spi nand): ``` setenv bootcmd 'nand read 0x50000000 0x100000 0xB00000;bootm 0x50000000';sa setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=cramfs mtdparts=nand:1M(boot),11M(kernel),5M(rootfs)';sa ``` ##### squashfs文件系统制作 squashfs和cramfs都是只读文件系统,但是squashfs压缩率高(同样sdk下的rootfs_glibc_arm64,carmfs制作出来的文件系统大小为4.6M,squashfs制作出来的文件系统大小为3.9M),且没有cramfs单个文件不能超过16M的限制,建议优先选用squashfs。 1. 参考osdrv/readme_cn.txt编译整个sdk,生成osdrv/put/rootfs_glibc_arm64文件系统 2. 使用SDK下的kernel,无需修改 3. 调用mksquashfs生成rootfs ``` //-b 参数128K是从uboot打印中获取 ../bin/pc/mksquashfs ../rootfs_glibc_arm64 rootfs.squash -b 128k ``` 4. 烧录uboot,kermel,rootfs ![avatar](doc/squashfs.jpg) 5. uboot bootarg和bootcmd参数如下(spi nand): ``` setenv bootcmd 'nand read 0x50000000 0x100000 0xB00000;bootm 0x50000000';sa setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=squashfs mtdparts=nand:1M(boot),11M(kernel),4M(rootfs)';sa ```