(转)Gstreamer工作原理分析

Tech

Gstreamer工作原理分析

Guide

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 2 of 22

Revision History

Date Issue Description Author

<7/03/2008> <0.5> First draft wangfei

目录

1. ABSTRACT ................................................................................................................................................. 3

2. INTRODUCTION ....................................................................................................................................... 3

3. 原理分析...................................................................................................................................................... 3

3.1 术语介绍. ............................................................................................................................................. 3

3.1.1 元素............................................................................................................................................... 3

3.1.2 一些特别的元素。......................................................................................................................... 3

3.2 插件的工作原理。................................................................................................................................ 5

3.3 GST-LAUNCH的工作逻辑............................................................................................................................ 7

3.4 动态PIPELINE的创建原理........................................................................................................................ 9

3.5 DECODEBIN的工作原理............................................................................................................................ 10

3.6 TYPEFIND的实现原理............................................................................................................................. 12

3.7 SETUP ELEMENT........................................................................................................................................ 12

3.8 PLAYBIN的工作原理............................................................................................................................... 14

3.9 数据流动............................................................................................................................................. 16

3.10 总结................................................................................................................................................. 20

4. REFERENCE ............................................................................................................................................ 20

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 3 of 22

1. Abstract

主要讲的是gstreamer的工作原理,包括gst-launch的分析和playbin的分析,以及数据的

流动分析。

2. Introduction

先介绍一些术语,然后介绍了插件的工作原理,后面接着介绍了

gst-launch,playbin,decodebin,typefind,数据流动.

3. 原理分析

3.1 术语介绍.

3.1.1 元素

代码里面的类型是GstElement,可以理解为gstreamer里面的基类。

3.1.2 一些特别的元素。

Source:可以理解为源头,也就是数据流的起始地,就像长江的发源地是沱沱河一样。

Sink:就是这个数据流最终要流向的地方,就像长江最终要流向东海一样。

Filter:过滤器,就像是筛子一样滤掉我们不感兴趣的东西,流下我们想要的东西,或者从代码上来

说就是拦截下数据,对这个数据做一定的修改或者其它动作,当然你什么也不做也是可以的,然后

再把数据传出去:

Pipeline:典型的pipeline是这样的:

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 4 of 22

更复杂一点的:

Bin:有点像pipeline,它们的区别就是pipeline肯定是一个bin,但bin不一定是pipeline,它就像一个盒

子,里面放了什么东西你可以不关心。

Ghostpad:文档上说ghost pad就像linux里面的link文件,我的理解是在一个盒子上开一个口,这样里

就可以访问这个盒子了。

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 5 of 22

3.2 插件的工作原理。

如下图所示,这个所有的基于插件的程序的工作原理类似,本质上都是通过读取动态库实现的,只

需要每个动态库都实现某一个特定的接口就可以了,比如XX_init等,这里就是plugin_init。

里面会有个像注册表一样的数据结构会存储所有的插件的信息。

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 6 of 22

gst_element_register

GST_PLUGIN_DEFINE

(GST_VERSION_MAJOR,

GST_VERSION_MINOR,

"playbin",

"player bin", plugin_init,

VERSION, GST_LICENSE,

GST_PACKAGE_NAME,

GST_PACKAGE_ORIGIN)

gst_plugin_load_file

g_module_open

g_module_symbol

(“gst_plugin_des

c”)

#define

GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,package,origi

n) /

GST_PLUGIN_EXPORT GstPluginDesc gst_plugin_desc = { /

major, /

minor, /

name, /

description, /

init, /

version, /

license, /

PACKAGE, /

package, /

origin, /

GST_PADDING_INIT /

};

gst_plugin_register_

func

gst_default_registry

_add_plugin

(desc->plugin_init)

(plugin)

plugin_init

gst_registry_add_feature

(gst_registry_get_default

(),

GST_PLUGIN_FEATUR

E (factory))

load_plugin_func

init_post

gst_init_get_option_

group

main(gst-launch.c)

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 7 of 22

3.3 Gst-launch的工作逻辑

它的工作原理就是根据 !号来划分输入的字符串,然后为每个元素构建一个element,最后建立一个pipeline

把这些元素加入,最后通过setstate来启动整个数据循环。

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 8 of 22

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 9 of 22

3.4 动态pipeline的创建原理

我们经常需要创建动态的pipeline,因为我们不知道源头是什么格式的,这时候需要这么

做:

比如demuxer,

