Basic tutorial 10: GStreamer 工具

Basic tutorial 10: GStreamer tools

目标

GStreamer附带了一系列工具,从基本必备的工具到方便灵活的小工具,应有尽有。本章教程无代码,将讲解如下内容:

  • 无需任何C代码,如何从命令行构建和运行一个GStreamer的pipelines
  • 如何找出可用的GStreamer elements(元素)及其capabilities(能力)
  • 如何发现媒体文件的内部结构

gst-launch-1.0

该工具接受文本形式描述的pipeline,实例化它,并且将此pipeline设置为PLAYING状态。它可以让你在使用GStreamer API调用前迅速的验证给定的pipeline是否能正常工作。

请记住,它只能创建简单的pipeline(管道)。特别是,它只能模拟管道与应用程序在一定级别上的交互。在任何情况下,快速测试pipeline(管道)都非常方便,全球的GStreamer开发人员每天都在使用它。

请注意,gst-launch-1.0主要是作为开发人员的调试工具。你不应该使用它构建应用程序。你应该使用GStreamer的APIgst_parse_launch()函数来构建管道。

尽管构建pipeline的描述规则非常简单,但是包含多个elements连接的描述规则可能又会变得复杂起来。

gst-launch-1.0的命令行包含一个选项列表,后面跟着一个PIPELINE-DESCRIPTION。下面给出了一些简化的说明,请参阅gst-launch-1.0的参考页上的完整文档。

Elements(元素)

简单来说,PIPELINE-DESCRIPTION是由感叹号(!)分隔开的elements类型列表,如下面这个示例:

gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink

你应该看到一个带有动画视频模式的窗口。在终端上使用CTRL+C停止程序。这个实例创建了一个videotestsrc的element(生成测试视频的element),一个videoconvert的element(原始视频格式转化的element,确保在它左右两端的element可以相互理解,其实就是协商成功)和一个autovideosink的element(根据系统软硬件环境自动选择合适的video sink)。然后,GStreamer尝试按照列出的顺序将各element连接起来(将左边element的src连到右边element的sink)。如果element有多个可用的Pad,这时会尝试通过PadCaps来匹配兼容的Pad对(左边element的src和右边element的sink)。

Properties(属性)

Properties可用附加到Elements后面,格式为property=value(可指定多个property,用空格分隔)。使用gst-inspect-1.0工具(下面将介绍)可查看element的可用property。

gst-launch-1.0 videotestsrc pattern=11 ! videoconvert ! autovideosink

您应该会看到一个由圆圈组成的静态测试视频。

Named elements(有名元素)

之前的教程说过任何一个element都包含一个name属性,它是一个字符串,继承自GstObject。可以使用name属性命名element,这样就可以创建涉及多分支的复杂pipeline。可以通过names引用在之前描述中创建的element,并且对于使用具有多个输出pad的element,names是必不可少的,例如demuxers或tee。

引用已命名的element时只要在它的names后面跟个点号(.)。示例如下:

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

您应该看到两个视频窗口,显示相同的测试视频。如果你只看到一个,试着移动它,因为它可能在第二个窗口的顶部。

这个例子实例化了一个videotestsrc,它链接到一个videoconvertvideoconvert又链接到一个tee(还记得基础教程7:多线程和Pad可用性,tee将所有通过其输入Pad的内容复制到每个输出Pad)。tee被简单地命名为“t”(使用name属性),然后链接到一个queue和一个autovideosink。同样的tee也用t.来引用。’(注意这个点),然后链接到第二个queue和第二个autovideosink

要了解为什么queue是必要的,请阅读基础教程7:多线程和Pad可用性。

Pads(链接点)

在链接两个element时,您可能希望直接指定Pad,而不是让GStreamer选择使用哪个Pad。你可以在element名称后加上一个点加上Pad名称(类似于结构体的成员引用,它必须是一个namedelement)来做到这一点。使用gst-inspect-1.0工具了解element的pad名称。

这很有用,例如,当你想从demuxer中检索一个特定的流时:

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

包含媒体数据的文件一般叫做container,例如mp4,ogg,avi等。它们可以包含1个或者多个流,如视频,音频,字幕,同类型的流也可以有多个存在。

