[gst-devel] Problem using gstrtpbin

Tiago Katcipis katcipis at inf.ufsc.br
Mon May 11 18:55:50 CEST 2009


i still didnt the teste, but i found this

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpssrcdemux.html#GstRtpSsrcDemux-new-ssrc-pad

the GstRtpSsrcDemux sends the signal, i tried to get the signal from the bin
with:

g_signal_connect (rtp_bin, "new-ssrc-pad", G_CALLBACK (on_new_ssrc_pad),
rtp_decoder);

but i didnt got the signal.

My question is, i can get the signal from an element inside the bin from the
bin or i have to retrieve the element from the bin and then connect? and if
i have to get the element from the bin (in this case the GstRtpSsrcDemux),
how is the cleanest way of doing this?

thanks for all the help.
Best regards,
Katcipis

here goes the src:

#include <gst/gst.h>
#include <glib.h>

#define PORTA_UDP_ENTRADA 5000

static gboolean
bus_call (GstBus     *bus,
          GstMessage *msg,
          gpointer    data)
{
  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;

    case GST_MESSAGE_ERROR: {
      gchar  *debug;
      GError *error;

      gst_message_parse_error (msg, &error, &debug);
      g_free (debug);

      g_printerr ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      g_print("Tipo da mensagem [%d], Nome da mensagem [%s]\n",
GST_MESSAGE_TYPE (msg), GST_MESSAGE_TYPE_NAME(msg));
      break;
  }

  return TRUE;
}


