首页 > 其他分享 >走向必然王国:如何有把握地构建 GStreamer 管道?

走向必然王国:如何有把握地构建 GStreamer 管道?

时间:2023-03-10 10:57:36浏览次数:48  
标签:1.0 gst omxh264enc GStreamer omxh264dec 有把握 管道 videotestsrc 必然王国

本文转载自许野平的博客

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

GStreamer 是一款非常优秀的媒体流构建工具。由于相关参考资料缺乏,官网介绍不够详尽,初学者往往费尽周折,也搞不定一个定制的管道架构,最后只好从网络上东拼西凑,摸着别人的例子过河。

如果您有类似的困惑,本文将带领您走出这个困境,迈出正确构建 GStreamer 管道的第一步。

1. 最简单的视频管道

由于一个管道至少有一个起点和一个终点,因此最简单的管道至少有两个元素,一个用来做 src(流的起点),另一个做 sink(流的终点)。

  • videotestsrc:提供测试视频信号源。它绝对不会出错,可以提供可靠、稳定的信号源。
  • autovideosink:可以把为压缩编码的视频信号显示在屏幕上。我用的是 Jetson Nano 硬件平台,这个元素直接把画面全屏显示了。

我们把它两个连接起来,用下面的命令测试一下。

$ gst-launch-1.0 videotestsrc ! autovideosink
  • 1

屏幕显示如下信号:
在这里插入图片描述

这个让我想起三十多年前当电视机维修工的时候,用的那个视频信号发生器,输出的就是类似这样的信号。人生如梦,当年手拿烙铁和万用表的时候,老子怎么也没想到将来有一天会靠敲键盘在机器视觉行业混饭。

2. 自己创建一个问题

我打算做个简单的实验,在 videotestsrc 后面加上一个 h.264 编码器,然后再紧跟一个 h.264 解码器。我觉得这个效果应该和上面的例子一样——因为图像编码后再解码,等于啥也没做。

输入下面的命令后,一大堆错误信息,让我瞬间崩溃了:

$ gst-launch-1.0 videotestsrc ! omxh264enc ! omxh264dec ! autovideosink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Framerate set to : 30 at NvxVideoEncoderSetParameterNvMMLiteOpen : Block : BlockType = 4
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
H264: Profile = 66, Level = 40
ERROR: from element /GstPipeline:pipeline0/GstOMXH264Enc-omxh264enc:omxh264enc-omxh264enc0: Internal data stream error.
Additional debug info:
/dvs/git/dirty/git-master_linux/3rdparty/gst/gst-omx/omx/gstomxvideoenc.c(1383): gst_omx_video_enc_loop (): /GstPipeline:pipeline0/GstOMXH264Enc-omxh264enc:omxh264enc-omxh264enc0:
stream stopped, reason not-negotiated
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3. 有用的 fakesink

GStreamer 提供了一个万能的管道终点元素 fakesink。这个元素对输入数据没有任何要求,来者不拒,同时,它啥工作也不做,感觉就是个黑洞,任何数据到它这里都接受,也不做任何处理,然后就没有然后了。因此,它前面可以对接任何合理的元素。

fakesink 的作用在于,可以在任何位置让你正在构建的管道合法地结束。这可以让我们采用增量方式,步步为营,慢慢增加管道长度,直到完整地构建出管道。

例如,为了正确构建上面的例子,我输入下面这两行命令,都是可以正常执行的。这说明管道的 videotestsrc ! omxh264enc 这一部分是可以正常工作的。

$ gst-launch-1.0 videotestsrc ! fakesink
$ gst-launch-1.0 videotestsrc ! omxh264enc ! fakesink
  • 1
  • 2

但是下面这一行就不行了:

$ gst-launch-1.0 videotestsrc ! omxh264enc ! omxh264dec ! fakesink
  • 1

这说明,元素 omxh264dec 与管道前面的那个部分不能衔接。接下来我们分析一下原因。

4. gst-inspect-1.0:随手可得的元素/插件说明书

我们用下面两行命令查看 omxh264enc 和 omxh264dec 的说明,重点查看 omxh264enc 的输出数据(src pad caps)和 omxh264dec 的输入数据 (sink pad caps) 的兼容性。为了便于理解,下面的屏幕输出内容我做了删减。

