Sophie

Sophie

distrib > Mandriva > 10.0-com > i586 > by-pkgid > f0a9f2b9c81d34eadc43f527947c0b70 > files > 109

libgstreamer0.7-devel-0.7.4-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Your second application</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="GStreamer Application Development Manual"
HREF="index.html"><LINK
REL="UP"
TITLE="Advanced GStreamer concepts"
HREF="part-advanced.html"><LINK
REL="PREVIOUS"
TITLE="Another approach to autoplugging"
HREF="section-autoplugging-spider.html"><LINK
REL="NEXT"
TITLE="Dynamic Parameters"
HREF="chapter-dparams.html"></HEAD
><BODY
CLASS="chapter"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
><SPAN
CLASS="application"
>GStreamer</SPAN
> Application Development Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="section-autoplugging-spider.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="chapter-dparams.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="chapter"
><H1
><A
NAME="chapter-hello2"
></A
>Chapter 29. Your second application</H1
><P
>&#13;    FIXME: delete this section, talk more about the spider. In a previous chapter we created a first
    version of the helloworld application. We then explained a better way of creating the elements
    using factories identified by MIME types and the autoplugger.
  </P
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="AEN995"
>29.1. Autoplugging helloworld</A
></H1
><P
> 
      We will create a second version of the helloworld application using
      autoplugging. Its source code is a bit more complicated but 
      it can handle many more data types.  It can even play the audio track
      of a video file.
    </P
><P
> 
      Here is the full program listing.  Start by looking at the main ()
      function.
    </P
><PRE
CLASS="programlisting"
>&#13;/* example-begin helloworld2.c */
#include &#60;gst/gst.h&#62;

static void 	gst_play_have_type 	(GstElement *typefind, GstCaps *caps, GstElement *pipeline);
static void 	gst_play_cache_empty 	(GstElement *element, GstElement *pipeline);

static void
gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
{
  GstElement *osssink;
  GstElement *new_element;
  GstAutoplug *autoplug;
  GstElement *autobin;
  GstElement *filesrc;
  GstElement *cache;

  g_print ("GstPipeline: play have type\n");

  gst_element_set_state (pipeline, GST_STATE_PAUSED);

  filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
  autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
  cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");

  /* unlink the typefind from the pipeline and remove it */
  gst_element_unlink (cache, typefind);
  gst_bin_remove (GST_BIN (autobin), typefind);
      
  /* and an audio sink */
  osssink = gst_element_factory_make ("osssink", "play_audio");
  g_assert (osssink != NULL);

  autoplug = gst_autoplug_factory_make ("staticrender");
  g_assert (autoplug != NULL);

  new_element = gst_autoplug_to_renderers (autoplug, caps, osssink, NULL);

  if (!new_element) {
    g_print ("could not autoplug, no suitable codecs found...\n");
    exit (-1);
  }

  gst_element_set_name (new_element, "new_element");

  gst_bin_add (GST_BIN (autobin), new_element);

  g_object_set (G_OBJECT (cache), "reset", TRUE, NULL);

  gst_element_link (cache, new_element);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
}

static void
gst_play_cache_empty (GstElement *element, GstElement *pipeline)
{
  GstElement *autobin;
  GstElement *filesrc;
  GstElement *cache;
  GstElement *new_element;

  g_print ("have cache empty\n");

  gst_element_set_state (pipeline, GST_STATE_PAUSED);

  filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
  autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
  cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");
  new_element = gst_bin_get_by_name (GST_BIN (autobin), "new_element");

  gst_element_unlink (filesrc, cache);
  gst_element_unlink (cache, new_element);
  gst_bin_remove (GST_BIN (autobin), cache);
  gst_element_link (filesrc, new_element);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  g_print ("done with cache_empty\n");
}

