跳转至

sample_vgs 快速入门

1. 概述与作用

sample_vgs 是 Hi3516CV610 MPP 套件中用于演示 Video Graphics Sub-system(VGS)模块能力的样例程序。

VGS 是一条独立的 2D 图形流水线,可在不占用 VPSS 与 VENC 资源的前提下完成缩放(Scale)、Cover(纯色矩形遮挡)、Corner Rect(角框标记,例如自动对焦角框)、Draw Line(在帧上画线)、Rotation(90/180/270 度旋转)、Luma(区域亮度和统计)等多种图形任务。样例从一份 1920x1080 YUV 文件读入源帧,调用 ss_mpi_vgs_begin_job、ss_mpi_vgs_end_job、ss_mpi_vgs_cancel_job 管理任务生命周期,并通过 ss_mpi_vgs_add_scale_task/cover_task/corner_rect_task/draw_line_task/rotation_task/luma_task/online_task 等接口提交具体图形作业,将处理之后的图像保存到当前工作目录,便于开发者查看效果。适用于在 Hi3516CV610 上评估 2D 图形叠加、缩放、旋转等能力的开发者入门。

2. 执行准备

在编译本样例之前,请参照Hi3516CV610环境搭建指南和快速上手指南完成编译环境的搭建。

2.1 编译

进入样例目录执行 make 即可完成编译:

cd samples/mpp/vgs && make

编译成功之后,在当前目录下会生成一个sample_vgs的可执行文件,可以放社区支持的开发板上运行。

2.2 加载 KO 与依赖环境

ko加载脚本位于 output/mpp/ko/load_ko,有两个脚本,load3516cv610_20s和load3516cv610_20s_debug。区别为load3516cv610_20s_debug脚本会打开 logmpp_show=1(日志记录)、proc_show=1(proc信息打印),并将 mem_process_isolation 置为 0(不启用进程间mmz隔离)。

由于当前版本不支持进程间mmz隔离,因此需要在load3516cv610_20s脚本中将 mem_process_isolation 置为 0或者使用load3516cv610_20s_debug脚本,此处以load3516cv610_20s_debug脚本为例,20s内存大小为128MB,默认分配为 32MB OS、96MB MMZ,加载命令为:

./load3516cv610_20s_debug -i

可以通过-h命令查看具体用法:

./load3516cv610_20s_debug -h
Usage:  ./load3516cv610_20s_debug [-option] [-sensor0~1] 
options:
    -i                       insert modules
    -r                       remove modules
    -a                       remove modules first, then insert modules
    -sensor0~1 sensor_name   config sensor type    [default: hy006_3814_0011]
    -mmz_start               config MMZ start addr [default: 0x42000000]
    -mmz_size                config MMZ mem size [unit: M, default: 96M]
    -ir_auto                 config ir_auto enable [default: 0]
    -profile                 config sys_profile [default: 0]
    -h                       help information
Available sensors:hy006_3814_0011 bt1120/bt656/bt601
for example: ./load3516cv610_20s_debug -i -sensor0 hy006_3814_0011 -sensor1 hy006_3814_0011 -mmz_start 0x42000000 -mmz_size 96M -ir_auto 1

如果需要调整os和mmz的大小,需要参考《内存布局调整指南》对内存大小进行调整。

如果是使用社区默认提供的镜像,这些ko已经打包到文件系统中,烧录到单板上后位于/ko目录下,在系统启动后会自动加载这些ko。

2.3 运行时依赖文件

在运行样例前,需要提前准备:

  • 指定运行时依赖的so库路径

MPP样例依赖的so库位于soc/libs/musl下,需要将该目录下的so库拷贝到开发板上(或将这些so库所在的目录挂载到开发板上),并指定运行时依赖库的环境变量,假设这些so库位于/mnt/libs/,执行如下命令:

```shell
export LD_LIBRARY_PATH=/mnt/libs/:$LD_LIBRARY_PATH
```

如果是使用社区默认提供的镜像,这些so库已经打包到文件系统中,烧录到单板上后位于/usr/lib目录下,该目录是系统默认搜索目录,不需要执行export LD_LIBRARY_PATH命令去指定。

  • 启动MPP服务

当前MPP媒体模块处于用户态,通过一个独立进程提供相关接口的调用服务,该进程位于samples/mpp/sdk_server下,执行如下命令即可生成sdk_server可执行文件:

```shell
cd samples/mpp/sdk_server && make
```

