您的位置:首页 > 移动开发 > IOS开发

Gstreamer/Plugin-base/audiosink: AlsaSink AlsaSrc 结构解析

2015-06-19 10:54 706 查看


1. 引言

GstAlsaPlugin 是Gstreamer中的重要插件,其代码位于 gst-plugin-base 中,应用可以通过它来实现音频的采集和播放。 它是通过ALSA libary API封装实现的,相较于 gst-plugin-good 包中的GstPulsePlugin 实现更高效,延迟更低。在分析GstAlsaSink 和GstAlsaSrc 实现之前我们先了解一下他们的继承关系和另外一个重要的类:GstAudioRingBuffer。

2. GstAlsaSink 详细信息

在终端输入“gst-inspect-1.0 alsasink”便会打印出alsasink的详细信息,
Plugin Details:
Name alsa
Description ALSA plugin library
Filename /usr/local/lib/gstreamer-1.0/libgstalsa.so
Version 1.5.0.1
License LGPL
Source module gst-plugins-base
Source release date 2014-11-12 06:24 (UTC)
Binary package GStreamer Base Plug-ins git
Origin URL Unknown package origin
其中,libgstalsa.so 是AlsaPlugin的库文件,

GObject
+----GInitiallyUnowned
+----GstObject
+----GstElement
+----GstBaseSink
+----GstAudioBaseSink
+----GstAudioSink
+----GstAlsaSink
以上为GstAlsaSink的继承关系树,其直接父类为GstAudioSink,对于需要自己写AudioPlugin的开发者来说Gstreamer推荐直接继承GstAudioSink这个基类,因为该类为其子类提供了一个简明的向下接口(如,open(),prepare(),write()等),子类只要按照功能复写这些虚函数即可,比较简便。在这个继承关系树中,我们只需要关心GstElement一下的各类,GstObject及以上的类属于GObject对象编程的范畴,对于初接触GObject的人有必要了解一下,对于理解该体系的代码很有帮助,请参考https://developer.gnome.org/gobject/stable/

Element Implementation:
Has change_state() function: gst_audio_base_sink_change_state
这里给出了AlsaSink 的Element实现函数change_state,它是在GstAudioBaseSink类中实现的。该函数根据pipleline的状态变化执行相应的配置、预处理和播放等操作。


3. GstAlsaSrc 详细信息

GstAlsaSrc的详细信息内容和Sink的类似,不同的是在Src的继承关系树中多了GstPushSrc类,该类多在没有随机访问能力或访问速度较慢的场合使用,且多以push模式工作,alsasrc没有用到该类,所以在此就不多细述。
Plugin Details:
Name alsa
Description ALSA plugin library
Filename /usr/local/lib/gstreamer-1.0/libgstalsa.so
Version 1.5.0.1
License LGPL
Source module gst-plugins-base
Source release date 2014-11-12 06:24 (UTC)
Binary package GStreamer Base Plug-ins git
Origin URL Unknown package origin

GObject
+----GInitiallyUnowned
+----GstObject
+----GstElement
+----GstBaseSrc
+----GstPushSrc
+----GstAudioBaseSrc
+----GstAudioSrc
+----GstAlsaSrc
Element Implementation:
Has change_state() function: gst_alsasrc_change_state

4. GstAudioRingBuffer

This object is the base class for audio ringbuffers used by the base audio source and sink classes.

The ringbuffer abstracts a circular buffer of data. One reader and one writer can operate on the data from different threads in
a lockfree manner. The base class is sufficiently flexible to be used as an abstraction for DMA based ringbuffers as well as a pure software implementations.

Object hierachy:

GObject+----GInitiallyUnowned           +----GstObject                 +----GstAudioRingBuffer
Some key member functions :


gst_audio_ring_buffer_read ()

guintgst_audio_ring_buffer_read (GstAudioRingBuffer *buf,guint64 sample,guint8 *data,guint len,GstClockTime *timestamp);

Read len samples from the ringbuffer into the memory pointed to by data .
The first sample should be read from position sample in the ringbuffer.
len should not be a multiple of the segment size of the ringbuffer although it is recommended.
timestamp will return the timestamp associated with the data returned.

gst_audio_ring_buffer_acquire ()
gbooleangst_audio_ring_buffer_acquire (GstAudioRingBuffer *buf,GstAudioRingBufferSpec *spec);

Allocate the resources for the ringbuffer. This function fills in the data pointer of the ring buffer with a valid GstBuffer to
which samples can be written.

gst_audio_ring_buffer_activate ()
gbooleangst_audio_ring_buffer_activate (GstAudioRingBuffer *buf,gboolean active);

Activate buf to start or stop pulling data.

gst_audio_ring_buffer_commit ()
guintgst_audio_ring_buffer_commit (GstAudioRingBuffer *buf,guint64 *sample,guint8 *data,gint in_samples,gint out_samples,gint *accum);

Commit in_samples samples pointed to by data to
the ringbuffer buf .
in_samples and out_samples define the rate conversion to perform on the samples in data .
For negative rates, out_samples must be negative and in_samples positive.
When out_samples is positive, the first sample will be written at position sample in the ringbuffer.
When out_samples is negative, the last sample will be written to sample in reverse order.
out_samples does not need to be a multiple of the segment size of the ringbuffer although it is recommended for optimal performance.
accum will hold a temporary accumulator used in rate conversion and should be set to 0 when this function is first called. In case the commit
operation is interrupted, one can resume the processing by passing the previously returned accum value back to this function.

The virtual functions that subclass should to override:

acquire ()
allocate the resources for the ringbuffer using the given spec
release ()
free resources of the ringbuffer
close_device ()
close the device
start ()
start processing of samples
pause ()
pause processing of samples
resume ()
resume processing of samples after pause
stop ()
stop processing of samples
delay ()
get number of samples queued in device
activate ()
activate the thread that starts pulling and monitoring the consumed segments in the device.
commit ()
write samples into the ringbuffer
clear_all ()
clear the entire ringbuffer.
More information please refer to: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudioringbuffer.html

5. AlsaSink 结构



上图给出了AlsaSink类中主要接口的关系图,在AudioSink中实现了AudioBaseSink的虚函数Create_ringbuffer(),其实现需要创建一个AudioSinkRingBuffer,并调用AlsaLib API来实现从父类AudioRingBuffer继承来的虚函数。AudioRingBuffer_thread_func()是一个被Gst_audio_ring_buffer_activate()函数激活的独立线程,它负责将ringbuffer中的音频数据写到alsa声卡中。而Gst_audio_ring_buffer_commit()函数则负责将上游传递过来的数据写到ringbuffer中,在GstAudioBaseSink中被Gst_audio_base_sink_render()函数调用。

6. AlsaSrc 结构



AlsaSrc中的实现方式与AlsaSink中类似,在此不再赘述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: