Jetson边缘嵌入式实战课程第八讲:GStreamer视频流实战,YUY2和MJPEG到底怎么选?


📺 B站 嵌入式孙老师博主个人介绍
📘 博主书籍-京东购买链接Yocto项目实战教程
📘 加博主微信,进技术交流群jerrydev


大家好,我是孙杰。

在这里插入图片描述

最近我和 与非网、贸泽电子 合作,做了一套 Jetson 边缘嵌入式实战课程。前面六讲,我们把 Jetson 的硬件平台、JetPack、L4T、Yocto、Secure Boot,以及 OP-TEE 安全体系都逐步讲清楚了。第七讲,我们又专门讲了 GStreamer 是什么,先把 Pipeline、Element、Caps、Plugin 这些基础概念梳理了一遍。

到了第八讲,课程开始从“理解 GStreamer”进入“真正跑视频流”。

这一讲的主题是:

GStreamer 视频流实战:在 Jetson 上把 USB 摄像头画面跑起来,并搞清楚 YUY2 和 MJPEG 到底怎么选。

很多同学在 Jetson 上接摄像头时,最容易遇到的问题不是模型推理,而是视频链路本身:

  • 摄像头能识别,但画面打不开;
  • /dev/video0 存在,但 Pipeline 报错;
  • 同样是 30fps,为什么 YUY2 只能低分辨率?
  • 为什么 MJPEG 可以跑到 2K 30fps?
  • 画面显示出来了,怎么判断 Jetson 的硬件负载是否正常?

这一讲我尽量用工程视角,把视频流里的分辨率、FPS、V4L2 格式查询、GStreamer Caps、YUY2/MJPEG 对比,以及 Jetson 硬件负载观察讲清楚。
在这里插入图片描述

本文基于第八讲课程 PPT 内容整理。


一、为什么要讲 GStreamer 视频流实战

第七讲我们讲的是 GStreamer 的基础概念,重点是建立“流水线思维”:

Source → Convert → Encoder → Mux → Sink

到了第八讲,就要把这条流水线真正跑起来。

在边缘 AI、机器人、工业相机、智能摄像头这些场景里,视频链路通常是这样的:

摄像头采集
    ↓
格式转换 / 解码
    ↓
显示 / 编码 / 保存 / 推流
    ↓
AI 推理

如果前面的视频流没有打通,后面的 AI 推理、目标检测、录像、推流都无从谈起。

所以这一讲的核心不是背命令,而是建立一个调试顺序:

先确认摄像头支持什么格式
        ↓
再写对应的 GStreamer Caps
        ↓
把画面显示出来
        ↓
最后观察 Jetson 硬件负载

很多 GStreamer 问题,本质上不是命令复杂,而是格式、分辨率、帧率和带宽没有匹配好。


二、这一讲主要讲什么

这一讲内容可以压缩成四件事:

  1. 视频流中的分辨率、像素数量、FPS 到底影响什么;
  2. 如何用 V4L2 查看摄像头支持哪些格式;
  3. YUY2 和 MJPEG 两种格式在 Jetson 上怎么显示;
  4. 如何用 GPU Power GUI 和 tegrastatus 观察 Jetson 硬件状态。

把这四件事理顺,后面再做视频录制、网络推流、多路摄像头、AI 推理,思路就会清楚很多。


三、几个核心知识点

1. 视频流最基础的三个参数:分辨率、像素数量、FPS

在这里插入图片描述

视频流里最关键的三个参数是:

参数含义影响
分辨率画面宽高,例如 1920×1080决定画面细节
像素数量宽 × 高决定单帧数据量
FPS每秒帧数决定流畅度和吞吐压力

比如 1080P:

1920 × 1080 = 2,073,600 像素

如果是 30fps,就意味着系统每秒要处理 30 张 1080P 图像。

在 GStreamer Pipeline 中,这些参数通常会写在 Caps 里:

gst-launch-1.0 v4l2src ! \
"video/x-raw,width=1920,height=1080,framerate=30/1" ! \
videoconvert ! autovideosink

这条命令里的核心含义是:

分辨率:1920×1080
帧率:30fps
格式:RAW 原始视频流

这里要注意,分辨率越高、FPS 越高,不只是画面更清晰,也意味着数据量更大,对 USB 带宽、内存搬运、格式转换、显示和编码都会带来压力。

所以视频流调试不要一上来就追求最高规格,更合理的方式是:

先低分辨率跑通链路
        ↓
再提高分辨率
        ↓
再提高 FPS
        ↓
最后观察系统负载

2. 写 Pipeline 之前,先用 V4L2 查摄像头能力

在 Jetson 上调试 USB 摄像头,第一步不是直接写复杂的 GStreamer 命令,而是先确认摄像头到底支持什么格式。

常用命令如下。

查看设备列表:

v4l2-ctl --list-devices

查看当前格式:

v4l2-ctl -d /dev/video0 --get-fmt-video

查看全部支持格式:

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

常见视频格式大致可以分为三类:

