13、多媒体与编解码:GStreamer框架安装、硬件编解码器测试、视频流处理Pipeline构建
说到 Jetson 的多媒体能力,GStreamer 是绕不开的核心。我最早接触它是在做视频监控项目的时候,那时候刚拿到 Jetson 板子,心想这玩意儿能硬解 4K 吗?结果一试,嗯,真香。
这一章,我们就来把 GStreamer 框架装好,测试硬件编解码器,再亲手搭几条视频流处理 Pipeline。说白了,就是让 Jetson 的多媒体硬件真正跑起来。
13.1 GStreamer 框架安装与基础验证
JetPack SDK 默认带了 GStreamer,但版本可能不是最新的。我个人习惯先确认一下当前状态:
# 检查 GStreamer 版本
gst-launch-1.0 --version
# 检查已安装的插件
gst-inspect-1.0 | grep -i nvidia
如果输出里能看到 nvcamerasrc、nvv4l2decoder、nvv4l2encoder 这些元素,说明硬件加速插件已经在了。我曾经遇到过一次,刷完系统后这些插件没装全,折腾了半天才发现是 JetPack 版本选错了。
如果缺东西,别慌,补装就行:
sudo apt update
sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev
装完后,跑个最简单的测试:
gst-launch-1.0 videotestsrc ! autovideosink
如果屏幕上出现一个彩条测试图案,恭喜你,GStreamer 基础环境通了。
autovideosink 换成 fakesink,只验证 Pipeline 能否正常启动。
13.2 硬件编解码器测试
Jetson 的硬件编解码器是它最大的卖点之一。你想想看,用 CPU 软解 4K 视频,帧率可能只有个位数;但用硬件解码器,轻松跑到 60fps。我做过一个对比测试,同样一段 4K H.265 视频,软解 CPU 占用 90%,硬解只有 15%。
13.2.1 硬件解码测试
先准备一个 H.264 或 H.265 的测试文件。如果没有,可以用 gst-launch-1.0 自己生成:
# 生成一段 H.264 测试视频
gst-launch-1.0 videotestsrc num-buffers=300 ! \
video/x-raw,width=1920,height=1080 ! \
nvv4l2h264enc ! h264parse ! qtmux ! \
filesink location=test_h264.mp4
然后测试硬件解码:
gst-launch-1.0 filesrc location=test_h264.mp4 ! \
qtdemux ! h264parse ! nvv4l2decoder ! \
nv3dsink
这里的关键元素是 nvv4l2decoder,它调用了 Jetson 的 V4L2 硬件解码器。如果一切正常,你会看到视频流畅播放。
nvv4l2decoder 找不到,检查一下是不是用了 gst-inspect-1.0 nvv4l2decoder 确认插件存在。我曾经在 JetPack 4.6 上遇到过插件名带版本号后缀的情况,比如 nvv4l2decoder-1.0。
13.2.2 硬件编码测试
编码测试更简单,直接从摄像头取流编码:
gst-launch-1.0 nvarguscamerasrc ! \
video/x-raw,width=1280,height=720,framerate=30/1 ! \
nvv4l2h264enc bitrate=4000000 ! \
h264parse ! qtmux ! filesink location=output.mp4
这里 nvarguscamerasrc 是 Jetson 专用的摄像头源,nvv4l2h264enc 是硬件 H.264 编码器。bitrate 参数控制码率,单位是 bps,4Mbps 对于 720p 来说画质还不错。
我个人习惯在编码时加上 profile=high 参数,能提升压缩效率:
nvv4l2h264enc bitrate=4000000 profile=high
13.3 视频流处理 Pipeline 构建
Pipeline 是 GStreamer 的灵魂。说白了,就是把各种元素像水管一样接起来,数据从一头流到另一头。下面我分享几个实际项目中用过的 Pipeline。
13.3.1 摄像头实时预览 + 编码存储
这个场景很常见:一边在屏幕上预览,一边把视频存成文件。用 tee 元素分流:
gst-launch-1.0 nvarguscamerasrc ! \
video/x-raw,width=1920,height=1080,framerate=30/1 ! \
tee name=t ! \
queue ! nv3dsink \
t. ! queue ! nvv4l2h264enc bitrate=8000000 ! \
h264parse ! qtmux ! filesink location=record.mp4
这里 tee 把视频流分成两路:一路去显示,一路去编码存储。queue 元素用来缓冲,防止阻塞。
13.3.2 RTSP 视频流拉取与硬件解码
从网络摄像头拉 RTSP 流,用硬件解码:
gst-launch-1.0 rtspsrc location=rtsp://192.168.1.100:554/stream1 ! \
rtph264depay ! h264parse ! nvv4l2decoder ! \
nv3dsink
注意 rtspsrc 会自动处理 TCP/UDP 传输模式。如果遇到花屏或卡顿,可以强制 TCP 模式:
rtspsrc location=rtsp://... protocols=tcp ! ...
rtspsrc 的 drop-on-latency 参数默认开启,网络抖动时会丢包。加上 drop-on-latency=false 后,稳定性好了很多。
13.3.3 视频缩放与格式转换
很多时候,我们需要把 4K 视频缩小到 1080p 再处理。用 nvivafilter 或 videoconvert 配合 videoscale:
gst-launch-1.0 filesrc location=4k_video.mp4 ! \
qtdemux ! h264parse ! nvv4l2decoder ! \
nvvidconv ! video/x-raw,width=1920,height=1080 ! \
nv3dsink
nvvidconv 是 Jetson 专用的视频转换元素,支持硬件加速的缩放和颜色空间转换。比用 CPU 做 videoconvert + videoscale 快得多。
13.4 核心知识体系
下面这张图总结了本章的核心逻辑,我把它画成了 SVG,方便你理解各个组件之间的关系:
13.5 性能调优与常见问题
在实际项目中,Pipeline 搭好了不代表就能跑得稳。我遇到过几个典型问题,分享给你:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 视频卡顿、丢帧 | Pipeline 中缺少 queue 元素 |
在关键节点后加 queue 缓冲 |
| 编码器报错 "Resource busy" | 硬件编码器被其他进程占用 | 用 nvpmodel -q 检查状态,或重启板子 |
| RTSP 流延迟大 | 默认缓冲策略偏重稳定性 | 加 latency=0 参数降低延迟 |
| 解码 4K 视频花屏 | 码率过高或解码器配置不当 | 检查 nvv4l2decoder 的 num-extra-surfaces 参数 |
nvvidconv 就别用 videoconvert,能用 nvv4l2decoder 就别用 avdec_h264。
嗯,这一章的内容就到这里。GStreamer 的 Pipeline 构建是个熟能生巧的过程,多搭几条不同的 Pipeline,你就能摸清每个元素的脾气了。