4、元素探秘:使用 gst-inspect-1.0 查看元素属性、信号、pad模板,理解工厂与实例
说实话,刚接触 GStreamer 那会儿,我最头疼的就是记不住元素的名字和参数。什么 videotestsrc、autovideosink,光拼写就够呛。后来老同事丢给我一句话:「别背,用 gst-inspect-1.0 查。」
这一查,就打开了新世界的大门。今天我就带你彻底搞懂这个命令,顺便把「工厂与实例」这对概念掰扯清楚。
4.1 工厂模式:元素是怎么来的?
先问一个问题:你在管道里写 videotestsrc,GStreamer 是怎么知道该创建什么东西的?
答案就是「工厂模式」。每个元素在 GStreamer 内部都对应一个 插件工厂(GstPluginFeature)。你写名字的时候,框架就去工厂里找对应的「模具」,然后「冲压」出一个实例来。
核心概念:工厂是静态的注册信息,实例是运行时动态创建的对象。同一个工厂可以创建无数个实例,每个实例拥有独立的状态。
我打个比方。工厂就像一张蛋糕配方,实例就是按配方烤出来的蛋糕。配方不会变,但每块蛋糕可以加不同的奶油和水果——这就是属性设置的作用。
用代码验证一下:
// 伪代码逻辑
GstElementFactory *factory;
GstElement *element;
// 通过名字查找工厂
factory = gst_element_factory_find("videotestsrc");
// 工厂创建实例
element = gst_element_factory_create(factory, "my-source");
// 同一个工厂可以再创建另一个实例
GstElement *another = gst_element_factory_create(factory, "my-source-2");
两个实例互不干扰,各有各的属性值。这就是工厂模式的好处。
4.2 gst-inspect-1.0 实战:把元素扒个精光
好,理论讲完,上真家伙。打开终端,输入:
gst-inspect-1.0 videotestsrc
你会看到一大屏输出。别慌,我带你逐段看。
4.2.1 头部信息:工厂详情
最上面几行是工厂的「身份证」:
Factory Details:
Rank none (0)
Long-name Video test source
Klass Source/Video
Description Creates a test video stream
Author David I. Lehn <dlehn@users.sourceforge.net>
这里有个小细节:Klass 字段用斜杠分隔层级,比如 Source/Video 表示「这是一个视频源」。GStreamer 用这个分类来做自动插件选择,后面讲 autovideosink 时会用到。
我的习惯:拿到一个陌生元素,先看 Klass。如果是 Source/* 就是生产者,Sink/* 就是消费者,Filter/* 就是中间处理节点。这个分类能帮你快速定位元素在管道里的角色。
4.2.2 Pad 模板:元素的「接口」
再往下翻,你会看到 Pad 模板(Pad Templates):
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
video/x-raw
format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, RGB, BGR, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB16, BGR16, AYUV64 }
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
video/x-raw(meta:video/x-raw-meta)
...
这里的信息量很大。我拆开讲:
- SRC template:源模板,表示这个元素往外输出数据。名字叫
src。 - Availability: Always:这个 pad 一直存在。还有
On request和Sometimes,后面讲动态 pad 时会遇到。 - Capabilities:能力集。说白了就是「我能输出什么格式的视频」。这里列出了支持的像素格式、分辨率范围、帧率范围。
你看那个 width: [ 1, 2147483647 ],意思是宽度从 1 像素到 21 亿像素都支持。当然实际硬件跑不了那么大,但模板就是这么写的。
我曾经踩过的坑:有一次我写了一个滤镜,死活连不上 videotestsrc。查了半天,发现我的滤镜只接受 video/x-raw, format=RGB,而 videotestsrc 默认输出 I420。GStreamer 不会自动帮你转格式,必须手动插入 videoconvert。从那以后,我拿到元素第一件事就是看它的 pad 模板能力集。
4.2.3 元素属性:拧旋钮的地方
继续往下翻,到了属性部分:
Element Properties:
name : The name of the object
flags: readable, writable
String. Default: "videotestsrc0"
num-buffers : Number of buffers to output before sending EOS
flags: readable, writable
Unsigned Integer. Range: 0 - 4294967295 Default: 0
pattern : Type of test pattern to generate
flags: readable, writable
Enum "GstVideoTestSrcPattern" Default: 0, "smpte"
(0): smpte - SMPTE 100% color bars
(1): snow - Random (television snow)
(2): black - 100% Black
(3): white - 100% White
(4): red - Red
...
属性就是你可以调节的参数。每个属性都有:
- 类型:String、Integer、Enum、Boolean 等
- 读写标志:
readable表示可以读取,writable表示可以设置 - 默认值:不设置时用的值
- 取值范围:对于数值类型,会给出范围
比如 pattern 属性是个枚举,默认是 smpte(彩条)。你可以改成 snow(雪花)或者 red(纯红)。
在命令行设置属性很简单:
gst-launch-1.0 videotestsrc pattern=2 ! autovideosink
这样出来的就是纯黑画面。pattern=2 对应 black。
4.2.4 信号:元素会「喊」你
再往下翻,有些元素会有信号(Signals)部分:
Signals:
"pad-added" : void user_function (GstElement* object, GstPad* pad, gpointer user_data);
"pad-removed" : void user_function (GstElement* object, GstPad* pad, gpointer user_data);
"no-more-pads" : void user_function (GstElement* object, gpointer user_data);
信号是 GStreamer 用来通知你「有事发生了」的机制。比如 pad-added 信号,当元素动态创建了一个新 pad 时就会触发。这在处理 uridecodebin 这类元素时特别重要——你事先不知道它会创建几个输出 pad。
我建议:写代码时多用 g_signal_connect 连接这些信号。命令行里虽然用不到,但理解信号机制对后面写应用程序至关重要。
4.3 一张图看懂元素结构
说了这么多,我画张图帮你把关系理清楚:
4.4 实战演练:用 gst-inspect 诊断问题
光看不练假把式。我给你一个真实场景。
假设你写了一个管道:
gst-launch-1.0 videotestsrc ! x264enc ! mp4mux ! filesink location=test.mp4
结果报错说无法连接 pad。怎么办?
第一步,查 x264enc 的 sink pad 模板:
gst-inspect-1.0 x264enc | grep -A 20 "SINK template"
输出可能显示它只接受 video/x-raw, format=I420。而 videotestsrc 默认输出什么?查一下:
gst-inspect-1.0 videotestsrc | grep -A 10 "SRC template"
你会发现它默认输出 I420,格式匹配没问题。那问题在哪?再查 x264enc 的属性:
gst-inspect-1.0 x264enc | grep -A 5 "Element Properties"
哦,原来 x264enc 需要设置 bitrate 属性,否则默认值可能为 0,导致编码失败。
诊断三板斧:
- 查上游元素的 SRC pad 能力集——看它能输出什么
- 查下游元素的 SINK pad 能力集——看它要接收什么
- 查下游元素的必填属性——看有没有漏设置的参数
4.5 常用元素速查表
我整理了几个常用元素的 inspect 关键信息,方便你快速参考:
| 元素名 | Klass | 关键属性 | Pad 能力要点 |
|---|---|---|---|
| videotestsrc | Source/Video | pattern, num-buffers | 输出 video/x-raw,多种格式可选 |
| autovideosink | Sink/Video | 无特殊属性 | 接收 video/x-raw,自动选择显示后端 |
| videoconvert | Filter/Converter/Video | 无特殊属性 | 输入输出都是 video/x-raw,自动转换格式 |
| x264enc | Codec/Encoder/Video | bitrate, speed-preset | 输入 video/x-raw(I420),输出 video/x-h264 |
| filesink | Sink/File | location | 接收任意类型,写入文件 |
我的习惯:每次安装新的 GStreamer 插件后,我都会跑一遍 gst-inspect-1.0 | grep -i myplugin 确认注册成功。如果 inspect 里看不到,管道里肯定也用不了。
4.6 小结
这一章我们干了三件事:
- 理解了工厂与实例的关系——工厂是模板,实例是运行时对象
- 学会了用
gst-inspect-1.0查看元素的属性、信号、pad 模板 - 掌握了用 inspect 诊断管道连接问题的基本方法
嗯,说实话,inspect 这个工具我每天至少用十几次。写管道之前查一下,报错之后查一下,写代码时查一下。它就像 GStreamer 世界的「man 手册」,是你最可靠的伙伴。