From cb3af06726b828006efa8bd2898d62e6595c9060 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 25 Jun 2000 22:21:44 +0000 Subject: [PATCH] Added more accurate mpeg system stream detection (MPEG1 and MPEG2) Original commit message from CVS: Added more accurate mpeg system stream detection (MPEG1 and MPEG2) Added mpeg2 playback for gstplay --- gstplay/Makefile.am | 2 +- gstplay/codecs.h | 4 + gstplay/main.c | 8 +- gstplay/mpeg2.c | 169 ++++++++++++++++++++++++++++++++ libs/videoscale/gstvideoscale.c | 2 +- libs/videoscale/gstvideoscale.h | 2 +- 6 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 gstplay/mpeg2.c diff --git a/gstplay/Makefile.am b/gstplay/Makefile.am index 0b9a7b6e58..4a3405d579 100644 --- a/gstplay/Makefile.am +++ b/gstplay/Makefile.am @@ -8,7 +8,7 @@ bin_PROGRAMS = gstplay gstplay_SOURCES = \ main.c \ - mpeg1.c avi.c\ + mpeg1.c mpeg2.c avi.c\ support.c support.h \ interface.c interface.h \ callbacks.c callbacks.h diff --git a/gstplay/codecs.h b/gstplay/codecs.h index a94c22406a..4b21957ef8 100644 --- a/gstplay/codecs.h +++ b/gstplay/codecs.h @@ -3,5 +3,9 @@ void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline); void mpeg1_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline); +/* mpeg2.c */ +void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline); +void mpeg2_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline); + /* avi.c */ void avi_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline); diff --git a/gstplay/main.c b/gstplay/main.c index a21f433467..96ec3ae606 100644 --- a/gstplay/main.c +++ b/gstplay/main.c @@ -41,11 +41,16 @@ void have_type(GstSink *sink) { gst_pad_disconnect(gst_element_get_pad(src,"src"), gst_element_get_pad(GST_ELEMENT(sink),"sink")); - if (strstr(gsttype->mime, "mpeg-system")) { + if (strstr(gsttype->mime, "mpeg1-system")) { parse = gst_elementfactory_make("mpeg1parse","parse"); gtk_signal_connect(GTK_OBJECT(parse),"new_pad", GTK_SIGNAL_FUNC(mpeg1_new_pad_created),pipeline); } + else if (strstr(gsttype->mime, "mpeg2-system")) { + parse = gst_elementfactory_make("mpeg2parse","parse"); + gtk_signal_connect(GTK_OBJECT(parse),"new_pad", + GTK_SIGNAL_FUNC(mpeg2_new_pad_created),pipeline); + } else if (strstr(gsttype->mime, "avi")) { parse = gst_elementfactory_make("parseavi","parse"); gtk_signal_connect(GTK_OBJECT(parse),"new_pad", @@ -80,6 +85,7 @@ main (int argc, char *argv[]) gnome_init ("gstreamer", VERSION, argc, argv); gst_init(&argc,&argv); gst_plugin_load("mpeg1parse"); + gst_plugin_load("mpeg2parse"); gst_plugin_load("mp1videoparse"); gst_plugin_load("mp3parse"); gst_plugin_load("parsewav"); diff --git a/gstplay/mpeg2.c b/gstplay/mpeg2.c new file mode 100644 index 0000000000..f99456e722 --- /dev/null +++ b/gstplay/mpeg2.c @@ -0,0 +1,169 @@ + +#define BUFFER 1 +#define VIDEO_DECODER "mpeg2play" + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "codecs.h" + + +extern gboolean _gst_plugin_spew; +extern GstElement *show; + +void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) +{ + GstElement *parse_audio, *decode, *play; + GstElement *audio_queue; + GstElement *audio_thread; + + g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); + + // connect to audio pad + //if (0) { + if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) { + gst_plugin_load("ac3parse"); + gst_plugin_load("ac3dec"); + // construct internal pipeline elements + parse_audio = gst_elementfactory_make("ac3parse","parse_audio"); + g_return_if_fail(parse_audio != NULL); + decode = gst_elementfactory_make("ac3dec","decode_audio"); + g_return_if_fail(decode != NULL); + play = gst_elementfactory_make("audiosink","play_audio"); + g_return_if_fail(play != NULL); + + // create the thread and pack stuff into it + audio_thread = gst_thread_new("audio_thread"); + g_return_if_fail(audio_thread != NULL); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(audio_thread), + gst_element_get_pad(parse_audio,"sink")); + gst_pad_connect(gst_element_get_pad(parse_audio,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(play,"sink")); + + // construct queue and connect everything in the main pipelie + audio_queue = gst_elementfactory_make("queue","audio_queue"); + gtk_object_set(GTK_OBJECT(audio_queue),"max_level",30,NULL); + 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")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + 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); + } + // connect to audio pad + //if (0) { + if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { + gst_plugin_load("mp3parse"); + gst_plugin_load("mpg123"); + // 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); + + // create the thread and pack stuff into it + audio_thread = gst_thread_new("audio_thread"); + g_return_if_fail(audio_thread != NULL); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(audio_thread), + gst_element_get_pad(parse_audio,"sink")); + gst_pad_connect(gst_element_get_pad(parse_audio,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(play,"sink")); + + // construct queue and connect everything in the main pipelie + audio_queue = gst_elementfactory_make("queue","audio_queue"); + gtk_object_set(GTK_OBJECT(audio_queue),"max_level",BUFFER,NULL); + 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")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + 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) { + //} else if (0) { + mpeg2_setup_video_thread(pad, show, pipeline); + } +} + +void mpeg2_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline) +{ + GstElement *parse_video, *decode_video; + GstElement *video_queue; + GstElement *video_thread; + + gst_plugin_load("mp1videoparse"); + gst_plugin_load(VIDEO_DECODER); + // construct internal pipeline elements + parse_video = gst_elementfactory_make("mp1videoparse","parse_video"); + g_return_if_fail(parse_video != NULL); + decode_video = gst_elementfactory_make(VIDEO_DECODER,"decode_video"); + g_return_if_fail(decode_video != NULL); + + // create the thread and pack stuff into it + 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_video)); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(video_thread), + gst_element_get_pad(parse_video,"sink")); + gst_pad_connect(gst_element_get_pad(parse_video,"src"), + gst_element_get_pad(decode_video,"sink")); + gst_pad_connect(gst_element_get_pad(decode_video,"src"), + gst_element_get_pad(show,"sink")); + + // construct queue and connect everything in the main pipeline + video_queue = gst_elementfactory_make("queue","video_queue"); + gtk_object_set(GTK_OBJECT(video_queue),"max_level",BUFFER,NULL); + 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")); + + // set up thread state and kick things off + 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"); +} + diff --git a/libs/videoscale/gstvideoscale.c b/libs/videoscale/gstvideoscale.c index b047bdb4be..824a93d1c5 100644 --- a/libs/videoscale/gstvideoscale.c +++ b/libs/videoscale/gstvideoscale.c @@ -270,7 +270,7 @@ static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int pos += inc; } *eip++ = RETURN; - DEBUG("scaler start/end %p %p %p\n", copy_row, eip, eip-copy_row); + g_print("scaler start/end %p %p %p\n", copy_row, eip, eip-copy_row); } diff --git a/libs/videoscale/gstvideoscale.h b/libs/videoscale/gstvideoscale.h index a96d67b7c4..6287706131 100644 --- a/libs/videoscale/gstvideoscale.h +++ b/libs/videoscale/gstvideoscale.h @@ -39,7 +39,7 @@ struct _GstVideoScale { guint format; GstVideoScaleMethod method; /* private */ - guchar copy_row[4096]; + guchar copy_row[8192]; guchar *temp; void (*scale) (GstVideoScale *scale, unsigned char *src, unsigned char *dest); void (*scaler) (GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);