在单板上执行./sdk_server &即可启动MPP服务。

  1. sdk_server同样依赖soc/libs/musl下的so库,因此也需要参照上述export LD_LIBRARY_PATH指定路径;
  2. 如果是使用社区默认提供的镜像,sdk_server进程已经打包到文件系统中,烧录到单板上后位于/usr/bin目录下,并在系统启动时会自动启动sdk_server。
  • 样例运行时候需要的资源文件

样例固定读入一份输入文件res/1920_1080_p420.yuv。该文件约 3.0MB,格式为 1920x1080 YVU planar 420。所有 case 均从该路径读入帧,并将处理之后的图像以 vgs_sample*.yuv 写到样例运行的目录

2.4 运行样例

调用语法为 ./sample_vgs <index>,index 为单数字 0–4。可以执行./sample_vgs -h查看用法。

image-20260807180311712

3. 支持的 Case 列表

本样例的五个 case 覆盖了 VGS 最常用的五类任务,开发者可参照实现将其组合到实际业务中。例如智能交通场景中,可先用 scale task 将 4M 缩放到 D1,再用 cover task 遮挡车牌区域,再用 draw line task 标注车道线,最后用 luma task 统计车灯亮度判断昼夜。安防对焦场景中,可用 corner_rect task 在画面四角绘制对焦框辅助用户调焦。所有 task 均支持自定义颜色、线宽、坐标,开发者可在源码中修改参数后重新编译验证。

3.1 代码流程

  1. 初始化 sys 和 common vb,打开文件。
  2. 读取文件内容,获取 buffer 配置和 VB 块。
  3. ss_mpi_vgs_begin_job 启动(创建)job。
  4. ss_mpi_vgs_add_xx_task 添加 1 个或多个任务。
  5. ss_mpi_vgs_end_job 提交 job。
  6. sample_vgs_save_sp42_x_to_planar 保存帧到文件。
  7. 释放 sys 和 vb 资源退出。

图 1 代码流程图

3.2 case 0 FILE→VGS(scale)→FILE

对图像进行缩放操作,典型用途包括将图像缩小作为画中画的小图,以及降低图像分辨率以减少内存占用。该case将 1920x1080 缩放到 1280x720。该 case 是 VGS 缩放能力的最小验证路径。

如下方效果示例图所示:

调用命令

./sample_vgs 0
输出文件

输出文件为 ./vgs_sample0_1280x720_p420.yuv。

控制台日志

成功结束时打印 vgs sample 0 exit normally!;

若信号异常或接口返回失败,则打印红色 program exit abnormally!。

正确性判断

输出图像应为缩小后的 1280x720 画面,整体内容与原图一致,无明显锯齿。

软件配置流程

参考代码流程,在上述代码流程的第 4 步中添加任务时用 ss_mpi_vgs_add_scale_task,重点是在 ot_vgs_task_attr vgs 任务属性结构体中对输入图像 img_in 和输出图像 img_out 的分辨率进行配置,img_in 和 img_out 是缩放时的关键参数。

注意

输入输出帧是否在同一 buffer 需由使用者判断,本 scale sample 中默认输入输出不在同一 buffer。

3.3 case 1 FILE→VGS(cover+corner_rect)→FILE

在画面上叠加一个绿色 cover 矩形(位置 200,300,尺寸 400x300)以及 5 个品红色 corner rect(角框)。该 case 演示 VGS 在单帧内并发多个不同类型任务的能力。

该case应用于在图像中打 COVER 或 CORNER_RECT。对图像某块区域进行遮挡时,向该区域叠加纯色块;重点突出画面中的区域和某个目标(例如人脸、宠物等)时,可使用空心矩形框(实线框)或角框圈出来。

如下方效果示例图所示:

调用命令

./sample_vgs 1
输出文件

输出文件为 ./vgs_sample1_1920x1080_p420.yuv。

控制台日志

成功结束时打印 vgs sample 1 exit normally!;

若信号异常或接口返回失败,则打印红色 program exit abnormally!。

正确性判断

输出图像应可见绿色矩形 cover 覆盖 (200,300) 起 400x300 区域,以及 5 个品红 corner rect 位于预设坐标。

软件配置流程

