seek.c 32.2 KB
Newer Older
1 2 3
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
4
#include <stdlib.h>
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
5 6 7 8 9
#include <glib.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <string.h>

10
static GList *seekable_pads = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
11
static GList *rate_pads = NULL;
12
static GList *seekable_elements = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
13 14

static GstElement *pipeline;
15
static guint64 duration;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
16
static GtkAdjustment *adjustment;
17
static GtkWidget *hscale;
18
static gboolean stats = FALSE;
19 20
static gboolean elem_seek = FALSE;
static gboolean verbose = FALSE;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
21 22 23

static guint update_id;

24 25
//#define SOURCE "gnomevfssrc"
#define SOURCE "filesrc"
26

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
27 28 29
#define UPDATE_INTERVAL 500

#define THREAD
30
#define PAD_SEEK
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
31 32 33

typedef struct
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
34 35 36
  const gchar *padname;
  GstPad *target;
  GstElement *bin;
37 38
}
dyn_link;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
39

40
static GstElement *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
41
gst_element_factory_make_or_warn (gchar * type, gchar * name)
42 43 44 45
{
  GstElement *element = gst_element_factory_make (type, name);

  if (!element) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
46
    g_warning ("Failed to create element %s of type %s", name, type);
47 48 49 50 51
  }

  return element;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
52
static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
53
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
54
{
55
  dyn_link *connect = (dyn_link *) data;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
56 57 58 59

  if (!strcmp (gst_pad_get_name (newpad), connect->padname)) {
    gst_element_set_state (pipeline, GST_STATE_PAUSED);
    gst_bin_add (GST_BIN (pipeline), connect->bin);
60
    gst_pad_link (newpad, connect->target);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
61 62
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

63
    seekable_pads = g_list_prepend (seekable_pads, newpad);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
64 65 66 67 68
    rate_pads = g_list_prepend (rate_pads, newpad);
  }
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
69 70
setup_dynamic_link (GstElement * element, const gchar * padname,
    GstPad * target, GstElement * bin)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
71
{
72
  dyn_link *connect;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
73

74
  connect = g_new0 (dyn_link, 1);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
75 76 77
  connect->padname = g_strdup (padname);
  connect->target = target;
  connect->bin = bin;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
78

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
79 80
  g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
      connect);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
81 82
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
83 84
static GstElement *
make_mod_pipeline (const gchar * location)
85 86 87 88
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
89

90 91
  pipeline = gst_pipeline_new ("app");

92 93
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("modplug", "decoder");
94
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
95 96 97 98 99 100 101 102
  //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);

103 104
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
105 106 107 108 109 110 111 112 113

  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
114 115
static GstElement *
make_dv_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
116 117 118 119
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink, *videosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
120

Wim Taymans's avatar
Wim Taymans committed
121 122 123 124
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("dvdec", "decoder");
125 126
  videosink = gst_element_factory_make_or_warn (DEFAULT_VIDEOSINK, "v_sink");
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "a_sink");
Wim Taymans's avatar
Wim Taymans committed
127 128 129 130 131 132 133 134 135
  //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);
  gst_bin_add (GST_BIN (pipeline), videosink);

136 137 138
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
  gst_element_link (decoder, videosink);
Wim Taymans's avatar
Wim Taymans committed
139 140 141 142 143 144 145 146 147 148 149 150

  seekable = gst_element_get_pad (decoder, "video");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  seekable = gst_element_get_pad (decoder, "audio");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
151 152
static GstElement *
make_wav_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
153 154 155 156
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
157

Wim Taymans's avatar
Wim Taymans committed
158 159
  pipeline = gst_pipeline_new ("app");

160 161
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
162
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
163 164 165 166 167 168 169 170
  //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);

171 172
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
Wim Taymans's avatar
Wim Taymans committed
173 174 175 176 177 178 179 180 181

  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
182 183
static GstElement *
make_flac_pipeline (const gchar * location)
184 185 186 187
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
188

