Changes to gstreamer-config to include gtk+ libs manual changes: queues, threads...
authorWim Taymans <wim.taymans@gmail.com>
Sat, 9 Sep 2000 16:36:10 +0000 (16:36 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sat, 9 Sep 2000 16:36:10 +0000 (16:36 +0000)
Original commit message from CVS:
Changes to gstreamer-config to include gtk+ libs
manual changes: queues, threads, programs
gsteditor does not crash anymore.
gstpipline new should return a GstElement *
fixed ac3dec for new getbits
fixes to gstreamer-launch
more efficient startup for gstplay.

36 files changed:
docs/manual/gstreamer-manual.sgml
docs/manual/helloworld.sgml
docs/manual/helloworld2.sgml
docs/manual/programs.sgml
docs/manual/queues.sgml
docs/manual/threads.sgml
editor/editor.c
editor/gsteditor.c
editor/gsteditor.h
editor/gstelementselect.c
examples/helloworld/Makefile
examples/helloworld/helloworld.c
examples/helloworld2/Makefile
examples/helloworld2/helloworld2.c
gst/elements/gstdisksrc.h
gst/elements/gstelements.c
gst/gst.c
gst/gst.h
gst/gstbin.h
gst/gstelementfactory.c
gst/gstpipeline.c
gst/gstpipeline.h
gst/gstplugin.c
gst/gstsrc.c
gst/gstthread.c
gst/gstthread.h
gstplay/mpeg1.c
gstplay/mpeg2.c
gstreamer-config.in
plugins/elements/gstdisksrc.h
plugins/elements/gstelements.c
tests/old/examples/helloworld/Makefile
tests/old/examples/helloworld/helloworld.c
tests/old/examples/helloworld2/Makefile
tests/old/examples/helloworld2/helloworld2.c
tools/gstreamer-launch.c

index eb7fb5d..ac94d65 100644 (file)
@@ -51,7 +51,7 @@
       </para>
     </legalnotice>
 
-    <title>GStreamer Application Development Manual</title>
+    <title><application>GStreamer</application> Application Development Manual</title>
 
   </bookinfo>
       
   <part id="overview"><title>Overview</title>
     <partintro>
       <para> 
-        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 <application>GStreamer</application>
+        design goals. Chapter 2 rapidly covers the basics of <application>GStreamer</application>
         programming. In chapter 3 we will move on to the examples. 
-        Since GStreamer adheres to the GTK+ programming model, the reader is 
+        Since <application>GStreamer</application> 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 <emphasis>GTK+
         Tutorial</emphasis> or Eric Harlow's book <emphasis>Developing Linux
@@ -84,7 +84,7 @@
   <part id="basic-concepts"><title>Basic concepts</title>
     <partintro>
       <para> 
-        We will first describe the basics of the GStreamer programming by
+        We will first describe the basics of the <application>GStreamer</application> programming by
         introducing the different objects needed to create a media pipeline.
       </para>
       <para> 
     <partintro>
       <para>
         With the basic concepts out of the way, you're ready to start building a
-        full-scale GStreamer application. 
+        full-scale <application>GStreamer</application> application. 
       </para>
       <para>
         We assume the reader is familiar with GTK+/GNOME programming.
 
 <!-- ############ Advanced GStreamer - part ############# -->
 
-  <part id="advanced"><title>Advanced GStreamer concepts</title>
+  <part id="advanced"><title>Advanced <application>GStreamer</application> concepts</title>
 
     <partintro>
       <para>
-        In this part we will cover the more advanced features of GStreamer.
+        In this part we will cover the more advanced features of <application>GStreamer</application>.
        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 <application>GStreamer</application>.
       </para>      
     </partintro>
 
 
 <!-- ############ XML in GStreamer - part ############# -->
 
-  <part id="xml-gstreamer"><title>XML in GStreamer</title>
+  <part id="xml-gstreamer"><title>XML in <application>GStreamer</application></title>
 
     <partintro>
       <para>
-        GStreamer has the posibility to externalize the pipelines
+        <application>GStreamer</application> 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.
       </para>      
 
 <!-- ############ XML in GStreamer - part ############# -->
 
-  <part id="plugins"><title>plugin development in GStreamer</title>
+  <part id="plugins"><title>plugin development in <application>GStreamer</application></title>
 
     <partintro>
       <para>
         In this part we will describe how you create a new plugin
-       to be used in GStreamer.
+       to be used in <application>GStreamer</application>.
       </para>      
     </partintro>
 
 
     <partintro>
       <para>
-        GStreamer comes prepackaged with a few programs.
+        <application>GStreamer</application> comes prepackaged with a few programs.
       </para>
     </partintro>
 
index 9b87097..043b21b 100644 (file)
@@ -39,8 +39,6 @@ int main(int argc,char *argv[])
   }
 
   gst_init(&amp;argc,&amp;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));
