本文简单介绍下AppSrc的使用。
GStreamer版本0.10.35.
应用程序可以使用多种方式向Pipeline中注入数据,而使用AppSrc是最简单的一种。
AppSrc可以工作在俩种模式下:Pull模式和Push模式。Pull模式下,AppSrc会在需要的时候向应用程序请求数据(信号:need-data),而Push模式下,应用程序主动向AppSrc注入数据(信号:enough-data)。
向AppSrc注入数据需要用于GStreamer的Buffer对象:数据拷贝到GstBuffer之后,通过信号:push-buffer传递给AppSrc。
下面实现一个最简单的Pull模式的AppSrc使用例子,用于播放一个mp3文件:
#include <stdio.h>
#include <stdlib.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
static FILE * fp;
void _needData( GstAppSrc * src, guint arg1, gpointer user_data )
{
GstBuffer * _buf;
GstFlowReturn * _ret;
int _size;
_buf = gst_buffer_new_and_alloc( arg1 );
_size = fread( GST_BUFFER_DATA( _buf ), 1, arg1, fp );
if( _size < arg1 )//读到文件尾了,从头再读
{
fseek( fp, 0, SEEK_SET );
fread( GST_BUFFER_DATA( _buf ) + _size, 1, arg1 - _size, fp );
}
g_signal_emit_by_name( src, "push-buffer", _buf, &_ret );//数据送入pipeline
gst_buffer_unref( _buf );
}
void _enoughData( GstElement * src, gpointer user_data )
{
g_message( "%s", __func__ );
}
/*
* === FUNCTION ======================================================================
* Name: main
* Description:
* =====================================================================================
*/
int main ( int argc, char *argv[] )
{
GstElement * _pipeline, * _src, * _codec, * _sink;
fp = fopen( "/root/2.mp3", "r" );
g_assert( fp != NULL );
gst_init( &argc, &argv );
g_assert( _src = gst_element_factory_make( "appsrc", "source" ));
g_assert( _codec = gst_element_factory_make( "mad", "codec" ));//mad mp3 decoder
g_assert( _sink = gst_element_factory_make( "alsasink", "sink" ));
_pipeline = gst_pipeline_new( "pipeline" );
gst_bin_add_many( GST_BIN( _pipeline ), _src, _codec, _sink, NULL );
gst_element_link_many( _src, _codec, _sink, NULL );
g_signal_connect ( _src, "need-data", G_CALLBACK( _needData ), NULL );
gst_element_set_state( _pipeline, GST_STATE_PLAYING );
pause();
return 0;
} /* ---------- end of function main ---------- */