189 190
  pipeline = gst_pipeline_new ("app");

191 192
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("flacdec", "decoder");
193
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
194
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
195 196 197 198 199 200 201

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);

202 203
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
204 205 206 207 208 209 210 211 212

  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
213 214
static GstElement *
make_sid_pipeline (const gchar * location)
215 216 217 218
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
219

220 221
  pipeline = gst_pipeline_new ("app");

222 223
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("siddec", "decoder");
224
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
225 226 227 228 229 230 231 232
  //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);

233 234
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
235 236 237 238 239 240 241 242 243

  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
244 245
static GstElement *
make_parse_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
246 247 248 249
{
  GstElement *pipeline;
  GstElement *src, *parser, *fakesink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
250

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
251 252
  pipeline = gst_pipeline_new ("app");

253 254 255
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  parser = gst_element_factory_make_or_warn ("mpegparse", "parse");
  fakesink = gst_element_factory_make_or_warn ("fakesink", "sink");
Wim Taymans's avatar
Wim Taymans committed
256 257
  g_object_set (G_OBJECT (fakesink), "silent", TRUE, NULL);
  g_object_set (G_OBJECT (fakesink), "sync", TRUE, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
258 259 260 261 262 263 264

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), parser);
  gst_bin_add (GST_BIN (pipeline), fakesink);

