基于LINUX的多媒体框架Gstreamer开发与使用

1.  Gstreamer介绍

GStreamer是一个创建流媒体应用程序的框架。其基本设计思想来自于俄勒冈(Oregon)研究生学院有关视频管道的创意, 同时也借鉴了DirectShow的设计思想。

如果你把GStreamer理解为是一种媒体播放器的话,那就大错特错了。上面说了,它只是流媒体程序的开发框架而已,它本身是C语言开发的,提供了大量已知媒体的编程接口,供程序员调用,同时也允许程序员自行开发插件来定制自己所需的功能和格式
   GStreamer最显著的用途是在构建一个播放器上。GStreamer已经支持很多格式的文件了, 包括: MP3、Ogg/Vorbis、MPEG-1/2、AVI、Quicktime、 mod等等。从这个角度看,GStreamer更象是一个播放器。但是它主要的优点却是在于: 它的可插入组件能够很方便的接入到任意的管道当中。这个优点使得利用GStreamer编写一个万能的可编辑音视频应用程序成为可能。

Element :简单说就是节点。Element的input和output称为Pads 。 source pads是指Element的输出(output), sink pads指Element的输入(input)。BIN:用以将一组Element以链接组成一个逻辑单元,Element的容器,同时也是 Element的子类。PipeLine是一种特定的Top-Level的BIN,PipeLine启动后,在单独的线程中运行。下边是一个典型的 PIPELLINE示例: 

    GStreamer定义了几类Element,Source Element是指只有source pad没有sink pad的Element,是起始的Element,例如:从文件/网络读入多媒体数据。Filter Element有一个sink pad 和src pad同时存在的节点,是中间处理的Element,例如完成convertors, demuxers, muxers and codecs的工作。sink Elemen和source Element相反,只有sink pad,没有source pad,一个终结的Element,完成像写入到磁盘、播放到声卡等工作。

    Bus:Bus负责PipeLine线程和宿主的程序之间的通信,每个PipeLine缺省创建一个Bus。宿主程序有两种方法是用Bus,第一种是使用 GLib/Gtk+ main loop及gst_bus_add_watch () or gst_bus_add_signal_watch ()事件回调函数机制。第二种是程序通过gst_bus_peek () /gst_bus_poll ()主动检查Bus中的消息.

    GStreamer的发布包中分成几种Plug-ins:GStreamer Core Plugins、GStreamer Base Plugins、GStreamer Good Plugins、GStreamer Ugly Plugins、GStreamer Bad Plugins、GStreamer Non-Linear Multimedia Editing Plugins。其文档中有详细描述每种plugins包含哪些Elements,对某种版本的Linux,很可能只包含 Core Plugins、Base Plugins、Good Plugins,其他的plugins基于版权或者架构的理由并不包含在内。

2.  GSTREAMER源码、文档及下载

官方网址:

http://gstreamer.freedesktop.org/

FAQ网址:

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/faq/html/

插件用户指南( 必读 )

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html

文档网址:

http://gstreamer.freedesktop.org/documentation

库函数的功能、调用及参数说明文档:

Core Reference

Core Libraries Reference (核心库函数使用说明)

GStreamer  base  Plugins Libraries Reference (基本插件库函数使用说明)

插件的所包含的元素,元素的属性及调用说明:

GStreamer  xxx  Plugins Reference

Download   source download directory 

通用的下载为:

核心程序: gstreamer/   目前最高版本为:gstreamer-0.10.30

基本插件库: gst-plugins-base/  与核心程序版本一一对应

测试通过插件库: gst-plugins-good/  

可能有缺陷插件库: gst-plugins-ugly/

通过  http://gstreamer.freedesktop.org/documentation/可查看每个库中包括的插件。比如在ugly库中你就可以找到播放MP3的插件  mad — Uses mad code to decode mp3 streams 。

3.  GSTREAMER交叉编译

ARM编译器:montavista5.0

HOST: ubuntu9.10

1) 创建依赖库目录

mkdir /home/wangbi/disk/gstreamer/arm_target

2) 安装glib-2.24.0.tar.bz2

Get glib-2.24.0.tar.bz2