上面例子使用souphttpsrc从网络上获取一个媒体文件,格式是webm。我们使用matroskademux打开这个container文件,此文件包含音频和视频,因此matroskademux会生成2个输出类型的pad(src pad),会被自动命名为video_0audio_0

为啥会是这种格式的pad名呢?通过gst-inspect-1.0看到matroskademuxPad Templates:

Pad Templates:
SRC template: 'video_%u'
Availability: Sometimes
Capabilities:
ANY

SRC template: 'audio_%u'
Availability: Sometimes
Capabilities:
ANY

SRC template: 'subtitle_%u'
Availability: Sometimes

SRC template就指定了它的命名格式,类似于printf的格式化

我们将video_0链接到一个matroskamux element,将视频流重新打包到一个新的container中,最后将其链接到一个filesink,该element将把视频流写入名为“sintel_video.mkv”的文件中。(location属性指定文件的名称)。

总而言之,我们取了一个webm文件,去掉了音频数据,并将视频数据生成到一个新的matroska格式文件。如果我们只想保留音频:

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

vorbisparse 元素需要从流中提取一些信息并将其放入Pad Caps中,以便下一个元素matroskamux知道如何处理流。在视频的情况下,这是不必要的,因为matroskademux已经提取了该信息并将其添加到Caps中。

注意,在上面的两个例子中,没有媒体文件被解码或播放。我们只是从一个容器移动到另一个容器(多次进行demux和mux操作)。

这里又涉及到一个概念mux和demux,复用和解复用。从一个container中分离出流的过程就叫做demux,把1个或多个流整到一个container的过程就叫mux。

需要注意,这里为啥处理视频选择matroskamux, matroskademu,处理音频使用vorbisparse?其实是根据sintel_trailer-480p.webm这个文件来的,为了方便演示,提前获取了这个container里面包含的流的格式,然后直接使用对应格式的muxer、demuxer、parser。正常情况下,是通过一个叫findtype的element探测的。使用GStreamer的另一个工具gst-discoverer-1.0可以查看container的里面包含的流信息。

我们把这个文件下下来,然后用gst-discoverer-1.0查看

wget https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm
gst-discoverer-1.0 sintel_trailer-480p.webm
Analyzing file:///home/a/Videos/sintel_trailer-480p.webm
Done discovering file:///home/a/Videos/sintel_trailer-480p.webm

Topology:
  container: WebM
    audio: Vorbis
    video: VP8

Properties:
  Duration: 0:00:52.250000000
  Seekable: yes
  Live: no
  Tags: 
      container format: Matroska
      language code: en
      title: Audio, Sintel Trailer, Audio, Audio, Sintel Trailer
      encoder: Xiph.Org libVorbis I 20090709
      bitrate: 80000
      artist: Durian Open Movie Team
      copyright: (c) copyright Blender Foundation | durian.blender.org
      license: Creative Commons Attribution 3.0 license
      video codec: VP8 video
      application name: ffmpeg2theora-0.24
      encoder version: 0
      audio codec: Vorbis
      nominal bitrate: 80000

Caps filters(Caps过滤器)

当一个element有多个输出pad时(src pad),可能出现链接到下一个element时不明确到底该用哪个pad的情况:下一个element可能包含多个兼容的输入pad(sink pad),或者只有个输入pad,但是这个输入pad与前面那个element的多个输出pad兼容。在这种情况下GStreamer将使用第一个可用的pad进行链接,可以认为此时选择哪个输出pad是随机的。

如下pipeline:

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

这个例子中媒体文件和demuxer和上一个例子是一样的。filesink的输入pad的Caps是ANY,意味着它可以接受任何类型的媒体。那matroskademux的2个输出pad哪个会链接到filesink 呢?video_0还是audio_0?不得而知。

不过,你可以通过named pad,或者caps filters来消除这里的模糊性:

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

Caps filter的行为就像一个直通的element,它啥也不做,仅仅接受带有指定Caps的媒体,有效的消除了歧义。在这个例子中,在matroskademuxmatroskamux之间,我们添加了一个video/x -vp8的caps filter来指定我们感兴趣的输出pad,这样它就可以产生这种格式的视频。