265 266
  gst_element_link (src, parser);
  gst_element_link (parser, fakesink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
267 268

  seekable = gst_element_get_pad (parser, "src");
269
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
270 271 272 273 274 275
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (parser, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
276 277
static GstElement *
make_vorbis_pipeline (const gchar * location)
278 279 280 281
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
282

283 284
  pipeline = gst_pipeline_new ("app");

285 286
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("vorbisfile", "decoder");
287
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
288
  g_object_set (G_OBJECT (audiosink), "sync", TRUE, NULL);
289 290 291 292 293 294 295

  g_object_set (G_OBJECT (src), "location", location, NULL);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (pipeline), audiosink);

296 297
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
298 299 300 301 302 303 304 305 306

  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
307 308
static GstElement *
make_mp3_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
309 310
{
  GstElement *pipeline;
311
  GstElement *src, *decoder, *audiosink, *queue, *audio_thread;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
312
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
313

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
314 315
  pipeline = gst_pipeline_new ("app");

316 317 318
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("mad", "dec");
  queue = gst_element_factory_make_or_warn ("queue", "queue");
319
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "sink");
320 321 322

  audio_thread = gst_thread_new ("a_decoder_thread");

323
  seekable_elements = g_list_prepend (seekable_elements, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
324 325

  g_object_set (G_OBJECT (src), "location", location, NULL);
326
  g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
327

328 329 330
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (audio_thread), queue);
331
  gst_bin_add (GST_BIN (audio_thread), audiosink);
332
  gst_bin_add (GST_BIN (pipeline), audio_thread);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
333

334 335
  gst_element_link (src, decoder);
  gst_element_link (decoder, queue);
336
  gst_element_link (queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
337

338 339
  seekable = gst_element_get_pad (queue, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
340 341 342 343 344 345
  rate_pads = g_list_prepend (rate_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
346 347
static GstElement *
make_avi_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
348 349 350
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
351 352
  GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue =
      NULL, *video_thread = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
353
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
354

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
355 356
  pipeline = gst_pipeline_new ("app");

357
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
358 359
  g_object_set (G_OBJECT (src), "location", location, NULL);

360
  demux = gst_element_factory_make_or_warn ("avidemux", "demux");
361
  seekable_elements = g_list_prepend (seekable_elements, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
362 363 364

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
365
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
366 367

  audio_bin = gst_bin_new ("a_decoder_bin");
368
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
369
  audio_thread = gst_thread_new ("a_decoder_thread");
370
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "a_sink");
371
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
372
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
373 374
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
375 376 377 378
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
  gst_bin_add (GST_BIN (audio_bin), audio_thread);
  gst_bin_add (GST_BIN (audio_thread), a_queue);
  gst_bin_add (GST_BIN (audio_thread), audiosink);
Wim Taymans's avatar
Wim Taymans committed
379
  gst_element_set_state (audio_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
380

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
381
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
382
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
383 384

  seekable = gst_element_get_pad (a_queue, "src");
385
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
386
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
387 388
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
389 390

  video_bin = gst_bin_new ("v_decoder_bin");
391
  //v_decoder = gst_element_factory_make_or_warn ("identity", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
392
  //v_decoder = gst_element_factory_make_or_warn ("windec", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
393
  v_decoder = gst_element_factory_make_or_warn ("ffmpegdecall", "v_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
394
  video_thread = gst_thread_new ("v_decoder_thread");
395
  videosink = gst_element_factory_make_or_warn (DEFAULT_VIDEOSINK, "v_sink");
396
  //videosink = gst_element_factory_make_or_warn ("fakesink", "v_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
397
  //g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
398
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
Wim Taymans's avatar
Wim Taymans committed
399
  //g_object_set (G_OBJECT (v_queue), "max_level", 10, NULL);
400 401
  gst_element_link (v_decoder, v_queue);
  gst_element_link (v_queue, videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
402 403 404 405 406
  gst_bin_add (GST_BIN (video_bin), v_decoder);
  gst_bin_add (GST_BIN (video_bin), video_thread);
  gst_bin_add (GST_BIN (video_thread), v_queue);
  gst_bin_add (GST_BIN (video_thread), videosink);

Wim Taymans's avatar
Wim Taymans committed
407
  gst_element_set_state (video_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
408

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
409
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
410
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
411 412

  seekable = gst_element_get_pad (v_queue, "src");
413
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
414
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
415 416
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
417 418 419 420

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
421 422
static GstElement *
make_mpeg_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
423 424
{
  GstElement *pipeline, *audio_bin, *video_bin;
425 426
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
427 428
  GstElement *a_queue, *audio_thread, *v_queue, *video_thread;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
429

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
430 431
  pipeline = gst_pipeline_new ("app");

432
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
433 434
  g_object_set (G_OBJECT (src), "location", location, NULL);

435
  demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
Wim Taymans's avatar
Wim Taymans committed
436
  g_object_set (G_OBJECT (demux), "sync", FALSE, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
437

438 439
  seekable_elements = g_list_prepend (seekable_elements, demux);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
440 441
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
442
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
443 444

  audio_bin = gst_bin_new ("a_decoder_bin");
445
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
446
  audio_thread = gst_thread_new ("a_decoder_thread");
447
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
448
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "a_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
449
  g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
450 451
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
452 453 454 455 456
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
  gst_bin_add (GST_BIN (audio_bin), audio_thread);
  gst_bin_add (GST_BIN (audio_thread), a_queue);
  gst_bin_add (GST_BIN (audio_thread), audiosink);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
457
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
458
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
459 460

  seekable = gst_element_get_pad (a_queue, "src");
461
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
462
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
463 464
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
465 466

  video_bin = gst_bin_new ("v_decoder_bin");
467
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
468
  video_thread = gst_thread_new ("v_decoder_thread");
Wim Taymans's avatar
Wim Taymans committed
469
  //g_object_set (G_OBJECT (video_thread), "priority", 2, NULL);
470
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
471
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
472
  videosink = gst_element_factory_make_or_warn (DEFAULT_VIDEOSINK, "v_sink");
473
  gst_element_link_many (v_decoder, v_queue, v_filter, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
474

475
  gst_element_link (v_filter, videosink);
476
  gst_bin_add_many (GST_BIN (video_bin), v_decoder, video_thread, NULL);
477
  gst_bin_add_many (GST_BIN (video_thread), v_queue, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
478

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
479
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
480
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
481 482

  seekable = gst_element_get_pad (v_queue, "src");
483
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
484
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
485 486
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
487 488 489 490

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
491 492
static GstElement *
make_mpegnt_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
493 494 495 496 497 498
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
  GstElement *a_queue, *audio_thread;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
499

Wim Taymans's avatar
Wim Taymans committed
500 501 502 503 504 505 506 507 508 509 510 511
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  g_object_set (G_OBJECT (src), "location", location, NULL);

  demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
  //g_object_set (G_OBJECT (demux), "sync", TRUE, NULL);

  seekable_elements = g_list_prepend (seekable_elements, demux);

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
512
  gst_element_link (src, demux);
Wim Taymans's avatar
Wim Taymans committed
513 514 515 516 517

  audio_bin = gst_bin_new ("a_decoder_bin");
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
  audio_thread = gst_thread_new ("a_decoder_thread");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
518
  audiosink = gst_element_factory_make_or_warn (DEFAULT_AUDIOSINK, "a_sink");
Wim Taymans's avatar
Wim Taymans committed
519 520
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
521 522
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Wim Taymans's avatar
Wim Taymans committed
523 524 525 526 527
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
  gst_bin_add (GST_BIN (audio_bin), audio_thread);
  gst_bin_add (GST_BIN (audio_thread), a_queue);
  gst_bin_add (GST_BIN (audio_thread), audiosink);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
528
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
529
          "sink"), audio_bin);
Wim Taymans's avatar
Wim Taymans committed
530 531 532 533

  seekable = gst_element_get_pad (a_queue, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
534 535
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
536 537 538

  video_bin = gst_bin_new ("v_decoder_bin");
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
539
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
540
  videosink = gst_element_factory_make_or_warn (DEFAULT_VIDEOSINK, "v_sink");
541
  gst_element_link_many (v_decoder, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
542

Wim Taymans's avatar
Wim Taymans committed
543 544
  gst_bin_add_many (GST_BIN (video_bin), v_decoder, v_filter, videosink, NULL);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
545
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
546
          "sink"), video_bin);
Wim Taymans's avatar
Wim Taymans committed
547 548 549 550

  seekable = gst_element_get_pad (v_decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
551 552
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
553 554 555 556

  return pipeline;
}

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
static GstCaps *
fixate (GstPad * pad, const GstCaps * in_caps, gpointer data)
{
  GstCaps *caps;
  GstStructure *s;

  if (gst_caps_get_size (in_caps) > 1)
    return NULL;

  /* nothing if fixed already */
  s = gst_caps_get_structure (in_caps, 0);
  if (gst_structure_has_field_typed (s, "width", G_TYPE_INT) &&
      gst_structure_has_field_typed (s, "height", G_TYPE_INT) &&
      gst_structure_has_field_typed (s, "framerate", G_TYPE_DOUBLE))
    return NULL;

  /* fixate */
  caps = gst_caps_copy (in_caps);
  s = gst_caps_get_structure (caps, 0);
  gst_caps_structure_fixate_field_nearest_int (s, "width", 200);
  gst_caps_structure_fixate_field_nearest_int (s, "height", 150);
  gst_caps_structure_fixate_field_nearest_double (s, "framerate", 10.0);

  return caps;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
583 584
static GstElement *
make_playerbin_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
585
{
586
  GstElement *player, *vis;
587 588

  player = gst_element_factory_make ("playbin", "player");
589
  vis = gst_element_factory_make ("synaesthesia", "vis");
590
  g_assert (player);
591
  g_assert (vis);
592

593 594 595
  g_signal_connect (gst_element_get_pad (vis, "src"), "fixate",
      G_CALLBACK (fixate), NULL);
  g_object_set (G_OBJECT (player), "uri", location, "vis-plugin", vis, NULL);
596 597 598 599 600 601 602

  seekable_elements = g_list_prepend (seekable_elements, player);

  /* force element seeking on this pipeline */
  elem_seek = TRUE;

  return player;
Wim Taymans's avatar
Wim Taymans committed
603 604
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
605 606
static gchar *
format_value (GtkScale * scale, gdouble value)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
607
{
608 609 610 611 612 613 614
  gint64 real;
  gint64 seconds;
  gint64 subseconds;

  real = value * duration / 100;
  seconds = (gint64) real / GST_SECOND;
  subseconds = (gint64) real / (GST_SECOND / 100);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
615

616 617
  return g_strdup_printf ("%02" G_GINT64_FORMAT ":%02" G_GINT64_FORMAT ":%02"
      G_GINT64_FORMAT, seconds / 60, seconds % 60, subseconds % 100);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
618 619 620 621 622 623
}

typedef struct
{
  const gchar *name;
  const GstFormat format;
624 625
}
seek_format;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
626

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
627 628 629 630 631 632
static seek_format seek_formats[] = {
  {"tim", GST_FORMAT_TIME},
  {"byt", GST_FORMAT_BYTES},
  {"buf", GST_FORMAT_BUFFERS},
  {"def", GST_FORMAT_DEFAULT},
  {NULL, 0},
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
};

G_GNUC_UNUSED static void
query_rates (void)
{
  GList *walk = rate_pads;

  while (walk) {
    GstPad *pad = GST_PAD (walk->data);
    gint i = 0;

    g_print ("rate/sec  %8.8s: ", GST_PAD_NAME (pad));
    while (seek_formats[i].name) {
      gint64 value;
      GstFormat format;

      format = seek_formats[i].format;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
651
      if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
652
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
653
      } else {
654
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
655 656 657 658 659 660 661 662 663 664 665
      }

      i++;
    }
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
query_durations_elems ()
{
  GList *walk = seekable_elements;

  while (walk) {
    GstElement *element = GST_ELEMENT (walk->data);
    gint i = 0;

    g_print ("durations %8.8s: ", GST_ELEMENT_NAME (element));
    while (seek_formats[i].name) {
      gboolean res;
      gint64 value;
      GstFormat format;

      format = seek_formats[i].format;
      res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
      if (res) {
683
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
684 685 686 687 688 689 690 691 692 693 694 695 696
      } else {
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
      }
      i++;
    }
    g_print (" %s\n", GST_ELEMENT_NAME (element));

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
query_durations_pads ()
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
697
{
698 699 700 701 702 703 704 705 706 707 708 709 710
  GList *walk = seekable_pads;

  while (walk) {
    GstPad *pad = GST_PAD (walk->data);
    gint i = 0;

    g_print ("durations %8.8s: ", GST_PAD_NAME (pad));
    while (seek_formats[i].name) {
      gboolean res;
      gint64 value;
      GstFormat format;

      format = seek_formats[i].format;
Wim Taymans's avatar
Wim Taymans committed
711
      res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
712
      if (res) {
713
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
714
      } else {
715
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
716 717
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
718
    }
719
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
720

721
    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
722 723 724 725
  }
}

G_GNUC_UNUSED static void
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
query_positions_elems ()
{
  GList *walk = seekable_elements;

  while (walk) {
    GstElement *element = GST_ELEMENT (walk->data);
    gint i = 0;

    g_print ("positions %8.8s: ", GST_ELEMENT_NAME (element));
    while (seek_formats[i].name) {
      gboolean res;
      gint64 value;
      GstFormat format;

      format = seek_formats[i].format;
      res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
      if (res) {
743
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
744 745 746 747 748 749 750 751 752 753 754 755 756
      } else {
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
      }
      i++;
    }
    g_print (" %s\n", GST_ELEMENT_NAME (element));

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
query_positions_pads ()
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
757
{
758 759 760 761 762 763 764 765 766 767 768 769 770
  GList *walk = seekable_pads;

  while (walk) {
    GstPad *pad = GST_PAD (walk->data);
    gint i = 0;

    g_print ("positions %8.8s: ", GST_PAD_NAME (pad));
    while (seek_formats[i].name) {
      gboolean res;
      gint64 value;
      GstFormat format;

      format = seek_formats[i].format;
Wim Taymans's avatar
Wim Taymans committed
771
      res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
772
      if (res) {
773
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
774
      } else {
775
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
776 777
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
778
    }
779 780 781
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
782 783 784 785
  }
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
786
update_scale (gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
787 788
{
  GstClock *clock;
789 790
  guint64 position;
  GstFormat format = GST_FORMAT_TIME;
791
  gboolean res;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
792

793
  duration = 0;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
794 795
  clock = gst_bin_get_clock (GST_BIN (pipeline));

796 797 798
  if (elem_seek) {
    if (seekable_elements) {
      GstElement *element = GST_ELEMENT (seekable_elements->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
799

800 801 802 803 804 805
      res = gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
      if (!res)
        duration = 0;
      res = gst_element_query (element, GST_QUERY_POSITION, &format, &position);
      if (!res)
        position = 0;
806 807 808 809 810
    }
  } else {
    if (seekable_pads) {
      GstPad *pad = GST_PAD (seekable_pads->data);

811 812 813 814 815 816
      res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &duration);
      if (!res)
        duration = 0;
      res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &position);
      if (!res)
        position = 0;
817
    }
818
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
819

820
  if (stats) {
821
    if (clock) {
David Schleef's avatar
David Schleef committed
822 823
      g_print ("clock:                  %13" G_GUINT64_FORMAT "  (%s)\n",
          position, gst_object_get_name (GST_OBJECT (clock)));
824 825 826 827 828 829 830 831 832
    }

    if (elem_seek) {
      query_durations_elems ();
      query_positions_elems ();
    } else {
      query_durations_pads ();
      query_positions_pads ();
    }
833
    query_rates ();
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
834
  }
835 836
  if (position >= duration)
    duration = position;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
837 838 839

  if (duration > 0) {
    gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
840
    gtk_widget_queue_draw (hscale);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
841 842 843 844 845 846 847 848 849 850
  }

  return TRUE;
}

static gboolean
iterate (gpointer data)
{
  gboolean res;

851 852 853
  if (!GST_FLAG_IS_SET (GST_OBJECT (data), GST_BIN_SELF_SCHEDULABLE)) {
    res = gst_bin_iterate (GST_BIN (data));
  } else {
854
    g_usleep (500);
855 856 857
    res = gst_element_get_state (GST_ELEMENT (data)) == GST_STATE_PLAYING;
  }

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
858 859 860 861 862 863 864 865
  if (!res) {
    gtk_timeout_remove (update_id);
    g_print ("stopping iterations\n");
  }
  return res;
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
866
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
867 868 869 870 871 872 873 874
{
  gst_element_set_state (pipeline, GST_STATE_PAUSED);
  gtk_timeout_remove (update_id);

  return FALSE;
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
875
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
876 877 878 879
{
  gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
  gboolean res;
  GstEvent *s_event;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
880

881 882
  if (!elem_seek) {
    GList *walk = seekable_pads;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
883

884 885
    while (walk) {
      GstPad *seekable = GST_PAD (walk->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
886

887
      g_print ("seek to %" G_GINT64_FORMAT " on pad %s:%s\n", real,
888 889 890 891
          GST_DEBUG_PAD_NAME (seekable));
      s_event =
          gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
          GST_SEEK_FLAG_FLUSH, real);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
892

893
      res = gst_pad_send_event (seekable, s_event);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
894

895 896 897 898
      walk = g_list_next (walk);
    }
  } else {
    GList *walk = seekable_elements;
899

900 901
    while (walk) {
      GstElement *seekable = GST_ELEMENT (walk->data);
902

903
      g_print ("seek to %" G_GINT64_FORMAT " on element %s\n", real,
904 905 906 907
          gst_element_get_name (seekable));
      s_event =
          gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
          GST_SEEK_FLAG_FLUSH, real);
908

909
      res = gst_element_send_event (seekable, s_event);
910

911 912
      walk = g_list_next (walk);
    }
913
  }