Jetson边缘嵌入式实战课程第七讲:GStreamer到底是什么,它在Jetson上怎么用


Jetson边缘嵌入式实战课程第七讲:GStreamer到底是什么,它在Jetson上怎么用


大家好,我是孙杰

最近我和 与非网、贸泽电子 合作,做了一套 Jetson 边缘嵌入式实战课程。前面六讲,我们把 Jetson 的硬件平台、JetPack、L4T、Yocto、Secure Boot,以及上一讲的 OP-TEE 安全体系都逐步讲清楚了。到了这一讲,课程开始往多媒体处理这条主线走,主题是:

GStreamer 到底是什么?它在 Jetson 上是怎么把摄像头、编解码、显示这些能力串起来的?

很多人第一次接触 GStreamer,会被一长串 v4l2src ! nvvidconv ! nveglglessink 这样的命令吓到,感觉每个词都认识,连起来就不知道在干嘛。其实只要你抓住一个核心概念------Pipeline(流水线),后面所有命令都会变得很好懂。

这一讲我尽量用偏工程的视角,把 GStreamer 的定位、插件体系、Pipeline 工作机制,以及它和 Jetson 硬件的对应关系讲明白。你不需要一开始就会写复杂命令,只要把这条主线看顺,后面做相机采集、视频编码、推流都会轻松很多。

一、为什么要讲 GStreamer 这一节

做边缘视觉、做嵌入式 AI,几乎绕不开一件事:把摄像头的画面拿进来,处理一下,再显示或存下来。

听起来简单,真正做起来你会遇到一堆问题:

  • 摄像头出来的是 MJPEG 还是 YUY2?要不要解码?
  • 格式不对,显示器不认怎么办?
  • 想用 Jetson 的 GPU 加速,又不知道该插哪个模块?
  • 想边显示边录像,怎么让一路数据分两条走?

如果每一步都自己写代码去抠,工作量大、还容易出错。GStreamer 的价值就在于:它把这些音视频处理能力都做成了标准化的"积木",你只要按顺序把积木拼起来,一条完整的处理链路就跑起来了。

所以这一讲,本质上是在帮你建立一种"用流水线思维处理音视频"的工程习惯。

二、这一讲主要讲什么

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

  1. GStreamer 是什么、怎么装;
  2. 插件(Plugin)和元素(Element)是什么关系;
  3. Pipeline 是怎么把数据从输入跑到输出的;
  4. Jetson 的硬件流水线,和 GStreamer 的软件流水线是怎么对应的。

把这四件事理顺,你就能看懂、也能自己改大部分 Jetson 上的 GStreamer 命令了。

三、几个核心知识点

1. GStreamer 是一个"流水线式"的多媒体框架

先给一个最朴素的理解:

GStreamer 就是一条工厂流水线,音视频数据像零件一样从一头进去,经过一道道工序加工,最后从另一头出来。

它能做的事情很多:视频采集(USB / CSI 摄像头)、解码(H.264 / H.265 / MJPEG)、颜色格式转换(比如 YUY2 → NV12)、GPU 加速处理(Jetson 专属的 nvvidconvNVMM)、视频显示(nveglglessink)、视频编码存储(nvv4l2h264enc)。

安装也很简单,Jetson 上一般这样装:

bash 复制代码
sudo apt-get update
sudo apt-get install gstreamer1.0-tools gstreamer1.0-alsa \
    gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav

装完用一条命令验证版本:

bash 复制代码
gst-inspect-1.0 --version

2. 插件提供能力,元素才真正干活

这是初学者最容易混的地方,记住一句话就行:

插件(Plugin)是一个 .so 动态库,里面装着很多元素(Element),真正干活的是元素。

打个比方:插件就像一个工具箱,元素就是箱子里一件件具体的工具。工具箱本身不干活,你得把里面的螺丝刀(元素)拿出来用,它才起作用。元素被 Pipeline 调用之后,才会真正执行采集、转换、编码、解码、显示这些动作。

插件按功能分成四类:Source(输入)/ Filter(处理)/ Codec(编解码)/ Sink(输出)

在 Jetson 上有几个"关键工具"一定要眼熟:nvarguscamerasrc(CSI 相机)、nvv4l2decoder(硬解码)、nvv4l2h264enc(硬编码)、nvvidconv(硬件格式转换/缩放)、nveglglessink(显示)。这些带 nv 前缀的,基本都是 NVIDIA 提供的硬件加速元素------能不能用上 GPU,很大程度就看你有没有用对它们。

3. Pipeline:整条链路的"总指挥"

Pipeline(管道/流水线)是 GStreamer 里最高层的运行实体 ,它描述的是一条完整路径:数据从哪里来 → 怎么被处理 → 最终去哪里。

一条 Pipeline 内部由这几样东西构成:

  • Elements :最小功能模块,比如 v4l2srcnvvidconv
  • Pads :元素之间的连接点,分 src(出)和 sink(进);
  • Caps:格式能力协商,比如 NV12 / YUY2 / JPEG,相邻元素要"谈得拢"才能连上;
  • State Machine :状态机,按 NULL → READY → PAUSED → PLAYING 一步步切换。

