Rearranged and updated mp1parse. Indentation is sane again (what editor and it now uses threads. Playback is clean ...

Original commit message from CVS:
Rearranged and updated mp1parse.  Indentation is sane again (what editor
are you using, Wim?), and it now uses threads.  Playback is clean (at
least, audio and video are running smoothly.  Video is still a little
choppy on my test stream (first 1MB from disk two of Mulan VCD), and it's
still wildly out of sync, but it's looking VERY COOL.
This commit is contained in:
Erik Walthinsen 2000-02-12 23:09:57 +00:00
parent 1f05e5a957
commit d224516279

View file

@ -1,11 +1,10 @@
#include <gst/gst.h> #include <gst/gst.h>
extern gboolean _gst_plugin_spew; extern gboolean _gst_plugin_spew;
GstPipeline *pipeline;
void eof(GstSrc *src) { void eof(GstSrc *src) {
g_print("have eof, quitting\n"); g_print("have eos, quitting\n");
exit(0); exit(0);
} }
void mp1parse_info_chain(GstPad *pad,GstBuffer *buf) { void mp1parse_info_chain(GstPad *pad,GstBuffer *buf) {
@ -13,115 +12,123 @@ void mp1parse_info_chain(GstPad *pad,GstBuffer *buf) {
gst_buffer_unref(buf); gst_buffer_unref(buf);
} }
void new_pad_created(GstElement *parse, GstPad *pad) { void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
GstElementFactory *parsefactory, *decodefactory, *playfactory;
GstElement *parse_audio, *parse_video, *decode, *decode_video, *play; GstElement *parse_audio, *parse_video, *decode, *decode_video, *play;
GstPipeline *audio_pipeline, *video_pipeline; GstElement *audio_queue, *video_queue;
GstElement *audio_thread, *video_thread;
GstPad *infopad; GstPad *infopad;
g_print("a new pad %s was created\n", gst_pad_get_name(pad)); g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
// connect to audio pad // connect to audio pad
if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
// construct internal pipeline elements
parse_audio = gst_elementfactory_make("mp3parse","parse_audio");
g_return_if_fail(parse_audio != NULL);
decode = gst_elementfactory_make("mpg123","decode_audio");
g_return_if_fail(decode != NULL);
play = gst_elementfactory_make("audiosink","play_audio");
g_return_if_fail(play != NULL);
parsefactory = gst_elementfactory_find("mp3parse"); // create the thread and pack stuff into it
g_return_if_fail(parsefactory != NULL); audio_thread = gst_thread_new("audio_thread");
decodefactory = gst_elementfactory_find("mpg123"); g_return_if_fail(audio_thread != NULL);
g_return_if_fail(decodefactory != NULL); gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
playfactory = gst_elementfactory_find("audiosink"); gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
g_return_if_fail(playfactory != NULL); gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play));
parse_audio = gst_elementfactory_create(parsefactory,"parse_audio"); // set up pad connections
g_return_if_fail(parse_audio != NULL); gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
decode = gst_elementfactory_create(decodefactory,"decode_audio"); gst_element_get_pad(parse_audio,"sink"));
g_return_if_fail(decode != NULL); gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
play = gst_elementfactory_create(playfactory,"play_audio"); gst_element_get_pad(decode,"sink"));
g_return_if_fail(play != NULL); gst_pad_connect(gst_element_get_pad(decode,"src"),
gst_element_get_pad(play,"sink"));
audio_pipeline = gst_pipeline_new("audio_pipeline"); // construct queue and connect everything in the main pipelie
g_return_if_fail(audio_pipeline != NULL); audio_queue = gst_elementfactory_make("queue","audio_queue");
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
gst_pad_connect(pad,
gst_element_get_pad(audio_queue,"sink"));
gst_pad_connect(gst_element_get_pad(audio_queue,"src"),
gst_element_get_pad(audio_thread,"sink"));
gst_bin_add(GST_BIN(audio_pipeline),GST_ELEMENT(parse_audio)); // set up thread state and kick things off
gst_bin_add(GST_BIN(audio_pipeline),GST_ELEMENT(decode)); gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
gst_bin_add(GST_BIN(audio_pipeline),GST_ELEMENT(play)); g_print("setting to RUNNING state\n");
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_pipeline)); gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
infopad = gst_pad_new("sink",GST_PAD_SINK);
gst_pad_set_chain_function(infopad,mp1parse_info_chain);
gst_pad_connect(gst_element_get_pad(parse,gst_pad_get_name(pad)), // construct internal pipeline elements
gst_element_get_pad(parse_audio,"sink")); parse_video = gst_elementfactory_make("mp1videoparse","parse_video");
gst_pad_connect(gst_element_get_pad(parse_audio,"src"), g_return_if_fail(parse_video != NULL);
gst_element_get_pad(decode,"sink")); decode = gst_elementfactory_make("mpeg_play","decode_video");
gst_pad_connect(gst_element_get_pad(decode,"src"), g_return_if_fail(decode_video != NULL);
gst_element_get_pad(play,"sink"));
g_print("setting to RUNNING state\n"); // create the thread and pack stuff into it
gst_element_set_state(GST_ELEMENT(audio_pipeline),GST_STATE_RUNNING); video_thread = gst_thread_new("video_thread");
g_return_if_fail(video_thread != NULL);
gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(parse_video));
gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(decode));
} // set up pad connections
else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { gst_element_add_ghost_pad(GST_ELEMENT(video_thread),
gst_element_get_pad(parse_video,"sink"));
parsefactory = gst_elementfactory_find("mp1videoparse");
g_return_if_fail(parsefactory != NULL);
decodefactory = gst_elementfactory_find("mpeg_play");
g_return_if_fail(parsefactory != NULL);
parse_video = gst_elementfactory_create(parsefactory,"parse_video");
g_return_if_fail(parse_video != NULL);
decode = gst_elementfactory_create(decodefactory,"decode_video");
g_return_if_fail(decode_video != NULL);
video_pipeline = gst_pipeline_new("video_pipeline");
g_return_if_fail(video_pipeline != NULL);
infopad = gst_pad_new("sink",GST_PAD_SINK);
gst_pad_set_chain_function(infopad,mp1parse_info_chain);
gst_bin_add(GST_BIN(video_pipeline),GST_ELEMENT(parse_video));
gst_bin_add(GST_BIN(video_pipeline),GST_ELEMENT(decode));
gst_pad_connect(gst_element_get_pad(parse,gst_pad_get_name(pad)),
gst_element_get_pad(parse_video,"sink"));
gst_pad_connect(gst_element_get_pad(parse_video,"src"), gst_pad_connect(gst_element_get_pad(parse_video,"src"),
gst_element_get_pad(decode,"sink")); gst_element_get_pad(decode,"sink"));
gst_pad_connect(gst_element_get_pad(decode,"src"), gst_pad_connect(gst_element_get_pad(decode,"src"),
infopad); infopad);
// construct queue and connect everything in the main pipeline
video_queue = gst_elementfactory_make("queue","video_queue");
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread));
gst_pad_connect(pad,
gst_element_get_pad(video_queue,"sink"));
gst_pad_connect(gst_element_get_pad(video_queue,"src"),
gst_element_get_pad(video_thread,"sink"));
g_print("setting to RUNNING state\n"); // set up thread state and kick things off
gst_element_set_state(GST_ELEMENT(video_pipeline),GST_STATE_RUNNING); gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING);
} }
g_print("\n");
} }
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
GstElementFactory *srcfactory, *parsefactory; GstPipeline *pipeline;
GstElement *src, *parse; GstElement *src, *parse;
g_print("have %d args\n",argc); g_print("have %d args\n",argc);
_gst_plugin_spew = TRUE; _gst_plugin_spew = TRUE;
gst_init(&argc,&argv); gst_init(&argc,&argv);
// gst_plugin_load("mp3parse");
gst_plugin_load_all(); gst_plugin_load_all();
pipeline = gst_pipeline_new("pipeline"); pipeline = gst_pipeline_new("pipeline");
g_return_if_fail(pipeline != NULL); g_return_if_fail(pipeline != NULL);
srcfactory = gst_elementfactory_find("disksrc"); src = gst_elementfactory_make("disksrc","src");
g_return_if_fail(srcfactory != NULL);
parsefactory = gst_elementfactory_find("mpeg1parse");
g_return_if_fail(parsefactory != NULL);
src = gst_elementfactory_create(srcfactory,"src");
g_return_if_fail(src != NULL); g_return_if_fail(src != NULL);
gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL); gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL);
g_print("should be using file '%s'\n",argv[1]); g_print("should be using file '%s'\n",argv[1]);
parse = gst_elementfactory_create(parsefactory,"parse");
parse = gst_elementfactory_make("mpeg1parse","parse");
g_return_if_fail(parse != NULL); g_return_if_fail(parse != NULL);
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse));
gtk_signal_connect(GTK_OBJECT(parse),"new_pad", gtk_signal_connect(GTK_OBJECT(parse),"new_pad",
GTK_SIGNAL_FUNC(new_pad_created),NULL); GTK_SIGNAL_FUNC(new_pad_created),pipeline);
gtk_signal_connect(GTK_OBJECT(src),"eos", gtk_signal_connect(GTK_OBJECT(src),"eos",
GTK_SIGNAL_FUNC(eof),NULL); GTK_SIGNAL_FUNC(eof),NULL);
@ -132,6 +139,8 @@ int main(int argc,char *argv[]) {
g_print("setting to RUNNING state\n"); g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING);
xmlSaveFile("mp1parse.xml",gst_xml_write(GST_ELEMENT(pipeline)));
g_print("about to enter loop\n"); g_print("about to enter loop\n");
while (1) while (1)
gst_src_push(GST_SRC(src)); gst_src_push(GST_SRC(src));