GStreamer 简明教程(八):常用工具介绍

系列文章目录



前言

本章内容是对 GStreamer 官方教程中第九、十和十一三章的一个介绍。这几章涉及的代码不多,主要是介绍 GStreamer 中工具,包括 GstDiscoverer、gst-discoverer-1.0、gst-launch-1.0、gst-inspect-1.0 、日志工具等。这块可以扩展的内容比较少,但我又不想漏了这块,因此本文只是做一些粗粒度的总结。

一、GstDiscoverer

GstDiscoverer 是 pbutils 库(Plugin-Base 工具类)中的一个实用对象,它接受一个 URI 或 URI 列表,并返回有关它们的信息。它可以在同步或异步模式下工作。
它类似于 FFmpeg 中的 ffprobe 工具,用来获取媒体文件的信息,例如编解码器、视频分辨率、比特率等等
下面是 https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm 文件使用 GstDiscoverer 获取的结果

Duration: 0:00:52.250000000
Tags:
  video codec: On2 VP8
  language code: en
  container format: Matroska
  application name: ffmpeg2theora-0.24
  encoder: Xiph.Org libVorbis I 20090709
  encoder version: 0
  audio codec: Vorbis
  nominal bitrate: 80000
  bitrate: 80000
Seekable: yes
Stream information:
  container: WebM
    audio: Vorbis
      Tags:
        language code: en
        container format: Matroska
        audio codec: Vorbis
        application name: ffmpeg2theora-0.24
        encoder: Xiph.Org libVorbis I 20090709
        encoder version: 0
        nominal bitrate: 80000
        bitrate: 80000
    video: VP8
      Tags:
        video codec: VP8 video
        container format: Matroska

在代码中我们使用 GstDiscoverer 模块的相关 API 来获取信息,但 GStreamer 也提供了 gst-inspect-1.0 工具,与 ffprobe 类似,它是一个可执行程序,你可以运行它来获取信息(后面会再细说)。

GstDiscoverer API 使用请参考 basic-tutorial-9.c,我这边就不细说了,也没啥好说。

二、gst-launch-1.0、gst-discoverer-1.0、gst-inspect-1.0

这些工具位于 GStreamer 二进制文件的 bin 目录中。由于这个目录没有被添加到系统的 PATH 环境变量中(为了避免过度污染环境变量),你需要进入这个目录才能执行这些工具。

只需打开终端(或控制台窗口),进入 GStreamer 安装目录下的 bin 目录(重新阅读 GStreamer 安装部分以了解具体位置),就可以开始输入本教程中给出的命令了。

如果你是源码编译的,在运行这些工具之前,需要设置开发用的环境变量,关于开发环境变量我在 GStreamer 源码编译,在 Clion 下搭建调试环境 文中有提及。

2.1 gst-launch-1.0

gst-launch-1.0 是一个命令行工具,用于测试和调试GStreamer框架中的媒体管道。作为GStreamer项目的一部分,它允许用户通过命令行直接构建和运行媒体处理流水线,而无需编写完整的应用程序。这在开发和测试阶段特别有用,因为它能够快速验证GStreamer管道的正确性和性能。

以下是 gst-launch-1.0 的一些关键功能和特性:

  1. 管道创建:允许用户通过将不同的GStreamer元素连接起来描述一个多媒体管道。每个元素执行一个特定的功能,例如解码、编码、过滤及音视频同步等。

  2. 文本描述:用户通过文本形式描述管道,并且命令行解析器会实例化这些元素并创建实际的运行管道。

  3. 调试支持:作为一个调试工具,它可以帮助开发者快速发现和修复管道中的问题,比如元素不兼容或媒体格式不支持。

  4. 灵活性:由于GStreamer插件的模块化设计,gst-launch-1.0 可以立即支持新添加的插件和功能,无需修改工具本身。

  5. 跨平台:可在多种操作系统上运行,包括Linux、Windows和macOS,适用于开发跨平台多媒体应用程序的环境。

  6. 管道动态管理:可以通过动态参数调整和事件响应控制管道的行为。

gst-launch-1.0 通常用于调试和原型构建阶段,而在生产应用中,开发者更倾向于使用GStreamer的C语言API来实现更复杂和优化的多媒体处理任务。

