<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-text-html" lang="x-western">
      <div style="color:#000; background-color:#fff; font-family:times
        new roman, new york, times, serif;font-size:12pt">
        <div>I have compiled the helloWorld example from the GStreamer
          documentation and it worked.<br>
          <br>
          To attempt to understand Bins and Pipelines and so on a bit
          better, I tried to split the helloworld into two parts.  I
          made two bins - but they would not link together.  Then, I
          re-read the documentation and realised that my bins needed
          Ghost Pads so that they could talk to each other.  However, I
          have not got it right.<br>
          <br>
          The program fails after printing "Step 2a" because in
          gst_ghost_pad_new, the assertion GST_IS_PAD failed.  Clearly,
          I don't know what I am doing.  Help would be appreciated.<br>
          <br>
          <br>
          #include <gst/gst.h><br>
          #include <glib.h><br>
          <br>
          <br>
          static gboolean<br>
          bus_call (GstBus     *bus,<br>
                    GstMessage *msg,<br>
                    gpointer    data)<br>
          {<br>
            GMainLoop *loop = (GMainLoop *) data;<br>
          <br>
            switch (GST_MESSAGE_TYPE (msg)) {<br>
          <br>
              case GST_MESSAGE_EOS:<br>
                g_print ("End of stream\n");<br>
                g_main_loop_quit (loop);<br>
                break;<br>
          <br>
              case GST_MESSAGE_ERROR: {<br>
                gchar  *debug;<br>
                GError *error;<br>
          <br>
                gst_message_parse_error (msg, &error, &debug);<br>
                g_free (debug);<br>
          <br>
                g_printerr ("Error: %s\n", error->message);<br>
                g_error_free (error);<br>
          <br>
                g_main_loop_quit (loop);<br>
                break;<br>
              }<br>
              default:<br>
                break;<br>
            }<br>
          <br>
            return TRUE;<br>
          }<br>
          <br>
          <br>
          static void<br>
          on_pad_added (GstElement *element,<br>
                        GstPad     *pad,<br>
                        gpointer    data)<br>
          {<br>
            GstPad *sinkpad;<br>
            GstElement *decoder = (GstElement *) data;<br>
          <br>
            /* We can now link this pad with the vorbis-decoder sink pad
          */<br>
            g_print ("Dynamic pad created, linking demuxer/decoder\n");<br>
          <br>
            sinkpad = gst_element_get_static_pad (decoder, "sink");<br>
          <br>
            gst_pad_link (pad, sinkpad);<br>
          <br>
            gst_object_unref (sinkpad);<br>
          }<br>
          <br>
          <br>
          <br>
          int<br>
          main (int   argc,<br>
                char *argv[])<br>
          {<br>
            GMainLoop *loop;<br>
          <br>
            GstElement *bin1, *bin2, *pipeline, *pipeline1, *pipeline2,
          *source, *demuxer, *decoder, *conv, *sink, *ghostsrc,
          *ghostsink;<br>
            GstBus *bus;<br>
            GstPad *pad1, *pad2;<br>
            guint bus_watch_id;<br>
          <br>
            /* Initialisation */<br>
            gst_init (&argc, &argv);<br>
          <br>
            loop = g_main_loop_new (NULL, FALSE);<br>
          <br>
          <br>
            /* Check input arguments */<br>
            if (argc != 2) {<br>
              g_printerr ("Usage: %s <Ogg/Vorbis filename>\n",
          argv[0]);<br>
              return -1;<br>
            }<br>
          <br>
          <br>
            /* Create gstreamer elements */<br>
            pipeline = gst_pipeline_new ("audio-player");<br>
            pipeline1 = gst_pipeline_new ("pipe1");<br>
            pipeline2 = gst_pipeline_new ("pipe2");<br>
            bin1 = gst_bin_new ("bin1");<br>
            bin2 = gst_bin_new ("bin2");<br>
            source   = gst_element_factory_make ("filesrc",      
          "file-source");<br>
            demuxer  = gst_element_factory_make ("oggdemux",     
          "ogg-demuxer");<br>
            decoder  = gst_element_factory_make ("vorbisdec",    
          "vorbis-decoder");<br>
            conv     = gst_element_factory_make ("audioconvert", 
          "converter");<br>
            sink     = gst_element_factory_make ("autoaudiosink",
          "audio-output");<br>
            ghostsrc = gst_element_factory_make ("fakesrc",      
          "ghostsrc");<br>
            ghostsink =gst_element_factory_make ("fakesink",     
          "ghostsink");<br>
          <br>
            if (!pipeline || !pipeline1 || !pipeline2 || !bin1 ||  !bin2
          || !source || !demuxer || !decoder || !conv || !sink) {<br>
              g_printerr ("One element could not be created.
          Exiting.\n");<br>
              return -1;<br>
            }<br>
          <br>
            /* Set up the pipeline */<br>
          <br>
            /* we set the input filename to the source element */<br>
            g_object_set (G_OBJECT (source), "location", argv[1], NULL);<br>
          <br>
            /* we add a message handler */<br>
            bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));<br>
            bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);<br>
            gst_object_unref (bus);<br>
          <br>
            /* we add all elements into the pipeline */<br>
            /* file-source | ogg-demuxer | vorbis-decoder | converter |
          alsa-output */<br>
            g_print ("Step 1...\n");<br>
            gst_bin_add_many (GST_BIN (bin1),<br>
                              source, demuxer, decoder, ghostsrc, NULL);<br>
            g_print ("Step 2...\n"); <br>
            pad1 = gst_element_get_static_pad (ghostsrc, "ghostsrc");<br>
            g_print ("Step 2a...\n"); <br>
            gst_element_add_pad (bin1, gst_ghost_pad_new ("ghostsrc",
          pad1));<br>
            g_print ("Step 2b...\n"); <br>
            gst_object_unref (GST_OBJECT (pad1));<br>
            g_print ("Step 3...\n");<br>
            gst_bin_add_many (GST_BIN (bin2),<br>
                              ghostsink, conv, sink, NULL);<br>
            g_print ("Step 4...\n");   <br>
            pad2 = gst_element_get_static_pad (ghostsink, "ghostsink");<br>
            g_print ("Step 4a...\n"); <br>
            gst_element_add_pad (bin2, gst_ghost_pad_new ("ghostsink",
          pad2));<br>
            g_print ("Step 4b...\n"); <br>
            gst_object_unref (GST_OBJECT (pad2));   <br>
            g_print ("Step 5...\n");<br>
            gst_bin_add_many (GST_BIN (pipeline), bin1, bin2, NULL);<br>
          <br>
            /* we link the elements together */<br>
            /* file-source -> ogg-demuxer ~> vorbis-decoder ->
          converter -> alsa-output */<br>
            g_print ("Step 6...\n");<br>
            gst_element_link (source, demuxer);<br>
            g_print ("Step 7...\n");<br>
            gst_element_link_many (conv, sink, NULL);<br>
            g_print ("Step 8...\n");<br>
            gst_element_link (bin1, bin2);<br>
            g_print ("Step 9...\n");<br>
            g_signal_connect (demuxer, "pad-added", G_CALLBACK
          (on_pad_added), decoder);<br>
          <br>
            /* note that the demuxer will be linked to the decoder
          dynamically.<br>
               The reason is that Ogg may contain various streams (for
          example<br>
               audio and video). The source pad(s) will be created at
          run time,<br>
               by the demuxer when it detects the amount and nature of
          streams.<br>
               Therefore we connect a callback function which will be
          executed<br>
               when the "pad-added" is emitted.*/<br>
          <br>
          <br>
            /* Set the pipeline to "playing" state*/<br>
            g_print ("Now playing: %s\n", argv[1]);<br>
            gst_element_set_state (pipeline, GST_STATE_PLAYING);<br>
          <br>
          <br>
            /* Iterate */<br>
            g_print ("Running...\n");<br>
            g_main_loop_run (loop);<br>
          <br>
          <br>
            /* Out of the main loop, clean up nicely */<br>
            g_print ("Returned, stopping playback\n");<br>
            gst_element_set_state (pipeline, GST_STATE_NULL);<br>
          <br>
            g_print ("Deleting pipeline\n");<br>
            gst_object_unref (GST_OBJECT (pipeline));<br>
            g_source_remove (bus_watch_id);<br>
            g_main_loop_unref (loop);<br>
          <br>
            return 0;<br>
          }<br>
        </div>
      </div>
    </div>
    <br>
    <br>
    <br>
    <br>
    <div class="moz-signature">-- <br>
      --<br>
      Ian Davidson<br>
      --<br>
      Facts used in this message may or may not reflect an underlying
      objective reality. Facts are supplied for personal use only.<br>
      Recipients quoting supplied information do so at their own risk.
      Facts supplied may vary in whole or part from widely accepted
      standards.<br>
      While painstakingly researched, facts may or may not be indicative
      of actually occurring events or natural phenomena.<br>
      The author accepts no responsibility for personal loss or injury
      resulting from memorisation and subsequent use.
    </div>
  </body>
</html>