参考代码流程,在上述代码流程的第 4 步中使用 sample_vgs_add_case2_task(样例内部封装)添加 ss_mpi_vgs_add_cover_task 和 ss_mpi_vgs_add_corner_rect_task。

  • 在 ss_mpi_vgs_add_cover_task 任务中,重点是对第 3 个参数 ot_cover 结构体数组指针和第 4 个参数 array_size 进行配置,ot_cover 中包括 cover type(矩形/任意四边形)和对应属性、颜色,array_size 为 cover 数目。
  • 在 ss_mpi_vgs_add_corner_rect_task 任务中,重点是第 3 个参数 ot_corner_rect、第 4 个参数 ot_corner_rect_attr、第 5 个参数 array_size 同样为 corner_rect 数目。ot_corner_rect 包括区域和水平/垂直线长以及线宽,ot_corner_rect_attr 包括角框类型(角框/实线框)和颜色。
  • 在非压缩场景中,输入输出图像必须在同一 buffer 内。

3.4 case 2 FILE→VGS(draw_line)→FILE

在画面上画一条蓝色线段,起点 (50,50)、终点 (1600,900),线宽 thick=2。该 case 适合作为运动轨迹标注或电子围栏的基础。

应用场景为在图像上叠加显示多条宽度/颜色不同的直线,根据自身需求,能够通过多次画线实现任意多边形、虚线的效果。

如下方效果示例图所示:

调用命令

./sample_vgs 2
输出文件

输出文件为 ./vgs_sample2_1920x1080_p420.yuv。

控制台日志

成功结束时打印 vgs sample 2 exit normally!;

若信号异常或接口返回失败,则打印红色 program exit abnormally!。

正确性判断

输出图像应可见从 (50,50) 到 (1600,900) 的蓝色粗线,宽度 2 像素,端点位置准确。

软件配置流程

参考代码流程,在上述代码流程的第 4 步中添加任务时使用 ss_mpi_vgs_add_draw_line_task。

  • 在 ss_mpi_vgs_add_draw_line_task 任务中,重点是对第 3 个参数 ot_vgs_line 和第 4 个参数 array_size 线条个数,其中 ot_vgs_line 中包括线段起始点和终点,以及它们的厚度和颜色。
  • 在非压缩场景中,输入输出图像必须在同一 buffer 内。

3.5 case 3 FILE→VGS(rotate)→FILE

将画面旋转 90 度,输出宽高互换为 1080x1920。该 case 验证 VGS 旋转后帧尺寸变化的处理。

应用场景为对图像进行旋转操作,用于用户对操作界面进行旋转或设备旋转安装时的场景。

如下方效果示例图所示:

调用命令

./sample_vgs 3
输出文件

输出文件为 ./vgs_sample3_1080x1920_p420.yuv。

控制台日志

成功结束时打印 vgs sample 3 exit normally!;

若信号异常或接口返回失败,则打印红色 program exit abnormally!。

正确性判断

输出图像应为顺时针 90 度旋转后的 1080x1920 竖向画面,原画面左上方变为新画面顶部。

软件配置流程

参考代码流程,在上述代码流程的第 4 步中添加任务时使用 ss_mpi_vgs_add_rotation_task。

  • 在 ss_mpi_vgs_add_rotation_task 任务中,重点是第 3 个参数旋转角度,配置需要的旋转角度即可。
  • 当旋转 90 度或 270 度时,输入输出必须为不同 buffer。

3.6 case 4 FILE→VGS(luma)→FILE + 数据

对 4 个 40x40 矩形区域做 luma 亮度统计,stdout 打印 luma_rect: N,luma_data: M;输出文件为 ./vgs_sample4_1920x1080_p420.yuv,并附带 4 行 luma 数据。该 case 适合作为自动曝光或场景检测的基础数据来源。

应用场景为计算图像指定区域亮度和,用于 OSD 反色控制。

调用命令

./sample_vgs 4
输出文件

输出文件为 ./vgs_sample4_1920x1080_p420.yuv。

控制台日志

成功结束时打印:

若信号异常或接口返回失败,则打印红色 program exit abnormally!。

正确性判断

输出图像与原图一致,但 stdout 4 行 luma 数据应为非零值,具体数值取决于原图对应区域的亮度分布。若原图对应区域明显偏亮(如天空),luma_data 应较大;若偏暗(如阴影),luma_data 应较小。

软件配置流程

参考代码流程,在上述代码流程的第 4 步中添加任务时使用 ss_mpi_vgs_add_luma_task。

  • 在 ss_mpi_vgs_add_luma_task 任务中,第 3 个参数配置需要计算亮度和的区域数组指针,第 4 个参数是亮度和区域数目,第 5 个参数是存储亮度和的数组指针。
  • 亮度和任务仅检查输入帧的合法性。