pipeline = gst_pipeline_new ("my_pipeline");

//创建pipeline

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

//创建src

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

//设置输入文件路径

demux = gst_element_factory_make ("oggdemux", "demuxer");

//创建demux元素

gst_bin_add_many (GST_BIN (pipeline), source, demux, NULL);

//把这两个元素加入到pipeline里面

gst_element_link_pads (source, "src", demux, "sink");

//把这两个元素连接起来

g_signal_connect (demux, "pad-added", G_CALLBACK (cb_new_pad), NULL);

//这里是关键,demux会创建出一个pad,于是发出信号,等待我们设定的函数cb_new_pad.

gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

//启动整个数据流循环

loop = g_main_loop_new (NULL, FALSE);

g_main_loop_run (loop);

//启动gloop事件循环

static void

cb_new_pad (GstElement *element,

GstPad *pad,

gpointer data)

{

gchar *name;

name = gst_pad_get_name (pad);

g_print ("A new pad %s was created/n", name);

g_free (name);

/* here, you would setup a new pad link for the newly created pad */

…...

}

在这里就可以根据不同pad来连接不同的后面的element,比如:

gst_element_link_pads (pad, "src", fakesink, "sink");

而如何发现源数据的类型则是这样的:

typefind = gst_element_factory_make ("typefind", "typefinder");

g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), loop);

每当typefine插件查出类型的时候就会发出这个信号。

“Once a media type has been detected, you can plug an element (e.g. a demuxer or decoder) to the

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 10 of 22

source pad of the typefind element, and decoding of the media stream will start right after.”

总结:从上面这些例子可以看出,它的工作过程是这样的:

首先连接能够连接的原素,比如前端src->decodebin,然后后端连接

converter->resampler->volume->

audiosink。

通过decodebin的信号,根据源类型创建特定的src pad,再把这个pad连接到后端(后端可以

创建一个ghost pad以方便使用)这样一个pipeline就建好了

3.5 Decodebin的工作原理

3.4节已经用文字介绍了decodebin的工作原理,下面的图是讲它的内部实现的:

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 11 of 22

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 12 of 22

3.6 Typefind的实现原理

这里是讲程序是如何查找出对应文件应该选用什么解码器之类的,可以简单理解为source识别。

3.7 Setup element

这里主要讲的是如何把这些播放一个source所需要的element连接起来的:

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 13 of 22

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 14 of 22

3.8 Playbin的工作原理

有了上面几个步骤就可以很容易理解playbin的工作原理,不过细节依然非常的复杂,我只是画了框

架图:

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 15 of 22

setup_source

gst_play_base_bin_

change_state

gen_source_element analyse_source

http

make_decoder

gst_play_bin_chang

e_state

gstlaunch

gstreamer

null ->ready,

ready->pause ,

setup_source

ready pause

raw

g_signal_connect (decoder, "elementadded",

G_CALLBACK

(decodebin_element_added_cb),

play_base_bin);

g_signal_connect (G_OBJECT

(decoder),

"new-decoded-pad",

G_CALLBACK (new_decoded_pad),

play_base_bin);

g_signal_connect (G_OBJECT

(decoder), "no-more-pads",

G_CALLBACK (no_more_pads),

play_base_bin);

decoder

gst_element_link

source

decorder

decodebin_element

_added_cb new_decoded_pad

new_decoded_pad_f

ull

gen_preroll_element

sinkpad =

gst_element_get_request_pad

(group->type[type - 1].selector,

"sink%d");

gst_pad_link (pad, sinkpad);

add_stream no_more_pads_full

group_commit

decodebin

preroll =

gst_element_factory_make

("queue", name);

overrun_sig = g_signal_connect

(G_OBJECT (preroll), "overrun",

G_CALLBACK

(queue_overrun), play_base_bin);

queue_overrun

res =

GST_PLAY_BASE

_BIN_GET_CLASS

(play_base_bin)->

setup_output_pads

(play_base_bin,

group);

basebin

setup_substreamprepare_output s

gst_pad_add_event_

probe

probe_triggered

eos

setup

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 16 of 22

3.9 数据流动

下面讲的是里面最复杂的数据流动的分析,我主要分析了src的流动和sink的流动,因为中间的数据流动太多,

比如解码器,filter等等,实在没空,但是我想有这两元素的分析,其它的元素就很容易了:

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 17 of 22

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 18 of 22

gst_pad_push

gst_pad_emit_have_

data_signal

(peer =

GST_PAD_PEER

(pad))

