GStreamer Application Development Manual
+ GStreamer 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 GStreamer 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 GStreamer
- 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 GStreamer
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 @@
+
+ gstreamer-config
+
+ 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
+
+
+
+
+
+ gstreamer-register
+
+ 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.
+
+
+
+
+ gstreamer-launch
+
+ 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.
+
+
+
+
+
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
+
+
+
+
+ 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;
}