CC=arm_v5t_le-gcc ./configure --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target glib_cv_stack_grows=no glib_cv_uscore=no ac_cv_func_posix_getpwuid_r=yes ac_cv_func_posix_getgrgid_r=yes ac_cv_lib_rt_clock_gettime=no glib_cv_monotonic_clock=yes USE_ARCH=32 NM=nm

Make 

Make install

3) 安装liboil-0.3.16.tar.gz

Get liboil-0.3.16.tar.gz

CC=arm_v5t_le-gcc ./configure PKG_CONFIG_PATH=/home/wangbi/disk/gstreamer/arm_target/lib/pkgconfig --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target USE_ARCH=32 NM=nm

Make

Make install

4) 安装libxml2-2.7.7.tar.gz

Get libxml2-2.7.7.tar.gz

CC=arm_v5t_le-gcc ./configure --with-gnu-ld --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target

Make

Make install

5) 安装alsa-utils-1.0.22.tar.bz2

Get alsa-utils-1.0.22.tar.bz2

CC=arm_v5t_le-gcc ./configure --with-gnu-ld --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target

Make

Make install

6) 安装libid3tag-0.15.1b.tar.gz

Get libid3tag-0.15.1b.tar.gz

CC=arm_v5t_le-gcc ./configure --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target

Make

Make install

7) 安装libmad-0.15.1b.tar.gz

Get libmad-0.15.1b.tar.gz

CC=arm_v5t_le-gcc ./configure --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target \

CFLAGS=-I/home/wangbi/disk/gstreamer/arm_target/include LDFLAGS=-L/home/wangbi/disk/gstreamer/arm_target/lib

Make

Make install

8) 安装gstreamer-0.10.29.tar.bz2

Get gstreamer-0.10.29.tar.bz2

CC=arm_v5t_le-gcc  PKG_CONFIG_PATH=/home/wangbi/disk/gstreamer/arm_target/lib/pkgconfig ./configure --build=i686-linux --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target CFLAGS=-I/home/wangbi/disk/gstreamer/arm_target/include --disable-gtk-doc ac_cv_func_register_printf_function=no --disable-valgrind USE_ARCH=32 NM=nm --disable-gst-debug --disable-alloc-trace  --disable-debug --disable-trace --disable-parse --disable-option-parsing --disable-loadsave

Make

Make install

9) 安装gst-plugins-base-0.10.29.tar.gz

Get gst-plugins-base-0.10.29.tar.gz

CC=arm_v5t_le-gcc ./configure --build=i686-linux PKG_CONFIG_PATH=/home/wangbi/disk/gstreamer/arm_target/lib/pkgconfig --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target CFLAGS=-I/home/wangbi/disk/gstreamer/arm_target/include LDFLAGS=-L/home/wangbi/disk/gstreamer/arm_target/lib USE_ARCH=32 NM=nm \

ALSA_CFLAGS=-I/home/wangbi/disk/tools/montavista/pro/devkit/arm/v5t_le/target/usr/include

Make

Make install

10) 安装gst-plugins-good-0.10.22.tar.gz

Get gst-plugins-good-0.10.22.tar.gz

CC=arm_v5t_le-gcc ./configure --build=i686-linux PKG_CONFIG_PATH=/home/wangbi/disk/gstreamer/arm_target/lib/pkgconfig --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target CFLAGS=-I/home/wangbi/disk/gstreamer/arm_target/include LDFLAGS=-L/home/wangbi/disk/gstreamer/arm_target/lib USE_ARCH=32 NM=nm --disable-jpeg \

ALSA_CFLAGS=-I/home/wangbi/disk/tools/montavista/pro/devkit/arm/v5t_le/target/usr/include \

--disable-valgrind --disable-examples --disable-gconftool --disable-avi --disable-id3demux --disable-libpng --disable-jpeg --disable-gdk_pixbuf --disable-x --disable-aalib --disable-cairo  --disable-esd --disable-hal --disable-directsound --disable-xvideo --disable-gconf --disable-libdv --disable-libpng --disable-soup --disable-taglib --disable-bz2 --disable-zlib --disable-shout2  --disable-shout2test  --disable-speex

Make

Make install

11) 安装gst-plugins-ugly-0.10.14.tar.gz

Get gst-plugins-ugly-0.10.14.tar.gz