static void
on_new_ssrc (GstElement* gstrtpbin,
                   guint session,
                   guint ssrc,
                   gpointer data)
{
  GstPad* sinkpad;
  GstPad* srcpad[1];
  GstElement* decoder = (GstElement *) data;
  GstIterator* iter;
  gint done, linked, iter_count;

  g_print ("New session stabilished, linking gstrtpbin session src pad to
the rtp_decoder\n");

  sinkpad = gst_element_get_static_pad(decoder, "sink");
  // TODO Esta dificil de pegar o pad src do gstrtpbin que eh criado ao
iniciar uma sessao nova.
  if(!sinkpad){
      g_warning("Error getting rtp_decoder sink pad");
      return;
  }
  /*
     unique pad recv_rtp_src_%d_%d_%d on gstrtpbin with the session number,
SSRC and payload type respectively as the pad name.

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html
  */

  iter = gst_element_iterate_src_pads(gstrtpbin);
  if(!iter){
      g_warning("Error getting gstrtpbin pads iterator");
      return;
  }

  done = FALSE;
  linked = FALSE;
  iter_count = 0;

  while (!done) {
      switch (gst_iterator_next (iter, (gpointer *) srcpad)) {
          case GST_ITERATOR_OK:
              if(gst_pad_link (*srcpad, sinkpad) != GST_PAD_LINK_OK){
                  g_warning("Error linking gstrtpbin pad[%s] to rtp_decoder
pad[%s]", gst_pad_get_name(*srcpad), gst_pad_get_name(sinkpad));
              }else{
                  g_warning("Linked gstrtpbin pad[%s] to rtp_decoder pad[%s]
with success", gst_pad_get_name(*srcpad), gst_pad_get_name(sinkpad));
                  linked = TRUE;
              }
              iter_count++;
              gst_object_unref (*srcpad);
          break;
          case GST_ITERATOR_RESYNC:
              gst_iterator_resync (iter);
          break;
          case GST_ITERATOR_ERROR:
              done = TRUE;
          break;
          case GST_ITERATOR_DONE:
              done = TRUE;
          break;
      }
   }
  if(!linked){
      g_warning("failed to found a valid recv_src_pad on gstrtpbin");
  }
  g_debug("GstRtpBin has [%d] src pads", iter_count);

  gst_iterator_free (iter);
  gst_object_unref (sinkpad);
}

static void
on_new_ssrc_pad (GstElement *element,
                 GstPad     *pad,
                 guint      ssrc,
                 gpointer   data)
{
  GstPad *sinkpad;
  GstElement *decoder = (GstElement *) data;

  /* We can now link this pad with the converter sink pad */
  g_print ("Dynamic ssrc pad created, linking the pad to the
rtp_decoder\n");

  sinkpad = gst_element_get_static_pad (decoder, "sink");
  if(gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK){
      gchar* name = gst_pad_get_name(pad);
      g_warning("Error linking the pad[%s] to rtp_decoder sinkpad", name);
      g_free(name);
  }

  gst_object_unref (sinkpad);
}

int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;

  GstElement *pipeline, *source, *rtp_bin, *rtp_decoder, *sink;
  GstPad *gstrtp_sink_pad;
  GstBus *bus;

  /* Initialisation */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline    = gst_pipeline_new ("audio-player");
  source      = gst_element_factory_make ("udpsrc","udp-source");
  rtp_bin     = gst_element_factory_make ("gstrtpbin", "gst_rtpbin");
  rtp_decoder = gst_element_factory_make ("rtpL16depay", "rtp_decoder");
  sink        = gst_element_factory_make ("filesink", "file-sink");

  if (!pipeline || !source || !sink || !rtp_decoder || !rtp_bin) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  gstrtp_sink_pad = gst_element_get_request_pad(rtp_bin, "recv_rtp_sink_0");
  if (!gstrtp_sink_pad) {
    g_printerr ("Sink pad could not be created. Exiting.\n");
    return -1;
  }

  /* Set up the pipeline */
  g_object_set (G_OBJECT (source), "port", PORTA_UDP_ENTRADA , NULL);
  g_object_set (G_OBJECT (sink), "location", "dados_recebidos_rtp" , NULL);

  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  /* we add all elements into the pipeline */
  /* file-source | ogg-demuxer | vorbis-decoder | converter | alsa-output */
  gst_bin_add_many (GST_BIN (pipeline),
                    source, sink, rtp_bin, rtp_decoder, NULL);

  /* we link the elements together */
  if(gst_pad_link(gst_element_get_static_pad(source, "src"),
gstrtp_sink_pad) != GST_PAD_LINK_OK){
      g_warning("Error linking source to the gstrtp_sink_pad");
      gst_object_unref (GST_OBJECT (pipeline));
      return 0;
  }

  /*
    After the packets are released from the jitterbuffer, they will be
forwarded to a GstRtpsSrcDemux element.
    The GstRtpsSrcDemux element will demux the packets based on the payload
type and will create a unique pad
    recv_rtp_src_%d_%d_%d on gstrtpbin with the session number, SSRC and
payload type respectively as the pad name.
    Because of that we have to dinamicaly link the src pads on runtime.
  */
  g_signal_connect (rtp_bin, "new-ssrc-pad", G_CALLBACK (on_new_ssrc_pad),
rtp_decoder);
  g_signal_connect (rtp_bin, "on-new-ssrc",  G_CALLBACK (on_new_ssrc),
rtp_decoder);

  if(!gst_element_link (rtp_decoder, sink)){
      g_warning("Error linking the rtp_decoder to the sink");
      gst_object_unref (GST_OBJECT (pipeline));
      return -1;
  }

  /* Set the pipeline to "playing" state*/
  g_print ("listening on port: %d\n", PORTA_UDP_ENTRADA);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);

  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping listening on port\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}


On Sat, May 9, 2009 at 3:40 PM, Aurelien Grimaud <gstelzz at yahoo.fr> wrote:

> Sorry, I misread your code.
> the pad-added signal is a signal of elements, documented in the element
> documentation.
> Do you receive RTP ?
> Because the pad wont be created if you do not receive RTP.
> What does tcpdump tell ?
>
> Aurelien
> Tiago Katcipis a écrit :
> > i did it, the pad never is created :-(, but i get no message of
> > warning or error neither. And on the list of signals of the gstrtpbin
> > there is no "pad-added" signal, its normal to the signal dont be there?
> > *
> > g_signal_connect (rtp_bin, "pad-added",   G_CALLBACK (on_pad_added),
> > rtp_decoder);*
> >
> > On Sat, May 9, 2009 at 3:55 AM, Aurelien Grimaud <gstelzz at yahoo.fr
> > <mailto:gstelzz at yahoo.fr>> wrote:
> >
> >     You should add the pad-added signal on the rtpbin.
> >     When it triggers, check the pad name to find out which pad it is.
> >     If pad is a recv_rtp_src_%d_%d_%d, link your decoder and sink in the
> >     call back.
> >
> >     Aurelien
> >
> >     Tiago Katcipis a écrit :
> >     > Im trying to do a rtp stream sending data and another side
> receiving
> >     > the data, the part that sends the data is working fine, but the
> part
> >     > that receives is giving me a lot of trouble. At
> >     >
> >
> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html
> >     > i have read:
> >     >
> >     > "To use GstRtpBin
> >     >
> >     <
> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html#GstRtpBin
> >
> >     > as an RTP receiver, request a recv_rtp_sink_%|d| pad. The session
> >     > number must be specified in the pad name. Data received on the
> >     > recv_rtp_sink_%|d| pad will be processed in the gstrtpsession
> >     manager
> >     > and after being validated forwarded on GstRtpsSrcDemux element.
> Each
> >     > RTP stream is demuxed based on the SSRC and send to a
> >     > GstRtpJitterBuffer
> >     >
> >     <
> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpjitterbuffer.html#GstRtpJitterBuffer
> >.
> >     > After the packets are released from the jitterbuffer, they will be
> >     > forwarded to a GstRtpsSrcDemux element. The GstRtpsSrcDemux element
> >     > will demux the packets based on the payload type and will create a
> >     > unique pad recv_rtp_src_%|d_|%|d_|%|d| on gstrtpbin with the
> session
> >     > number, SSRC and payload type respectively as the pad name. "
> >     >
> >     > on my application i cant get the recv_rtp_src_%|d_|%|d_|%|d,  |i
> >     > already tried on a lot of ways, my last shot was try to iterate
> over
> >     > all the pads on the bin and try to conect, i discovered that the
> src
> >     > pad never shows up. No error is given. I can get the on-new-ssrc
> >     > signal...and other signals as  |on-ssrc-validated... but on all
> this
> >     > signals the | recv_rtp_src_%|d_|%|d_|%|d is not created yet, i also
> >     > tried to get the "on-pad-added" signal but this signal never
> >     happens|.
> >     >
> >     > My problem is, when the recv_rtp_src_%|d_|%|d_|%|d is created|.
> >     When i
> >     > iterate over the pads i always get a
> >     > ** (teste_rtp:9516): DEBUG: GstRtpBin has [0] src pads
> >     >
> >     > here goes the source code, is a little messy because im all day
> >     trying
> >     > a lot of different ways to do this. And i get no error message.
> >     >
> >     > #include <gst/gst.h>
> >     > #include <glib.h>
> >     >
> >     > #define PORTA_UDP_ENTRADA 5000
> >     >
> >     > static gboolean
> >     > bus_call (GstBus     *bus,
> >     >           GstMessage *msg,
> >     >           gpointer    data)
> >     > {
> >     >   GMainLoop *loop = (GMainLoop *) data;
> >     >
> >     >   switch (GST_MESSAGE_TYPE (msg)) {
> >     >
> >     >     case GST_MESSAGE_EOS:
> >     >       g_print ("End of stream\n");
> >     >       g_main_loop_quit (loop);
> >     >       break;
> >     >
> >     >     case GST_MESSAGE_ERROR: {
> >     >       gchar  *debug;
> >     >       GError *error;
> >     >
> >     >       gst_message_parse_error (msg, &error, &debug);
> >     >       g_free (debug);
> >     >
> >     >       g_printerr ("Error: %s\n", error->message);
> >     >       g_error_free (error);
> >     >
> >     >       g_main_loop_quit (loop);
> >     >       break;
> >     >     }
> >     >     default:
> >     >       g_print("Tipo da mensagem [%d], Nome da mensagem [%s]\n",
> >     > GST_MESSAGE_TYPE (msg), GST_MESSAGE_TYPE_NAME(msg));
> >     >       break;
> >     >   }
> >     >
> >     >   return TRUE;
> >     > }
> >     >
> >     >
> >     > static void
> >     > on_new_ssrc (GstElement* gstrtpbin,
> >     >                    guint session,
> >     >                    guint ssrc,
> >     >                    gpointer data)
> >     > {
> >     >   GstPad* sinkpad;
> >     >   GstPad* srcpad[1];
> >     >   GstElement* decoder = (GstElement *) data;
> >     >   GstIterator* iter;
> >     >   gint done, linked, iter_count;
> >     >
> >     >   g_print ("New session stabilished, linking gstrtpbin session
> >     src pad
> >     > to the rtp_decoder\n");
> >     >
> >     >   sinkpad = gst_element_get_static_pad(decoder, "sink");
> >     >   // TODO Esta dificil de pegar o pad src do gstrtpbin que eh
> criado
> >     > ao iniciar uma sessao nova.
> >     >   if(!sinkpad){
> >     >       g_warning("Error getting rtp_decoder sink pad");
> >     >       return;
> >     >   }
> >     >   /*
> >     >      unique pad recv_rtp_src_%d_%d_%d on gstrtpbin with the session
> >     > number, SSRC and payload type respectively as the pad name.
> >     >
> >     >
> >
> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html
> >     >   */
> >     >
> >     >   iter = gst_element_iterate_src_pads(gstrtpbin);
> >     >   if(!iter){
> >     >       g_warning("Error getting gstrtpbin pads iterator");
> >     >       return;
> >     >   }
> >     >
> >     >   done = FALSE;
> >     >   linked = FALSE;
> >     >   iter_count = 0;
> >     >
> >     >   while (!done) {
> >     >       switch (gst_iterator_next (iter, (gpointer *) srcpad)) {
> >     >           case GST_ITERATOR_OK:
> >     >               if(gst_pad_link (*srcpad, sinkpad) !=
> >     GST_PAD_LINK_OK){
> >     >                   g_warning("Error linking gstrtpbin pad[%s] to
> >     > rtp_decoder pad[%s]", gst_pad_get_name(*srcpad),
> >     > gst_pad_get_name(sinkpad));
> >     >               }else{
> >     >                   g_warning("Linked gstrtpbin pad[%s] to
> rtp_decoder
> >     > pad[%s] with success", gst_pad_get_name(*srcpad),
> >     > gst_pad_get_name(sinkpad));
> >     >                   linked = TRUE;
> >     >               }
> >     >               iter_count++;
> >     >               gst_object_unref (*srcpad);
> >     >           break;
> >     >           case GST_ITERATOR_RESYNC:
> >     >               gst_iterator_resync (iter);
> >     >           break;
> >     >           case GST_ITERATOR_ERROR:
> >     >               done = TRUE;
> >     >           break;
> >     >           case GST_ITERATOR_DONE:
> >     >               done = TRUE;
> >     >           break;
> >     >       }
> >     >    }
> >     >   if(!linked){
> >     >       g_warning("failed to found a valid recv_src_pad on
> >     gstrtpbin");
> >     >   }
> >     >   g_debug("GstRtpBin has [%d] src pads", iter_count);
> >     >
> >     >   gst_iterator_free (iter);
> >     >   gst_object_unref (sinkpad);
> >     > }
> >     >
> >     > static void
> >     > on_pad_added (GstElement *element,
> >     >               GstPad     *pad,
> >     >               gpointer    data)
> >     > {
> >     >   GstPad *sinkpad;
> >     >   GstElement *decoder = (GstElement *) data;
> >     >
> >     >   /* We can now link this pad with the converter sink pad */
> >     >   g_print ("Dynamic pad created, linking wavparser/converter\n");
> >     >
> >     >   sinkpad = gst_element_get_static_pad (decoder, "sink");
> >     >   if(gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK){
> >     >       g_warning("Error linking recv_rtp_src pad to sinkpad");
> >     >   }
> >     >   gst_object_unref (sinkpad);
> >     > }
> >     >
> >     > int
> >     > main (int   argc,
> >     >       char *argv[])
> >     > {
> >     >   GMainLoop *loop;
> >     >
> >     >   GstElement *pipeline, *source, *rtp_bin, *rtp_decoder, *sink;
> >     >   GstPad *gstrtp_sink_pad;
> >     >   GstBus *bus;
> >     >
> >     >   /* Initialisation */
> >     >   gst_init (&argc, &argv);
> >     >
> >     >   loop = g_main_loop_new (NULL, FALSE);
> >     >
> >     >   /* Create gstreamer elements */
> >     >   pipeline    = gst_pipeline_new ("audio-player");
> >     >   source      = gst_element_factory_make ("udpsrc","udp-source");
> >     >   rtp_bin     = gst_element_factory_make ("gstrtpbin",
> >     "gst_rtpbin");
> >     >   rtp_decoder = gst_element_factory_make ("rtpL16depay",
> >     "rtp_decoder");
> >     >   sink        = gst_element_factory_make ("filesink", "file-sink");
> >     >
> >     >   if (!pipeline || !source || !sink || !rtp_decoder || !rtp_bin) {
> >     >     g_printerr ("One element could not be created. Exiting.\n");
> >     >     return -1;
> >     >   }
> >     >
> >     >   gstrtp_sink_pad = gst_element_get_request_pad(rtp_bin,
> >     > "recv_rtp_sink_0");
> >     >   if (!gstrtp_sink_pad) {
> >     >     g_printerr ("Sink pad could not be created. Exiting.\n");
> >     >     return -1;
> >     >   }
> >     >
> >     >   /* Set up the pipeline */
> >     >   g_object_set (G_OBJECT (source), "port", PORTA_UDP_ENTRADA ,
> >     NULL);
> >     >   g_object_set (G_OBJECT (sink), "location", "dados_recebidos_rtp"
> ,
> >     > NULL);
> >     >
> >     >   /* we add a message handler */
> >     >   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
> >     >   gst_bus_add_watch (bus, bus_call, loop);
> >     >   gst_object_unref (bus);
> >     >
> >     >   /* we add all elements into the pipeline */
> >     >   /* file-source | ogg-demuxer | vorbis-decoder | converter |
> >     > alsa-output */
> >     >   gst_bin_add_many (GST_BIN (pipeline),
> >     >                     source, sink, rtp_bin, rtp_decoder, NULL);
> >     >
> >     >   /* we link the elements together */
> >     >   if(gst_pad_link(gst_element_get_static_pad(source, "src"),
> >     > gstrtp_sink_pad) != GST_PAD_LINK_OK){
> >     >       g_warning("Error linking source to the gstrtp_sink_pad");
> >     >       gst_object_unref (GST_OBJECT (pipeline));
> >     >       return 0;
> >     >   }
> >     >
> >     >   /*
> >     >     After the packets are released from the jitterbuffer, they
> >     will be
> >     > forwarded to a GstRtpsSrcDemux element.
> >     >     The GstRtpsSrcDemux element will demux the packets based on the
> >     > payload type and will create a unique pad
> >     >     recv_rtp_src_%d_%d_%d on gstrtpbin with the session number,
> SSRC
> >     > and payload type respectively as the pad name.
> >     >     Because of that we have to dinamicaly link the src pads on
> >     runtime.
> >     >   */
> >     >   g_signal_connect (rtp_bin, "pad-added",   G_CALLBACK
> >     (on_pad_added),
> >     > rtp_decoder);
> >     >   g_signal_connect (rtp_bin, "on-new-ssrc", G_CALLBACK
> >     (on_new_ssrc),
> >     > rtp_decoder);
> >     >
> >     >   if(!gst_element_link (rtp_decoder, sink)){
> >     >       g_warning("Error linking the rtp_decoder to the sink");
> >     >       gst_object_unref (GST_OBJECT (pipeline));
> >     >       return -1;
> >     >   }
> >     >
> >     >   /* Set the pipeline to "playing" state*/
> >     >   g_print ("listening on port: %d\n", PORTA_UDP_ENTRADA);
> >     >   gst_element_set_state (pipeline, GST_STATE_PLAYING);
> >     >
> >     >   /* Iterate */
> >     >   g_print ("Running...\n");
> >     >   g_main_loop_run (loop);
> >     >
> >     >   /* Out of the main loop, clean up nicely */
> >     >   g_print ("Returned, stopping listening on port\n");
> >     >   gst_element_set_state (pipeline, GST_STATE_NULL);
> >     >
> >     >   g_print ("Deleting pipeline\n");
> >     >   gst_object_unref (GST_OBJECT (pipeline));
> >     >
> >     >   return 0;
> >     > }
> >     >
> >     >
> >
> ------------------------------------------------------------------------
> >     >
> >     >
> >
> ------------------------------------------------------------------------------
> >     > The NEW KODAK i700 Series Scanners deliver under ANY
> >     circumstances! Your
> >     > production scanning environment may not be a perfect world - but
> >     thanks to
> >     > Kodak, there's a perfect scanner to get the job done! With the
> >     NEW KODAK i700
> >     > Series Scanner you'll get full speed at 300 dpi even with all image
> >     > processing features enabled. http://p.sf.net/sfu/kodak-com
> >     >
> >
> ------------------------------------------------------------------------
> >     >
> >     > _______________________________________________
> >     > gstreamer-devel mailing list
> >     > gstreamer-devel at lists.sourceforge.net
> >     <mailto:gstreamer-devel at lists.sourceforge.net>
> >     > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> >     >
> >
> >
> >
> ------------------------------------------------------------------------------
> >     The NEW KODAK i700 Series Scanners deliver under ANY
> >     circumstances! Your
> >     production scanning environment may not be a perfect world - but
> >     thanks to
> >     Kodak, there's a perfect scanner to get the job done! With the NEW
> >     KODAK i700
> >     Series Scanner you'll get full speed at 300 dpi even with all image
> >     processing features enabled. http://p.sf.net/sfu/kodak-com
> >     _______________________________________________
> >     gstreamer-devel mailing list
> >     gstreamer-devel at lists.sourceforge.net
> >     <mailto:gstreamer-devel at lists.sourceforge.net>
> >     https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> >
> >
> >
> >
> > --
> > "it might be a profitable thing to learn Java, but it has no
> > intellectual value whatsoever" Alexander Stepanov
> > ------------------------------------------------------------------------
> >
> >
> ------------------------------------------------------------------------------
> > The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
> > production scanning environment may not be a perfect world - but thanks
> to
> > Kodak, there's a perfect scanner to get the job done! With the NEW KODAK
> i700
> > Series Scanner you'll get full speed at 300 dpi even with all image
> > processing features enabled. http://p.sf.net/sfu/kodak-com
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > gstreamer-devel mailing list
> > gstreamer-devel at lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> >
>
>
>
> ------------------------------------------------------------------------------
> The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
> production scanning environment may not be a perfect world - but thanks to
> Kodak, there's a perfect scanner to get the job done! With the NEW KODAK
> i700
> Series Scanner you'll get full speed at 300 dpi even with all image
> processing features enabled. http://p.sf.net/sfu/kodak-com
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>



-- 
"it might be a profitable thing to learn Java, but it has no intellectual
value whatsoever" Alexander Stepanov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20090511/6a5087c6/attachment.htm>


More information about the gstreamer-devel mailing list