请注意,它只能创建简单的管道。特别是,它只能在一定程度上模拟管道与应用程序的交互。不过,它对于快速测试管道非常方便,世界各地的 GStreamer 开发者每天都在使用它。

请注意,gst-launch-1.0 主要是面向开发者的调试工具。你不应该基于它构建应用程序。相反,应该使用 GStreamer API 中的 gst_parse_launch() 函数,作为从管道描述构建管道的简单方法。

2.1.1 使用说明

创建并连接元素

在简单形式下,管道描述(PIPELINE-DESCRIPTION)是由感叹号(!)分隔的元素类型列表

gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink

你应该能看到一个显示动画视频图案的窗口。在终端中使用 CTRL+C 可以停止程序。

设置属性
gst-launch-1.0 videotestsrc pattern=11 ! videoconvert ! autovideosink

属性可以附加到元素后,形式为property=value(可以指定多个属性,属性之间用空格分隔)。

pipeline 结构如下:

videotestsrc (pattern=11) --> videoconvert --> autovideosink
命名元素

可以使用 name 属性给元素命名,这样就可以创建包含分支的复杂管道。名称允许链接到在描述中较早创建的元素,对于使用具有多个输出端口的元素(如分离器或分流器)来说是必不可少的。

命名元素通过其名称后跟一个点来引用。

gst-launch-1.0 videotestsrc ! videoconvert ! tee name=t ! queue ! autovideosink t. ! queue ! autovideosink

pipeline 结构如下

videotestsrc --> videoconvert --> tee (name=t) -----> queue --> autovideosink
                                      |
                                      |
                                      +-------> queue --> autovideosink
Pads

在链接两个元素时,与其让GStreamer自行选择要使用的Pad,您可以直接指定Pad。您可以通过在元素名称后加上一个点和Pad名称来做到这一点(元素必须是已命名的)。使用gst-inspect-1.0工具可以了解元素的Pad名称。

例如,当您想从解复用器中获取特定的流时,这将非常有用:

gst-launch-1.0 souphttpsrc location=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! matroskademux name=d d.video_0 ! matroskamux ! filesink location=sintel_video.mkv

这将使用souphttpsrc从网络中获取一个媒体文件,该文件为webm格式(一种特殊的Matroska容器,参见基本教程2:GStreamer概念)。然后我们使用matroskademux打开该容器。这个媒体包含音频和视频,所以matroskademux将创建两个输出Pad,分别命名为video_0和audio_0。我们将video_0链接到一个matroskamux元素,以将视频流重新打包到一个新容器中,最后链接到一个filesink,它会将流写入名为"sintel_video.mkv"的文件中(location属性指定文件名)。

pipeline 结构如下:

souphttpsrc --> matroskademux (name=d) --[video_0]--> matroskamux --> filesink
(webm file)                                                          (sintel_video.mkv)

如果我们只想保留音频:

gst-launch-1.0 souphttpsrc location=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! matroskademux name=d d.audio_0 ! vorbisparse ! matroskamux ! filesink location=sintel_audio.mka
Caps filters

当一个元素有多个输出Pad时,链接到下一个元素可能会出现歧义:下一个元素可能有多个兼容的输入Pad,或者其输入Pad可能与所有输出Pad的Pad Caps兼容。在这些情况下,GStreamer将使用第一个可用的Pad进行链接,这基本上意味着GStreamer会随机选择一个输出Pad。

考虑以下管道:

gst-launch-1.0 souphttpsrc location=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! matroskademux ! filesink location=test

这是与前一个示例中相同的媒体文件和解复用器。filesink的输入Pad Caps是ANY,这意味着它可以接受任何类型的媒体。那么matroskademux的两个输出Pad中的哪一个会链接到filesink呢?是video_0还是audio_0?你无法知道。

不过,您可以通过使用命名的Pad(如前一小节中所述)或使用Caps过滤器来消除这种歧义:

gst-launch-1.0 souphttpsrc location=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! matroskademux ! video/x-vp8 ! matroskamux ! filesink location=sintel_video.mkv

Caps过滤器表现得像一个通道元素,它不做任何事情,只接受具有给定Caps的媒体,有效地解决了歧义。在这个例子中,在matroskademux和matroskamux之间,我们添加了一个video/x-vp8的Caps过滤器,以指定我们感兴趣的是matroskademux的能够产生此类视频的输出Pad。

