目标
有时,程序不能按照预期的执行并且从bus检索到的错误消息也不能提供足够多的信息。幸运的是,GStreamer携带有大量的调试信息,这些信息通常会提示我们可能存在的问题。这个教程的目标:
- 怎样从GStreamer获取到更多的debug 信息。
- 怎么样打印自己的debug信息到GStreamer 日志。
- 怎样获取到管道的图表。
打印debug信息
debug日志
GStreamer和它的插件充满了调试信息的跟踪。这就是说,在代码中的位置,有一段特别有趣的信息片段被打印到控制台,以及时间戳、流程、类别、源代码文件、功能和元素信息。
调试输出由GST_DEBUG环境变量控制。下面是GST_DEBUG=2的例子:
0:00:00.868050000 1592 09F62420 WARN filesrc gstfilesrc.c:1044:gst_file_src_start:<filesrc0> error: No such file "non-existing-file.webm"
如你所见,这是相当多的信息。事实上,GStreamer调试日志非常冗长,当完全启用它时,它可能会导致应用程序没有响应(由于控制台滚动)或填满数兆字节的文本文件(当重定向到一个文件时)。因此,日志是分类的,您很少需要一次启用所有分类。
第一类是调试级别,它是一个指定所需输出数量的数字:
# | 名称 | 描述 |
0 | none | 无debug 信息输出. |
1 | ERROR | 记录所有致命的错误,这些错误不允许内核或元素去执行别请求的action。如果编程去处理错误触发的条件,应用程序仍然可以修复。 |
2 | WARNING | 记录所有的警告。代表性的指那些非致命的错误,除了将要发生的且用户可见的问题。 |
3 | FIXME | 记录所有"fixme"信息。通常情况下,已知不完整的代码路径已被触发。它在大多数情况下可能有效,但在特定的情况下可能会导致问题。 |
4 | INFO | 记录所有信息性的消息。通常情况下用于在系统中只发生一次的事件。或者是在这个level下的足够重要或罕见的信息。 |
5 | DEBUG | 记录所有debug消息。那些通常的dubug消息用于在一个对象的生命周期内,发生有限次数的事件。这些包括:安装(setup),卸载(teardown),参数的改变等。 |
6 | LOG | 记录所有日志信息。这些消息用于对象生命周期内反复发生的事件;这包括流动和steady-state条件。例如,这用于在元素中的每个缓冲区中发生的日志消息。 |
7 | TRACE | 记录所有跟踪消息。这些都是经常发生的信息。例如,每次修改GstMiniObject(如GstBuffer或GstEvent)的引用计数时。 |
9 | MEMDUMP | 记录所有内存转储消息。这是最重的日志记录,可能包括转储内存块的内容。 |
为了使能debug输出,设置GST_DEBUG环境变量来设置为所需的调试级别。也将显示低于该级别的所有级别(即,如果您设置GST_DEBUG=2
,您将同时收到ERROR
和 WARNING
消息)。
此外,每个插件或 GStreamer 的一部分都定义了自己的类别,因此您可以为每个单独的类别指定调试级别。例如,GST_DEBUG=2,audiotestsrc:6
,
将对audiotestsrc
元素使用调试级别 6 ,对所有其他元素使用调试级别2。
GST_DEBUG 环境变量是一个以逗号分隔的 category:level 对列表,开头有一个可选的 level,代表所有类别的默认调试级别。
'*' 通配符也可用。例如 GST_DEBUG=2,audio*:6 将对以单词 audio 开头的所有类别使用调试级别 5。 GST_DEBUG=*:2 相当于 GST_DEBUG=2。
使用 gst-launch-1.0 --gst-debug-help 获取所有已注册类别的列表。请记住,每个插件都注册了自己的类别,因此,在安装或删除插件时,此列表可能会发生变化。
当 GStreamer 总线上发布的错误信息无法帮助您确定问题时,请使用 GST_DEBUG。通常的做法是将输出日志重定向到一个文件,然后稍后检查它,搜索特定消息。
GStreamer 允许自定义调试信息处理程序,但使用默认处理程序时,调试输出中每一行的内容如下所示:
0:00:00.868050000 1592 09F62420 WARN filesrc gstfilesrc.c:1044:gst_file_src_start:<filesrc0> error: No such file "non-existing-file.webm"
//对应的关系:
//时间戳 发出消息的进程ID 发出消息的线程ID 调试信息的等级 调试消息的种类 GStreamer源码的源文件和行号 发出消息的函数 发出消息的对象名 真正的消息
添加自己的调试信息
在与 GStreamer 交互的代码部分,使用 GStreamer 的调试工具很有趣。通过这种方式,您将所有调试输出保存在同一个文件中,并且保留了不同消息之间的时间关系。
为此,请使用 GST_ERROR()、GST_WARNING()、GST_INFO()、GST_LOG() 和 GST_DEBUG() 宏。它们接受与 printf 相同的参数,并使用默认类别(默认将在输出日志中显示为 Debug 类别)。
要将类别更改为更有意义的内容,请在代码顶部添加这两行:
GST_DEBUG_CATEGORY_STATIC (my_category);
#define GST_CAT_DEFAULT my_category
然后是在您使用 gst_init() 初始化 GStreamer 之后的这个:
GST_DEBUG_CATEGORY_INIT (my_category, "my category", 0, "This is my very own");
这会注册一个新类别(这是在您的应用程序期间:它不存储在任何文件中),并将其设置为您的代码的默认类别。请参阅 GST_DEBUG_CATEGORY_INIT() 的文档。
获取管道图
对于那些管道开始变得太大并且您无法跟踪什么与什么相关联的情况,GStreamer 具有输出图形文件的能力。这些是 .dot 文件,可以使用 GraphViz 等免费程序读取,这些文件描述了管道的拓扑结构,以及每个链接中协商的上限。
这在使用 playbin 或 uridecodebin 等多合一元素时也非常方便,实例化其中的几个元素。使用 .dot 文件了解他们在内部创建了什么管道(并在此过程中学习了一些 GStreamer)。
要获取 .dot 文件,只需将 GST_DEBUG_DUMP_DOT_DIR 环境变量设置为指向要放置文件的文件夹。gst-launch-1.0 将在每次状态更改时创建一个 .dot 文件,因此您可以看到 caps 协商的演变。取消设置变量以禁用此功能。在您的应用程序中,您可以在方便时使用 GST_DEBUG_BIN_TO_DOT_FILE() 和 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS() 宏来生成 .dot 文件。