$ gst-inspect-1.0 omxh264enc 
...
Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-h264
                  width: [ 16, 4096 ]
                 height: [ 16, 4096 ]
          stream-format: { (string)byte-stream, (string)avc }
              alignment: au
...

$ gst-inspect-1.0 omxh264dec
...
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-h264
parsed: true
alignment: au
stream-format: byte-stream
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
...

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

看出区别了吗?omxh264dec 要求输入数据必须满足 parsed=true,而元素 omxh264enc 却不提供这个保障。

顾名思义,这说明 omxh264enc 的输出结果需要进一步解析后,才能发送给 omxh264dec 解码。查找一些 h.264 数据解析插件,发现 h265parse 符合要求。于是我们构造下面的命令:

$ gst-launch-1.0 videotestsrc ! omxh264enc ! h264parse ! omxh264dec ! autovideosink
  • 1

运行后,非常完美。忽然又突发奇想,再长一些行不行?输入下面的命令:

$ gst-launch-1.0 videotestsrc ! omxh264enc ! h264parse ! omxh264dec ! omxh264enc ! h264parse ! omxh264dec ! autovideosink
  • 1

依旧完美!OK,从今天起,我们可以借助 gst-inspect-1.0 和 fakesink 这两个工具,逐步排查管道连接中存在的 caps 协商异常问题,建立可靠的媒体流管道。如果本文对您有帮助,请点赞、收藏,谢谢!

标签:1.0,gst,omxh264enc,GStreamer,omxh264dec,有把握,管道,videotestsrc,必然王国
From: https://www.cnblogs.com/thammer/p/17202603.html

相关文章

  • Basic tutorial 10: GStreamer 工具
    Basictutorial10:GStreamertools目标GStreamer附带了一系列工具,从基本必备的工具到方便灵活的小工具,应有尽有。本章教程无代码,将讲解如下内容:无需任何C代码,如何从......
  • gstreamer样例
    #!/bin/bashxrandr-s0--outputDSI-1xrandr-s0--outputHDMI-1xrandr--fb1024x600--outputDSI-1--mode1024x600--panning0x0*xrandr--outputHD......
  • Ubuntu 的源相关介绍(最近在配gstreamer的时候,紧急补充的知识)
    PS:要转载请注明出处,本人版权所有。PS:这个只是基于《我自己》的理解,如果和你的原则及想法相冲突,请谅解,勿喷。前置说明  本文作为本人csdnblog的主站的备份。(BlogID......
  • GStreamer基础教程13 - 调试Pipeline
    摘要在很多情况下,我们需要对GStreamer创建的Pipeline进行调试,来了解其运行机制以解决所遇到的问题。为此,GStreamer提供了相应的调试机制,方便我们快速定位问题。 查......
  • GStreamer系列 - 基本介绍
    什么是Gstreamer?Gstreamer是一个支持Windows,Linux,Android,iOS的跨平台的多媒体框架,应用程序可以通过管道(Pipeline)的方式,将多媒体处理的各个步骤串联起来,达到预期的效果。......
  • GStreamer基础教程01 - Hello World
    摘要在面对一个新的软件库时,第一步通常实现一个“helloworld”程序,来了解库的用法。对于GStreamer,我们可以实现一个极简的播放器,来了解GStreamer的使用。 环境配置为......
  • GStreamer基础教程02 - 基本概念
    摘要在 Gstreamer基础教程01-HelloWorld中,我们介绍了如何快速的通过一个字符串创建一个简单的pipeline。为了能够更好的控制pipline中的element,我们需要单独创建eleme......
  • GStreamer基础教程03 - 媒体类型与Pad
    摘要在上一篇文章中,我们介绍了如何将多个element连接起来构造一个pipline,进行数据传输。那么GStreamer是通过何种方式保证element之间能正常的进行数据传输?今天就将介......
  • c++ gstreamer使用2
    1,播放教程playbin#include<gst/gst.h>#include<stdio.h>/*Structuretocontainallourinformation,sowecanpassitaround*/typedefstruct_CustomData......
  • gstreamer 基础知识
    Gstreamer基础知识1.Gstreamer组件创建一个Gstelement办法是借助于GstElementFactory工厂对象。//mad是工厂对象的名称decoder是创建出element的名字。e......