news 2026/7/3 5:32:48

RK3588(OrangePi 5 Ultra)三路 USB UVC 相机稳定30FPS录制实践:从采集抖动到 RGA 硬件转换的完整排查过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3588(OrangePi 5 Ultra)三路 USB UVC 相机稳定30FPS录制实践:从采集抖动到 RGA 硬件转换的完整排查过程

一、项目背景

最近在做一个基于RK3588(OrangePi 5 Ultra)的多路视频采集与录制项目。

系统需要同时接入三路 USB UVC 相机

  • video3:第一路核心相机
  • video5:第二路核心相机
  • video1:第三路辅助相机

项目要求:

  • 两路核心相机必须稳定 30FPS
  • 同时录制 MP4 文件
  • 后续还需要进行实时推流和 AI 推理
  • CPU 占用尽量低

整体数据流如下:

USB Camera │ ▼ MJPEG 30FPS │ ▼ Hardware Decode(MPP) │ ▼ RGA 色彩转换 │ ▼ MPP H264/H265 Encoder │ ▼ MP4 Recorder

最终目标不是 ffprobe 显示 30fps,而是真实采集、真实编码都稳定达到 30FPS。


二、硬件环境

开发板:

OrangePi 5 Ultra RK3588 Ubuntu 22.04 Kernel 5.10

相机:

USB UVC Camera 960×720 MJPEG 30FPS

编码:

Rockchip MPP mppjpegdec mpph264enc mpph265enc

色彩转换:

librga

三、首先确认相机本身是否支持30FPS

第一步一定不要急着写程序。
先确认相机到底支持什么格式。

查看:

v4l2-ctl-d/dev/video5 --list-formats-ext

得到:

MJPG 960x720 30fps 1280x720 30fps YUYV 960x720 10fps

这里得到两个重要结论:

  • MJPEG 可以 30FPS
  • YUYV 最大只有 10FPS

因此后续所有录制方案都必须基于 MJPEG。


四、第一步排查——到底是不是采集问题?

很多人第一反应就是:

GStreamer 怎么只有 28FPS?

实际上第一步应该先验证V4L2 驱动采集能力

测试:

v4l2-ctl\-d/dev/video5\--stream-mmap\--stream-count=600\--stream-to=/dev/null

结果:

30.07 fps 30.08 fps 30.06 fps

说明:

  • 相机本身没问题。
  • USB 没问题。
  • V4L2 驱动也没问题。

真正的问题发生在后面的处理链路。


五、第二步排查——GStreamer 是否已经开始掉帧?

继续验证:

gst-launch-1.0-v\v4l2srcdevice=/dev/video5 io-mode=2\!image/jpeg,width=960,height=720,framerate=30/1\!queue\!fpsdisplaysink\video-sink=fakesink\sync=false\text-overlay=false

观察:

current=30.08 ↓ 28.20 ↓ 26.30 ↓ 30.07

平均:

28.xx FPS

这里说明:

采集虽然平均还能接近30FPS,但是整个 GStreamer Pipeline 已经开始发生抖动。
虽然没有真正丢帧,但 Pipeline 已经出现 Scheduling 抖动。


六、第三步——验证最简单的录制

先不要编码。
直接保存 MJPEG。

Pipeline:

v4l2src ↓ jpegparse ↓ avimux ↓ AVI

命令:

gst-launch-1.0-e\v4l2srcdevice=/dev/video5\!image/jpeg,width=960,height=720,framerate=30/1\!jpegparse\!avimux\!filesinklocation=test.avi

优点:

  • 不解码
  • 不编码
  • CPU 非常低
  • 基本可以保持 30FPS

缺点:

  • 文件巨大
    三分钟接近1GB+

显然不能用于实际项目。


七、第四步——尝试硬件 H264/H265 编码

开始尝试:

MJPEG ↓ mppjpegdec ↓ videoconvert ↓ NV12 ↓ mpph264enc

测试命令:

gst-launch-1.0-e\v4l2srcdevice=/dev/video5\!image/jpeg,width=960,height=720,framerate=30/1\!jpegparse\!mppjpegdec\!videoconvert\!video/x-raw,format=NV12\!mpph264enc\!h264parse\!mp4mux\!filesinklocation=test.mp4

