学习《GStreamer开发手册》的一些记录
直接先上helloworld.c的代码,再进行笔记
#include <gst/gst.h>//使用GStreamer必须包含的头文件
/***创建所需元件(全局变量)***/
GstElement *pipeline,*source,*parser,*decoder,*converter,*sink;
/***总线消息***/
static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = data;
//判断消息类型,做出相应的处理
switch(GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:{//音频播放结束,退出GLib循环
g_print("End of streamer\n");
g_main_loop_quit(loop);
break;
}
case GST_MESSAGE_ERROR:{//出现错误,提示错误信息,退出GLib循环
gchar *debug;
GError *err;
//获取错误信息
gst_message_parse_error(msg,&err,&debug);
//显示错误信息
g_printerr("Error from element %s:%s\n",GST_OBJECT_NAME(msg->src),err->message);
g_printerr("Debugging informatin:%s\n",debug);
//释放错误信息
g_free(debug);
g_error_free(error);
//退出GLib循环
g_main_loop_quit(loop);
break;
}
default:
break;
}
/***动态创建pad***/
static void new_pad(GstElemet *element, GstPad *pad, gpointer data)
{
GstPad *sinkpad;
//创建一个sink_pad连接元件parser和decoder
sinkpad = gat_element_get_pad(decoder,"sink");
gst_pad_link(pad,sinkpad);
g_print("Dynamic pad created,linking parser/decoder\n");
//释放创建的sinkpad
gst_object_unref(sinkpad);
}
/***主函数***/
int main(int argc, char *argv[])
{
GMainLoop *loop
GstBus *bus
//初始化Gsteamer,GStreamer使用前需要初始化
gst_init(&argc,&argv);
//创建GLib循环
loop = g_main_loop_new(NULL,FALSE);
//检查输入的参数是否正确
if(argc != 2)
{
g_print("Usage:%s<Ogg/Vorbis filename>\n",argv[0]);
return -1;
}
//创建元件
pipeline = gst_pipeline_new("audio-player");//名为audio-player的管道
//名为file-source,类型为filesrc的源元件,可以读取给出文件的数据
source = gst_element_factory_make("filesrc","file-source");
//名为ogg-parser,类型为oggdemux的分析器
parser = gst_element_factory_make("oggdemux","ogg-parser");
//名为vorbis-decoder,类型为vorbisdec的解调器
decoder = gst_element_factory_make("vorbisdec","vorbis-decoder");
//名为converter,类型为audioconvert的转换器
converter = gst_element_factory_make("audioconvert","converter");
//名为alsa-output,类型为alsasink的接收元件
sink = gst_element_factory_make("alsasink","alsa-output");
//判断元件是否被创建,如果出错可以一个个来判断看看,也可以用断言
if(!pipeline || !source || !parser || !decoder || !converter || !sink)
{
g_print("One element could not be created\n");
return -1;
}
//给源元件source提供数据,参数argv[1]是该数据的路径
g_object(G_OBJECT(source),"location",argv[1],NULL);
//为管道创建总线,并侦听管消息,之后释放
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
gst_bus_add_watch(bus,bus_call,loop);//侦听总线消息,调用bus_call函数处理总线消息
gst_object_unref(bus);
//把元件加入管道(箱柜)
gst_bin_add_many(GST_BIN(pipeline),source,parser,decoder,converter,sink,NULL);
//把元件连接在一起,由于parser的pad需要动态创建,所以要先创建动态pad再讲parser和decoder连接起来
gst_element_link(source,parse);
gst_element_link_many(decoder,converter,sink,NULL);
//调用new_pad函数动态创建pad并连接parser和decoder
g_signal_connect(parser,"pad-adder",G_CALLBACK(new_pad),NULL);
//设置播放状态,进行播放,开启GLib循环
g_print("Setting to PLAYING\n");
gst_element_Set_state(pipeline,GST_STATE_PLAYING);
g_print("Running\n");
g_main_loop_run(loop);
//播放结束,释放管道
g_print("Returned,stopping playback\n");
gst_element_set_state(pipeline,GST_STATE_NULL);
g_print("Deleting pipeline\n");
gst_object_unref(GST_OBJECT(pipeline));
return 0;
}
这个代码是《GStreamer开发手册》中helloworld.c的代码,我进行了一点注释和略微的修改,后面根据这个代码进行学习笔记。
菜鸟学习,有什么错误希望大家指出来,有什么问题希望我们能一起探讨。
完!