类型常见格式特点
未压缩 RAWRGB888、YUYV、NV12数据量大,质量好
压缩格式MJPG、H.264、H.265数据量小,需要解码
传感器 RAW BayerSRGGB10、BGGR12需要 ISP 处理

本节课使用的是 USB UVC 摄像头。通过 v4l2-ctl 查询可以看到一个很典型的现象:

MJPEG:最高支持 2560×1440@30fps
YUYV:30fps 下仅支持 640×480

这也是本节课最核心的问题来源:

同一个摄像头,为什么 MJPEG 可以跑 2K 30fps,而 YUY2 只能跑 640×480@30fps?

答案不在 Jetson 算力,而在数据格式。


3. 一个容易误解的点:一个 video 节点可以支持多种格式

USB UVC 摄像头通常只暴露一个 /dev/video0 节点。

但这不代表它只有一种输出能力。

不同格式不是通过多个 /dev/video 节点区分,而是通过同一个 video 节点里的 pixel format 选择:

/dev/video0
  ├── YUYV / YUY2
  ├── MJPEG
  └── 其他格式

所以调试时,不能只看有没有 /dev/video0

真正要看的,是这个节点支持哪些:

format
width
height
framerate

很多 Pipeline 报错,根源都是 Caps 写了摄像头不支持的格式组合。


4. YUY2:RAW 原始流,适合调试链路

YUY2 / YUYV 属于未压缩 RAW 视频格式。

它的特点是:

  • 数据没有压缩;
  • 每一帧都是原始像素;
  • 链路简单,延迟低;
  • 但数据量大,对 USB 带宽和内存压力高。

课程中的 YUY2 显示命令如下:

gst-launch-1.0 v4l2src device=/dev/video0 ! \
"video/x-raw,format=YUY2,width=640,height=480,framerate=30/1" ! \
nvvidconv ! nveglglessink

这条 Pipeline 可以拆成:

v4l2src
    ↓
YUY2 RAW 帧
    ↓
nvvidconv
    ↓
nveglglessink

每个模块的作用如下:

模块作用
v4l2src从 USB 摄像头采集视频
video/x-raw,format=YUY2指定摄像头输出 YUY2 RAW
640×480@30fps限制分辨率,降低带宽压力
nvvidconvJetson 上进行格式 / 内存转换
nveglglessinkGPU 显示输出

YUY2 更适合:

  • 摄像头驱动验证;
  • Pipeline 基础调试;
  • 底层链路问题定位;
  • 低延迟、小分辨率预览。

一句话总结:

YUY2 更适合看链路是否通。


5. MJPEG:压缩流,适合高分辨率应用

MJPEG 是压缩格式。

它的特点是:

  • 摄像头端已经完成 JPEG 压缩;
  • USB 上传输的是压缩后的图像;
  • 带宽压力比 RAW 小很多;
  • 可以支持更高分辨率;
  • 显示前需要先解码。

课程中的 MJPEG 显示命令如下:

gst-launch-1.0 v4l2src device=/dev/video0 ! \
'image/jpeg,width=2560,height=1440,framerate=30/1' ! \
jpegdec ! nvvidconv ! nveglglessink

这条 Pipeline 可以拆成:

v4l2src
    ↓
MJPEG 压缩帧
    ↓
jpegdec
    ↓
nvvidconv
    ↓
nveglglessink

每个模块的作用如下:

模块作用
v4l2src从 USB 摄像头采集视频
image/jpeg指定摄像头输出 MJPEG
2560×1440@30fps启用 2K 分辨率
jpegdec对 MJPEG 进行解码
nvvidconv转换为适合 Jetson 显示的格式
nveglglessinkGPU 显示输出

MJPEG 更适合:

  • 实际产品显示;
  • 高分辨率预览;
  • USB 摄像头工程交付;
  • 需要稳定 2K 30fps 的场景。

一句话总结:

MJPEG 更适合真正跑应用。


6. YUY2 和 MJPEG 怎么选

在这里插入图片描述

两者对比如下:

对比项YUY2 / RAWMJPEG
数据形态未压缩原始像素JPEG 压缩帧
数据量
USB 带宽压力
是否需要解码不需要需要 jpegdec
延迟较低略高
高分辨率支持受带宽限制明显更容易支持
本节课示例640×480@30fps2560×1440@30fps
适合场景调试链路产品预览

核心结论:

YUY2 是原始像素流,MJPEG 是压缩后的图像流。
YUY2 更适合调试,MJPEG 更适合高分辨率应用。


7. Jetson 上不能只看画面,还要看硬件负载

Jetson 的视频和 AI 性能,不是只由 GPU 决定。

它是一套异构并行架构,视频链路中可能涉及 CPU、GPU、NVDEC、NVENC、VIC、内存和温度等多个模块。

模块关注指标常见异常
GPU / GR3D利用率、频率、温度、功耗频率不上升、利用率低
CPU每核频率、占用率单核 100%、频率偏低
NVDEC解码利用率解码瓶颈导致掉帧
NVENC编码利用率编码占满导致延迟
VIC缩放、格式转换负载转换过多导致推理延迟
RAM内存、Swap内存不足导致卡顿
温度CPU/GPU/SoC 温度高温导致降频

