管道技术训练计划(gstreamer)

本文介绍了GStreamer在Ubuntu 16.04上的安装步骤及常见问题解决方法,并通过实例详细讲解了GStreamer的基本概念、管道搭建以及声音播放测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先参考官网(ubuntu16.04安装会有问题)和部分博客入门,形成对gstreamer的认识!

1.安装

gstreamer对应的github推荐使用packages安装,而不是自己编译,原文如下:

INSTALLING FROM PACKAGES
------------------------

You should always prefer installing from packages first.  GStreamer is
well-maintained for a number of distributions, including Fedora, Debian,
Ubuntu, Mandrake, Gentoo, ...

Only in cases where you:
- want to hack on GStreamer
- want to verify that a bug has been fixed
- do not have a sane distribution
should you choose to build from source tarballs or git.

因此,ubuntu16.04系统下,可采用:

sudo apt-cache search gstreamer    #查询系统源(比如我设置的清华镜像源)中包含的gst

sudo apt-get install gstreamer1.0*   #安装上述搜索的packages

上述步骤中install可能会有错误 ,比如我的:

The following packages have unmet dependencies:
 gstreamer1.0-hybris:i386 : Depends: libmedia1:i386 but it is not going to be installed

通常ubuntu安装包分为amd64(64bit)和i386(32bit)两种,这里需要在64位的系统上安装i386的包 ,因此需要手动安装。安装原则:提示差什么包就安装什么包,如这里需要安装libmedia1:i386

sudo apt-get install libmedia1:i386

2.概念

博客中写的太好,所以摘抄一段!!!

2.1 GstElement是组成管道的基本构件;

可细分3类Source Element 数据源元件只有输出端,它仅能用来产生供管道消费的数据,而不能对数据做任何处理。一个典型的数据源元件的例子是音频捕获单元,它负责从声卡读取原始的音频数据,然后作为数据源提供给其它模块使用。
Filter Element 过滤器元件既有输入端又有输出端,它从输入端获得相应的数据,并在经过特殊处理之后传递给输出端。一个典型的过滤器元件的例子是音频编码单元,它首先从外界获得音频数据,然后根据特定的压缩算法对其进行编码,最后再将编码后的结果提供给其它模块使用。
Sink Element 接收器元件只有输入端,它仅具有消费数据的能力,是整条媒体管道的终端。一个典型的接收器元件的例子是音频回放单元,它负责将接收到的数据写到声卡上,通常这也是音频处理过程中的最后一个环节。

å¾1

现在有了组成管道的基本构件GstElement,那么怎么与外界连接呢?就得用到衬垫(pad)

2.2 pad是元件(element)与外界的连接通道,对于框架中的某个特定元件来说,其能够处理的媒体类型正是通过衬垫暴露给其它元件的。

现在本来已经可以使用管道(pipeline)技术了,但是gstreamer还把上面的几种Element装到一个箱子里面,方便统一管理,于是就有了bin

2.3 bin是GStreamer框架中的容器元件,它通常被用来容纳其它的元件对象,但由于其自身也是一个GstElement对象,因此实际上也能够被用来容纳其它的箱子对象。

å¾3

3.gstreamer测试

测试源文件test.c

#include <stdio.h>
#include <gst/gst.h>

int main (int   argc, char *argv[])
{
  const gchar *nano_str;
  guint major, minor, micro, nano;

  gst_init (&argc, &argv);

  gst_version (&major, &minor, &micro, &nano);

  if (nano == 1)
    nano_str = "(CVS)";
  else if (nano == 2)
    nano_str = "(Prerelease)";
  else
    nano_str = "";

  printf ("This program is linked against GStreamer %d.%d.%d %s\n",
          major, minor, micro, nano_str);

  return 0;
}

编译CMakeLists.txt

用到了pkg-config查找库信息(包括库的路径、头文件路径),官网解释:

It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c `pkg-config --libs --cflags glib-2.0`for instance, rather than hard-coding values on where to find glib (or other libraries).

命令测试:

pkg-config --libs --cflags glib-2.0

输出:-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 (字体有点看不出来,前两个-I是头文件路径,后一个-l是库路径)

cmake_minimum_required(VERSION 2.8)

project(gst)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0)
include_directories(
  ${GLIB_INCLUDE_DIRS}
)
link_directories(
  ${GLIB_LIBRARY_DIRS}
)
set(GSTREAMER_MINIMUM_VERSION 1.0.5)