gst_pad_chain_unch

ecked (peer, buffer);

(chainfunc =

GST_PAD_CHAIN

FUNC (pad))

gst_pad_emit_have_

data_signal

ret = chainfunc (pad,

buffer);

src pad

peer

pad chainfunc

gst_pad_set_chain_f

unction

plugin init

chainfunc,

chainfunc sink

gst_base_sink_chain

gst_base_sink_chain

_unlocked

gst_base_sink_queu

e_object_unlocked

gst_base_sink_prero

ll_object

gst_base_sink_rende

r_object

gst_base_transform_

handle_buffer

ret = bclass-

>transform_ip

(trans, inbuf);

gst_base_transform_

chain

gst_base_transform_

init

gst_pad_set_chain_functi

on (trans->sinkpad,

GST_DEBUG_FUNCPT

R

(gst_base_transform_cha

in));

gst_base_sink_chan

ge_state

volume

gstbasesink_class-

>render =

GST_DEBUG_FU

NCPTR

(gst_base_audio_si

nk_render);

gst_base_audio_sink

_class_init

赋值

gst_ring_buffer_co

mmit_full

gst_base_audio_sink

_render

gst_pad_push

gst_base_sink_do_s

ync

gst_base_sink_do_r

ender_stats

bclass->render

(basesink, buf);

gst_base_audio_sink

_change_state

gst_base_audio_sink

_do_play

gst_base_audio_sink

_async_play

Change_state

FWD_SAMPLES

memcpy

gst_audio_sink_crea

te_ringbuffer

gst_audio_src_class_init

gstbaseaudiosrc_class-

>create_ringbuffer =

GST_DEBUG_FUNCPTR

(gst_audio_sink_create_ringb

uffer);

设置

gst_base_audio_sink

_change_state

gst_audioringbuffer

_open_device

csrc->open (src);

gst_alsasink_open

For alsasink

gst_ring_buffer_star

t

rclass->start (buf);

start

3

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 19 of 22

audioringbuffer_thre

ad_func

gst_audioringbuffer

_acquire

csink->prepare

(sink, spec);

g_thread_create

((GThreadFunc)

audioringbuffer_th

read_func, buf,

TRUE,

NULL);

GST_AUDIORIN

G_BUFFER_WAI

T (buf);

gst_audioringbuffer_class_init

gstringbuffer_class->acquire =

GST_DEBUG_FUNCPTR

(gst_audioringbuffer_acquire);

赋值

gst_ring_buffer_acq

uire

res = rclass-

>acquire (buf, spec);

gst_base_audio_sink

_setcaps

gst_base_audio_sink_cl

ass_init

tbasesink_class-

>set_caps =

GST_DEBUG_FUNCP

TR

(gst_base_audio_sink_s

etcaps);

赋值

调用

gst_base_sink_pad_

setcaps

bclass->set_caps

(bsink, caps);

调用

gst_base_sink_init

gst_pad_set_setcaps_func

tion (basesink->sinkpad,

GST_DEBUG_FUNCPT

R

(gst_base_sink_pad_setca

ps));

设置

gst_pad_get_caps_u

nlocked

GST_PAD_GETCA

PSFUNC (pad)

(pad);

gst_pad_get_caps

gst_pad_link_check

_compatible_unlock

ed

gst_pad_link_prepar

e gst_pad_link

pad_link_maybe_gh

osting

gst_element_link_pa

ds

gen_audio_element gen_video_element

setup

gst_audioringbuffer

_start

gst_audioringbuffer_class_in

it:

gstringbuffer_class->start =

GST_DEBUG_FUNCPTR

(gst_audioringbuffer_start);

gst_ring_buffer_star

t

设置

gst_base_audio_sink

_render

2

rclass->start (buf);

调用

2

GST_AUDIORIN

G_BUFFER_SIGN

AL (buf);

发出信号

writefunc = csink-

>write;

gst_ring_buffer_pre

pare_read

writefunc (sink,

readptr + written,

left);

GST_AUDIORING_B

UFFER_SIGNAL

(buf);

GST_AUDIORING_B

UFFER_WAIT (buf);

signal wait

writefunc

render

gst_ring_buffer_commit_full

memcpy

g_cond_signal

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 20 of 22

3.10 总结

.时间有限,我只能分析这些框架了,估计看懂这几个图也不容易,

两个关键的函数是change_state,这是一个经常被重载的函数,基本上元素的初始化,