所以视频流调试不能只问:

画面有没有出来?

还要继续看:

CPU 是否跑满?
GPU 是否被限制?
VIC 是否压力过高?
温度是否导致降频?
功耗模式是否限制性能?

课程中提到两个工具:

工具特点适合场景
GPU Power GUI图形化,直观看 GPU 状态快速观察、课堂展示
tegrastatus命令行,信息更完整长时间监控、定位瓶颈

GPU Power GUI 适合快速看 GPU 利用率、频率、温度、功耗,以及 NVENC / NVDEC 是否 online。

但如果要进一步分析系统瓶颈,还是要结合命令行工具:

sudo tegrastats

重点观察:

  • CPU 是否长期低频;
  • GR3D 频率是否正常;
  • NVENC / NVDEC 是否启用;
  • RAM 是否接近满;
  • 温度是否过高;
  • 电源轨功耗是否变化。

一句话总结:

GPU Power GUI 适合快速看状态,tegrastatus 更适合定位瓶颈。


四、这一讲的重点

如果把这一讲再压缩,必须抓住下面几条:

  1. 视频性能由分辨率、像素数量和 FPS 共同决定;
  2. 写 GStreamer Pipeline 之前,先用 V4L2 查清摄像头支持格式;
  3. YUY2 是 RAW 未压缩流,数据量大,适合调试;
  4. MJPEG 是压缩流,带宽压力小,适合高分辨率预览;
  5. Jetson 上显示建议结合 nvvidconvnveglglessink
  6. 画面显示出来不代表系统稳定,还要看 GPU Power GUI 和 tegrastatus
  7. Pipeline 报错时,优先检查 Caps 是否和摄像头能力匹配。

这一讲的难点,主要在格式匹配和工程判断:

不是看到 /dev/video0 就说明摄像头没问题,也不是画面显示出来就说明系统性能没问题。

真正的调试习惯应该是:

查格式
    ↓
写 Caps
    ↓
跑 Pipeline
    ↓
看负载
    ↓
再优化

五、适合哪些人学习

如果你正处在下面这些阶段,这一讲会很适合你:

  • 想在 Jetson 上跑 USB 摄像头;
  • 想理解 YUY2、MJPEG、RAW、压缩流的区别;
  • 想搞清楚 GStreamer Caps 为什么重要;
  • 想做摄像头预览、录像、推流;
  • 想用 Jetson 做机器人视觉、工业相机、AI Box;
  • 后面准备把视频链路接到 AI 推理或 DeepStream 上。

哪怕你现在还写不出复杂 Pipeline,也没关系。

先把 YUY2 和 MJPEG 这两条链路跑通,很多视频流问题就已经能看懂一半了。


六、视频与课程入口

B站视频地址:

https://www.bilibili.com/video/BV1RS8i6zEEu

与非网课程入口:

https://www.eefocus.com/course/1993803.html

本系列课程《Jetson 嵌入式系统定制与边缘计算实战》,围绕 Jetson 平台的系统定制、边缘计算、多媒体处理和工程实战展开。

第七讲主要讲 GStreamer 的基础概念。
第八讲开始进入视频流实战。

建议大家重点把下面两条 Pipeline 亲自跑一遍:

gst-launch-1.0 v4l2src device=/dev/video0 ! \
"video/x-raw,format=YUY2,width=640,height=480,framerate=30/1" ! \
nvvidconv ! nveglglessink
gst-launch-1.0 v4l2src device=/dev/video0 ! \
'image/jpeg,width=2560,height=1440,framerate=30/1' ! \
jpegdec ! nvvidconv ! nveglglessink

一条是 RAW 原始流,一条是压缩视频流。
把这两条链路对比清楚,后面再看录像、推流、多路摄像头和 AI 推理,思路会顺很多。


七、最后想分享的话

我一直觉得,Jetson 边缘嵌入式开发里,视频流是一道绕不开的坎。

第一次把摄像头画面稳定显示出来,第一次搞清楚为什么同一个摄像头不同格式表现完全不同,第一次能从 v4l2-ctl、Caps、Pipeline、tegrastatus 这些信息里判断问题,这个过程会让你真正理解“工程调试”是什么。

GStreamer 看起来是一长串命令,本质上还是搭积木。

你需要先搞清楚每块积木的作用:

v4l2src 负责采集
Caps 负责指定格式
jpegdec 负责解码
nvvidconv 负责转换
nveglglessink 负责显示

再搞清楚它们之间的数据格式是否能接上。

第七讲我们建立了流水线思维,第八讲开始把这条流水线真正跑起来。后面无论是做视频录制、RTSP 推流、多路摄像头,还是接 AI 推理,这些基础都会反复用到。

如果你对 Jetson、GStreamer、Yocto、边缘 AI 和嵌入式 Linux 系统定制感兴趣,欢迎继续关注这个系列,后面我会把这些内容继续更新下去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值