要找出一个元素接受和产生的Caps,请使用gst-inspect-1.0工具。要找出包含在特定文件中的Caps,请使用gst-discoverer-1.0工具。要找出一个元素在特定管道中产生的Caps,像平常一样运行gst-launch-1.0,并使用–v选项来打印Caps信息。

示例

使用playbin播放媒体文件(如基本教程1:Hello world! 中所示):

gst-launch-1.0 playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm

一个完整的播放管道,带有音频和视频(与playbin内部创建的管道大致相同):

gst-launch-1.0 souphttpsrc location=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! matroskademux name=d ! queue ! vp8dec ! videoconvert ! autovideosink d. ! queue ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink

一个转码管道,它打开webm容器并解码两个流(通过uridecodebin),然后用不同的编解码器重新编码音频和视频分支,并将它们重新组合到一个Ogg容器中(仅为了演示)。

gst-launch-1.0 uridecodebin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm name=d ! queue ! theoraenc ! oggmux name=m ! filesink location=sintel.ogg d. ! queue ! audioconvert ! audioresample ! flacenc ! m.

一个重新缩放管道。当视频帧大小在输入和输出Caps中不同时,videoscale元素执行重新缩放操作。通过Caps过滤器将输出Caps设置为320x200。

gst-launch-1.0 uridecodebin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm ! queue ! videoscale ! video/x-raw-yuv,width=320,height=200 ! videoconvert ! autovideosink

这个关于gst-launch-1.0的简短描述应该足以让您入门。请记住,您可以在 Basic tutorial 10: GStreamer tools 获得完整的文档。

2.2 gst-inspect-1.0

gst-inspect-1.0 这个工具是常用的,在之前几章中我们使用它来查询元素的信息,该工具有三种操作模式:

  1. 如果不带参数,它会列出所有可用的元素类型,即可用于实例化新元素的类型。
  2. 如果带有文件名作为参数,它会将该文件视为一个GStreamer插件,尝试打开它,并列出其中描述的所有元素。
  3. 如果带有GStreamer元素名称作为参数,它会列出有关该元素的所有信息。

关于这个工具的更多内容参考 gst-inspect-1.0

2.3 gst-discoverer-1.0

这个工具是 GstDiscoverer 对象(在Basic tutorial 9: Media information gathering中有介绍)的一个包装器。它接受命令行中的 URI 并打印出 GStreamer 能够提取的所有媒体相关信息。它对于发现媒体使用了什么容器和编解码器很有用,从而帮助你确定在管道中需要放置哪些元素来播放它。

三、Debug 工具

3.1 日志等级

GStreamer 中有大量的日志,如果开放所有日志势必会影响性能,因此需要对日志进行分级,GStreamer 有 10 个日志等级

等级名称描述
0none不输出任何调试信息
1ERROR记录所有致命错误。这些错误会导致核心或元素无法执行请求的操作。如果应用程序编程时处理了触发错误的条件,仍然可以恢复。
2WARNING记录所有警告。通常这些不是致命的,但预计会发生用户可见的问题。
3FIXME记录所有"待修复"消息。这些通常表示已知不完整的代码路径被触发。在大多数情况下可能正常工作,但在特定情况下可能会出现问题。
4INFO记录所有信息性消息。这些通常用于系统中只发生一次的事件,或重要且罕见到需要在此级别记录的事件。
5DEBUG记录所有调试消息。这些是在对象生命周期内仅发生有限次数的事件的一般调试消息,包括设置、清理、参数更改等。
6LOG记录所有日志消息。这些是对象生命周期内重复发生的事件消息,包括流媒体和稳定状态条件。例如用于记录元素中每个缓冲区的日志消息。
7TRACE记录所有跟踪消息。这些是非常频繁发生的消息。例如,每次修改 GstMiniObject(如 GstBuffer 或 GstEvent)的引用计数时。
9MEMDUMP记录所有内存转储消息。这是最重量级的日志记录,可能包括内存块内容的转储。

要启用调试输出,可以将环境变量 GST_DEBUG 设置为所需的调试级别。所有低于该级别的消息也将被显示(例如,如果设置 GST_DEBUG=2,您将获得 ERROR 和 WARNING 消息)。