这里我要特别强调 Caps(格式协商) ,因为它是新手踩坑最多的地方。两个元素能不能接到一起,取决于上一个的输出格式,下一个收不收。很多 Pipeline 跑不起来,报错的根源就是格式没对上,而不是元素本身有问题。后面排错时,先怀疑格式,往往能少走很多弯路。

4. 一条标准 Pipeline 长什么样

GStreamer 处理多媒体的标准结构是这样的:

每一段的职责和常用元素:

阶段 干什么 典型元素
Source 提供输入(摄像头/文件/网络流) v4l2srcfilesrcnvarguscamerasrc
Convert 格式转换、分辨率缩放 videoconvertnvvidconv(硬件加速)
Filter 裁剪、限速、缓冲 videocropcapsfilterqueue
Encoder 压缩成 H.264/H.265/JPEG nvv4l2h264encx264enc
Mux 封装成 MP4/MKV/TS mp4muxmatroskamux
Sink 输出到屏幕/文件/网络 nveglglessinkfilesinkudpsink

来看一个能直接跑的例子------USB 摄像头采集,裁掉上下边,编码存成 MP4

bash 复制代码
gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! \
videocrop top=20 bottom=20 ! x264enc ! mp4mux ! \
filesink location=output.mp4

拆开看就是:v4l2src/dev/video0 采集 → videoconvert 转格式保证兼容 → videocrop 裁掉上下各 20 像素 → x264enc 压成 H.264 → mp4mux 封装 → filesink 落盘。一条命令,六个元素串起来,一个完整的录像功能就完成了。这就是 GStreamer "积木式拼装"的魅力。

如果只是想实时预览摄像头画面,那条命令更短,课程配套脚本里就有:

bash 复制代码
gst-launch-1.0 v4l2src device=/dev/video0 ! \
"image/jpeg,width=2560,height=1440,framerate=30/1" ! \
jpegdec ! nvvidconv ! nveglglessink

这条是 MJPEG 摄像头的预览:采集 → jpegdec 解码 → nvvidconv 走 Jetson 硬件转换 → nveglglessink 显示。

小提示:跑通后你会看到日志里出现 Pipeline is PREROLLED ...Setting pipeline to PLAYING ...,这说明状态机已经走到 PLAYING,Pipeline 正常运转了。

5. Jetson 硬件流水线 ≈ GStreamer 软件流水线

这是这一讲一个很巧妙的点。Jetson 内部其实也有一条硬件层面的数据通路:

它和 GStreamer 的软件 Pipeline 几乎是一一对应的:

  • Camera ≈ v4l2src / nvarguscamerasrc
  • NVDEC(硬解码)≈ nvv4l2decoder
  • Memory(NVMM 显存缓冲)≈ Buffer / NVMM
  • GPU/DLA/PVA ≈ nvvidconv / TensorRT 相关元素
  • NVENC(硬编码)≈ nvv4l2h264enc
  • Display ≈ nveglglessink
  • CPU ≈ Pipeline 的控制与调度

理解了这层对应关系,你就明白:当你在命令里写下那些 nv 开头的元素时,背后调用的其实是 Jetson 的专用硬件单元,这也是 Jetson 跑视频又快又省电的原因。

四、这一讲的重点

如果再压缩,这一讲必须抓住的就几条:

  1. GStreamer 是流水线框架,核心是"数据按固定流程一段段流过去"。
  2. 插件提供能力,元素才执行 ,带 nv 的元素 = Jetson 硬件加速。
  3. Pipeline 由 Element + Pad + Caps + 状态机组成,跑不起来先查 Caps(格式协商)。
  4. 软件 Pipeline 对应着 Jetson 的硬件通路,写对元素就等于用对了硬件。

这一讲的难点,主要在格式协商和多元素串接时的兼容性处理------也就是怎么在格式不匹配导致报错时,快速定位并修好它。这个能力是靠多拼几条 Pipeline 练出来的,不用怕踩坑。

五、适合哪些人学习

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

  • 想在 Jetson 上把 USB / CSI 摄像头跑起来;
  • 想理解视频采集、编解码、显示到底是怎么串起来的;
  • 准备做实时预览、录像、推流这类功能;
  • 想用上 Jetson 的硬件加速,但不知道该用哪些元素;
  • 后面打算把视频链路接到 AI 推理(TensorRT / DeepStream)上。

哪怕你现在还写不出复杂命令也没关系,只要先建立"流水线思维",后面往工程上落会顺很多。

六、视频与课程入口

B站视频地址

https://www.bilibili.com/video/BV1RZ786dEo1?vd_source=d5bd1dbd334bfacff2e75172dbc93b0e&spm_id_from=333.788.videopod.sections

与非网课程入口

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

七、最后想分享的话

我一直觉得,边缘嵌入式开发里,多媒体处理是一道绕不开、但又特别有成就感的坎。第一次把摄像头画面在屏幕上跑出来、第一次成功录下一段 MP4,那种"整条链路通了"的感觉,是会让人上瘾的。

GStreamer 看起来命令花哨,本质上就是搭积木:搞清楚每块积木干什么,再理解它们怎么拼,剩下的就是熟练度问题了。把这一讲的流水线思维建立起来,后面无论是接 AI 推理、做多路视频,还是搞 RTSP 推流,你都会发现思路是一脉相承的。

如果你对 Jetson 和边缘嵌入式开发感兴趣,欢迎继续关注我,后面我会把这个系列继续更新下去。