pkg_check_modules(GST1_TEST gstreamer-1.0)
if ( GST1_TEST_FOUND AND NOT ${GST1_TEST_VERSION} VERSION_LESS ${GSTREAMER_MINIMUM_VERSION} )
    pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
    pkg_check_modules(GSTREAMER-APP REQUIRED gstreamer-app-1.0)
    pkg_check_modules(GSTREAMER-AUDIO REQUIRED gstreamer-audio-1.0)
    pkg_check_modules(GSTREAMER-PBUTILS REQUIRED gstreamer-pbutils-1.0)
    pkg_check_modules(GSTREAMER-FFT REQUIRED gstreamer-fft-1.0)
    add_definitions(-DGST_API_VERSION_1=1)
else()
    # fallback to gstreamer-0.10
    unset(GSTREAMER_MINIMUM_VERSION)
    pkg_check_modules(GSTREAMER REQUIRED gstreamer-0.10)
    pkg_check_modules(GSTREAMER-APP REQUIRED gstreamer-app-0.10)
    pkg_check_modules(GSTREAMER-AUDIO REQUIRED gstreamer-audio-0.10)
    pkg_check_modules(GSTREAMER-FFT REQUIRED gstreamer-fft-0.10)
    set_source_files_properties(WebKitWebAudioSourceGStreamer.cpp PROPERTIES COMPILE_DEFINITIONS "GLIB_DISABLE_DEPRECATION_WARNINGS=1")
endif()

include_directories(
  ${GSTREAMER_INCLUDE_DIRS}
  ${GSTREAMER-APP_INCLUDE_DIRS}
  ${GSTREAMER-AUDIO_INCLUDE_DIRS}
  ${GSTREAMER-PBUTILS_INCLUDE_DIRS}
  ${GSTREAMER-FFT_INCLUDE_DIRS}
  ${CMAKE_CURRENT_SOURCE_DIR}
)

link_directories(
  ${GSTREAMER_LIBRARY_DIRS}
  ${GSTREAMER-APP_LIBRARY_DIRS}
  ${GSTREAMER-AUDIO_LIBRARY_DIRS}
  ${GSTREAMER-PBUTILS_LIBRARY_DIRS}
  ${GSTREAMER-FFT_LIBRARY_DIRS}
)

set( CMAKE_C_COMPILER gcc)
set( CMAKE_CXX_COMPILER g++)
set(test_LIBRARIES
  ${GSTREAMER_LIBRARIES}
  ${GSTREAMER-APP_LIBRARIES}
  ${GSTREAMER-AUDIO_LIBRARIES}
  ${GSTREAMER-PBUTILS_LIBRARIES}
  ${GSTREAMER-FFT_LIBRARIES}
    
  pthread
  ${GLIB_LIBRARIES}
  ${GLIB_GIO_LIBRARIES}
  ${GLIB_GOBJECT_LIBRARIES}
) 
set(src test.c)
add_executable(test ${src})
target_link_libraries(test ${test_LIBRARIES})

编译CMakeLists.txt输出

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Checking for module 'glib-2.0'
--   Found glib-2.0, version 2.48.2
-- Checking for module 'gstreamer-1.0'
--   Found gstreamer-1.0, version 1.8.3
-- Checking for module 'gstreamer-1.0'
--   Found gstreamer-1.0, version 1.8.3
-- Checking for module 'gstreamer-app-1.0'
--   Found gstreamer-app-1.0, version 1.8.3
-- Checking for module 'gstreamer-audio-1.0'
--   Found gstreamer-audio-1.0, version 1.8.3
-- Checking for module 'gstreamer-pbutils-1.0'
--   Found gstreamer-pbutils-1.0, version 1.8.3
-- Checking for module 'gstreamer-fft-1.0'
--   Found gstreamer-fft-1.0, version 1.8.3
CMake Warning (dev) at CMakeLists.txt:74 (add_executable):
  Policy CMP0037 is not set: Target names should not be reserved and should
  match a validity pattern.  Run "cmake --help-policy CMP0037" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  The target name "test" is reserved or not valid for certain CMake features,
  such as generator expressions, and may result in undefined behavior.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done-- Build files have been written to: /media/lab/873821cf-d234-44cf-bd63-4372eac823a1/ARM_SYSTEM/raspberrypi/gstreamer/test/build

make后运行结果:

This program is linked against GStreamer 1.8.3

4.声音测试

4.1 命令测试

测试命令:

gst-launch-1.0 audiotestsrc ! autoaudiosink

系统中可能会有多个版本的gstreamer(可以通过whereis命令查看:whereis gst-inspect-1.0),比如我的Ubuntu系统中,anaconda环境下还有一个gstreamer(安装不完整),因此我将anaconda环境下的gstreamer 卸载了。

conda list | grep gst #查看gstreamer的包

卸载上述命令找到的所有包: 

conda remove gstreamer

重新安装gstreamer:

