diff --git a/docs/manual/gstreamer-manual.sgml b/docs/manual/gstreamer-manual.sgml index eb7fb5d12b..ac94d65c2e 100644 --- a/docs/manual/gstreamer-manual.sgml +++ b/docs/manual/gstreamer-manual.sgml @@ -51,7 +51,7 @@ - GStreamer Application Development Manual + <application>GStreamer</application> Application Development Manual @@ -60,10 +60,10 @@ Overview - The first chapter of the book gives you an overview of GStreamer - design goals. Chapter 2 rapidly covers the basics of GStreamer + The first chapter of the book gives you an overview of GStreamer + design goals. Chapter 2 rapidly covers the basics of GStreamer programming. In chapter 3 we will move on to the examples. - Since GStreamer adheres to the GTK+ programming model, the reader is + Since GStreamer adheres to the GTK+ programming model, the reader is assumed to understand the basics of GTK+. For a gentle introduction to GTK+, you may wish to read the GTK+ Tutorial or Eric Harlow's book Developing Linux @@ -84,7 +84,7 @@ Basic concepts - We will first describe the basics of the GStreamer programming by + We will first describe the basics of the GStreamer programming by introducing the different objects needed to create a media pipeline. @@ -111,7 +111,7 @@ With the basic concepts out of the way, you're ready to start building a - full-scale GStreamer application. + full-scale GStreamer application. We assume the reader is familiar with GTK+/GNOME programming. @@ -127,15 +127,15 @@ - Advanced GStreamer concepts + Advanced <application>GStreamer</application> concepts - In this part we will cover the more advanced features of GStreamer. + In this part we will cover the more advanced features of GStreamer. With the basics you learned in the prevous part you should be able to create a 'simple' pipeline. If you want more control over the media types and the pipeline you should use the more - low-level features of GStreamer. + low-level features of GStreamer. @@ -156,11 +156,11 @@ - XML in GStreamer + XML in <application>GStreamer</application> - GStreamer has the posibility to externalize the pipelines + GStreamer has the posibility to externalize the pipelines you create using an XML format. You can load a previously created pipeline by loading the XML file. @@ -171,12 +171,12 @@ - plugin development in GStreamer + plugin development in <application>GStreamer</application> In this part we will describe how you create a new plugin - to be used in GStreamer. + to be used in GStreamer. @@ -190,7 +190,7 @@ - GStreamer comes prepackaged with a few programs. + GStreamer comes prepackaged with a few programs. diff --git a/docs/manual/helloworld.sgml b/docs/manual/helloworld.sgml index 9b8709774e..043b21b2cd 100644 --- a/docs/manual/helloworld.sgml +++ b/docs/manual/helloworld.sgml @@ -39,8 +39,6 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ bin = gst_bin_new("bin"); @@ -89,6 +87,7 @@ int main(int argc,char *argv[]) gst_element_set_state(bin, GST_STATE_NULL); gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(decoder)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); @@ -120,16 +119,6 @@ int main(int argc,char *argv[]) - - For simplicity, we are going to load all known plugins. This has the effect - that all the codecs known to GStreamer are registered to the system. - - - ... - gst_plugin_load_all(); - ... - - We are going to create 4 elements and one bin. Since all objects are in fact elements, we can define them as: @@ -318,8 +307,8 @@ void eos(GstSrc *src) To compile the helloworld example, use: - gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c \ - -o helloworld `gstreamer-config --libs` `gtk-config --libs` + gcc -Wall `gstreamer-config --cflags --libs` helloworld.c \ + -o helloworld This uses the program gstreamer-config, which comes with GStreamer. This program "knows" diff --git a/docs/manual/helloworld2.sgml b/docs/manual/helloworld2.sgml index bc9db8e0ab..7fd7c8027f 100644 --- a/docs/manual/helloworld2.sgml +++ b/docs/manual/helloworld2.sgml @@ -16,7 +16,7 @@ We will create a second version of the helloworld application using autoplugging. Its source code is considerably more easy to write and - can also much more data types. + can also handle much more data types. @@ -25,7 +25,7 @@ static gboolean playing; -/* eos will be called when the src element has an end os stream */ +/* eos will be called when the src element has an end of stream */ void eos(GstSrc *src) { g_print("have eos, quitting\n"); @@ -36,7 +36,7 @@ void eos(GstSrc *src) int main(int argc,char *argv[]) { GstElement *disksrc, *audiosink; - GstPipeline *pipeline; + GstElement *pipeline; if (argc != 2) { g_print("usage: %s <filename>\n", argv[0]); @@ -44,8 +44,6 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ pipeline = gst_pipeline_new("pipeline"); @@ -63,7 +61,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(pipeline), disksrc); gst_bin_add(GST_BIN(pipeline), audiosink); - if (!gst_pipeline_autoplug(pipeline)) { + if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } @@ -159,8 +157,8 @@ int main(int argc,char *argv[]) To compile the helloworld2 example, use: - gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c \ - -o helloworld2 `gstreamer-config --libs` `gtk-config --libs` + gcc -Wall `gstreamer-config --cflags --libs` helloworld2.c \ + -o helloworld2 You can run the example with (substitute helloworld.mp3 with you favorite MP3 file): @@ -175,7 +173,7 @@ int main(int argc,char *argv[]) the pipeline. - ./helloworld2 helloworld.mpeg + ./helloworld2 mymovie.mpeg diff --git a/docs/manual/programs.sgml b/docs/manual/programs.sgml index d2fcd39991..386ae67ce9 100644 --- a/docs/manual/programs.sgml +++ b/docs/manual/programs.sgml @@ -3,4 +3,104 @@ + + <command>gstreamer-config</command> + + gstreamer-config is a script to get information about the installed + version of GStreamer. + This program "knows" what compiler switches are needed to compile programs that use + GStreamer. + + + + gstreamer-config accepts the following options: + + + + + Print the currently installed version of + GStreamer on the standard output. + + + + + Print the linker flags that are necessary to link a + GStreamer program. + + + + + Print the compiler flags that are necessary to compile a + GStreamer program. + + + + + + If specified, use PREFIX instead of the installation + prefix that GStreamer was built with when computing the + output for the and options. + This option is also used for the exec prefix if + was not specified. This option must be specified before any + or options. + + + + + + If specified, use PREFIX instead of the installation exec + prefix that GStreamer was built with when computing the + output for the and options. This option must be + specified before any or + options. + + + + + + A simple Makefile will contain something like: + +CC = gcc + +helloworld2: helloworld2.c + $(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2 + +clean: + rm -f *.o helloworld2 + + + + + + <command>gstreamer-register</command> + + gstreamer-register is used to rebuild the database of plugins. + It is used after a new plugin has been added to the system. The plugin database + can be found in /etc/gstreamer/reg.xml. + + + + + <command>gstreamer-launch</command> + + This is a tool that will construct pipelines based on a command-line + syntax. + + + A simple commandline looks like: + + +gstreamer-launch disksrc hello.mp3 ! mp3parse ! mpg123 ! audiosink-oss + + + A more complex pipeline looks like: + + +gstreamer-launch disksrc redpill.vob ! css-descramble ! private_stream_1.0 ! \ + (ac3parse ! ac3dec ! audiosink) video_0 ! (mpeg2dec ! videosink) + + + + + diff --git a/docs/manual/queues.sgml b/docs/manual/queues.sgml index 1a77d71aff..aaf86cb8bb 100644 --- a/docs/manual/queues.sgml +++ b/docs/manual/queues.sgml @@ -1,6 +1,32 @@ Queues + A GstQueue is an implementation of a GstConnection. + Queues can be used to connect two elements in such way that the data can + be buffered. + + + A buffer that is sinked to a Queue will not automatically be pushed to the + next connected element but will be buffered. It will be pushed to the next + element as soon as gst_connection_push() is called. + + + Queues are mostly used in conjunction with a GstThread to + provide an external connection for the thread elements. You could have one + thread feeding buffers into a GstQueue and another + thread repeadedly calling gst_connection_push() on the queue to feed its + internal elements. + + Below is a figure of a two-threaded decoder. We have one thread (the main execution + thread) reading the data from a file, and another thread decoding the data. + +
+ a two-threaded decoder with a queue + +
+ + +
diff --git a/docs/manual/threads.sgml b/docs/manual/threads.sgml index cb6592dd9d..9c484e54a2 100644 --- a/docs/manual/threads.sgml +++ b/docs/manual/threads.sgml @@ -1,6 +1,142 @@ Threads + GStreamer has support for multithreading throught the use of + the GstThread object. This object is in fact + a special GstBin that will become a thread when started. + + To construct a new thread you will perform something like: + + + + GstElement *my_thread; + + // create the thread object + my_thread = gst_thread_new("my_thread"); + g_return_if_fail(audio_thread != NULL); + + // add some plugins + gst_bin_add(GST_BIN(my_thread),GST_ELEMENT(funky_src)); + gst_bin_add(GST_BIN(my_thread),GST_ELEMENT(cool_effect)); + + // connect the elements here... + ... + + // prepare the thread + gst_element_set_state(GST_ELEMENT(my_thread),GST_STATE_READY); + + // start playing + gst_element_set_state(GST_ELEMENT(my_thread),GST_STATE_PLAYING); + + + + + The above program will create a thread with two elements in it. As soon + as it is set to the PLAYING state, the thread will start to iterate. + + + + + The thread must contain at least one element of type GstSrc + or GstConnection in order to work. + + + + + A thread will be visualised as below + +
+ a thread + +
+ + + As an example we show the helloworld program using a thread. + + + +#include <gst/gst.h> + +/* eos will be called when the src element has an end os stream */ +void eos(GstSrc *src, gpointer data) +{ + GstThread *thread = GST_THREAD(data); + g_print("have eos, quitting\n"); + + /* stop the bin */ + gst_element_set_state(GST_ELEMENT(thread), GST_STATE_NULL); + + gst_main_quit(); +} + +int main(int argc,char *argv[]) +{ + GstElement *disksrc, *audiosink; + GstElement *pipeline; + GstElement *thread; + + if (argc != 2) { + g_print("usage: %s <filename>\n", argv[0]); + exit(-1); + } + + gst_init(&argc,&argv); + + /* create a new thread to hold the elements */ + thread = gst_thread_new("thread"); + g_assert(thread != NULL); + + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new("pipeline"); + g_assert(pipeline != NULL); + + /* create a disk reader */ + disksrc = gst_elementfactory_make("disksrc", "disk_source"); + g_assert(disksrc != NULL); + gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); + gtk_signal_connect(GTK_OBJECT(disksrc),"eos", + GTK_SIGNAL_FUNC(eos), thread); + + /* and an audio sink */ + audiosink = gst_elementfactory_make("audiosink", "play_audio"); + g_assert(audiosink != NULL); + + /* add objects to the main pipeline */ + gst_bin_add(GST_BIN(pipeline), disksrc); + gst_bin_add(GST_BIN(pipeline), audiosink); + + /* automatically setup the pipeline */ + if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { + g_print("unable to handle stream\n"); + exit(-1); + } + + /* remove the source element from the pipeline */ + gst_bin_remove(GST_BIN(pipeline), disksrc); + + /* insert the source element in the thread, remember a thread needs at + least one source or connection element */ + gst_bin_add(GST_BIN(thread), disksrc); + + /* add the pipeline to the thread too */ + gst_bin_add(GST_BIN(thread), GST_ELEMENT(pipeline)); + + /* make it ready */ + gst_element_set_state(GST_ELEMENT(thread), GST_STATE_READY); + /* start playing */ + gst_element_set_state(GST_ELEMENT(thread), GST_STATE_PLAYING); + + /* do whatever you want here, the thread will be playing */ + ... + + gst_main(); + + gst_pipeline_destroy(thread); + + exit(0); +} + +
diff --git a/editor/editor.c b/editor/editor.c index 6dcd80672a..45602fa69b 100644 --- a/editor/editor.c +++ b/editor/editor.c @@ -37,6 +37,7 @@ int main(int argc,char *argv[]) { _gst_plugin_spew = TRUE; gst_init(&argc,&argv); gst_plugin_load_all(); + gst_plugin_load("gstelements"); gnome_init("GST Graph Editor",VERSION,argc,argv); appwindow = gnome_app_new("gst-editor","GST Graph Editor"); diff --git a/editor/gsteditor.c b/editor/gsteditor.c index 62f4eee39a..238ecda51e 100644 --- a/editor/gsteditor.c +++ b/editor/gsteditor.c @@ -120,7 +120,7 @@ static void gst_editor_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch (id) { case ARG_NAME: gtk_object_set(GTK_OBJECT(editor),"label",GTK_VALUE_STRING(*arg),NULL); - gst_element_set_name(GST_OBJECT(editor->pipeline), + gst_element_set_name(GST_ELEMENT(editor->pipeline), GTK_VALUE_STRING(*arg)); break; default: @@ -135,7 +135,7 @@ static void gst_editor_get_arg(GtkObject *object,GtkArg *arg,guint id) { switch (id) { case ARG_NAME: GTK_VALUE_STRING(*arg) = - gst_element_get_name(GST_OBJECT(editor->pipeline)); + gst_element_get_name(GST_ELEMENT(editor->pipeline)); break; default: arg->type = GTK_TYPE_INVALID; diff --git a/editor/gsteditor.h b/editor/gsteditor.h index 4bc04e123c..2603abb1e7 100644 --- a/editor/gsteditor.h +++ b/editor/gsteditor.h @@ -56,7 +56,7 @@ struct _GstEditor { GtkFrame frame; /* the actual pipeline to be associated with this thing */ - GstPipeline *pipeline; + GstElement *pipeline; /* the editor canvas */ GstEditorCanvas *canvas; diff --git a/editor/gstelementselect.c b/editor/gstelementselect.c index e467b9cd23..4c7b0b9c84 100644 --- a/editor/gstelementselect.c +++ b/editor/gstelementselect.c @@ -201,6 +201,7 @@ GstElementFactory *element_select_dialog() { elements = gst_elementfactory_get_list(); while (elements) { element = (GstElementFactory *)(elements->data); + printf("%s %s\n", element->name, element->details->class); /* split up the factory's class */ classes = g_strsplit(element->details->class,"/",0); class = classes; diff --git a/examples/helloworld/Makefile b/examples/helloworld/Makefile index 8057681985..ab164c83f5 100644 --- a/examples/helloworld/Makefile +++ b/examples/helloworld/Makefile @@ -2,7 +2,7 @@ CC = gcc helloworld: helloworld.c - $(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs` + $(CC) -Wall `gstreamer-config --cflags --libs` helloworld.c -o helloworld clean: rm -f *.o helloworld diff --git a/examples/helloworld/helloworld.c b/examples/helloworld/helloworld.c index bee8275344..2a3a4867b3 100644 --- a/examples/helloworld/helloworld.c +++ b/examples/helloworld/helloworld.c @@ -2,7 +2,7 @@ gboolean playing; -/* eos will be called when the src element has an end os stream */ +/* eos will be called when the src element has an end of stream */ void eos(GstSrc *src) { g_print("have eos, quitting\n"); @@ -20,8 +20,6 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ bin = gst_bin_new("bin"); @@ -40,6 +38,7 @@ int main(int argc,char *argv[]) /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin), disksrc); + gst_bin_add(GST_BIN(bin), parse); gst_bin_add(GST_BIN(bin), decoder); gst_bin_add(GST_BIN(bin), audiosink); @@ -69,6 +68,7 @@ int main(int argc,char *argv[]) gst_element_set_state(bin, GST_STATE_NULL); gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(decoder)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/examples/helloworld2/Makefile b/examples/helloworld2/Makefile index 937424ae1d..22e6148b47 100644 --- a/examples/helloworld2/Makefile +++ b/examples/helloworld2/Makefile @@ -2,7 +2,7 @@ CC = gcc helloworld2: helloworld2.c - $(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c -o helloworld2 `gstreamer-config --libs` `gtk-config --libs` + $(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2 clean: rm -f *.o helloworld2 diff --git a/examples/helloworld2/helloworld2.c b/examples/helloworld2/helloworld2.c index 42a194a673..2405310cca 100644 --- a/examples/helloworld2/helloworld2.c +++ b/examples/helloworld2/helloworld2.c @@ -2,7 +2,7 @@ static gboolean playing; -/* eos will be called when the src element has an end os stream */ +/* eos will be called when the src element has an end of stream */ void eos(GstSrc *src) { g_print("have eos, quitting\n"); @@ -13,7 +13,7 @@ void eos(GstSrc *src) int main(int argc,char *argv[]) { GstElement *disksrc, *audiosink; - GstPipeline *pipeline; + GstElement *pipeline; if (argc != 2) { g_print("usage: %s \n", argv[0]); @@ -41,7 +41,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(pipeline), disksrc); gst_bin_add(GST_BIN(pipeline), audiosink); - if (!gst_pipeline_autoplug(pipeline)) { + if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } diff --git a/gst/elements/gstdisksrc.h b/gst/elements/gstdisksrc.h index 26afb42658..da27358e60 100644 --- a/gst/elements/gstdisksrc.h +++ b/gst/elements/gstdisksrc.h @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ -GstElementDetails gst_disksrc_details; +extern GstElementDetails gst_disksrc_details; #define GST_TYPE_DISKSRC \ @@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details; #define GST_IS_DISKSRC(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC)) #define GST_IS_DISKSRC_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC)) // NOTE: per-element flags start with 16 for now typedef enum { diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index 9900496a47..366de28356 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) { GstElementFactory *factory; int i = 0; - if (gst_plugin_find("gstelements") != NULL) return NULL; - plugin = gst_plugin_new("gstelements"); g_return_val_if_fail(plugin != NULL,NULL); diff --git a/gst/gst.c b/gst/gst.c index 606134db92..c41153dfe4 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -57,3 +57,13 @@ void gst_init(int *argc,char **argv[]) { gst_trace_set_default(gst_trace); } } + +void gst_main() { + gdk_threads_enter(); + gtk_main(); + gdk_threads_leave(); +} + +void gst_main_quit() { + gtk_main_quit(); +} diff --git a/gst/gst.h b/gst/gst.h index 1f08293508..5ac3c681fe 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -50,6 +50,9 @@ /* initialize GST */ void gst_init(int *argc,char **argv[]); +void gst_main(); +void gst_main_quit(); + /* debugging */ #ifndef DEBUG #ifdef DEBUG_ENABLED diff --git a/gst/gstbin.h b/gst/gstbin.h index f169c99c9a..a1962fab4d 100644 --- a/gst/gstbin.h +++ b/gst/gstbin.h @@ -32,7 +32,7 @@ extern "C" { #endif /* __cplusplus */ -GstElementDetails gst_bin_details; +extern GstElementDetails gst_bin_details; #define GST_TYPE_BIN \ diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 50d53df2cc..566a1293fa 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -122,6 +122,7 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory, // create an instance of the element element = GST_ELEMENT(gtk_type_new(factory->type)); g_assert(element != NULL); + gst_object_ref(GST_OBJECT(element)); // attempt to set the elemenfactory class pointer if necessary oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass); diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index 104a500737..100005db6b 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -102,12 +102,12 @@ static void gst_pipeline_init(GstPipeline *pipeline) { * * Returns: newly created GstPipeline */ -GstPipeline *gst_pipeline_new(guchar *name) { +GstElement *gst_pipeline_new(guchar *name) { GstPipeline *pipeline; pipeline = gtk_type_new(gst_pipeline_get_type()); gst_element_set_name(GST_ELEMENT(pipeline),name); - return pipeline; + return GST_ELEMENT(pipeline); } static void gst_pipeline_prepare(GstPipeline *pipeline) { @@ -157,6 +157,7 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element) gst_pad_disconnect(gst_element_get_pad(element,"src"), gst_element_get_pad(typefind,"sink")); gst_bin_remove(GST_BIN(pipeline), typefind); + gst_object_unref(GST_OBJECT(typefind)); return type_id; } @@ -223,7 +224,7 @@ end: gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { GList *elements; - GstElement *element, *srcelement, *sinkelement; + GstElement *element, *srcelement = NULL, *sinkelement= NULL; GList *factories; GstElementFactory *factory; GList *src_types, *sink_types; diff --git a/gst/gstpipeline.h b/gst/gstpipeline.h index 97772657c3..f186eaf705 100644 --- a/gst/gstpipeline.h +++ b/gst/gstpipeline.h @@ -29,7 +29,7 @@ extern "C" { #endif /* __cplusplus */ -GstElementDetails gst_pipeline_details; +extern GstElementDetails gst_pipeline_details; #define GST_TYPE_PIPELINE \ @@ -55,7 +55,7 @@ struct _GstPipelineClass { }; GtkType gst_pipeline_get_type(void); -GstPipeline *gst_pipeline_new(guchar *name); +GstElement *gst_pipeline_new(guchar *name); #define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline)) gboolean gst_pipeline_autoplug(GstPipeline *pipeline); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index bcb2f9a774..9c1c102354 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -253,7 +253,7 @@ gboolean gst_plugin_load_absolute(gchar *name) { return TRUE; } else if (_gst_plugin_spew) { // if (strstr(g_module_error(),"No such") == NULL) - gst_info("error loading plugin: %s\n",g_module_error()); + gst_info("error loading plugin: %s, reasion: %s\n", name, g_module_error()); } return FALSE; diff --git a/gst/gstsrc.c b/gst/gstsrc.c index 429e804341..73acd95c4d 100644 --- a/gst/gstsrc.c +++ b/gst/gstsrc.c @@ -70,7 +70,7 @@ gst_src_class_init(GstSrcClass *klass) { gst_src_signals[EOS] = gtk_signal_new("eos",GTK_RUN_LAST,gtkobject_class->type, GTK_SIGNAL_OFFSET(GstSrcClass,eos), - gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1, + gtk_marshal_NONE__NONE,GTK_TYPE_NONE,0, GST_TYPE_SRC); gtk_object_class_add_signals(gtkobject_class,gst_src_signals,LAST_SIGNAL); } @@ -90,7 +90,7 @@ void gst_src_signal_eos(GstSrc *src) { g_return_if_fail(src != NULL); g_return_if_fail(GST_IS_SRC(src)); - gtk_signal_emit(GTK_OBJECT(src),gst_src_signals[EOS],src); + gtk_signal_emit(GTK_OBJECT(src),gst_src_signals[EOS]); } /** diff --git a/gst/gstthread.c b/gst/gstthread.c index 9547c8f408..41adceb055 100644 --- a/gst/gstthread.c +++ b/gst/gstthread.c @@ -217,11 +217,17 @@ static GstElementStateReturn gst_thread_change_state(GstElement *element) { gst_thread_signal_thread(thread); break; case GST_STATE_PAUSED: - gst_info("gstthread: stopping thread \"%s\"\n", + gst_info("gstthread: pausing thread \"%s\"\n", gst_element_get_name(GST_ELEMENT(element))); GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING); gst_thread_signal_thread(thread); break; + case GST_STATE_NULL: + gst_info("gstthread: stopping thread \"%s\"\n", + gst_element_get_name(GST_ELEMENT(element))); + GST_FLAG_SET(thread,GST_THREAD_STATE_REAPING); + gst_thread_signal_thread(thread); + break; default: break; } @@ -253,7 +259,7 @@ void *gst_thread_main_loop(void *arg) { } GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING); - //pthread_join(thread->thread_id,0); + pthread_join(thread->thread_id,0); gst_info("gstthread: thread \"%s\" is stopped\n", gst_element_get_name(GST_ELEMENT(thread))); diff --git a/gst/gstthread.h b/gst/gstthread.h index 0f96eb00ec..7e221f2632 100644 --- a/gst/gstthread.h +++ b/gst/gstthread.h @@ -30,7 +30,7 @@ extern "C" { #endif /* __cplusplus */ -GstElementDetails gst_thread_details; +extern GstElementDetails gst_thread_details; typedef enum { diff --git a/gstplay/mpeg1.c b/gstplay/mpeg1.c index d02c743fad..4febea6064 100644 --- a/gstplay/mpeg1.c +++ b/gstplay/mpeg1.c @@ -20,17 +20,20 @@ void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); - gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); // connect to audio pad //if (0) { if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0 && audio_render_queue) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); mpeg1_setup_audio_thread(pad, audio_render_queue, pipeline); } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { //} else if (0) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); mpeg1_setup_video_thread(pad, video_render_queue, pipeline); } + else return; + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); } diff --git a/gstplay/mpeg2.c b/gstplay/mpeg2.c index 26b12eca98..990f3185e1 100644 --- a/gstplay/mpeg2.c +++ b/gstplay/mpeg2.c @@ -23,15 +23,16 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) GstElement *audio_thread; g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); - gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); // connect to audio pad if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); mpeg2_setup_video_thread(pad, video_render_queue, pipeline); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); return; } else if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); gst_plugin_load("ac3parse"); gst_plugin_load("ac3dec"); // construct internal pipeline elements @@ -40,12 +41,14 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) decode = gst_elementfactory_make("ac3dec","decode_audio"); g_return_if_fail(decode != NULL); } else if (strncmp(gst_pad_get_name(pad), "subtitle_stream_4", 17) == 0) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); gst_pad_connect(pad, gst_element_get_pad(merge_subtitles,"subtitle")); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); return; } else if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); gst_plugin_load("mp3parse"); gst_plugin_load("mpg123"); // construct internal pipeline elements @@ -55,7 +58,6 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) g_return_if_fail(decode != NULL); } else { - gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); return; } diff --git a/gstreamer-config.in b/gstreamer-config.in index cef310e334..ad9c04863f 100644 --- a/gstreamer-config.in +++ b/gstreamer-config.in @@ -45,16 +45,16 @@ while test $# -gt 0; do if test $prefix -ef @builddir@ ; then includes=-I@builddir@ elif test @includedir@ != /usr/include ; then - includes=-I@includedir@ + includes=-I@includedir@ fi - echo $includes + echo $includes `gtk-config --cflags` ;; --libs) if test $prefix -ef @builddir@ ; then - echo @builddir@/libgst.la + echo @builddir@/libgst.la `gtk-config --libs` else libdirs=-L@libdir@ - echo $libdirs -lgst + echo $libdirs -lgst `gtk-config --libs` fi ;; *) diff --git a/plugins/elements/gstdisksrc.h b/plugins/elements/gstdisksrc.h index 26afb42658..da27358e60 100644 --- a/plugins/elements/gstdisksrc.h +++ b/plugins/elements/gstdisksrc.h @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ -GstElementDetails gst_disksrc_details; +extern GstElementDetails gst_disksrc_details; #define GST_TYPE_DISKSRC \ @@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details; #define GST_IS_DISKSRC(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC)) #define GST_IS_DISKSRC_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC)) // NOTE: per-element flags start with 16 for now typedef enum { diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index 9900496a47..366de28356 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) { GstElementFactory *factory; int i = 0; - if (gst_plugin_find("gstelements") != NULL) return NULL; - plugin = gst_plugin_new("gstelements"); g_return_val_if_fail(plugin != NULL,NULL); diff --git a/tests/old/examples/helloworld/Makefile b/tests/old/examples/helloworld/Makefile index 8057681985..ab164c83f5 100644 --- a/tests/old/examples/helloworld/Makefile +++ b/tests/old/examples/helloworld/Makefile @@ -2,7 +2,7 @@ CC = gcc helloworld: helloworld.c - $(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs` + $(CC) -Wall `gstreamer-config --cflags --libs` helloworld.c -o helloworld clean: rm -f *.o helloworld diff --git a/tests/old/examples/helloworld/helloworld.c b/tests/old/examples/helloworld/helloworld.c index bee8275344..2a3a4867b3 100644 --- a/tests/old/examples/helloworld/helloworld.c +++ b/tests/old/examples/helloworld/helloworld.c @@ -2,7 +2,7 @@ gboolean playing; -/* eos will be called when the src element has an end os stream */ +/* eos will be called when the src element has an end of stream */ void eos(GstSrc *src) { g_print("have eos, quitting\n"); @@ -20,8 +20,6 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ bin = gst_bin_new("bin"); @@ -40,6 +38,7 @@ int main(int argc,char *argv[]) /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin), disksrc); + gst_bin_add(GST_BIN(bin), parse); gst_bin_add(GST_BIN(bin), decoder); gst_bin_add(GST_BIN(bin), audiosink); @@ -69,6 +68,7 @@ int main(int argc,char *argv[]) gst_element_set_state(bin, GST_STATE_NULL); gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(decoder)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/tests/old/examples/helloworld2/Makefile b/tests/old/examples/helloworld2/Makefile index 937424ae1d..22e6148b47 100644 --- a/tests/old/examples/helloworld2/Makefile +++ b/tests/old/examples/helloworld2/Makefile @@ -2,7 +2,7 @@ CC = gcc helloworld2: helloworld2.c - $(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c -o helloworld2 `gstreamer-config --libs` `gtk-config --libs` + $(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2 clean: rm -f *.o helloworld2 diff --git a/tests/old/examples/helloworld2/helloworld2.c b/tests/old/examples/helloworld2/helloworld2.c index 42a194a673..2405310cca 100644 --- a/tests/old/examples/helloworld2/helloworld2.c +++ b/tests/old/examples/helloworld2/helloworld2.c @@ -2,7 +2,7 @@ static gboolean playing; -/* eos will be called when the src element has an end os stream */ +/* eos will be called when the src element has an end of stream */ void eos(GstSrc *src) { g_print("have eos, quitting\n"); @@ -13,7 +13,7 @@ void eos(GstSrc *src) int main(int argc,char *argv[]) { GstElement *disksrc, *audiosink; - GstPipeline *pipeline; + GstElement *pipeline; if (argc != 2) { g_print("usage: %s \n", argv[0]); @@ -41,7 +41,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(pipeline), disksrc); gst_bin_add(GST_BIN(pipeline), audiosink); - if (!gst_pipeline_autoplug(pipeline)) { + if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } diff --git a/tools/gstreamer-launch.c b/tools/gstreamer-launch.c index fb5e8c4931..932c5e7e64 100644 --- a/tools/gstreamer-launch.c +++ b/tools/gstreamer-launch.c @@ -66,7 +66,7 @@ void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) { // snag the length in advance; len = strlen(argv[i]); // if it's just a connection, pick the 'src' pad and move on - if ((ptr = strchr(argv[i],'|')) != 0) { + if ((ptr = strchr(argv[i],'!')) != 0) { // if there's a previous pad name if (ptr != argv[i]) { ptr[0] = '\0'; @@ -91,29 +91,18 @@ void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) { } int main(int argc,char *argv[]) { - int t; GstElement *pipeline; gst_init(&argc,&argv); - gst_plugin_load_all(); - gst_info("\n\n"); + pipeline = gst_thread_new("launch"); - pipeline = gst_elementfactory_make("thread","launch"); - if ((t = atoi(argv[1]))) - parse(argc,argv,pipeline,2,0); - else - parse(argc,argv,pipeline,1,0); - - xmlSaveFile("launch.xml",gst_xml_write(pipeline)); + parse(argc,argv,pipeline,1,0); gst_element_set_state(pipeline,GST_STATE_READY); gst_element_set_state(pipeline,GST_STATE_PLAYING); - if (t) - sleep(t); - else - sleep(5); + gst_main(); - return 1; + return 0; }