@@ -121,16 +120,6 @@ int main(int argc,char *argv[])
     </programlisting>
 
     <para>
-      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.
-    </para>
-    <programlisting>
-  ...
-  gst_plugin_load_all();
-  ...
-    </programlisting>
-
-    <para>
       We are going to create 4 elements and one bin. Since all objects are
       in fact elements, we can define them as:
     </para>
@@ -318,8 +307,8 @@ void eos(GstSrc *src)
       To compile the helloworld example, use: 
     </para>
     <programlisting>
-       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 
     </programlisting>
     <para>
       This uses the program gstreamer-config, which comes with GStreamer. This program "knows" 
index bc9db8e..7fd7c80 100644 (file)
@@ -16,7 +16,7 @@
     <para> 
       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.
     </para>
 
     <programlisting>
@@ -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 &lt;filename&gt;\n", argv[0]);
@@ -44,8 +44,6 @@ int main(int argc,char *argv[])
   }
 
   gst_init(&amp;argc,&amp;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: 
     </para>
     <programlisting>
-       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 
     </programlisting>
     <para>
       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.
     </para>
     <programlisting>
-      ./helloworld2 helloworld.mpeg
+      ./helloworld2 mymovie.mpeg
     </programlisting>
 
   </sect1>
index d2fcd39..386ae67 100644 (file)
@@ -3,4 +3,104 @@
   <para> 
   </para>
 
+  <sect1>
+    <title><command>gstreamer-config</command></title>
+    <para> 
+      <command>gstreamer-config</command> is a script to get information about the installed 
+      version of <application>GStreamer</application>.
+      This program "knows" what compiler switches are needed to compile programs that use 
+      <application>GStreamer</application>. 
+    </para>
+      
+    <para> 
+      <command>gstreamer-config</command> accepts the following options:
+     <itemizedlist>
+       <listitem>
+         <para>
+          <option>--version</option> Print the currently installed version of 
+            <application>GStreamer</application> on the standard output. 
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+          <option>--libs</option> Print the linker flags that are necessary to link a 
+           <application>GStreamer</application> program. 
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <option>--cflags</option> Print the compiler flags that are necessary to compile a 
+            <application>GStreamer</application> program. 
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <option>--prefix=<replaceable>PREFIX</replaceable></option>
+             If specified, use <replaceable>PREFIX</replaceable> instead of the installation 
+            prefix that <application>GStreamer</application> was built with when computing the
+             output for the <option>--cflags</option> and <option>--libs</option> options. 
+            This option is also used for the exec prefix if 
+            <option>--exec-prefix</option> was not specified. This option must be specified before any 
+            <option>--libs</option> or <option>--cflags</option> options. 
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <option>--exec-prefix=<replaceable>PREFIX</replaceable></option> 
+             If specified, use <replaceable>PREFIX</replaceable> instead of the installation exec 
+            prefix that <application>GStreamer</application> was built with when computing the
+             output for the <option>--cflags</option> and <option>--libs</option> options. This option must be 
+            specified before any <option>--libs</option> or <option>--cflags</option>
+             options. 
+         </para>
+       </listitem>
+     </itemizedlist>
+    </para>
+    <para>
+      A simple <filename>Makefile</filename> will contain something like:
+      <programlisting>
+CC = gcc
+
+helloworld2: helloworld2.c
+   $(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2
+
+clean:
+   rm -f *.o helloworld2
+      </programlisting>
+    </para>
+  </sect1>
+
+  <sect1>
+    <title><command>gstreamer-register</command></title>
+    <para> 
+      <command>gstreamer-register</command> 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 <filename>/etc/gstreamer/reg.xml</filename>.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title><command>gstreamer-launch</command></title>
+    <para> 
+      This is a tool that will construct pipelines based on a command-line
+      syntax.  
+    </para> 
+    <para> 
+      A simple commandline looks like:
+
+    <screen>
+gstreamer-launch disksrc hello.mp3 ! mp3parse ! mpg123 ! audiosink-oss
+    </screen>
+
+      A more complex pipeline looks like:
+
+    <screen>
+gstreamer-launch disksrc redpill.vob ! css-descramble ! private_stream_1.0 ! \
+         (ac3parse ! ac3dec ! audiosink) video_0 ! (mpeg2dec ! videosink)
+    </screen>
+
+    </para>
+  </sect1>
+
 </chapter>
index 1a77d71..aaf86cb 100644 (file)
@@ -1,6 +1,32 @@
 <chapter id="cha-queues">
   <title>Queues</title>
   <para> 
+    A <classname>GstQueue</classname> is an implementation of a <classname>GstConnection</classname>.
+    Queues can be used to connect two elements in such way that the data can 
+    be buffered.
   </para>
+  <para> 
+    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.
+  </para>
+  <para> 
+    Queues are mostly used in conjunction with a <classname>GstThread</classname> to
+    provide an external connection for the thread elements. You could have one
+    thread feeding buffers into a <classname>GstQueue</classname> and another
+    thread repeadedly calling gst_connection_push() on the queue to feed its 
+    internal elements.
+  </para>
+
+  <para> 
+    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.
+  </para>
+  <figure float="1" id="sec-queues-img">
+    <title>a two-threaded decoder with a queue</title>
+    <graphic fileref="images/queue" format="png"></graphic>
+  </figure>
+
+
 
 </chapter>
index cb6592d..9c484e5 100644 (file)
@@ -1,6 +1,142 @@
 <chapter id="cha-threads">
   <title>Threads</title>
   <para> 
+    GStreamer has support for multithreading throught the use of
+    the <classname>GstThread</classname> object. This object is in fact
+    a special <classname>GstBin</classname> that will become a thread when started.
   </para>
 
+  <para> 
+    To construct a new thread you will perform something like:
+  </para>
+
+  <programlisting>
+  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);
+
+  </programlisting>
+
+  <para> 
+    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.
+  </para>
+  
+  <note> 
+    <para> 
+      The thread must contain at least one element of type <classname>GstSrc</classname>
+      or <classname>GstConnection</classname> in order to work.
+    </para> 
+  </note>
+  
+  <para> 
+    A thread will be visualised as below
+  </para>
+  <figure float="1" id="sec-threads-img">
+    <title>a thread</title>
+    <graphic fileref="images/thread" format="png"></graphic>
+  </figure>
+
+  <para> 
+    As an example we show the helloworld program using a thread.
+  </para>
+  
+  <programlisting>
+#include &lt;gst/gst.h&gt;
+
+/* 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 &lt;filename&gt;\n", argv[0]);
+    exit(-1);
+  }
+
+  gst_init(&amp;argc,&amp;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);
+}
+  </programlisting>
+
 </chapter>
index 6dcd806..45602fa 100644 (file)
@@ -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");
index 62f4eee..238ecda 100644 (file)
@@ -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;
index 4bc04e1..2603abb 100644 (file)
@@ -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;
index e467b9c..4c7b0b9 100644 (file)
@@ -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;
index 8057681..ab164c8 100644 (file)
@@ -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
index bee8275..2a3a486 100644 (file)
@@ -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));
index 937424a..22e6148 100644 (file)
@@ -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
index 42a194a..2405310 100644 (file)
@@ -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 <filename>\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);
   }
index 26afb42..da27358 100644 (file)
@@ -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 {
index 9900496..366de28 100644 (file)
@@ -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);
 
index 606134d..c41153d 100644 (file)
--- 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();
+}
index 1f08293..5ac3c68 100644 (file)
--- 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
index f169c99..a1962fa 100644 (file)
@@ -32,7 +32,7 @@
 extern "C" {
 #endif /* __cplusplus */
 
-GstElementDetails gst_bin_details;
+extern GstElementDetails gst_bin_details;
 
 
 #define GST_TYPE_BIN \
index 50d53df..566a129 100644 (file)
@@ -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);
index 104a500..100005d 100644 (file)
@@ -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;
index 9777265..f186eaf 100644 (file)
@@ -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);
index bcb2f9a..9c1c102 100644 (file)
@@ -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;
index 429e804..73acd95 100644 (file)
@@ -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]);
 }
 
 /**
index 9547c8f..41adceb 100644 (file)
@@ -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)));
index 0f96eb0..7e221f2 100644 (file)
@@ -30,7 +30,7 @@
 extern "C" {
 #endif /* __cplusplus */
 
-GstElementDetails gst_thread_details;
+extern GstElementDetails gst_thread_details;
 
 
 typedef enum {
index d02c743..4febea6 100644 (file)
@@ -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);
 }
 
index 26b12ec..990f318 100644 (file)
@@ -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;
   }
 
index cef310e..ad9c048 100644 (file)
@@ -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
       ;;
     *)
index 26afb42..da27358 100644 (file)
@@ -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 {
index 9900496..366de28 100644 (file)
@@ -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);
 
index 8057681..ab164c8 100644 (file)
@@ -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
index bee8275..2a3a486 100644 (file)
@@ -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));
index 937424a..22e6148 100644 (file)
@@ -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
index 42a194a..2405310 100644 (file)
@@ -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 <filename>\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);
   }
index fb5e8c4..932c5e7 100644 (file)
@@ -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;
 }