状态的改变都会在这里面会被处理, 另外一个非常关键的chaingfunc这个函数是开

启数据流动的关键函数,通常src调用chainfunc函数,在这个函数里面会取出peer pad

的chainfunc,然后调用src对应的sink的chainfunc,另外一个让我迷惑了很久的是到sink

的数据是如何流动的,最后分析的 结果是它使用了一个环行缓冲,并且使用了线程

同步操作来实现生产者消费者 的模式以加快数据的传递,所以数据的最终传递是通

过发出p、v操作来实现的,里面先把数据取出来调用memcpy来copy到环行缓冲,然

后发出v操作,对应的消费者被唤醒调用sink插件的write操作把数据写到设备里面

去,这里面还有几块我没有分析的,比如时间戳的处理,各种元素之间的延迟的协

商,以及音频视频之间的同步播放等,这里面涉及很多多线程问题,如果要分析估

计得花很多的时间。

4. reference

[1] http://gstreamer.freedesktop.org/documentation/

补充:

#playbin的工作流程

1,创建source。

2,创建decodebin。

3,为decodebin添加typefind。

4,在向bin添加元素的时候都会发出element-added的信号。

5,向decodebin添加fakesink。

6,把decodebin加入到playbin.

7, 等待typefind元素发出的have-type信号,并调用回调函数,注意这里的信号实际是只

包含了caps信息,而后,根据注册表里面的每个factory取出其提供的caps与typefind提供的

caps取交集,如果有交集则加入到一个list表中(find_compatibles)。

8,取出list里面的元素来连接,如果找到一个就结束,找到后把这个元素与src元素连

接起来,递归的进行这个元素本身的sinkpad的连接,直到收到了no_more_pads的消息。

9,decodebin收到no_more_pads消息后也会发出同样的消息,其余处理逻辑请看文档

<gstreamer工作原理》.

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 21 of 22

注意:close_pad_link

1,通常每一个element在被创建的时候都会添加自己的pad,所以都会发出pad-added的

信号。

2,close_link (GstElement * element, GstDecodeBin * decode_bin)

try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad, GList *

factories):这个函数的意思是从这个factories里面取出某个能够连接到pad的元素,和

srcelement连接起来,连接起来后还要为这个刚连接起来的元素寻找到它的归属,也就是为

它寻找它的sink,调用的函数是close_link,当从这个函数返回的时候,或则它的sinkpad已经被

装上或则如果是动态的则已经装上了信号处理器等待sink pad被动态装上,于是

gst_element_set_state (element, GST_STATE_PAUSED);当这个函数执行完后,所有的需要安

装sink的元素都已经好了,这个函数会发出pad-added信号,而这个信号的处理函数是

new_pad,在这个函数里面会调用close_pad_link根据pad和caps寻找适合这个pad的sink pad,

所有实际是从这个函数返回后,几乎所有的setup工作都已经over了,可以理解为将要从

typefind元素的have-type信号的信号处理函数type_fount返回了,当然之前还会收到

no_more_pads的信号执行处理函数no_more_pads,于是decodebin发出了no_more_pads的信

号,于是playbin会根据这个信号执行处理函数group_commit.

3,close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps, GstDecodeBin *

decode_bin, gboolean more):这个函数是根据pad和caps为它寻找到一个可以与之连接的一

个链表,或则如果这个caps代表raw数据则创建并添加一个ghostpad到decodebin里面去。

4,find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps):这个函数的意思

是根据这个caps从注册表里面找出和它有交集的GstElementFactory,并加入到list中返回。

5,close_link (GstElement * element, GstDecodeBin * decode_bin):这个函数的意思是为

element添加sink,如果它的src pad是动态的,则调用dynamic_add来添加信号处理函数,等待

它的动态的pad被添加上,如果不是动态的就调用close_pad_link来从注册表里面选择合适的

sink pad来加入。

TYPE_FIND_REGISTER (plugin, "video/mp4", GST_RANK_PRIMARY, m4v_type_find,

mp4_exts, M4V_CAPS, NULL, NULL);

行;需要移掉gstdecodebin.c 和gstdecodebin2.c里面的函数find_compatibles里面的to_try

= g_list_reverse (to_try)

How to Mount Maemo File System——Guide Issue: <0.5>

System Analysis and Design Documents Issue Date: <10/29/2007>

<Document identifier>

Tech, 2005 Page 22 of 22

你可能感兴趣的:(工作,Date,System,audio,Maemo,Signal)