要找出element接受和产生的Caps,可以使用gst-inspect-1.0工具。要找出特定文件中包含的Caps,请使用gst-discoverer-1. 0。要找出element为特定pipeline生成的Caps,可以像往常一样运行gst-launch-1.0,并使用-v选项打印Caps信息。

例子

使用playbin播放一个媒体文件:

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

完整的回放pipeline构建,带音、视频操作:

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

一个转码pipeline,它打开webm格式的容器文件,并且解码每个流(通过uridecodebin),然后再用不同的编解码器重新编码音视频流分支,最后由oggmux重新mux到一个ogg文件中。

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

一个缩放pipeline,当输入和输出帧的大小不同时,videoscale执行缩放操作,输出caps通过caps filter设置为320x200

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

gst-launch-1.0的简短描述应该足以让您入门,完整的文档,请查看

gst-inspect-1.0

该工具有三种操作模式:

  • 如果没有参数,它会列出所有可用的element类型,也就是可以用来实例化新element的类型。
  • 使用文件名作为参数,它将该文件视为GStreamer插件,尝试打开它,并列出其中描述的所有elements。
  • 使用GStreamer element名作为参数,它列出了关于该element的所有信息。

一个使用第三种模式的例子:

gst-inspect-1.0 vp8dec

Factory Details:
  Rank                     primary (256)
  Long-name                On2 VP8 Decoder
  Klass                    Codec/Decoder/Video
  Description              Decode VP8 video streams
  Author                   David Schleef <ds@entropywave.com>, Sebastian Dröge <sebastian.droege@collabora.co.uk>

Plugin Details:
  Name                     vpx
  Description              VP8 plugin
  Filename                 /usr/lib64/gstreamer-1.0/libgstvpx.so
  Version                  1.6.4
  License                  LGPL
  Source module            gst-plugins-good
  Source release date      2016-04-14
  Binary package           Fedora GStreamer-plugins-good package
  Origin URL               http://download.fedoraproject.org

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstVideoDecoder
                         +----GstVP8Dec

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-vp8

  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw
                 format: I420
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]


Element Flags:
  no flags set

Element Implementation:
  Has change_state() function: gst_video_decoder_change_state

Element has no clocking capabilities.
Element has no URI handling capabilities.

Pads:
  SINK: 'sink'
    Pad Template: 'sink'
  SRC: 'src'
    Pad Template: 'src'

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: "vp8dec0"
  parent              : The parent of the object
                        flags: readable, writable
                        Object of type "GstObject"
  post-processing     : Enable post processing
                        flags: readable, writable
                        Boolean. Default: false
  post-processing-flags: Flags to control post processing
                        flags: readable, writable
                        Flags "GstVP8DecPostProcessingFlags" Default: 0x00000403, "mfqe+demacroblock+deblock"
                           (0x00000001): deblock          - Deblock
                           (0x00000002): demacroblock     - Demacroblock
                           (0x00000004): addnoise         - Add noise
                           (0x00000400): mfqe             - Multi-frame quality enhancement
  deblocking-level    : Deblocking level
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 16 Default: 4
  noise-level         : Noise level
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 16 Default: 0
  threads             : Maximum number of decoding threads
                        flags: readable, writable
                        Unsigned Integer. Range: 1 - 16 Default: 0

最关键的部分是:

  • Pad Templates:这里列出了该element可以拥有的所有类型的pad,以及它们的功能。这是查找一个element是否可以与另一个element链接的地方。在这种情况下,它只有一个sink pad模板,只接受video/x-vp8(VP8格式的编码视频数据),只有一个src pad模板,产生视频/x-raw(解码的视频raw数据)。
  • Element Properties:这将列出element的属性,以及它们的类型和可接受的值,可读可写等。

更完整的文档,请查看

gst-discoverer-1.0

该工具接受来自命令行的URI,并打印关于GStreamer可以提取的媒体的所有信息。了解使用了哪些容器和编解码器来生成媒体,以及需要在pipeline中放入哪些元素来播放媒体是很有用的。-v选项可输出更详细的信息。

posted @ 2023-03-08 20:34  thammer  阅读(258)  评论(0编辑  收藏  举报