此外,GStreamer 的每个插件或部分都定义了自己的分类,因此您可以为每个单独的分类指定调试级别。例如,GST_DEBUG=2,audiotestsrc:6 将为 audiotestsrc 元素使用调试级别 6,而其他所有元素使用级别 2。

因此,GST_DEBUG 环境变量是一个以逗号分隔的 category:level 对的列表,开头可选择一个级别,代表所有分类的默认调试级别。

还提供了 ‘’ 通配符。例如 GST_DEBUG=2,audio:6 将对所有以 audio 开头的类别使用调试级别 6。GST_DEBUG=*:2 相当于 GST_DEBUG=2。

还可以通过 GST_DEBUG_FILE 环境变量将日志重定向到文件中,然后再进行排查,例如:

export GST_DEBUG_FILE=debug.log
export GST_DEBUG=2
gst-launch-1.0 videotestsrc ! autovideosink

在我们排查 GStreamer 内存泄漏的时候,可以设置 GST_DEBUG=“GST_TRACER:7” 和 GST_TRACERS=“leaks” 一起使用。所以这个组合的意义是:

  • GST_TRACERS 告诉 GStreamer 要使用什么跟踪器

  • GST_DEBUG 确保跟踪器的输出信息能够被看到
    这就像是:

  • GST_TRACERS 是安装了监控摄像头

  • GST_DEBUG 是打开了显示器来查看监控画面

3.2 日志设置自己的 TAG

在 Android 日志中我们常设置一个 TAG 来标识不同的日志,这是很常见的用法,方面过滤掉其他我们不感兴趣的日志

  1. Android 日志写法:
// Android
private static final String TAG = "my_category";
Log.d(TAG, "debug message");
Log.e(TAG, "error message");
  1. GStreamer 日志写法:
// GStreamer
// 1. 首先定义你的 TAG
GST_DEBUG_CATEGORY_STATIC (my_category);
#define GST_CAT_DEFAULT my_category

// 2. 在初始化时注册这个 TAG
GST_DEBUG_CATEGORY_INIT (my_category, "my category", 0, "This is my very own");

// 3. 使用这个 TAG 输出日志
GST_DEBUG("debug message");    // 等同于 Log.d
GST_ERROR("error message");    // 等同于 Log.e

主要区别:

  • Android 中直接使用字符串作为 TAG
  • GStreamer 需要先注册 TAG,然后才能使用
  • GStreamer 的方式可以更好地进行分类管理和级别控制

使用场景示例:

// 定义 TAG
GST_DEBUG_CATEGORY_STATIC (my_player);
#define GST_CAT_DEFAULT my_player

int main() {
    // 初始化 GStreamer
    gst_init(&argc, &argv);
    
    // 注册 TAG
    GST_DEBUG_CATEGORY_INIT (my_player, "MyPlayer", 0, "Custom player debug");
    
    // 使用自定义 TAG 输出日志
    GST_DEBUG("Player initializing...");
    GST_ERROR("Failed to load media");
    GST_INFO("Playback started");
}

这样的好处是:

  1. 可以更好地组织和过滤日志
  2. 可以针对特定 TAG 设置不同的日志级别
  3. 更容易定位和调试问题

3.3 导出 pipeline

GStreamer 支持导出 pipeline 结构为 .dot 文件,你可以使用 GraphViz 这样的工具来查看(这里推荐一个在线 GraphViz 网站:https://sketchviz.com/new)

这在使用像 playbin 或 uridecodebin 这样的多功能元素时特别有用,因为这些元素内部会实例化多个元素。你可以使用 .dot 文件来了解它们在内部创建了什么样的管道(同时也可以学习一些 GStreamer 的知识)。

3.1 基本设置

# 设置输出目录
export GST_DEBUG_DUMP_DOT_DIR=/path/to/your/folder

3.2在命令行中使用

# 运行 gst-launch-1.0,将自动在状态变化时生成 .dot 文件
gst-launch-1.0 videotestsrc ! autovideosink

3.3 在代码中使用

// 不带时间戳的版本
GST_DEBUG_BIN_TO_DOT_FILE(pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");

// 带时间戳的版本
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");

3.4 查看生成的文件

# 转换 .dot 文件为图片
dot -Tpng pipeline.dot > pipeline.png

或者在 https://sketchviz.com/new 中在线查看

3.5 禁用此功能

# 取消环境变量设置
unset GST_DEBUG_DUMP_DOT_DIR

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值