[gst-devel] Seek event problem

Tim Müller t.i.m at zen.co.uk
Sat Jan 29 06:28:25 CET 2005


On Thursday 27 January 2005 15:35, Raoul wrote:

> I'm working on a project and I want to use Gstreamer. But I'm having
> trouble to get the seek event working. I've made a little test program :
>
>           ...
>         pipeline = gst_pipeline_new ("pipeline");
>         source = gst_element_factory_make ("filesrc", "src");
>         sink = gst_element_factory_make ("esdsink", "sink");
>           ...
>         event = gst_event_new_seek (
>             GST_FORMAT_TIME |           /* seek on time */
>             GST_SEEK_METHOD_SET |       /* set the absolute position */
>             GST_SEEK_FLAG_FLUSH,        /* flush any pending data */
>             60 * GST_SECOND);           /* the seek offset (1 second) */
>
>         res = gst_element_send_event (sink, event);
>           ...
>
> But I can't get the seek event working. The gst_element_send_event() always
> return NULL! Am I doing something wrong?

The problem is that you are issuing a seek in GST_FORMAT_TIME, but filesrc 
only knows how to process GST_FORMAT_BYTES, and there is no element (parser, 
decoder) in between your sink and filesrc to convert the seek request from 
TIME to BYTES as the seek event is passed through the pipeline from your sink 
to the source.

Such an element would be the 'wavparse' element, for example.

However, this leads to another problem: You can't link wavparse and your sink 
immediately, you need to wait until wavparse has analysed the format of the 
input stream and created its source pad, which it will notify you of by 
emitting the 'new-pad' signal. Once you got that, you can create the sink, 
link it to wavparse, and send your seek event.

Something like this should work:

#include <gst/gst.h>

static void
send_seek (GstElement *element, guint64 new_pos)
{
  GstEvent *event;
  gboolean  res;

  event = gst_event_new_seek (
              GST_FORMAT_TIME |     /* seek on time */
              GST_SEEK_METHOD_SET | /* set the absolute position */
              GST_SEEK_FLAG_FLUSH,  /* flush any pending data */
              new_pos);             /* the seek offset */

  res = gst_element_send_event (GST_ELEMENT (element), event);
  if (!res)
  {
    g_warning ("seek failed");
  }
}

static void 
new_pad_cb (GstElement *wavparse, GstPad *new_pad, gpointer pipeline)
{
  GstElement *sink;

  g_print ("wavparse: new pad\n");

  gst_element_set_state (pipeline, GST_STATE_PAUSED);

  sink = gst_element_factory_make ("alsasink", "sink");

  gst_bin_add (GST_BIN (pipeline), sink);

  if (!gst_element_link (wavparse, sink))
    g_error ("link(wavparse, sink) failed!\n");

  send_seek (sink, 5 * GST_SECOND);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
}

int main (int argc, char *argv[])
{
  GstElement *pipeline, *source, *wavparse;

  /* initialize GStreamer */
  gst_init (&argc, &argv);

  /* check input arguments */
  if (argc != 2)
  {
    g_print ("Usage: %s <wave filename>\n", argv[0]);
    return -1;
  }

  /* create elements */
  pipeline = gst_pipeline_new ("pipeline");
  source = gst_element_factory_make ("filesrc", "src");
  wavparse = gst_element_factory_make ("wavparse", "parse");

  /* set filename property on the file source */
  g_object_set (G_OBJECT (source), "location", argv[1], NULL);

  gst_bin_add_many (GST_BIN (pipeline), source, wavparse, NULL);

  if (!gst_element_link (source, wavparse))
    g_error ("link(src, wavparse) failed!\n");

  g_signal_connect (wavparse, "new-pad",
                    G_CALLBACK (new_pad_cb),
                    pipeline);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  while (gst_bin_iterate (GST_BIN (pipeline))) ; //iterate

  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}

Cheers
 -Tim

(PS: The SourceForge mail server seems to be extremely laggy again, so 
apologies if this is the 29th reply).




More information about the gstreamer-devel mailing list