CC=arm_v5t_le-gcc ./configure --build=i686-linux PKG_CONFIG_PATH=/home/wangbi/disk/gstreamer/arm_target/lib/pkgconfig --host=arm-linux --prefix=/home/wangbi/disk/gstreamer/arm_target CFLAGS=-I/home/wangbi/disk/gstreamer/arm_target/include LDFLAGS=-L/home/wangbi/disk/gstreamer/arm_target/lib USE_ARCH=32 NM=nm \

ALSA_CFLAGS=-I/home/wangbi/disk/tools/montavista/pro/devkit/arm/v5t_le/target/usr/include

Make

Make install

12) 编译过程中如出现问题,则可能还需要安装如下依赖软件:

libiconv-1.13.1.tar.gz

libtool-2.2.tar.gz

flex-2.5.35.tar.bz2

gettext-0.18.tar.gz

bison-2.4.tar.gz

gtk+-2.20.0.tar.bz2

gtk-doc-1.15.tar.bz2

docbook-xsl-doc-1.75.2.tar.bz2

13) 运行

拷贝库到文件系统

Cp /home/wangbi/disk/gstreamer/arm_target/lib 到你的文件系统/usr/local

设置文件系统环境变量

export GGST_PLUGIN_SYSTEM_PATH='/usr/local/lib/gstreamer-0.10'

export GST_PLUGIN_PATH='/usr/local/lib/gstreamer-0.10'

export GST_REGISTRY_UPDATE='no'

export LD_LIBRARY_PATH='/lib:/usr/local/lib'

Export PATH='/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/sbin:/usr/sbin:/sbin'

拷贝播放工具放音

利用OSS放rain.wav文件,同时打开打印信息

./gst-launch-0.10  --gst-debug-level=2  filesrc location=rain.wav ! wavparse ! audioconvert ! Osssink

利用ALSA驱动播放rain.mp3文件

./gst-launch-0.10 filesrc location=rain.mp3 ! mad ! audioconvert ! audioresample  ! alsasink

注意放音时,如果放音异常,则有可能是音频流的声道不为驱动所支持,请切换单声道/双声道试试。

4.  GSTREAMER工具集

在GSTREAMER的核心程序编译之后,会在目录的tools下生成一系列的测试工具集。

播放工具:gst-launch-0.10

将各种功能的插件组合成一个功能,用于播放或录音等。

举例:

将本目当下的rain.mp3文件以mad插件解码后通过alsa驱动播放出来。

./gst-launch-0.10 filesrc location=rain.mp3 ! mad ! audioconvert ! audioresample  ! alsasink

将本目录下的rain.wav文件以wavparse插件解码后转化为整形,小端格式,不带符号,22.05k速率,8位的单声道数据流,通过ALSA设备放音。

./gst-launch-0.10 filesrc location=rain.wav ! wavparse !audio/x-raw-int, endianness=1234, signed=false,rate=22050,width=8, depth=8,channels=1! audioconvert ! audioresample ! Alsasink

注:关于audio的相关参数说明,请参考:

GStreamerPlugin Writer's Guide (0.10.30) 的附录: Table of Video Types

查询工具:gst-inspect-0.10

用于查看插件的名称,版本,作者,功能,输入输出,接口属性等信息

举例:

查看mad插件的信息,注意:Pad src是指支持的输入格式,Pad sink是指支持的输出数据格式。Pad是垫衬,是输入输出的接口,用于插件之间的连接与数据交换。

./gst-inspect-0.10 mad

Factory Details:

  Long name:    mad mp3 decoder

  Class:        Codec/Decoder/Audio

  Description:  Uses mad code to decode mp3 streams

  Author(s):    Wim Taymans 

  Rank:         secondary (128)

Plugin Details:

  Name:                 mad

  Description:          mp3 decoding based on the mad library

  Filename:             /usr/local/lib/gstreamer-0.10/libgstmad.so

  Version:              0.10.14

  License:              GPL

  Source module:        gst-plugins-ugly

  Binary package:       GStreamer Ugly Plug-ins source release

  Origin URL:           Unknown package origin

GObject

 +----GstObject

       +----GstElement

             +----GstMad