int 
main (int argc, char *argv[]) 
{
  GstElement *filesrc;
  GstElement *pipeline;
  GstElement *autobin;
  GstElement *typefind;
  GstElement *cache;

  gst_init (&#38;argc, &#38;argv);

  if (argc != 2) {
    g_print ("usage: %s &#60;filename with audio&#62;\n", argv[0]);
    exit (-1);
  }

  /* create a new pipeline to hold the elements */
  pipeline = gst_pipeline_new ("pipeline");
  g_assert (pipeline != NULL);

  /* create a disk reader */
  filesrc = gst_element_factory_make ("filesrc", "disk_source");
  g_assert (filesrc != NULL);
  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
  gst_bin_add (GST_BIN (pipeline), filesrc);

  autobin = gst_bin_new ("autobin");
  cache = gst_element_factory_make ("autoplugcache", "cache");
  g_signal_connect (G_OBJECT (cache), "cache_empty", 
		     G_CALLBACK (gst_play_cache_empty), pipeline);

  typefind = gst_element_factory_make ("typefind", "typefind");
  g_signal_connect (G_OBJECT (typefind), "have_type", 
		     G_CALLBACK (gst_play_have_type), pipeline);
  gst_bin_add (GST_BIN (autobin), cache);
  gst_bin_add (GST_BIN (autobin), typefind);

  gst_element_link (cache, typefind);
  gst_element_add_ghost_pad (autobin, 
                             gst_element_get_pad (cache, "sink"), "sink");

  gst_bin_add (GST_BIN( pipeline), autobin);
  gst_element_link (filesrc, autobin);

  /* start playing */
  gst_element_set_state( GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  while (gst_bin_iterate (GST_BIN (pipeline)));

  /* stop the pipeline */
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);

  gst_object_unref (GST_OBJECT (pipeline));

  exit(0);
}
/* example-end helloworld2.c */
    </PRE
><P
>&#13;      We start by constructing a 'filesrc' element and an 'autobin' element that
      holds the autoplugcache and the typefind element.
    </P
><P
>&#13;      We attach the "cache_empty" signal to gst_play_cache_empty and the 
      "have_type" to our gst_play_have_type function.
    </P
><P
>&#13;      The _have_type function first sets the pipeline to the PAUSED state
      so that it can safely modify the pipeline. It then finds the elements 
      it is going to manipulate in the pipeline with:
    </P
><PRE
CLASS="programlisting"
>&#13;  filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
  autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
  cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");
    </PRE
><P
>&#13;      Now we have a handle to the elements we are going to manipulate in
      the next step.
    </P
><P
>&#13;      We don't need the typefind element anymore so we remove it from 
      the pipeline: 
    </P
><PRE
CLASS="programlisting"
>&#13;  /* unlink the typefind from the pipeline and remove it */
  gst_element_unlink (cache, "src", typefind, "sink");
  gst_bin_remove (GST_BIN (autobin), typefind);
    </PRE
><P
>&#13;      Our next step is to construct an element that can play the type we just
      detected. We are going to use the autoplugger to create an element that
      links the type to an osssink. We add the new element to our 
      autobin.
    </P
><PRE
CLASS="programlisting"
>&#13;  /* and an audio sink */
  osssink = gst_element_factory_make("osssink", "play_audio");
  g_assert(osssink != NULL);

  autoplug = gst_autoplug_factory_make ("staticrender");
  g_assert (autoplug != NULL);

  new_element = gst_autoplug_to_renderers (autoplug,
           caps,
           osssink,
           NULL);

  if (!new_element) {
    g_print ("could not autoplug, no suitable codecs found...\n");
    exit (-1);
  }

  gst_element_set_name (new_element, "new_element");

  gst_bin_add (GST_BIN (autobin), new_element);
    </PRE
><P
>&#13;      Our next step is to reset the cache so that the buffers used by the
      typefind element are fed into the new element we just created. We reset
      the cache by setting the "reset" property of the cache element to TRUE.
    </P
><PRE
CLASS="programlisting"
>&#13;  g_object_set (G_OBJECT (cache), "reset", TRUE, NULL);

  gst_element_link (cache, "src", new_element, "sink");
    </PRE
><P
>&#13;     Finally we set the pipeline back to the playing state. At this point the
     cache will replay the buffers. We will be notified when the cache is empty 
     by the gst_play_cache_empty callback function.
    </P
><P
>&#13;      The cache empty function simply removes the autoplugcache element from
      the pipeline and relinks the filesrc to the autoplugged element.
    </P
><P
>&#13;      To compile the helloworld2 example, use: 
    </P
><PRE
CLASS="programlisting"
>&#13;       gcc -Wall `pkg-config gstreamer-0.7 --cflags --libs` helloworld2.c \
             -o helloworld2 
    </PRE
><P
>&#13;      You can run the example with 
      (substitute helloworld.mp3 with you favorite audio file):
    </P
><PRE
CLASS="programlisting"
>&#13;      ./helloworld2 helloworld.mp3
    </PRE
><P
>&#13;      You can also try to use an AVI or MPEG file as its input. 
      Using autoplugging,
      <SPAN
CLASS="application"
>GStreamer</SPAN
> 
      will automatically figure out how to 
      handle the stream. 
      Remember that only the audio part will be played because 
      we have only added an osssink to the pipeline.
    </P
><PRE
CLASS="programlisting"
>&#13;      ./helloworld2 mymovie.mpeg
    </PRE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="section-autoplugging-spider.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="chapter-dparams.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Another approach to autoplugging</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="part-advanced.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Dynamic Parameters</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>