sudo apt-get install gstreamer1.0*

音乐测试(filesrc是音乐源,mad是编码器,autoaudiosink是):

gst-launch-1.0 filesrc location=love.mp3 ! mad ! autoaudiosink

或以下命令:

gst-launch-1.0 filesrc location=love.mp3 ! mad ! playsink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Redistribute latency...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstPulseSinkClock
Got EOS from element "pipeline0".
Execution ended after 0:04:40.932763883
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

查看playsink和autoaudiosink

gst-inspect-1.0 playsink
gst-inspect-1.0 autoaudiosink

输出分别是:

filesrcmadplaysinkautoaudiosink

Factory Details:
  Rank                     primary (256)
  Long-name                File Source
  Klass                    Source/File
  Description              Read from arbitrary point in a file
  Author                   Erik Walthinsen <omega@cse.ogi.edu>

Plugin Details:
  Name                     coreelements
  Description              GStreamer core elements
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstcoreelements.so
  Version                  1.8.3
  License                  LGPL
  Source module            gstreamer
  Source release date      2016-08-19
  Binary package           GStreamer (Ubuntu)
  Origin URL               https://launchpad.net/distros/ubuntu/+source/gstreamer1.0

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseSrc
                         +----GstFileSrc

Implemented Interfaces:
  GstURIHandler

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      ANY

Factory Details:
  Rank                     secondary (128)
  Long-name                mad mp3 decoder
  Klass                    Codec/Decoder/Audio
  Description              Uses mad code to decode mp3 streams
  Author                   Wim Taymans <wim.taymans@gmail.com>

Plugin Details:
  Name                     mad
  Description              mp3 decoding based on the mad library
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmad.so
  Version                  1.8.3
  License                  GPL
  Source module            gst-plugins-ugly
  Source release date      2016-08-19
  Binary package           GStreamer Ugly Plugins (Ubuntu)
  Origin URL               https://launchpad.net/distros/ubuntu/+source/gst-plugins-ugly1.0

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstAudioDecoder
                         +----GstMad

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      audio/mpeg
            mpegversion: 1
                  layer: [ 1, 3 ]
                   rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }
               channels: [ 1, 2 ]

  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw
                 format: S32LE
                 layout: interleaved
                   rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }
               channels: [ 1, 2 ]
 

Factory Details:
  Rank                     none (0)
  Long-name                Player Sink
  Klass                    Generic/Bin/Sink
  Description              Convenience sink for multiple streams
  Author                   Wim Taymans <wim.taymans@gmail.com>

Plugin Details:
  Name                     playback
  Description              various playback elements
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstplayback.so
  Version                  1.8.3
  License                  LGPL
  Source module            gst-plugins-base
  Source release date      2016-08-19
  Binary package           GStreamer Base Plugins (Ubuntu)
  Origin URL               https://launchpad.net/distros/ubuntu/+source/gst-plugins-base1.0

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBin
                         +----GstPlaySink

Implemented Interfaces:
  GstChildProxy
  GstStreamVolume
  GstVideoOverlay
  GstNavigation
  GstColorBalance

Pad Templates:
  SINK template: 'audio_raw_sink'
    Availability: On request
      Has request_new_pad() function: gst_play_sink_request_new_pad
    Capabilities:
      ANY

  SINK template: 'audio_sink'
    Availability: On request
      Has request_new_pad() function: gst_play_sink_request_new_pad
    Capabilities:
      ANY

  SINK template: 'video_raw_sink'
    Availability: On request
      Has request_new_pad() function: gst_play_sink_request_new_pad
    Capabilities:
      ANY

  SINK template: 'video_sink'
    Availability: On request
      Has request_new_pad() function: gst_play_sink_request_new_pad
    Capabilities:
      ANY

  SINK template: 'text_sink'
    Availability: On request
      Has request_new_pad() function: gst_play_sink_request_new_pad
    Capabilities:
      ANY
 

Factory Details:
  Rank                     none (0)
  Long-name                Auto audio sink
  Klass                    Sink/Audio
  Description              Wrapper audio sink for automatically detected audio sink
  Author                   Jan Schmidt <thaytan@noraisin.net>

Plugin Details:
  Name                     autodetect
  Description              Plugin contains auto-detection plugins for video/audio in- and outputs
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstautodetect.so
  Version                  1.8.3
  License                  LGPL
  Source module            gst-plugins-good
  Source release date      2016-08-19
  Binary package           GStreamer Good Plugins (Ubuntu)
  Origin URL               https://launchpad.net/distros/ubuntu/+source/gst-plugins-good1.0

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBin
                         +----GstAutoDetect
                               +----GstAutoAudioSink

