Gstreamer
GStreamer是⼀个开源多媒体框架,⽬前Linux SDK(除了IPC外)的多媒体都主要⽤GStreamer来对接 app 和 编解码组件。利⽤GStreamer插件的强⼤特性,通过编写的GStreamer插件适配Rockchip硬件,使得app能够使⽤硬件编解码进⾏加速。
1. Gstreamer 简介
GStreamer 是一个跨平台的多媒体框架,用于构建流媒体应用程序。它提供了一个统一的接口,用于处理音视频数据。GStreamer 支持多种编解码器和格式,包括 H.264、H.265、MPEG-4、MPEG-2、MPEG-1、AAC、MP3、WAV 等。GStreamer 还支持多种容器格式,包括 MP4、MKV、FLV 等。
GStreamer 是一个开源项目,由 GNOME 社区开发。
1.1 基本概念
GStreamer 主要由以下几个组件组成:
Pipeline(管道):一个媒体处理管道,用于处理音视频数据。Pipeline是一个完整的GStreamer应用程序,它包含多个Element,这些Element可以连接在一起,形成一个数据流。Pipeline可以从文件、网络、摄像头等多种数据源读取音视频数据,并将其处理后输出到文件、网络、显示器等多种目的地。Pipeline还可以处理音视频数据的编解码、转码、缩放、裁剪、旋转、混音、滤波等多种操作。Pipeline必须以source和sink元素开始和结束,source元素用于读取音视频数据,sink元素用于输出音视频数据。
Element(元素):一个处理单元,用于处理音视频数据。GStreamer工作流中的每一个节点,例如source类元素、filter类元素、sink类元素。元素与元素之间通过【管道】进行数据传递。Element可以是一个插件,也可以是一个内置的元素。Element可以连接在一起,形成一个数据流。Element可以处理音视频数据的编解码、转码、缩放、裁剪、旋转、混音、滤波等多种操作。
Pad(衬垫):一个连接点,用于连接Element。Pad是Element的输入或输出端口。Pad可以连接到另一个Element的Pad,形成一个数据 流。Pad可以是一个用于接收数据的输入衬垫sinkPads或一个用于发送数据的输出衬垫srcPsds。
每一个元素都会至少一个衬垫,如source类元素和sink类元素;有些元素会有多个衬垫,如filter类元素,例如解复用器(demuxer)。
1.2 Gstreamer 工具
gst-launch-1.0:gst-launch-1.0是Gstreamer中一个常用和强大的工具,用于创建并启动多媒体管道图。它可以从标准命令行读取管道图的描述,用户可以在命令行中直接运行该描述。它不需要复杂的编程或脚本,使用户方便地测试和调试管道图。
gst-inspect-1.0:gst-inspect-1.0可以打印出可用 GStreamer 插件的信息、特定插件的信息或特定元素的信息。当在没有PLUGIN或ELEMENT参数的情况下执行时,gst-inspect-1.0将打印所有插件和元素的列表以及sumary。当使用PLUGIN或ELEMENT参数执行时,gst-inspect-1.0将打印有关该插件或元素的信息。
1.3 Gstreamer 调试信息
使用GST_DEBUG环境变量,可查看调用Gstreamer时所产生的打印信息。比如在终端输入以下命令。
export GST_DEBUG=2 # 如果想看到更详细的信息,调试等级可设为3。
2. Gstreamer 编码
2.1 保存录像
如果我们需要录制一个视频,我们可以使用gst-launch-1.0命令来实现。
gst-launch-1.0 \
v4l2src device=/dev/video0 ! \ # 通过 V4L2 (Video4Linux2) 接口从指定设备捕获视频
mpph264enc bps=60000000 ! \ # 使用 MPP 硬件编码器进行 H.264 编码,并设置编码比特率
filesink location=~/Desktop/share/1.h264 # 将处理后的数据流写入文件
-e # 优雅结束选项
执行该指令,会从/dev/video0设备捕获视频,使用 MPP 硬件编码器进行 H.264 编码,并将处理后的数据流写入文件~/Desktop/share/1.h264。
注解
v4l2src:V4L2 是 Linux 下的视频设备接口标准,v4l2src 是 GStreamer 中用于从 V4L2 设备读取视频流的插件。
mpph264enc:MPP 是 Rockchip 公司提供的硬件加速编解码库,mpph264enc 是 GStreamer 中用于使用 MPP 硬件编码器进行 H.264 编码的插件。
filesink:filesink 是 GStreamer 中用于将数据流写入文件的插件。
"!":表示数据流的管道,将 v4l2src 和 mpph264enc 连接起来。
2.2 UDP 推流
UDP 是一种常用的网络传输协议,它可以将视频流从一个设备推送到一个网络上的接收方。在 GStreamer 中,我们可以使用 udpsink 插件来实现 UDP 推流。
小技巧
GST管道整体架构: 摄像头采集 → 格式约束 → 颜色空间转换 → H.264硬件编码 → H.264解析 → RTP打包 → 缓冲区控制 → UDP发送
gst-launch-1.0 -v \
v4l2src device=/dev/video20 ! \ # 视频输入源:指定摄像头设备节点
video/x-raw,width=1920,height=1080,framerate=30/1 ! \ # 设置原始视频格式参数
videoconvert ! \ # 色彩空间转换器
mpph264enc bps=8000000 interval-intraframes=30 ! \ # H264编码器:8Mbps码率,30帧关键帧间隔
h264parse ! \ # H264流解析器
rtph264pay config-interval=1 ! \ # 封装RTP协议,每秒发送SPS/PPS
queue max-size-buffers=100 leaky=downstream ! \ # 缓冲区:最大100帧,下游饥饿时丢弃
udpsink host=192.168.3.191 port=8554 sync=false # UDP输出:目标IP和端口,禁用时钟同步
执行该指令,会从/dev/video0设备捕获视频,使用 MPP 硬件编码器进行 H.264 编码,并将处理后的数据流通过 UDP 协议推流到指定的主机和端口。
注解
video/x-raw:video/x-raw 是 GStreamer 中用于表示原始视频数据的格式。
videoconvert:videoconvert 是 GStreamer 中用于将视频数据从一种格式转换为另一种格式的插件。
h264parse:h264parse 是 GStreamer 中用于解析 H.264 码流的插件。
rtph264pay:rtph264pay 是 GStreamer 中用于将 H.264 码流打包成 RTP 数据包的插件。
queue:queue 是 GStreamer 中用于缓存数据的插件。max-size-buffers=100 表示队列的最大缓冲区大小为 100,leaky=downstream 表示当队列满时,新的数据会被丢弃。
udpsink:udpsink 是 GStreamer 中用于将 RTP 数据包通过 UDP 协议推流到指定的主机和端口的插件。sync=false(不适用同步时钟,适用于实时直播)
注解
UDP 特性:
无连接:UDP 是一种无连接的协议,发送方和接收方不需要建立连接。
不可靠:UDP 是一种不可靠的协议,发送方发送的数据可能会丢失或重复。
实时性:UDP 是一种实时性强的协议,适用于实时音视频传输,但网络波动时可能花屏。
以下简要介绍如何在接收端通过VLC播放器播放GStreamer推流的视频:
1. 打开VLC播放器。
2. 点击“媒体”菜单,选择“打开网络串流”。
3. 在弹出的对话框中,输入GStreamer推流的URL:udp://@192.168.3.191:8554。
4. 点击“打开”按钮,VLC播放器将开始播放GStreamer推流的视频。
另外针对复杂的RTP流,可以创建SDP(会话描述协议)文件:
# 创建stream.sdp文件
v=0
o=- 0 0 IN IP4 192.168.3.191
s=H.264 Stream from RK3588
c=IN IP4 192.168.3.191
t=0 0
m=video 8554 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1" > stream.sdp
# 在VLC中打开该SDP文件(也可以通过图形界面操作)
vlc stream.sdp
2.3 RTSP服务器
RTSP(Real-Time Streaming Protocol)是一种常用的网络传输协议,它可以将视频流从一个设备推送到一个网络上的接收方。rtsp服务器是一个可以接收RTSP客户端请求并返回相应的媒体流的服务器,我们可以通过gst-rtsp-server库实现高效的流媒体服务。 首先,通过apt-get 安装rtspServer相关库,指令如下:
sudo apt-get install libgstrtspserver-1.0-dev
然后,获取rtspServer应用的源码,指令如下:
```bash
wget https://raw.githubusercontent.com/GStreamer/gst-rtsp-server/1.14/examples/test-launch.c
最后,编译并运行rtspServer应用,指令如下:
gcc test-launch.c -o test-launch $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-rtsp-server-1.0)
成功生成test-launch后,运行rtspServer应用,指令如下:
./test-launch "v4l2src device=/dev/video20 ! mpph264enc ! rtph264pay name=pay0 pt=96"
执行该指令,就可以使用VLC通过8554端口拉取rtsp流。
vlc rtsp://192.168.3.191:8554/test # 也可以通过VLC可视化界面打开rtsp流
3. Gstreamer 解码
3.1 播放视频
现在我们尝试解码播放2.1录制保存的1.h264文件。
gst-launch-1.0 filesrc location=~/Desktop/share/1.h264 ! h264parse ! mppvideodec ! xvimagesink sync=false
该指令解析如下:
gst-launch-1.0 \
filesrc location=~/Desktop/share/1.h264 ! \ # 从文件读取数据
h264parse ! \ # 解析H.264流
mppvideodec ! \ # 使用MPP硬件解码器
xvimagesink sync=false # 显示视频(禁用同步)
命令执行后,桌面系统会出现一个窗口,并播放1.h264文件的内容。
3.2 RTSP 拉流
rtsp是一种常见的网络传输协议,它可以将视频流从一个设备推送到一个网络上的接收方。rtsp拉流是指通过RTSP协议从服务器上拉取视频流的过程。
现在假设我们要从一个地址为rtsp://admin:a12345678@192.168.3.73
的网络摄像头上拉取视频流,并将其解码后显示。
gst-launch-1.0 rtspsrc location=rtsp://admin:a12345678@192.168.3.73 ! rtph264depay ! h264parse ! mppvideodec ! xvimagesink sync=false
该指令解析如下:
gst-launch-1.0 \
rtspsrc location=rtsp://admin:a12345678@192.168.3.73 ! \ # RTSP源
rtph264depay ! \ # RTP解包
h264parse ! \ # H.264解析
mppvideodec ! \ # MPP硬件解码
xvimagesink sync=false # X Window显示
执行该指令后,即可显示该网络摄像头的视频流。
4. gst-inspect-1.0使用
gst-inspect-1.0 是 GStreamer 工具之一,用于查看 GStreamer 插件的信息。它可以列出所有可用的插件、特定插件的信息或特定元素的信息。
4.1 查看所有元素
gst-inspect-1.0
该指令会列出所有可用的插件、特定插件的信息或特定元素的信息。
4.2 查看元素信息
gst-inspect-1.0 v4l2src
该指令会列出 v4l2src 元素的信息。
4.3 使用技巧
gst-inspect-1.0可以配合grep来初步筛选自己感兴趣的【元素】,比如pcma格式相关的音频插件元素,如下所示。
gst-inspect-1.0 | grep pcma
gst-inspect-1.0 | grep law