Pad Templates:

  SRC template: 'src'

    Availability: Always

    Capabilities:

      audio/x-raw-int

             endianness: 1234

                 signed: true

                  width: 32

                  depth: 32

                   rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }

               channels: [ 1, 2 ]

  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 ]

Element Flags:

  no flags set

Element Implementation:

  Has change_state() function: 0x406013e8

  Has custom save_thyself() function: gst_element_save_thyself

  Has custom restore_thyself() function: gst_element_restore_thyself

Element has no clocking capabilities.

Indexing capabilities:

  element can do indexing

Element has no URI handling capabilities.

Pads:

  SRC: 'src'

    Implementation:

      Has custom eventfunc(): gst_mad_src_event

      Has custom queryfunc(): gst_mad_src_query

        Provides query types:

                (1):    position (Current position)

                (2):    duration (Total duration)

                (8):    convert (Converting between formats)

    Pad Template: 'src'

  SINK: 'sink'

    Implementation:

      Has chainfunc(): gst_mad_chain

      Has custom eventfunc(): gst_mad_sink_event

    Pad Template: 'sink'

Element Properties:

  name                : The name of the object

                        flags: readable, writable

                        String. Default: null Current: "mad0"

  half                : Generate PCM at 1/2 sample rate

                        flags: readable, writable

                        Boolean. Default: false Current: false

  ignore-crc          : Ignore CRC errors

                        flags: readable, writable

                        Boolean. Default: true Current: true

5.  GSTREAMER编程

以播放MP3文件为例写一段程序:

处理思想就是将需要的元件组合成一个流处理管道。播放MP3需要一个读文件元件,一个MP3解码元件,一个音频自动转换配置元件,一个放音元件。

GMainLoop *loop;

GstElement *pipeline, *source, *convert, *alawencoder, *sink,*madparse;

GstBus *bus;

/* gst初始化,和创建播放主循环体*/

  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

/* 创建管道和元件*/

  pipeline = gst_pipeline_new ("play wav/mp3");

  source   = gst_element_factory_make ("filesrc", "source");

  madparse = gst_element_factory_make ("mad", "mp3_parser");

  convert  = gst_element_factory_make ("audioconvert",  "audio_convert");

  sink     = gst_element_factory_make ("alsasink", "app-sink");

/* 设置参数数据源*/

g_object_set (G_OBJECT (source), "location", argv[1] , NULL);

/* 如有必要的话,增加一个管道消息处理函数,用于外部接收播放的状态,并处理*/

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  gst_bus_add_watch (bus, bus_msg_report, loop);

  gst_object_unref (bus);

/* 将元件加入管道并连接元件,此时管道处于READY状态*/

gst_bin_add_many (GST_BIN (pipeline), source,madparse,convert,sink, NULL);

  gst_element_link_many (source, madparse,convert,sink, NULL);

/*开始播放*/

gst_element_set_state (pipeline, GST_STATE_PLAYING);

/*进入主循环体,检测播放状态,默认播放结束后退出循环*/

g_main_loop_run (loop);

/*置管道状态无NULL,使元件释放其得到的资源*/

gst_element_set_state (pipeline, GST_STATE_NULL);

/*释放资源*/

gst_object_unref (GST_OBJECT (pipeline));

外部消息监测程序

static gboolean bus_msg_report (GstBus     *bus,

          GstMessage *msg,

          gpointer    data)

{

  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

/*播放完成后退出循环*/

    case GST_MESSAGE_EOS:

      g_print ("End of stream\n");

      g_main_loop_quit (loop);

      break;

/*播放错误时处理*/

    case GST_MESSAGE_ERROR: {

      gchar  *debug;

      GError *error;

      gst_message_parse_error (msg, &error, &debug);

      g_free (debug);

      g_printerr ("Error: %s\n", error->message);

      g_error_free (error);

     

      g_main_loop_quit (loop);

      break;

    }

    default:

      g_print("Msg type[%d], Msg type name[%s]\n", GST_MESSAGE_TYPE(msg), GST_MESSAGE_TYPE_NAME(msg));

      break;

  }

  return TRUE;

}

6.  参考资料

1. 插件用户指南(必读 )

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html

你可能感兴趣的:(Gstreamer)