参考文章海思 3403 MPP 全链路解析: VI、VPSS、VENC 的运行逻辑与实践_vi 4k switch to fhd - vpss - venc vo-CSDN博客一、Hi3516CV610 sdk目录层级sudo apt-get install tree # 预装tree命令。 tree -L 2 -d # -L 2:只显示目录的两层深度 -d只显示目录不显示文件。sdk根目录open_source/:所有第三方开源软件的完整源代码busybox/、linux/、u-boot/、optee/、mtd-utils/、ethtool/、squashfs/、zlib/、mbedtls/ 等。提供操作系统基础组件你可以在这些目录里修改配置、进行交叉编译。内核和 U-Boot 的源码都在这里驱动开发和设备树修改需要。package/:存放open_source/、platform/、smp/三个目录的.tgz压缩包备份。platform/存放secure/安全子系统。scripts/存放SDK 环境配置和依赖检查的Shell 脚本快速配置编译环境、检查系统依赖是否完整首次搭建编译环境使用。sdk.unpack解压 SDK。将package/目录下的.tgz压缩包open_source.tgz、platform.tgz、smp.tgz解压到对应目录构建完整的可编译环境sdk.cleanup清理 SDK。删除解压出来的目录如open_source/、platform/、smp/恢复到刚拿到 SDK 时的纯净状态~/sdk/Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/vendor/extdrv目录extdrv/存放外部设备的驱动源码和编译脚本ES8388 音频 Codec 驱动源码。Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/source目录bsp/components/:gsl(Generic System Library)和 secure_c安全世界的客户端库。运行在CPU 安全世界中的一个小型 RTOS 系统的源码。cfg.mak:顶层 Makefile 配置文件定义编译选项和路径。common/:内存管理子系统负责整个系统的内存分配、管理和多媒体大块内存MMZ的分配与回收。interdrv/:内部驱动1.mipi_rx/MIPI CSI-2 接收驱动负责接收 IMX586 摄像头的图像数据。2.ot_adc,ADC 驱动用于采集模拟信号如电池电压、光照强度等3.ot_usr,用户空间接口提供驱动与用户程序交互的通道。4.sysconfig,系统配置驱动管理硬件模块的使能/禁用、引脚复用等。5.wtdg,看门狗驱动防止系统死机时无法自动恢复。6.init,驱动初始化脚本或代码。mpp/:媒体处理平台。osal/操作系统抽象层屏蔽不同操作系统Linux/RTOS的差异提供统一的 API 接口如线程创建、互斥锁、信号量、内存分配等。out/编译产出头文件、库、驱动模块。out下的目录层级scripts/:编译脚本。scripts下目录层级sdk/Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/source/mpp目录RTSP推流示例程序Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\rtsp\sample_rtsp.cstruct sample_comm_venc_chn_param单个编码通道的参数配置结构体。frame_rate; // 帧率stats_time; // 码率统计时间gop; // GOP大小关键帧间隔venc_size; // 编码尺寸宽高实际存储宽和高。size; // 存储分辨率枚举ot_pic_size是一个枚举类型会有单独的函数将枚举类型转换成实际的宽和高。profile; // 编码档次baseline/main/high等is_rcn_ref_share_buf; // 参考帧共享缓冲gop_attr; // GOP属性type; // 编码类型H.264/H.265/JPEG等rc_mode; // 码率控制模式CBR/VBR/ABR等index只判断了通道1所以在推流时只推通道1。二、VI部分参考文档HI3516CV610-SIM-开发板资料\原厂sdk\ReleaseDoc\zh\01.software\board\MPP\MPP 媒体处理软件 V6.0 开发参考.pdfVI模块api位置Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\vie\sample_vie.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_sys.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_vi.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_vpss.c下面学习内容以 sample_vie.c 为出发点。阶段一系统初始化sample_vie_sys_init()→ sample_comm_sys_init_with_vb_supplement() // 初始化VB视频缓冲池→ ss_mpi_vi_set_vi_vpss_mode() // 设置VI/VPSS工作模式阶段二VI设备配置与启动sample_comm_vi_get_default_vi_cfg() //获取VI默认配置(sensor\mipi\dev\bind\gpr\pipe info).sample_vie_get_pipe_wrap_line()→ss_mpi_sys_get_vi_wrap_buffer_line() //获取VICAP-VPPROC离线卷绕模式下的buffer卷绕行数。buf_line行数与sensor时序、sensor路数及主从模式、VIPROC性能、VPSS性能、 VENC性能等多方面因素有关实际业务场景中如果CPU不能每帧都立即响应VI/VPSS/VENC中断存在中断延迟等情况客户需要以实际测试场景为准适当增大buf_line。sample_comm_vi_start_vi()→sample_comm_vi_start_mipi_rx() //MIPI RX 接口的初始化启动函数负责配置和启用 MIPI CSI 接收器。→sample_comm_vi_start_dev() //设备级初始化函数负责配置 VI 设备的硬件时序参数并启用设备。→sample_comm_vi_dev_bind_pipe() //设备与管道绑定函数负责建立 VI 设备VI DEV与 VI 管道VI PIPE之间的数据关联关系实现多路数据流的分发与汇聚。→sample_comm_vi_set_grp_info() //WDR宽动态融合组配置函数负责设置多帧曝光数据的融合策略实现高动态范围图像的合成。→sample_comm_vi_start_pipe() //遍历启动所有绑定的pipe。→sample_comm_vi_start_isp() //法的启动函数负责为每个 VI PIPE 加载并运行 ISP 固件实现图像信号处理的核心算法。PIPE 是 VI 模块的ISP 处理管道承担以下关键职责VI PIPE 是 VI 模块的 ISP 处理管道由硬件电路数据通路、ISP 硬核、行缓冲 FIFO和软件线程AE/AWB/AF/3DNR 算法共同组成。核心职责接收数据— 从 VI DEV 获取 Bayer RAW 数据ISP 处理— 硬件执行去马赛克、颜色校正、WDR 融合软件线程实时计算 3A 参数并反馈调节 Sensor时序控制— 帧率控制、帧同步、WDR 多帧时序对齐输出推送— 将处理后的 YUV 数据推送到 VI CHN后续流转— CHN 输出至 VPSS视频前处理或 VENC编码阶段三VI与VPSS绑定数据流转关键sample_comm_vi_bind_vpss() //配置vi端与vpss端通道结构体→ss_mpi_sys_bind() //VI 模块与 VPSS 模块的系统级绑定函数通过 MPPMedia Process Platform框架的标准绑定机制建立从 VI 通道到 VPSS 通道的数据流转通路。阶段四、VPSS图像处理启动sample_vie_start_vpss→sample_common_vpss_start() //创建并启动 VPSS 处理组及其下属通道实现图像的缩放、裁剪、格式转换等前处理功能。组GRP与通道CHN的层级关系组是资源管理单元每个grp对应一个dev即一个sensor。通道是物理通道单独处理输出。grp可以接收一个sensor在一个grp下存在多个chn每个chn可按要求输出不同规格的数据流。阶段五、VPSS与VENC绑定编码启动sample_vie_start_and_bind_venc→sample_vie_start_venc()//逐个创建编码通道并配置参数→sample_comm_venc_start() //逐个创建编码通道并配置参数→sample_comm_venc_start_get_stream() //创建线程轮询/阻塞获取编码后的H.264/H.265码流接着回调或写入文件/网络推流。→sample_comm_vpss_bind_venc() // vpss通道0/1绑定venc通道0/1。阶段六、业务功能运行代码支持的 VI 扩展能力VI 模块启动后可执行硬件级图像功能1.FPN 校准与矫正sample_vie_fpn() → 消除传感器固定模式噪声。2.LDC 畸变矫正 旋转sample_vie_ldc_rotation() → 90° 旋转、镜头畸变校正。3.低延迟模式sample_vie_lowdelay() → VIVPSS 双低延迟降低传输时延。4.用户自定义图像sample_vie_user_pic() → 加载自定义图片替代摄像头输入。5.双摄像头采集sample_vie_two_sensor() → 两路 VI 同时采集。6.模式切换线性模式 ↔ WDR 宽动态模式、分辨率切换4M→1080P。通过接口 sample_vie_execute_case(td_u32 case_index) 选择功能。阶段七、退出流程逆序释放资源sample_vie_stop_route()→sample_vie_stop_and_unbind_venc()→sample_comm_vpss_un_bind_venc() //解绑所有模块链路→ sample_vie_stop_venc() //停止编码→sample_vie_stop_vpss()→sample_common_vpss_stop()→ss_mpi_vpss_disable_chn() //关闭通道→ ss_mpi_vpss_stop_grp() //关闭通道→ss_mpi_vpss_destroy_grp()//释放GRP资源→sample_comm_vi_un_bind_vpss() //逆阶段五中 sample_comm_vpss_bind_venc()→sample_comm_vi_stop_vi()→sample_comm_vi_stop_isp() //停止ISP算法线程注销3A库→sample_comm_vi_stop_pipe() //销毁VI PIPE硬件资源→sample_comm_vi_dev_unbind_pipe() //解除DEV与PIPE的绑定关系→sample_comm_vi_stop_dev() //禁用VI DEV停止时序解析→sample_comm_vi_stop_mipi_rx() //关闭MIPI接收器复位Sensor→sample_comm_sys_exit() //系统退出→ss_mpi_sys_exit() //去初始化MPP系统。包括视频输入输出、视频编解码、视频叠加区域、视频处理、图形处理等模块都会被销毁或者禁用。→ss_mpi_vb_exit() //去初始化MPP视频缓存池。VI 模块的数据流向总结sensor(MIPI) → VI硬件采集ISP处理、FPN/LDC矫正→ VB PoolRAW/YUV数据→ VI通道输出→ VPSS缩放、双码流、包装→ VENCH265编码→ 最终码流输出三、VPSS部分阶段一、VPSS默认配置sample_comm_vpss_get_default_vpss_cfg()遍历物理通道初始化3DNR主码流使能。子码流是否使能、配置可选(配置了grp、chn、wrap)。阶段二、VPSS帧包装配置wrapsample_vie_vpss_get_wrap_cfg()1.根据sensor确定full_lines_std。full_lines_std用于表示sensor 一帧图像的有效行数 VBlank 行数用于计算wrap缓冲区的大小和跳转地址。不同 sensor 的垂直同步时序不同导致此值差异。2.配置wrap参数。VPSS Wrap 模式是一种内存优化机制图像数据在 DDR 中循环存储而非每次重新分配。通过复用缓冲区减少内存分配/释放开销。配合 VDEC解码或 VENC编码进行数据流转。3.记录所需缓冲区大小。阶段三、启动VPSSsample_vie_start_vpss()→sample_vie_vpss_set_wrap_grp_int_attr() //配置组属性→ sample_common_vpss_start() //创建组启动组启动通道→ss_mpi_vpss_set_chn_low_delay() //对通道1开启低延迟阶段四、VPSS与VI绑定参考VI部分阶段三。阶段五、VPSS与VENC绑定参考VI部分阶段五。阶段六、停止VPSS参考VI部分阶段七。四、VENC部分Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\venc\sample_venc.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_venc.c编号示例函数关键额外步骤说明0sample_venc_normal无基础流程章节 31sample_venc_intra_refreshsample_venc_set_intra_refresh→ss_mpi_venc_set_intra_refresh设置行/列内部刷新IR让编码器在特定位置强制 I 帧2sample_venc_roi_bgsample_venc_set_roi_attrss_mpi_venc_set_roi_bg_frame_rateROIRegion‑of‑Interest背景帧率调低节省码率3sample_venc_mjpeg_roi_setsample_venc_set_mjpeg_roi→ss_mpi_venc_set_jpeg_roi_attrMJPEG自定义 ROI仅对 JPEG 有效4sample_venc_svac3编码类型切换payload OT_PT_SVAC3sample_venc_set_svac3_video_paramSVAC3特定行业编码5sample_venc_inner_scalesample_venc_chn_bind_venc_chn→ 系统层sys_bind把VENC0输出直接绑定到VENC1输入实现内部缩放不经过 VPSS需要Mini‑Buf启用保证两路 VENC 能共享同一块内部缓冲区6sample_venc_qpmapsample_comm_venc_qpmap_send_frame→ 业务层把QP‑map每宏块的QP随帧送进 VENC需先把GOP参数取出来再创建通道7sample_venc_debreath_effectsample_venc_set_debreath_effect→ss_mpi_venc_set_debreath_effect呼吸光抑制参数配置8sample_venc_mjpeg_roimapsample_comm_venc_send_roimap_frame→ 按自定义 ROI Map发送帧业务层自行准备ot_venc_jpeg_roi_attr数组9sample_venc_mosaic_mapsample_comm_venc_mosaic_map_send_frame→马赛克Mosaic示例业务层会把马赛克块信息交给 VENC10sample_venc_compositeComposite复合·sample_composite_venc_start_venc打开composite_enc_en、mosaic_en·sample_composite_vpss_initVPSS 深度 2· 多线程composite_send_multi_frame_proc把两路马赛克 原图帧合成后送 VENCss_mpi_venc_send_multi_frame演示一帧内多路Mosaic 原图合成编码使用系统 bindsys_bind实现 VENC‑VENC 直接链路适合复合场景下面以模式0举例。阶段一、参数准备阶段二、系统初始化sample_venc_online_wrap_start_sys_vi_vpss() 内部追踪如下sample_venc_online_wrap_get_default_vpss_cfg()sample_venc_online_wrap_get_default_sys_cfg()→sample_venc_online_wrap_sys_init()→sample_venc_online_wrap_sys_init()→sample_venc_online_wrap_get_default_vb_cfg()sample_venc_vi_init()→sample_comm_vi_start_vi(vi_cfg);sample_venc_online_wrap_start_vpss()sample_comm_vi_bind_vpss()主要分为三个子步骤1.VB初始化 sample_venc_online_wrap_sys_initsample_venc_online_wrap_get_default_vb_cfg 计算输入(VI-YUV)与输出(VPSS-YUV)各自所需的块大小以及块数。填入ot_vb_cfg结构体的common_pool[i]中随后调用sample_comm_sys_vb_init 把VB资源加入系统。为什么要手动算块大小不同分辨率、像素格式、压缩模式会导致实际占用的显存不同。对每一路流都算一次防止VB 不够导致帧丢。2.VI初始化sample_venc_vi_initsample_comm_vi_start_vi会自动把vi_cfg分辨率、帧率、工作模式写入硬件寄存器开启传感器采流。3.VPSS初始化sample_venc_online_wrap_start_vpss外部传入配置好的vpss_cfg,再调用sample_common_vpss_start完成VPSS的创建把组号、属性交给底层驱动。4.VI → VPSS 绑定 (sample_comm_vi_bind_vpss)把 VI 的 Pipe 0 / Channel 0 的输出直接送给 VPSS 组 0 / 通道 0。这里 不需要再手动创建通路系统内部会自动在硬件上建立相应的 DMA 路径。阶段三、创建编码通道核心函数sample_venc_normal_start_encode1.码流配置GOPGroup Of Pictures两个关键帧即 I 帧间的一组画面模式决定关键帧、P‑帧的切换方式。GOP模式I帧、P帧、B帧的排列规则。sample_venc_set_video_param为每条通道这里是两条填好sample_comm_venc_chn_param帧率、GOP 长度、统计时间payload typeH.265、H.264码率控制模式CBR/VBR/ABR/…码流尺寸从enc_size取profile / mini‑buf内部缓冲区通过sample_comm_venc_mini_buf_en开启 Mini‑Buf 功能提升硬件复用率适合多路复用时。2.启动VENCsample_comm_venc_start();→ sample_comm_venc_create() //创建编码通道→ ss_mpi_venc_start_chn() //开启编码通道接收输入图像允许指定接收帧数超出指定的帧数后自动停止接收图像。3.VPSS与VENC绑定sample_comm_vpss_bind_venc(vpss_grp, vpss_chn[i], venc_chn[i]);把VPSS 物理通道0/1映射到VENC 逻辑通道0/1。这样 VPSS 输出的YUV 帧会直接送进对应的 VENC 编码器。注意绑定成功后如果不再使用某路 VENC一定要sample_comm_vpss_un_bind_venc解绑否则 VPSS 会一直往这个通道发送数据引起帧丢或卡死。向VENC发送VPSS输出的YUV帧sample_comm_qpmap_send_frame_proc()//线程处理函数#申请QP Map SkipWeight 硬件内存MMZ给编码算法用的专用内存→sample_comm_alloc_qpmap_skipweight_memory()//申请一块硬件内存用来存放 “每个区域用什么 QP” 的映射表。VENC 编码时会读这张表。#配置PSS通道缓冲区深度depth3防止送帧卡顿、丢帧→ss_mpi_vpss_get_chn_attr()// 获取当前VPSS通道属性→ss_mpi_vpss_set_chn_attr() // 把新配置写回硬件#正式启动把VPSS图像帧 → 送给VENC编码→sample_comm_qpmap_send_frame_start()→ss_mpi_vpss_get_chn_frame()//从 VPSS 通道**获取一帧图像**配置 QP Map 编码参数告诉编码器这块区域用什么QP、权重、映射表→sample_comm_qpmap_send_frame_ex()//把 **带QP映射的图像帧** 发送给VENC 编码→ss_mpi_vpss_release_chn_frame()//释放VPSS获取的帧必须释放否则硬件卡死出错会释放QP Map和SkipWeight内存QPMapQuantization Parameter的核心价值在于区域化码率控制普通模式整帧使用相同QP无法区分重要性。QPMap模式每个宏块独立QP重要区域高质量其他区域低质量。阶段四、码流的获取保存sample_comm_venc_start_get_stream()//创建线程注册下面的线程处理函数。sample_comm_venc_get_venc_stream_proc()//从每个通道中获取码流并保存→sample_comm_set_name_save_stream()1.决定码流文件名称打开文件保存码流→ss_mpi_venc_get_chn_attr()→sample_comm_venc_get_file_postfix()//获取文件后缀根据有效载荷即编码方式(payload)→sample_comm_set_file_name()2. 获取 VENC 通道文件描述符与码流缓冲区基础信息→ss_mpi_venc_get_fd()//获取VENC通道的文件描述符→ss_mpi_venc_get_stream_buf_info()//获取码流缓冲区信息视频数据的大小、位置....这里将码流保存到了文件中。阶段五、退出路径资源释放顺序非常重要先停止码流获取线程防止线程仍在读取已销毁的硬件。再解绑 VPSS–VENC确保 VPSS 不再往已经停止的 VENC 推帧。停止VENC、VPSS、VI。最后释放 VB防止还有块在使用时被系统收回。VENC在这套 Demo 中的核心是先准备好统一的内存VB → 把原始 YUV 通过 VI → VPSS 流向 VENC → 可选在 VENC 前做 ROI / QP‑map / DE‑Breath 等高级配置 → 把压好的码流取出来保存。所有业务的底层链路都是 “VI → VPSS → VENC → Get‑Stream”。不同模式的唯一区别就是在 VENC 创建后向 VENC 注入的额外属性payload、GOP、RC、ROI、QP‑map、Mosaic、Debreath、Composite以及发送帧时是否使用了带‑aux‑buffer 的专用 APIqpmap、roimap、mosaic、multi‑frame。五、加入RTSP推流位置Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\rtsp\sample_rtsp.c1.拿到 H264 裸流交给 RTSP你加的推流入口2.RTSP 核心调度打包 RTP、管理队列第一部分第二部分3.同步心跳发送 SR 包Sender Report4.真正发送到网络5.rtsp_do_eventRTSP 服务的主循环大脑负责接收连接、处理请求、发送音视频、处理网络事件
Hi3516CV610 sdk 源码学习
参考文章海思 3403 MPP 全链路解析: VI、VPSS、VENC 的运行逻辑与实践_vi 4k switch to fhd - vpss - venc vo-CSDN博客一、Hi3516CV610 sdk目录层级sudo apt-get install tree # 预装tree命令。 tree -L 2 -d # -L 2:只显示目录的两层深度 -d只显示目录不显示文件。sdk根目录open_source/:所有第三方开源软件的完整源代码busybox/、linux/、u-boot/、optee/、mtd-utils/、ethtool/、squashfs/、zlib/、mbedtls/ 等。提供操作系统基础组件你可以在这些目录里修改配置、进行交叉编译。内核和 U-Boot 的源码都在这里驱动开发和设备树修改需要。package/:存放open_source/、platform/、smp/三个目录的.tgz压缩包备份。platform/存放secure/安全子系统。scripts/存放SDK 环境配置和依赖检查的Shell 脚本快速配置编译环境、检查系统依赖是否完整首次搭建编译环境使用。sdk.unpack解压 SDK。将package/目录下的.tgz压缩包open_source.tgz、platform.tgz、smp.tgz解压到对应目录构建完整的可编译环境sdk.cleanup清理 SDK。删除解压出来的目录如open_source/、platform/、smp/恢复到刚拿到 SDK 时的纯净状态~/sdk/Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/vendor/extdrv目录extdrv/存放外部设备的驱动源码和编译脚本ES8388 音频 Codec 驱动源码。Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/source目录bsp/components/:gsl(Generic System Library)和 secure_c安全世界的客户端库。运行在CPU 安全世界中的一个小型 RTOS 系统的源码。cfg.mak:顶层 Makefile 配置文件定义编译选项和路径。common/:内存管理子系统负责整个系统的内存分配、管理和多媒体大块内存MMZ的分配与回收。interdrv/:内部驱动1.mipi_rx/MIPI CSI-2 接收驱动负责接收 IMX586 摄像头的图像数据。2.ot_adc,ADC 驱动用于采集模拟信号如电池电压、光照强度等3.ot_usr,用户空间接口提供驱动与用户程序交互的通道。4.sysconfig,系统配置驱动管理硬件模块的使能/禁用、引脚复用等。5.wtdg,看门狗驱动防止系统死机时无法自动恢复。6.init,驱动初始化脚本或代码。mpp/:媒体处理平台。osal/操作系统抽象层屏蔽不同操作系统Linux/RTOS的差异提供统一的 API 接口如线程创建、互斥锁、信号量、内存分配等。out/编译产出头文件、库、驱动模块。out下的目录层级scripts/:编译脚本。scripts下目录层级sdk/Hi3516CV610_SDK_V1.0.1.0-BAK/smp/a7_linux/source/mpp目录RTSP推流示例程序Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\rtsp\sample_rtsp.cstruct sample_comm_venc_chn_param单个编码通道的参数配置结构体。frame_rate; // 帧率stats_time; // 码率统计时间gop; // GOP大小关键帧间隔venc_size; // 编码尺寸宽高实际存储宽和高。size; // 存储分辨率枚举ot_pic_size是一个枚举类型会有单独的函数将枚举类型转换成实际的宽和高。profile; // 编码档次baseline/main/high等is_rcn_ref_share_buf; // 参考帧共享缓冲gop_attr; // GOP属性type; // 编码类型H.264/H.265/JPEG等rc_mode; // 码率控制模式CBR/VBR/ABR等index只判断了通道1所以在推流时只推通道1。二、VI部分参考文档HI3516CV610-SIM-开发板资料\原厂sdk\ReleaseDoc\zh\01.software\board\MPP\MPP 媒体处理软件 V6.0 开发参考.pdfVI模块api位置Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\vie\sample_vie.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_sys.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_vi.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_vpss.c下面学习内容以 sample_vie.c 为出发点。阶段一系统初始化sample_vie_sys_init()→ sample_comm_sys_init_with_vb_supplement() // 初始化VB视频缓冲池→ ss_mpi_vi_set_vi_vpss_mode() // 设置VI/VPSS工作模式阶段二VI设备配置与启动sample_comm_vi_get_default_vi_cfg() //获取VI默认配置(sensor\mipi\dev\bind\gpr\pipe info).sample_vie_get_pipe_wrap_line()→ss_mpi_sys_get_vi_wrap_buffer_line() //获取VICAP-VPPROC离线卷绕模式下的buffer卷绕行数。buf_line行数与sensor时序、sensor路数及主从模式、VIPROC性能、VPSS性能、 VENC性能等多方面因素有关实际业务场景中如果CPU不能每帧都立即响应VI/VPSS/VENC中断存在中断延迟等情况客户需要以实际测试场景为准适当增大buf_line。sample_comm_vi_start_vi()→sample_comm_vi_start_mipi_rx() //MIPI RX 接口的初始化启动函数负责配置和启用 MIPI CSI 接收器。→sample_comm_vi_start_dev() //设备级初始化函数负责配置 VI 设备的硬件时序参数并启用设备。→sample_comm_vi_dev_bind_pipe() //设备与管道绑定函数负责建立 VI 设备VI DEV与 VI 管道VI PIPE之间的数据关联关系实现多路数据流的分发与汇聚。→sample_comm_vi_set_grp_info() //WDR宽动态融合组配置函数负责设置多帧曝光数据的融合策略实现高动态范围图像的合成。→sample_comm_vi_start_pipe() //遍历启动所有绑定的pipe。→sample_comm_vi_start_isp() //法的启动函数负责为每个 VI PIPE 加载并运行 ISP 固件实现图像信号处理的核心算法。PIPE 是 VI 模块的ISP 处理管道承担以下关键职责VI PIPE 是 VI 模块的 ISP 处理管道由硬件电路数据通路、ISP 硬核、行缓冲 FIFO和软件线程AE/AWB/AF/3DNR 算法共同组成。核心职责接收数据— 从 VI DEV 获取 Bayer RAW 数据ISP 处理— 硬件执行去马赛克、颜色校正、WDR 融合软件线程实时计算 3A 参数并反馈调节 Sensor时序控制— 帧率控制、帧同步、WDR 多帧时序对齐输出推送— 将处理后的 YUV 数据推送到 VI CHN后续流转— CHN 输出至 VPSS视频前处理或 VENC编码阶段三VI与VPSS绑定数据流转关键sample_comm_vi_bind_vpss() //配置vi端与vpss端通道结构体→ss_mpi_sys_bind() //VI 模块与 VPSS 模块的系统级绑定函数通过 MPPMedia Process Platform框架的标准绑定机制建立从 VI 通道到 VPSS 通道的数据流转通路。阶段四、VPSS图像处理启动sample_vie_start_vpss→sample_common_vpss_start() //创建并启动 VPSS 处理组及其下属通道实现图像的缩放、裁剪、格式转换等前处理功能。组GRP与通道CHN的层级关系组是资源管理单元每个grp对应一个dev即一个sensor。通道是物理通道单独处理输出。grp可以接收一个sensor在一个grp下存在多个chn每个chn可按要求输出不同规格的数据流。阶段五、VPSS与VENC绑定编码启动sample_vie_start_and_bind_venc→sample_vie_start_venc()//逐个创建编码通道并配置参数→sample_comm_venc_start() //逐个创建编码通道并配置参数→sample_comm_venc_start_get_stream() //创建线程轮询/阻塞获取编码后的H.264/H.265码流接着回调或写入文件/网络推流。→sample_comm_vpss_bind_venc() // vpss通道0/1绑定venc通道0/1。阶段六、业务功能运行代码支持的 VI 扩展能力VI 模块启动后可执行硬件级图像功能1.FPN 校准与矫正sample_vie_fpn() → 消除传感器固定模式噪声。2.LDC 畸变矫正 旋转sample_vie_ldc_rotation() → 90° 旋转、镜头畸变校正。3.低延迟模式sample_vie_lowdelay() → VIVPSS 双低延迟降低传输时延。4.用户自定义图像sample_vie_user_pic() → 加载自定义图片替代摄像头输入。5.双摄像头采集sample_vie_two_sensor() → 两路 VI 同时采集。6.模式切换线性模式 ↔ WDR 宽动态模式、分辨率切换4M→1080P。通过接口 sample_vie_execute_case(td_u32 case_index) 选择功能。阶段七、退出流程逆序释放资源sample_vie_stop_route()→sample_vie_stop_and_unbind_venc()→sample_comm_vpss_un_bind_venc() //解绑所有模块链路→ sample_vie_stop_venc() //停止编码→sample_vie_stop_vpss()→sample_common_vpss_stop()→ss_mpi_vpss_disable_chn() //关闭通道→ ss_mpi_vpss_stop_grp() //关闭通道→ss_mpi_vpss_destroy_grp()//释放GRP资源→sample_comm_vi_un_bind_vpss() //逆阶段五中 sample_comm_vpss_bind_venc()→sample_comm_vi_stop_vi()→sample_comm_vi_stop_isp() //停止ISP算法线程注销3A库→sample_comm_vi_stop_pipe() //销毁VI PIPE硬件资源→sample_comm_vi_dev_unbind_pipe() //解除DEV与PIPE的绑定关系→sample_comm_vi_stop_dev() //禁用VI DEV停止时序解析→sample_comm_vi_stop_mipi_rx() //关闭MIPI接收器复位Sensor→sample_comm_sys_exit() //系统退出→ss_mpi_sys_exit() //去初始化MPP系统。包括视频输入输出、视频编解码、视频叠加区域、视频处理、图形处理等模块都会被销毁或者禁用。→ss_mpi_vb_exit() //去初始化MPP视频缓存池。VI 模块的数据流向总结sensor(MIPI) → VI硬件采集ISP处理、FPN/LDC矫正→ VB PoolRAW/YUV数据→ VI通道输出→ VPSS缩放、双码流、包装→ VENCH265编码→ 最终码流输出三、VPSS部分阶段一、VPSS默认配置sample_comm_vpss_get_default_vpss_cfg()遍历物理通道初始化3DNR主码流使能。子码流是否使能、配置可选(配置了grp、chn、wrap)。阶段二、VPSS帧包装配置wrapsample_vie_vpss_get_wrap_cfg()1.根据sensor确定full_lines_std。full_lines_std用于表示sensor 一帧图像的有效行数 VBlank 行数用于计算wrap缓冲区的大小和跳转地址。不同 sensor 的垂直同步时序不同导致此值差异。2.配置wrap参数。VPSS Wrap 模式是一种内存优化机制图像数据在 DDR 中循环存储而非每次重新分配。通过复用缓冲区减少内存分配/释放开销。配合 VDEC解码或 VENC编码进行数据流转。3.记录所需缓冲区大小。阶段三、启动VPSSsample_vie_start_vpss()→sample_vie_vpss_set_wrap_grp_int_attr() //配置组属性→ sample_common_vpss_start() //创建组启动组启动通道→ss_mpi_vpss_set_chn_low_delay() //对通道1开启低延迟阶段四、VPSS与VI绑定参考VI部分阶段三。阶段五、VPSS与VENC绑定参考VI部分阶段五。阶段六、停止VPSS参考VI部分阶段七。四、VENC部分Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\venc\sample_venc.cHi3516CV610_SDK_V1.0.1.0BAK\smp\a7_linux\source\mpp\sample\common\sample_comm_venc.c编号示例函数关键额外步骤说明0sample_venc_normal无基础流程章节 31sample_venc_intra_refreshsample_venc_set_intra_refresh→ss_mpi_venc_set_intra_refresh设置行/列内部刷新IR让编码器在特定位置强制 I 帧2sample_venc_roi_bgsample_venc_set_roi_attrss_mpi_venc_set_roi_bg_frame_rateROIRegion‑of‑Interest背景帧率调低节省码率3sample_venc_mjpeg_roi_setsample_venc_set_mjpeg_roi→ss_mpi_venc_set_jpeg_roi_attrMJPEG自定义 ROI仅对 JPEG 有效4sample_venc_svac3编码类型切换payload OT_PT_SVAC3sample_venc_set_svac3_video_paramSVAC3特定行业编码5sample_venc_inner_scalesample_venc_chn_bind_venc_chn→ 系统层sys_bind把VENC0输出直接绑定到VENC1输入实现内部缩放不经过 VPSS需要Mini‑Buf启用保证两路 VENC 能共享同一块内部缓冲区6sample_venc_qpmapsample_comm_venc_qpmap_send_frame→ 业务层把QP‑map每宏块的QP随帧送进 VENC需先把GOP参数取出来再创建通道7sample_venc_debreath_effectsample_venc_set_debreath_effect→ss_mpi_venc_set_debreath_effect呼吸光抑制参数配置8sample_venc_mjpeg_roimapsample_comm_venc_send_roimap_frame→ 按自定义 ROI Map发送帧业务层自行准备ot_venc_jpeg_roi_attr数组9sample_venc_mosaic_mapsample_comm_venc_mosaic_map_send_frame→马赛克Mosaic示例业务层会把马赛克块信息交给 VENC10sample_venc_compositeComposite复合·sample_composite_venc_start_venc打开composite_enc_en、mosaic_en·sample_composite_vpss_initVPSS 深度 2· 多线程composite_send_multi_frame_proc把两路马赛克 原图帧合成后送 VENCss_mpi_venc_send_multi_frame演示一帧内多路Mosaic 原图合成编码使用系统 bindsys_bind实现 VENC‑VENC 直接链路适合复合场景下面以模式0举例。阶段一、参数准备阶段二、系统初始化sample_venc_online_wrap_start_sys_vi_vpss() 内部追踪如下sample_venc_online_wrap_get_default_vpss_cfg()sample_venc_online_wrap_get_default_sys_cfg()→sample_venc_online_wrap_sys_init()→sample_venc_online_wrap_sys_init()→sample_venc_online_wrap_get_default_vb_cfg()sample_venc_vi_init()→sample_comm_vi_start_vi(vi_cfg);sample_venc_online_wrap_start_vpss()sample_comm_vi_bind_vpss()主要分为三个子步骤1.VB初始化 sample_venc_online_wrap_sys_initsample_venc_online_wrap_get_default_vb_cfg 计算输入(VI-YUV)与输出(VPSS-YUV)各自所需的块大小以及块数。填入ot_vb_cfg结构体的common_pool[i]中随后调用sample_comm_sys_vb_init 把VB资源加入系统。为什么要手动算块大小不同分辨率、像素格式、压缩模式会导致实际占用的显存不同。对每一路流都算一次防止VB 不够导致帧丢。2.VI初始化sample_venc_vi_initsample_comm_vi_start_vi会自动把vi_cfg分辨率、帧率、工作模式写入硬件寄存器开启传感器采流。3.VPSS初始化sample_venc_online_wrap_start_vpss外部传入配置好的vpss_cfg,再调用sample_common_vpss_start完成VPSS的创建把组号、属性交给底层驱动。4.VI → VPSS 绑定 (sample_comm_vi_bind_vpss)把 VI 的 Pipe 0 / Channel 0 的输出直接送给 VPSS 组 0 / 通道 0。这里 不需要再手动创建通路系统内部会自动在硬件上建立相应的 DMA 路径。阶段三、创建编码通道核心函数sample_venc_normal_start_encode1.码流配置GOPGroup Of Pictures两个关键帧即 I 帧间的一组画面模式决定关键帧、P‑帧的切换方式。GOP模式I帧、P帧、B帧的排列规则。sample_venc_set_video_param为每条通道这里是两条填好sample_comm_venc_chn_param帧率、GOP 长度、统计时间payload typeH.265、H.264码率控制模式CBR/VBR/ABR/…码流尺寸从enc_size取profile / mini‑buf内部缓冲区通过sample_comm_venc_mini_buf_en开启 Mini‑Buf 功能提升硬件复用率适合多路复用时。2.启动VENCsample_comm_venc_start();→ sample_comm_venc_create() //创建编码通道→ ss_mpi_venc_start_chn() //开启编码通道接收输入图像允许指定接收帧数超出指定的帧数后自动停止接收图像。3.VPSS与VENC绑定sample_comm_vpss_bind_venc(vpss_grp, vpss_chn[i], venc_chn[i]);把VPSS 物理通道0/1映射到VENC 逻辑通道0/1。这样 VPSS 输出的YUV 帧会直接送进对应的 VENC 编码器。注意绑定成功后如果不再使用某路 VENC一定要sample_comm_vpss_un_bind_venc解绑否则 VPSS 会一直往这个通道发送数据引起帧丢或卡死。向VENC发送VPSS输出的YUV帧sample_comm_qpmap_send_frame_proc()//线程处理函数#申请QP Map SkipWeight 硬件内存MMZ给编码算法用的专用内存→sample_comm_alloc_qpmap_skipweight_memory()//申请一块硬件内存用来存放 “每个区域用什么 QP” 的映射表。VENC 编码时会读这张表。#配置PSS通道缓冲区深度depth3防止送帧卡顿、丢帧→ss_mpi_vpss_get_chn_attr()// 获取当前VPSS通道属性→ss_mpi_vpss_set_chn_attr() // 把新配置写回硬件#正式启动把VPSS图像帧 → 送给VENC编码→sample_comm_qpmap_send_frame_start()→ss_mpi_vpss_get_chn_frame()//从 VPSS 通道**获取一帧图像**配置 QP Map 编码参数告诉编码器这块区域用什么QP、权重、映射表→sample_comm_qpmap_send_frame_ex()//把 **带QP映射的图像帧** 发送给VENC 编码→ss_mpi_vpss_release_chn_frame()//释放VPSS获取的帧必须释放否则硬件卡死出错会释放QP Map和SkipWeight内存QPMapQuantization Parameter的核心价值在于区域化码率控制普通模式整帧使用相同QP无法区分重要性。QPMap模式每个宏块独立QP重要区域高质量其他区域低质量。阶段四、码流的获取保存sample_comm_venc_start_get_stream()//创建线程注册下面的线程处理函数。sample_comm_venc_get_venc_stream_proc()//从每个通道中获取码流并保存→sample_comm_set_name_save_stream()1.决定码流文件名称打开文件保存码流→ss_mpi_venc_get_chn_attr()→sample_comm_venc_get_file_postfix()//获取文件后缀根据有效载荷即编码方式(payload)→sample_comm_set_file_name()2. 获取 VENC 通道文件描述符与码流缓冲区基础信息→ss_mpi_venc_get_fd()//获取VENC通道的文件描述符→ss_mpi_venc_get_stream_buf_info()//获取码流缓冲区信息视频数据的大小、位置....这里将码流保存到了文件中。阶段五、退出路径资源释放顺序非常重要先停止码流获取线程防止线程仍在读取已销毁的硬件。再解绑 VPSS–VENC确保 VPSS 不再往已经停止的 VENC 推帧。停止VENC、VPSS、VI。最后释放 VB防止还有块在使用时被系统收回。VENC在这套 Demo 中的核心是先准备好统一的内存VB → 把原始 YUV 通过 VI → VPSS 流向 VENC → 可选在 VENC 前做 ROI / QP‑map / DE‑Breath 等高级配置 → 把压好的码流取出来保存。所有业务的底层链路都是 “VI → VPSS → VENC → Get‑Stream”。不同模式的唯一区别就是在 VENC 创建后向 VENC 注入的额外属性payload、GOP、RC、ROI、QP‑map、Mosaic、Debreath、Composite以及发送帧时是否使用了带‑aux‑buffer 的专用 APIqpmap、roimap、mosaic、multi‑frame。五、加入RTSP推流位置Hi3516CV610_SDK_V1.0.1.0-BAK\smp\a7_linux\source\mpp\sample\rtsp\sample_rtsp.c1.拿到 H264 裸流交给 RTSP你加的推流入口2.RTSP 核心调度打包 RTP、管理队列第一部分第二部分3.同步心跳发送 SR 包Sender Report4.真正发送到网络5.rtsp_do_eventRTSP 服务的主循环大脑负责接收连接、处理请求、发送音视频、处理网络事件