Implemented Interfaces:
  GstChildProxy

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      ANY
 

source element(只有输出端)filter element(输出端+输入端)sink element(只有输入端),这个应该可以播放音频、视频、文本。sink element(只有输入端)

4.2 程序测试

/*****
命令行工具:gst-launch-1.0 filesrc location=${1.mp3} ! mad ! autoaudiosink
source:filesrc     filter:mad     sink:autoaudiosink
*****/
#include<gst/gst.h>
#include<stdio.h>

int main(int argc, char *argv[])
{
    //定义element pad bin等
    GstElement *pipeline, *filesrc, *decoder, *musicsink;
    GstBus *bus;
    GstMessage *msg;
    GstStateChangeReturn ret;
    gst_init(&argc, &argv); //初始化
    if (argc != 2) {
        g_print ("usage: %s <mp3 filename>\n", argv[0]);
        return -1;
    }
    pipeline = gst_pipeline_new("pipeline");
    filesrc = gst_element_factory_make("filesrc","disk_source");//文件源,从磁盘读取
    g_object_set(G_OBJECT(filesrc),"location",argv[1],NULL); //设置从argv[1]位置读取
    decoder = gst_element_factory_make("mad","decoder"); //“mad”元件中实际包含sink和src两个衬垫
    /*
    Pads:
      SINK template: ’sink’
        Availability: Always
        Capabilities:
        ’mad_sink’:
          MIME type: ’audio/mp3’:
      SRC template: ’src’
        Availability: Always
        Capabilities:
          ’mad_src’:
            MIME type: ’audio/raw’:
            format: String: int
            endianness: Integer: 1234
            width: Integer: 16
            depth: Integer: 16
            channels: Integer range: 1 - 2
            law: Integer: 0
            signed: Boolean: TRUE
            rate: Integer range: 11025 - 48000
    */
    musicsink = gst_element_factory_make("autoaudiosink","play_audio");//接收器Element,利用声卡播放  GstElement *gst_element_factory_make (const gchar *factoryname, const gchar *name)
    if (!pipeline || !filesrc || !decoder || !musicsink)
    {
        g_print("Not all elements could be created.\n");
        return -1;
    }
    gst_bin_add_many(GST_BIN(pipeline), filesrc, decoder, musicsink, NULL);//将Element添加到bin中
    gst_element_link_many(filesrc, decoder, musicsink, NULL);//将Element通过pad连接起来
    ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);//将pipeline设置为play状态
    if (ret == GST_STATE_CHANGE_FAILURE)
    {
         g_print("Unable to set the pipeline to playing state.\n");
        /*void gst_object_unref (gpointer object);
Decrements the reference count on object . If reference count hits zero, destroy object . This function does not take the lock on object as it relies on atomic refcounting.*/
        gst_object_unref(pipeline);
        return -1;
    }
    g_print("start to play music!");
    /* Wait until error or EOS */
    /*GstBus *gst_element_get_bus (GstElement *element);
      Returns the bus of the element. Note that only a GstPipeline will provide a bus for the application.*/
    bus = gst_element_get_bus (pipeline);
    /*GstMessage *gst_bus_timed_pop_filtered (GstBus *bus, GstClockTime timeout, GstMessageType types);
      Get a message from the bus whose type matches the message type mask types , waiting up to the specified timeout (and discarding any messages that do not match the mask provided).
      If timeout is 0, this function behaves like gst_bus_pop_filtered(). If timeout is GST_CLOCK_TIME_NONE, this function will block forever until a matching message was posted on the bus.*/
    msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
    g_print("msg:%s\n",msg);
    /* Parse message */
    if (msg != NULL) {
      GError *err;
      gchar *debug_info;

      switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_ERROR:
          gst_message_parse_error (msg, &err, &debug_info);
          g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
          g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
          g_clear_error (&err);
          g_free (debug_info);
          break;
        case GST_MESSAGE_EOS:
          g_print ("End-Of-Stream reached.\n");
          break;
        default:
          /* We should not reach here because we only asked for ERRORs and EOS */
          g_printerr ("Unexpected message received.\n");
          break;
      }
      gst_message_unref (msg);
    }
    gst_object_unref(bus);
    //while(gst_bin_iterate_sinks(GST_BIN(pipeline)));//不断迭代bin,直到没有数据
    gst_element_set_state(pipeline, GST_STATE_NULL);//将pipeline设置为NULL状态
    gst_object_unref(GST_OBJECT(pipeline));
    return 0;
}

编译方式:

  • 直接编译:gcc mp3.c -o mp3 `pkg-config --cflags --libs gstreamer-1.0`
  • 编写CMakeLists.txt编译(见上文)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值