深入浅出,快速弄明白 gst-launch-1.0 PIPELINE-DESCRIPTION 管道描述语法

本文转载自许野平的博客

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

他的博客有很多关于GStreamer的好文章,并非官网文档翻译,基本是按照他自己的理解来写,适合理解

1

话说 gst-launch-1.0 这条命令老牛掰了,看是很复杂的媒体流,用这条命令,一行代码就搞定了。看看下面这行代码,区区几十个字符,就建立了测试视频流:

gst-launch-1.0 videotestsrc ! autovideosink
  • 1

运行后可以在屏幕上显示视频测试图案,大概就是下面这个样子:
在这里插入图片描述

那些包含视频、音频,甚至用户定制信号的复杂媒体流,也能用 gst-launch-1.0 这样子玩吗?当然没问题。我们接下来聊聊如何构建复杂媒体流管道。

2

在刚才的例子中,我们的管道描述串是 videotestsrc ! autovideosink,它包括了三个部分:

  • 管道起始点: videotestsrc
  • 管道的终点: autovideosink
  • 起点和终点的连接:

这个管道描述串的意思是,把元素 videotestsrc 连接到元素 autovideosink 上。

说到这里,很多人很纳闷,不是说元素之间只能通过 Pad 链接吗?这里怎么直接连接元素呢?实际上这是一个简化用法,因为 videotestsrc 只有一个输出 Pad,autovideosink 也只有一个输入 Pad,这种情况下,就不需要再说明怎么样用 Pad 连接了。不过,上面这个例子完整的说明应该如下:

gst-launch-1.0 videotestsrc name=a a.src ! b.sink autovideosink name=b
  • 1

看晕了吧?其实不复杂,听我继续道来…

3

gst-launch-1.0 的基本语法是

gst-launch-1.0 元素名称 属性=... 元素名称 属性=... ... 元素.SrcPad名称 ! 元素.SinkPad名称
  • 1

所以,根据我们上面的例子,可以写出下面的命令行:

gst-launch-1.0 videotestsrc autovideosink 
  • 1

没看错吧?元素之间竟然没有 符号。没错,命令行运行后并没出现语法错误,只是这个管道并不会工作,因为没有链接。此时,管道描述符包含两个部分:

  • 第一个元素:videotestsrc
  • 第二个元素:autovideosink

要建立连接,就需要给元素命名:

gst-launch-1.0 videotestsrc name=a autovideosink name=b
  • 1

当然,因为还没加入链接,当然还是不工作。此时,管道描述符仍然只包含两个部分:

  • 第一个元素:videotestsrc name=a
  • 第二个元素:autovideosink name=b

下面加入链接:

gst-launch-1.0 videotestsrc name=a autovideosink name=b a.src ! b.sink
  • 1

运行一下,OK,很完美。

4

注意到没有,这次连接的位置竟然与刚才的例子不一样。其实,gst-launch-1.0 不在乎排列顺序。这个例子中,管道描述串包括三个部分:

  • 第一个元素:videotestsrc name=a
  • 第二个元素:autovideosink name=b
  • 连接:a.src ! b.sink

这三个部分可以任意排列。这三个部分之间并没有标点符号,会不会弄混?仔细分析一下就能发现,不会。因为元素名称前后都是空格,没有其他符号。元素的属性赋值(比如 name=a)有等号连接,连接描述有感叹号连接。所以,尽管描述串很复杂,而且无序,但不会弄错。

所以,前面看到的那个例子,管道描述串中也是由上面三个部分构成,只是顺序调整了一下,让人觉得很神的样子。你看一下能分出来三个部分吗?

gst-launch-1.0 videotestsrc name=a a.src ! b.sink autovideosink name=b
  • 1

5

我们怎么能知道 videotestsrc 的 Pad 名称是 src?这个不难,用命令 gst-inspect-1.0 videotestsrc 查看即可。gst-inspect-1.0 是研究插件库的好工具,一定要用好!

使用 gst-inspect-1.0 我们发现, videotestsrc 有一个叫做 pattern 的属性,默认值是 0,最大值可以取到 24。接下来我们改成 1 看看:

gst-launch-1.0 videotestsrc pattern=1 ! autovideosink
  • 1

gst-launch-1.0 videotestsrc pattern=1 ! autovideosink

正如 gst-inspect-1.0 说的那样,这个是雪花 snow 模式!

6

刚才的例子,分辨率太低了,能不能转换成高清视频?当然没问题,我们利用 CAPS 转换,强迫 Pad 之间的连接通过我们指定的 CAPS 进行。看下面的例子:

gst-launch-1.0 videotestsrc ! video/x-raw, width=1920, height=1080 ! autovideosink
  • 1

也可以:

gst-launch-1.0 videotestsrc name=a autovideosink name=b a.src ! video/x-raw, width=1920, height=1080 ! b.sink
  • 1

需要注意两点:

  • a.src ! video/x-raw, width=1920, height=1080 ! b.sink 是一个链接,不可乱序
  • video/x-raw, width=1920, height=1080 是 CAPS 说明,其中的属性之间用逗号隔开。这个表示方法与元素是不一样的,元素的属性是用空格隔开的。

7

因为 CAPS 的属性可能很复杂,比如 video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12 这种里面带括号的,无法直接放到 gst-launch-1.0。另外,CAPS标识如果太简单也可能与元素无法区别。于是,这类 CAPS 必须用单引号或双引号括起来,明确告诉 gst-launch-1.0 这是一个 CAPS 说明。所以下面的例子也是合法的:

gst-launch-1.0 videotestsrc ! 'video/x-raw, width=1920, height=1080' ! autovideosink
gst-launch-1.0 videotestsrc ! "video/x-raw, width=1920, height=1080" ! autovideosink
  • 1
  • 2

到此为止,我觉得建立管道描述串的知识应该够用了,我不能再讲了,否则你知道的就太多了,哈哈哈哈!

谢谢阅读,如果有用,请点赞收藏,如有问题,欢迎留言!

================

补充知识:GStreamer 插件体系简介

GStreamer 系统一个很重要的想法就是把媒体流拆解成了插件,插件通过连接组合,构造出复杂的媒体流管道。

GStreamer 的插件是以动态库,也就是 .so 形式发布,原则上我们不需要其源代码。这些插件在 GStreamer 系统中注册以后,我们就可以通过其注册名称找到它们,也可以通过其名称加载 .so 库代码,并调用相关功能。

建立一个这样的注册体系是一个很复杂的事情,但是我们用起来却省了很多事。我们可以在没有这些插件源代码的情况下,灵活运用这些插件。用一个简单的字符串,构造出通常需要成千上万行代码才能写出的系统。前面的那一条例子,如果用 C 语言写代码实现的话,即使同样利用这些插件,也需要几十行甚至数百行代码才能实现。

所以, gst-launch-1.0 这条命令,实际上扮演了一个解释程序的角色,可以把管道描述字符串翻译成复杂的代码,最终按照要求为我们构建的媒体流管道。

在我开发用的 Jetson Nano 上,GStreamer 的插件安装在目录 /usr/lib/aarch64-linux-gnu/gstreamer-1.0 下,文件名是:libgstvideotestsrc.so。参见下面的截图:

在这里插入图片描述

可以用 gst-inspect-1.0 命令查看 GStreamer 系统注册的插件。当然,我们也可以自己编写插件,最基本的入门参见:


参考资料

posted @ 2023-03-10 09:42  thammer  阅读(437)  评论(0编辑  收藏  举报