播放avi文件的gstreamer代码挂起
我是gstremaer的新手。我已经编写了一个使用gstreamer播放avi文件的代码。但是在执行代码时,它只是挂起了一会儿,我无法调试出什么问题,有人能帮我吗。 代码和输出如下所示:播放avi文件的gstreamer代码挂起,gstreamer,Gstreamer,我是gstremaer的新手。我已经编写了一个使用gstreamer播放avi文件的代码。但是在执行代码时,它只是挂起了一会儿,我无法调试出什么问题,有人能帮我吗。 代码和输出如下所示: Code: #include<stdio.h> #include<gst/gst.h> #include<glib.h> //Function to process message on bus of pipeline gb
Code:
#include<stdio.h>
#include<gst/gst.h>
#include<glib.h>
//Function to process message on bus of pipeline
gboolean process_message(GstBus *bus, GstMessage *msg,gpointer data);
//Function to add pad dynamically for ogg demux
void dynamic_addpad(GstElement *element, GstPad *pad, gpointer data);
void dynamic_decodepad (GstElement* object, GstPad* arg0, gboolean arg1,gpointer user_data);
GstElement *source, *demuxer, *audio_decoder, *video_decoder, *audio_convertor,*video_convertor, *audio_sink,*video_sink,*audioqueue,*videoqueue;//*audio_demuxer, *video_demuxer,
int main(int argc,char* argv[])
{
GstPipeline *pipeline;
GstBin *Bin;
GstBus *bus;
GMainLoop *Mainloop;
gst_init (&argc,&argv);
Mainloop = g_main_loop_new(NULL,FALSE);//NULL to use the current context and False to tell its not in running state
pipeline = gst_pipeline_new("PIPELINE");
Bin = GST_BIN(pipeline);
bus = gst_pipeline_get_bus(pipeline);
source = gst_element_factory_make("filesrc","file-source");
g_object_set(G_OBJECT(source),"location",argv[1],NULL);
demuxer = gst_element_factory_make("avidemux","avi-demuxer");
audioqueue = gst_element_factory_make("queue","Queue for audio");
videoqueue = gst_element_factory_make("queue","Queue for video");
video_decoder = gst_element_factory_make("decodebin","decoderbin");//"Vorbis audio decoder","vorbis");
audio_convertor = gst_element_factory_make("audioconvert","audio convertor");//"Audio converter","audioconvert");
video_convertor = gst_element_factory_make("videoscale","video convertor");//"Audio converter","audioconvert");
audio_sink = gst_element_factory_make("autoaudiosink","Auto audio sink");
video_sink = gst_element_factory_make("xvimagesink","XV video sink ");
if(!source || !demuxer || !audioqueue || !videoqueue || !video_decoder ||!audio_convertor || !video_convertor || !audio_sink || !video_sink )
{ g_print("Could not not create element\n");
return 0;
}
gst_bin_add(Bin,source);
gst_bin_add_many(Bin,demuxer,audioqueue,videoqueue,audio_convertor,video_decoder,video_convertor,audio_sink,video_sink,NULL);
gst_element_link(source,demuxer);
gst_element_link_many(audioqueue,video_decoder,audio_convertor,audio_sink,NULL);
gst_element_link_many(videoqueue,video_decoder,video_convertor,video_sink,NULL);
g_signal_connect(demuxer,"pad-added",G_CALLBACK(dynamic_addpad),NULL);//demuxer and decoder are passed as instance and data as pads of both the elements are linked in dynamic_addpad
g_signal_connect(video_decoder,"new-decoded-pad",G_CALLBACK(dynamic_decodepad),NULL);//demuxer and decoder are passed as instance and data as pads of both the elements are linked in dynamic_addpad
gst_bus_add_watch(bus,process_message,Mainloop); //Mainloop is passed as user data as in the process_message actions are taken on the loop
g_object_unref(bus);
g_print("In playing state\n");
gst_element_set_state(pipeline,GST_STATE_PLAYING);//Pipeline is also a bin and bin is also an element at abstract level and hence gst_element_set_state call is used to set state of pipeline.
g_main_loop_run(Mainloop);
g_print("In playing state2\n");
gst_element_set_state(pipeline,GST_STATE_NULL);
g_object_unref(G_OBJECT(pipeline));
}
//Function to process message on bus of pipeline
gboolean process_message(GstBus *bus, GstMessage *msg,gpointer data)
{
GError *error;
gchar *debug;
GMainLoop *loop = (GMainLoop *)data;
g_print(" In process message msg->type : %d\n",GST_MESSAGE_TYPE(msg));
switch(GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_UNKNOWN :
g_print("GST_MESSAGE_UNKNOWN \n");
break;
case GST_MESSAGE_EOS :
g_print("GST_MESSAGE_EOS \n");
g_main_loop_quit(loop);
break;
case GST_MESSAGE_ERROR :
g_print("GST_MESSAGE_ERROR \n");
gst_message_parse_error (msg, &error, &debug);
g_free(debug);
//if(!error)
{
g_print("GST_MESSAGE_ERROR message : %s \n",error->message);
}
g_main_loop_quit(loop);
break;
case GST_MESSAGE_WARNING :
g_print("GST_MESSAGE_WARNING \n");
break;
case GST_MESSAGE_INFO :
g_print("GST_MESSAGE_INFO \n");
break;
case GST_MESSAGE_TAG :
g_print("GST_MESSAGE_TAG \n");
break;
case GST_MESSAGE_BUFFERING:
g_print("GST_MESSAGE_BUFFERING \n");
break;
case GST_MESSAGE_STATE_CHANGED:
g_print("GST_MESSAGE_STATE_CHANGED \n");
break;
default :
g_print("default \n");
break;
}
return TRUE; //returns true always as it has to be always registered returning false will deregister the function
}
//Function to add pad dynamically for ogg demux
void dynamic_addpad(GstElement *element, GstPad *pad, gpointer data)
{
GstPad *audiodemuxsink;
GstPad *videodemuxsink;
GstElement *decoder = (GstElement *)data;
g_print(" In dynamic ADDING PAD\n");
audiodemuxsink = gst_element_get_static_pad(audioqueue,"sink");
gst_pad_link(pad,audiodemuxsink );
videodemuxsink = gst_element_get_static_pad(videoqueue,"sink");
gst_pad_link(pad,videodemuxsink );
g_print(" In dynamic ADDING PAD2\n");
}
void dynamic_decodepad (GstElement* object, GstPad* pad, gboolean arg1,gpointer user_data)
{
GstPad *videoconvertsink;
GstPad *audioconvertsink ;
g_print(" In dynamic_decodepad ADDING PAD\n");
videoconvertsink = gst_element_get_static_pad(video_convertor,"sink");
gst_pad_link(pad,videoconvertsink);
audioconvertsink = gst_element_get_static_pad(audio_convertor,"sink");
gst_pad_link(pad,audioconvertsink );
g_print(" In dynamic_decodepad ADDING PAD2\n");
}
Output:
In playing state
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 8192
default
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 8192
default
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 8192
default
In process message msg->type : 8192
default
In dynamic ADDING PAD
In dynamic ADDING PAD2
In dynamic ADDING PAD
In dynamic ADDING PAD2
In process message msg->type : 16
GST_MESSAGE_TAG
In process message msg->type : 16
GST_MESSAGE_TAG
In process message msg->type : 16
GST_MESSAGE_TAG
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In dynamic_decodepad ADDING PAD
In dynamic_decodepad ADDING PAD2
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
In process message msg->type : 64
GST_MESSAGE_STATE_CHANGED
代码:
#包括
#包括
#包括
//用于处理管道总线上的消息的函数
gboolean进程_消息(GstBus*总线、GstMessage*消息、gpointer数据);
//用于为ogg解复用器动态添加pad的函数
void dynamic_addpad(GstElement*元素、GstPad*pad、gpointer数据);
void dynamic_decodepad(GstElement*对象、GstPad*arg0、gboolean arg1、gpointer用户_数据);
GstElement*源、*解复用器、*音频解码器、*视频解码器、*音频转换器、*视频转换器、*音频接收器、*视频接收器、*音频队列、*视频队列//*音频解复用器,*视频解复用器,
int main(int argc,char*argv[])
{
GstPipeline*管道;
GstBin*Bin;
GstBus*总线;
GMainLoop*Mainloop;
gst_init(&argc,&argv);
Mainloop=g_main_loop_new(NULL,FALSE);//NULL表示使用当前上下文,FALSE表示其未处于运行状态
管道=gst_管道_新(“管道”);
Bin=GST_Bin(管道);
总线=gst\U管道\U get\U总线(管道);
来源=gst元素工厂制造(“文件来源”);
g_对象集(g_对象(源),“位置”,argv[1],空);
解复用器=商品及服务税、元件、工厂制造(“AVIDEMEX”、“avi解复用器”);
audioqueue=gst_元素_工厂_品牌(“队列”、“音频队列”);
videoqueue=gst_元素_工厂_品牌(“队列”、“视频队列”);
视频解码器=gst元素工厂制造(“decodebin”、“decoderbin”);/“Vorbis音频解码器”、“Vorbis”);
音频转换器=gst元素工厂制造(“音频转换器”、“音频转换器”);/“音频转换器”、“音频转换器”);
视频转换器=gst元素工厂制造(“视频秤”、“视频转换器”);/“音频转换器”、“音频转换器”);
音频接收器=gst元件工厂制造(“自动音频接收器”、“自动音频接收器”);
视频接收器=gst元件工厂制造(“xImage接收器”、“XV视频接收器”);
如果(!source | | |!demuxer | |!audioqueue | |!videoqueue | |!video |解码器|!audio |转换器|!video |转换器|!audio | sink |!video | sink)
{g_print(“无法创建元素\n”);
返回0;
}
gst_bin_add(bin,来源);
gst_bin_add_many(bin、解复用器、音频队列、视频队列、音频转换器、视频解码器、视频转换器、音频接收器、视频接收器、空);
gst_元素_链接(来源、解复用器);
gst元素链接(音频队列、视频解码器、音频转换器、音频接收器、空);
gst元素链接(视频队列、视频解码器、视频转换器、视频接收器、空);
g_signal_connect(demuxer,“pad added”,g_CALLBACK(dynamic_addpad),NULL);//demuxer和decoder作为实例传递,作为两个元素的pad的数据在dynamic_addpad中链接
g_signal_connect(视频_解码器,“新解码垫”,g_回调(动态_decodepad),NULL);//解复用器和解码器作为实例传递,数据作为两个元素的垫在动态_addpad中链接
gst_bus_add_watch(bus,process_message,Mainloop);//Mainloop作为用户数据传递,就像在process_message中对循环执行操作一样
g_object_unref(总线);
g_print(“处于播放状态”);
gst U element_set_state(pipeline,gst_state_PLAYING);//pipeline也是bin,bin也是抽象级别的元素,因此使用gst\u element_set_state call来设置管道状态。
g_主回路运行(主回路);
g_print(“处于播放状态2\n”);
gst\元素\集合\状态(管道,gst\状态\空);
g_object_unref(g_object(pipeline));
}
//用于处理管道总线上的消息的函数
gboolean进程\ U消息(GstBus*总线、GstMessage*消息、gpointer数据)
{
GError*错误;
gchar*调试;
GMainLoop*循环=(GMainLoop*)数据;
g_打印(“正在处理的消息消息->类型:%d\n”,GST_消息类型(消息));
开关(GST\信息\类型(msg))
{
案例GST\u消息\u未知:
g_打印(“GST_消息_未知\n”);
打破
案例GST\信息\ EOS:
g_打印(“GST_消息_EOS\n”);
g_主循环退出(循环);
打破
案例GST\u消息\u错误:
g_打印(“GST_消息错误\n”);
gst\消息\解析\错误(消息、错误和调试);
g_自由(调试);
//如果(!错误)
{
g_打印(“GST_消息\u错误消息:%s\n”,错误->消息);
}
g_主循环退出(循环);
打破
案例信息警告:
g_打印(“GST_消息\u警告”);
打破
案例商品及服务税信息:
g_打印(“GST_信息”);
打破
案例GST\信息\标签:
g_打印(“GST_消息_标签”);
打破
案例GST_消息_缓冲:
g_打印(“GST_消息缓冲\n”);
打破
案例GST\消息\状态\更改:
g_打印(“GST_消息_状态_更改\n”);
打破
违约:
g_打印(“默认\n”);
打破
}
return TRUE;//始终返回TRUE,因为它必须始终注册。返回false将注销函数
}
//用于为ogg解复用器动态添加pad的函数
void dynamic_addpad(GstElement*元素、GstPad*pad、gpointer数据)
{
GstPad*音频解复用;
GstPad*视频解复用;
GstElement*解码器=(GstElement*)数据;
g_print(“在动态添加垫中”);
audiodemuxsink=gst_元素_获取_静态_垫(audioqueue,“接收器”);
gst_pad_链接(pad、audiodemuxsink);
videodemuxsink=gst_元素_获取_静态_垫(videoqueue,“接收器”);
gst_pad_link(pad、videodemuxsink);
g_
- pipeline = gst_pipeline_new("PIPELINE");
+ GstElement *pipeline = gst_pipeline_new("PIPELINE");
Bin = GST_BIN(pipeline);
- bus = gst_pipeline_get_bus(pipeline);
+ bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
videoqueue = gst_element_factory_make("queue","Queue for video");
+ audio_decoder = gst_element_factory_make("decodebin","a_decodebin");
video_decoder = gst_element_factory_make("decodebin","decoderbin");//"Vorbis audio decoder","vorbis");
- gst_bin_add_many(Bin,demuxer,audioqueue,videoqueue,audio_convertor,video_decoder,video_convertor,audio_sink,video_sink,NULL);
+ gst_bin_add_many(
+ Bin,
+ demuxer,
+ audioqueue,videoqueue,
+ audio_decoder,audio_convertor,
+ video_decoder,video_convertor,
+ audio_sink,video_sink,
+ NULL);
gst_element_link(source,demuxer);
- gst_element_link_many(audioqueue,video_decoder,audio_convertor,audio_sink,NULL);
- gst_element_link_many(videoqueue,video_decoder,video_convertor,video_sink,NULL);
+ gst_element_link_many(audioqueue,audio_decoder,NULL);
+ gst_element_link_many(audio_convertor,audio_sink,NULL);
+ gst_element_link_many(videoqueue,video_decoder,NULL);
+ gst_element_link_many(video_convertor,video_sink,NULL);
+ g_signal_connect(audio_decoder,"new-decoded-pad",G_CALLBACK(dynamic_decodepad),NULL);
g_signal_connect(video_decoder,"new-decoded-pad",G_CALLBACK(dynamic_decodepad),NULL);
void dynamic_addpad(GstElement *element, GstPad *pad, gpointer data)
{
GstPad *audiodemuxsink;
GstPad *videodemuxsink;
GstElement *decoder = (GstElement *)data;
g_print(" In dynamic ADDING PAD\n");
audiodemuxsink = gst_element_get_static_pad(audioqueue,"sink");
gst_pad_link(pad,audiodemuxsink );
videodemuxsink = gst_element_get_static_pad(videoqueue,"sink");
gst_pad_link(pad,videodemuxsink );
g_print(" In dynamic ADDING PAD2\n");
}
void dynamic_addpad(GstElement *element, GstPad *pad, gpointer data)
{
char* pad_name = gst_pad_get_name(pad);
g_print(" In dynamic ADDING PAD %s\n", pad_name);
if (g_str_has_prefix(pad_name,"audio")) {
GstPad *audiodemuxsink = gst_element_get_static_pad(audioqueue,"sink");
gst_pad_link(pad,audiodemuxsink );
}
else if (g_str_has_prefix(pad_name,"video")) {
GstPad *videodemuxsink = gst_element_get_static_pad(videoqueue,"sink");
gst_pad_link(pad,videodemuxsink );
}
g_free (pad_name);
}
void dynamic_decodepad (GstElement* object, GstPad* pad, gboolean arg1,gpointer user_data)
{
GstPad* videoconvertsink = gst_element_get_static_pad(video_convertor,"sink");
if (gst_pad_can_link(pad,videoconvertsink)) {
gst_pad_link(pad,videoconvertsink);
}
GstPad* audioconvertsink = gst_element_get_static_pad(audio_convertor,"sink");
if (gst_pad_can_link(pad,audioconvertsink)) {
gst_pad_link(pad,audioconvertsink);
}
}