最终得到:

  • 画面正常
  • MP4正常
  • 但是三路录制开始掉帧

CPU 使用率明显升高。


八、定位真正瓶颈——videoconvert

为了确认到底是谁慢,分别测试:

① 只有:

mppjpegdec

mppjpegdec ↓ videoconvert

统计结果:

不使用 videoconvert

  • real ≈64s
  • user ≈8s

使用 videoconvert

  • real ≈70s
  • user ≈207s

CPU 时间暴涨。

说明:

真正瓶颈不是MPP Encoder,而是videoconvert(软件颜色转换)。


九、为什么会出现 NV16?

很多人会疑惑:
为什么 mppjpegdec 出来的不是 NV12?

查看 caps:

video/x-raw format=NV16

原因:

MJPEG 本质来自YUV422,Rockchip 的 mppjpegdec 会直接输出NV16
而编码器需要NV12

因此以前其实一直都是:

NV16 → videoconvert → NV12

CPU 就耗在这里。


十、尝试直接送编码器

于是尝试:

NV16 → mpph265enc

结果:

FPS 非常漂亮。

但是:

  • 颜色错误
  • 尺寸错误

例如:
输入 960×720,输出 1280×720,颜色也偏绿。

说明:不能直接使用。


十一、最终解决方案——RGA 硬件转换

于是改成:

MJPEG ↓ mppjpegdec ↓ NV16 ↓ RGA ↓ NV12 ↓ mpph265enc

转换代码:

imcvtcolor(src,dst,RK_FORMAT_YCbCr_422_SP,RK_FORMAT_YCbCr_420_SP);

整个转换完全走RGA Hardware,CPU 基本不参与。


十二、60秒严格30FPS测试

测试程序:

./rga_appsrc_h265_test\60\960\720\50\2\videos\1200000\/dev/video1\/dev/video3\/dev/video5

统计结果:

  • video3:1800 Frames,30.08FPS→ PASS
  • video5:1800 Frames,30.08FPS→ PASS
  • video1:1705 Frames,28.6FPS

项目要求只有 video3 和 video5 这两路核心相机必须严格 30FPS,第三路辅助相机允许略低帧率,因此最终方案满足需求。


十三、常用测试命令汇总

1)查看相机支持格式

v4l2-ctl-d/dev/video5 --list-formats-ext

2)查看当前参数

v4l2-ctl-d/dev/video5--all

3)测试底层采集 FPS

v4l2-ctl\-d/dev/video5\--set-parm=30\--stream-mmap\--stream-count=600\--stream-to=/dev/null

4)测试 GStreamer Pipeline FPS

gst-launch-1.0-v\v4l2srcdevice=/dev/video5 io-mode=2\!image/jpeg,width=960,height=720,framerate=30/1\!queue max-size-buffers=60\!fpsdisplaysink\video-sink=fakesink\sync=false\text-overlay=false

5)MJPEG 原始 AVI 录制

gst-launch-1.0-e\v4l2srcdevice=/dev/video5\!image/jpeg,width=960,height=720,framerate=30/1\!jpegparse\!avimux\!filesinklocation=test.avi

6)MPP H264 编码录制

gst-launch-1.0-e\v4l2srcdevice=/dev/video5\!image/jpeg,width=960,height=720,framerate=30/1\!jpegparse\!mppjpegdec\!videoconvert\!video/x-raw,format=NV12\!mpph264enc\!h264parse\!mp4mux\!filesinklocation=test.mp4

7)RGA + MPP H265 测试程序

./rga_appsrc_h265_test\60\960\720\50\2\videos\1200000\/dev/video1\/dev/video3\/dev/video5

8)检查录制结果

ffprobe\-hide_banner\-select_streamsv:0\-show_entries\stream=codec_name,width,height,avg_frame_rate,r_frame_rate,nb_frames,duration,bit_rate\video3_rga_nv12_h265_strict.mp4

期望输出:

width=960 height=720 avg_frame_rate=30/1 nb_frames=1800

十四、最终架构

最终采用如下录制架构:

