Sophie

Sophie

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

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Dynamic pipelines</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="Clocks in GStreamer"
HREF="chapter-clocks.html"><LINK
REL="NEXT"
TITLE="Type Detection"
HREF="chapter-typedetection.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="chapter-clocks.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="chapter-typedetection.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="chapter"
><H1
><A
NAME="chapter-dynamic"
></A
>Chapter 26. Dynamic pipelines</H1
><P
> 
    In this chapter we will see how you can create a dynamic pipeline. A
    dynamic pipeline is a pipeline that is updated or created while data
    is flowing through it. We will create a partial pipeline first and add
    more elements while the pipeline is playing. Dynamic pipelines cause
    all sorts of scheduling issues and will remain a topic of research for
    a long time in GStreamer.
  </P
><P
> 
    We will show how to create an MPEG1 video player using dynamic pipelines.
    As you have seen in the pad section, we can attach a signal to an element
    when a pad is created. We will use this to create our MPEG1 player.
  </P
><P
> 
    We'll start with a simple main function:
  </P
><PRE
CLASS="programlisting"
>&#13;
/* example-begin dynamic.c */
#include &#60;string.h&#62;
#include &#60;gst/gst.h&#62;

void 
eof (GstElement *src) 
{
  g_print ("have eos, quitting\n");
  exit (0);
}

gboolean 
idle_func (gpointer data) 
{
  gst_bin_iterate (GST_BIN (data));
  return TRUE;
}

void 
new_pad_created (GstElement *parse, GstPad *pad, GstElement *pipeline) 
{
  GstElement *decode_video = NULL;
  GstElement *decode_audio, *play, *color, *show;
  GstElement *audio_queue, *video_queue;
  GstElement *audio_thread, *video_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);

  /* link to audio pad */
  if (strncmp (gst_pad_get_name (pad), "audio_", 6) == 0) {

    /* construct internal pipeline elements */
    decode_audio = gst_element_factory_make ("mad", "decode_audio");
    g_return_if_fail (decode_audio != NULL);
    play = gst_element_factory_make ("osssink", "play_audio");
    g_return_if_fail (play != NULL);

    /* create the thread and pack stuff into it */
    audio_thread = gst_thread_new ("audio_thread");
    g_return_if_fail (audio_thread != NULL);

    /* construct queue and link everything in the main pipeline */
    audio_queue = gst_element_factory_make ("queue", "audio_queue");
    g_return_if_fail (audio_queue != NULL);

    gst_bin_add_many (GST_BIN (audio_thread), 
                      audio_queue, decode_audio, play, NULL);

    /* set up pad links */
    gst_element_add_ghost_pad (audio_thread,
                               gst_element_get_pad (audio_queue, "sink"),
                               "sink");
    gst_element_link (audio_queue, decode_audio);
    gst_element_link (decode_audio, play);

    gst_bin_add (GST_BIN (pipeline), audio_thread);

    gst_pad_link (pad, gst_element_get_pad (audio_thread, "sink"));

    /* set up thread state and kick things off */
    g_print ("setting to READY state\n");
    gst_element_set_state (GST_ELEMENT (audio_thread), GST_STATE_READY);

  } 
  else if (strncmp (gst_pad_get_name (pad), "video_", 6) == 0) {

    /* construct internal pipeline elements */
    decode_video = gst_element_factory_make ("mpeg2dec", "decode_video");
    g_return_if_fail (decode_video != NULL);

    color = gst_element_factory_make ("colorspace", "color");
    g_return_if_fail (color != NULL);

   
    show = gst_element_factory_make ("xvideosink", "show");
    g_return_if_fail (show != NULL);

    /* construct queue and link everything in the main pipeline */
    video_queue = gst_element_factory_make ("queue", "video_queue");
    g_return_if_fail (video_queue != NULL);

    /* create the thread and pack stuff into it */
    video_thread = gst_thread_new ("video_thread");
    g_return_if_fail (video_thread != NULL);
    gst_bin_add_many (GST_BIN (video_thread), video_queue, 
                      decode_video, color, show, NULL);

    /* set up pad links */
    gst_element_add_ghost_pad (video_thread,
                               gst_element_get_pad (video_queue, "sink"),
                               "sink");
    gst_element_link (video_queue, decode_video);
    gst_element_link_many (decode_video, color, show, NULL);

    gst_bin_add (GST_BIN (pipeline), video_thread);

    gst_pad_link (pad, gst_element_get_pad (video_thread, "sink"));

    /* set up thread state and kick things off */
    g_print ("setting to READY state\n");
    gst_element_set_state (GST_ELEMENT (video_thread), GST_STATE_READY);
  }
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
}

int 
main (int argc, char *argv[]) 
{
  GstElement *pipeline, *src, *demux;

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

  pipeline = gst_pipeline_new ("pipeline");
  g_return_val_if_fail (pipeline != NULL, -1);

  src = gst_element_factory_make ("filesrc", "src");
  g_return_val_if_fail (src != NULL, -1);
  if (argc &#60; 2) 
    g_error ("Please specify a video file to play !");

  g_object_set (G_OBJECT (src), "location", argv[1], NULL);

  demux = gst_element_factory_make ("mpegdemux", "demux");
  g_return_val_if_fail (demux != NULL, -1);

  gst_bin_add_many (GST_BIN (pipeline), src, demux, NULL);

  g_signal_connect (G_OBJECT (demux), "new_pad",
                     G_CALLBACK (new_pad_created), pipeline);

  g_signal_connect (G_OBJECT (src), "eos",
                     G_CALLBACK (eof), NULL);

  gst_element_link (src, demux);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  g_idle_add (idle_func, pipeline);

  gst_main ();

  return 0;
}
/* example-end dynamic.c */
  </PRE
><P
>&#13;    We create two elements: a file source and an MPEG demuxer. 
    There's nothing special about this piece of code except for 
    the signal 'new_pad' that we linked to the mpegdemux 
    element using:
  </P
><PRE
CLASS="programlisting"
>&#13;  g_signal_connect (G_OBJECT (demux), "new_pad",
                     G_CALLBACK (new_pad_created), pipeline);
  </PRE
><P
> 
    When an elementary stream has been detected in the system stream,
    mpegdemux will create a new pad that will provide the data of the
    elementary stream. A function 'new_pad_created' will be called when
    the pad is created.
  </P
><P
>&#13;    In the above example, we created new elements based on the name of 
    the newly created pad. We then added them to a new thread. 
    There are other possibilities to check the type of the pad, for
    example by using the MIME type and the properties of the pad.
  </P
></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="chapter-clocks.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-typedetection.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Clocks in GStreamer</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"
>Type Detection</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>