USB Camera │ ▼ MJPEG (30FPS) │ ▼ mppjpegdec │ ▼ NV16 │ ▼ RGA(NV16 → NV12) │ ▼ mpph264enc / mpph265enc │ ▼ MP4 Recorder │ ▼ Frame Monitor(统计帧率、掉帧、同步状态)

其中,Frame Monitor持续统计以下指标:

  • 实际采集帧数(Capture Frames)
  • 编码输出帧数(Encoded Frames)
  • 平均 FPS(Average FPS)
  • 最大帧间隔(Max Frame Interval)
  • 超过 40 ms / 50 ms 的帧数
  • 核心两路相机是否达到expected_frames = seconds × 30

这些统计信息能够快速判断问题究竟发生在采集、颜色转换还是编码阶段,对于后续定位性能瓶颈非常有帮助。


十五、总结

经过多轮测试与逐步排查,最终得到以下结论:

  • USB UVC 相机本身可以稳定输出 30FPS,V4L2 驱动不是瓶颈。
  • MPP(Rockchip 硬件编解码)性能充足,三路实时编码并非主要限制因素。
  • 软件videoconvert是三路实时录制最大的性能瓶颈,CPU 开销明显。
  • mppjpegdec原生输出为 NV16,直接送入编码器虽然帧率高,但会导致颜色和分辨率异常。
  • 使用 RGA 完成 NV16→NV12 的硬件色彩转换后,可以兼顾正确画面和低 CPU 占用。
  • 在当前方案下,两路核心相机(video3、video5)已经连续 60 秒实现严格 1800 帧(30FPS),满足项目需求。

下一步计划:

  1. 验证 RGA 输出的视频颜色和分辨率在长时间运行下保持正确。
  2. 完成 5 分钟、10 分钟压力测试,观察是否存在累计掉帧。
  3. 在实际业务曝光、补光条件下再次验证帧率稳定性。
  4. 将这套MPP + RGA的录制链路完整迁移到正式项目,实现三路采集、实时录制、推流与 AI 推理协同运行。

希望这篇实践记录能为使用RK3588、OrangePi 5 Ultra、GStreamer、MPP、RGA实现多路 USB UVC 相机稳定录制的开发者提供一些参考。欢迎交流更多关于多路采集、硬件编解码和嵌入式视觉系统优化的经验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 5:32:37

OpenClaw龙虾:新一代AI智能助手安装体验报告

用OpenClaw两周了,从最初的"试试看"到现在已经有点离不开了。这篇文章算是我的个人体验报告——不吹不黑,说说真实的使用感受、踩过的坑、以及我觉得值得和不值得的地方。 OpenClaw最新版本一键部署包下载地址:https://top.wokk.c…

作者头像 李华
网站建设 2026/7/3 5:31:20

从Jupyter到生产环境:机器学习模型落地的实战细节

1. 项目概述:当模型走出Jupyter,真正开始呼吸真实世界的空气“From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题本身就像一句暗号,懂的人立刻会心一笑。它不是在讲怎么调参、怎么画loss曲线,而…

作者头像 李华
网站建设 2026/7/3 5:29:34

爬虫转大模型:换个角度,用真实案例讲清边界

《爬虫转大模型:换个角度,用真实案例讲清边界》看起来是个大话题,但真落到项目里,常常就是几个具体选择。下面我尽量按实际开发时会遇到的问题来讲。摘要这篇面向想从爬虫和自动化采集转向 AI 数据工程的开发者,但不会…

作者头像 李华
网站建设 2026/7/3 5:26:34

炭黑在氮化镓(GaN)的作用

1. 引言 氮化镓(GaN)作为第三代半导体材料的代表,以其宽禁带、高电子迁移率、高热导率等优异特性,在功率电子、射频器件和光电子领域展现出巨大潜力。然而,GaN材料及其器件的性能优化与可靠性提升,往往离不…

作者头像 李华
网站建设 2026/7/3 5:25:24

Xshell中实际操作命令

一些命令在xshell中的具体操作和反馈是什么样子的呢,请看下文演示图和输出 1 创建操作目录2 查看进程快照3 动态监控4 kill 5 查看挂载信息6 磁盘空间总览7 卸载命令通常没有卸载目录所以说记住这个方法就好 8 创建测试数据并排序9 搜索字符串grep10.打包11 压缩 至…

作者头像 李华