seek.c 38 KB
Newer Older
1
#include <stdlib.h>
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
2 3 4 5 6
#include <glib.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <string.h>

7
static GList *seekable_pads = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
8
static GList *rate_pads = NULL;
9
static GList *seekable_elements = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
10 11

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

static guint update_id;
20 21
static guint seek_timeout_id = 0;
static gulong changed_id;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
22

23
//#define SOURCE "gnomevfssrc"
24
#define SOURCE "gnomevfssrc"
25 26
#define ASINK "alsasink"
//#define ASINK "osssink"
27

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

30 31 32 33
/* number of milliseconds to play for after a seek */
#define SCRUB_TIME 250
#define SCRUB

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
34
#define THREAD
35
#define PAD_SEEK
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
36 37 38

typedef struct
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
39 40 41
  const gchar *padname;
  GstPad *target;
  GstElement *bin;
42 43
}
dyn_link;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
44

45
static GstElement *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
46
gst_element_factory_make_or_warn (gchar * type, gchar * name)
47 48 49 50
{
  GstElement *element = gst_element_factory_make (type, name);

  if (!element) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
51
    g_warning ("Failed to create element %s of type %s", name, type);
52 53 54 55 56
  }

  return element;
}

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

62 63 64 65
  if (connect->padname == NULL ||
      !strcmp (gst_pad_get_name (newpad), connect->padname)) {
    if (connect->bin)
      gst_bin_add (GST_BIN (pipeline), connect->bin);
66
    gst_pad_link (newpad, connect->target);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
67

68
    //seekable_pads = g_list_prepend (seekable_pads, newpad);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
69 70 71 72 73
    rate_pads = g_list_prepend (rate_pads, newpad);
  }
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
74 75
setup_dynamic_link (GstElement * element, const gchar * padname,
    GstPad * target, GstElement * bin)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
76
{
77
  dyn_link *connect;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
78

79
  connect = g_new0 (dyn_link, 1);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
80 81 82
  connect->padname = g_strdup (padname);
  connect->target = target;
  connect->bin = bin;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
83

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
84 85
  g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
      connect);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
86 87
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
88 89
static GstElement *
make_mod_pipeline (const gchar * location)
90 91 92 93
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
94

95 96
  pipeline = gst_pipeline_new ("app");

97 98
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("modplug", "decoder");
99
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
100 101 102 103 104 105 106 107
  //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);

108 109
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
110 111 112 113 114 115 116 117 118

  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
119 120
static GstElement *
make_dv_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
121 122 123 124
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink, *videosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
125

Wim Taymans's avatar
Wim Taymans committed
126 127 128 129
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("dvdec", "decoder");
130
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
131
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
Wim Taymans's avatar
Wim Taymans committed
132 133 134 135 136 137 138 139 140
  //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);

141 142 143
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
  gst_element_link (decoder, videosink);
Wim Taymans's avatar
Wim Taymans committed
144 145 146 147 148 149 150 151 152 153 154 155

  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
156 157
static GstElement *
make_wav_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
158 159 160 161
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
162

Wim Taymans's avatar
Wim Taymans committed
163 164
  pipeline = gst_pipeline_new ("app");

165 166
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
167
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
168 169 170 171 172 173 174 175
  //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);

176 177
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
Wim Taymans's avatar
Wim Taymans committed
178 179 180 181 182 183 184 185 186

  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
187 188
static GstElement *
make_flac_pipeline (const gchar * location)
189 190 191 192
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
193

194 195
  pipeline = gst_pipeline_new ("app");

196 197
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("flacdec", "decoder");
198
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
199
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
200 201 202 203 204 205 206

  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);

207 208
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
209 210 211 212 213 214 215 216 217

  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
218 219
static GstElement *
make_sid_pipeline (const gchar * location)
220 221 222 223
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
224

225 226
  pipeline = gst_pipeline_new ("app");

227 228
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("siddec", "decoder");
229
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
230 231 232 233 234 235 236 237
  //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);

238 239
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
240 241 242 243 244 245 246 247 248

  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
249 250
static GstElement *
make_parse_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
251 252 253 254
{
  GstElement *pipeline;
  GstElement *src, *parser, *fakesink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
255

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
256 257
  pipeline = gst_pipeline_new ("app");

258 259 260
  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
261 262
  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
263 264 265 266 267 268 269

  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);

270 271
  gst_element_link (src, parser);
  gst_element_link (parser, fakesink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
272 273

  seekable = gst_element_get_pad (parser, "src");
274
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
275 276 277 278 279 280
  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
281 282
static GstElement *
make_vorbis_pipeline (const gchar * location)
283
{
284 285
  GstElement *pipeline, *audio_bin;
  GstElement *src, *demux, *decoder, *convert, *audiosink;
286
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
287

288 289
  pipeline = gst_pipeline_new ("app");

290
  src = gst_element_factory_make_or_warn (SOURCE, "src");
291 292 293
  demux = gst_element_factory_make_or_warn ("oggdemux", "demux");
  decoder = gst_element_factory_make_or_warn ("vorbisdec", "decoder");
  convert = gst_element_factory_make_or_warn ("audioconvert", "convert");
294
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
295
  g_object_set (G_OBJECT (audiosink), "sync", TRUE, NULL);
296 297 298

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

299 300
  audio_bin = gst_bin_new ("a_decoder_bin");

301
  gst_bin_add (GST_BIN (pipeline), src);
302 303 304 305 306
  gst_bin_add (GST_BIN (pipeline), demux);
  gst_bin_add (GST_BIN (audio_bin), decoder);
  gst_bin_add (GST_BIN (audio_bin), convert);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
  gst_bin_add (GST_BIN (pipeline), audio_bin);
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
  gst_element_link (src, demux);
  gst_element_link (decoder, convert);
  gst_element_link (convert, audiosink);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (decoder, "sink"), NULL);

  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;
}

static GstElement *
make_theora_pipeline (const gchar * location)
{
  GstElement *pipeline, *video_bin;
  GstElement *src, *demux, *decoder, *convert, *videosink;
  GstElement *queue;
  GstPad *seekable;

  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  demux = gst_element_factory_make_or_warn ("oggdemux", "demux");
  queue = gst_element_factory_make_or_warn ("queue", "queue");
  decoder = gst_element_factory_make_or_warn ("theoradec", "decoder");
  convert = gst_element_factory_make_or_warn ("ffmpegcolorspace", "convert");
  videosink = gst_element_factory_make_or_warn ("xvimagesink", "sink");

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

  video_bin = gst_bin_new ("v_decoder_bin");

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
  gst_bin_add (GST_BIN (pipeline), queue);
  gst_bin_add (GST_BIN (video_bin), decoder);
  gst_bin_add (GST_BIN (video_bin), convert);
  gst_bin_add (GST_BIN (video_bin), videosink);
  gst_bin_add (GST_BIN (pipeline), video_bin);

  gst_element_link (src, demux);
  gst_element_link (queue, decoder);
  gst_element_link (decoder, convert);
  gst_element_link (convert, videosink);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (queue, "sink"), NULL);
357 358 359 360 361 362 363 364 365

  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;
}

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
static GstElement *
make_vorbis_theora_pipeline (const gchar * location)
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *a_convert, *v_decoder, *v_convert;
  GstElement *audiosink, *videosink;
  GstElement *a_queue, *v_queue;
  GstPad *seekable;

  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 ("oggdemux", "demux");

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
  gst_element_link (src, demux);

  audio_bin = gst_bin_new ("a_decoder_bin");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
  a_decoder = gst_element_factory_make_or_warn ("vorbisdec", "a_dec");
  a_convert = gst_element_factory_make_or_warn ("audioconvert", "a_convert");
390
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

  gst_element_link (a_queue, a_decoder);
  gst_element_link (a_decoder, a_convert);
  gst_element_link (a_convert, audiosink);

  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
  gst_bin_add (GST_BIN (audio_bin), a_convert);
  gst_bin_add (GST_BIN (audio_bin), audiosink);

  gst_bin_add (GST_BIN (pipeline), audio_bin);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (a_queue, "sink"), NULL);

  video_bin = gst_bin_new ("v_decoder_bin");
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
  v_decoder = gst_element_factory_make_or_warn ("theoradec", "v_dec");
  v_convert =
      gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_convert");
  videosink = gst_element_factory_make_or_warn ("xvimagesink", "v_sink");
  gst_element_link_many (v_queue, v_decoder, v_convert, videosink, NULL);

  gst_bin_add (GST_BIN (video_bin), v_queue);
  gst_bin_add (GST_BIN (video_bin), v_decoder);
  gst_bin_add (GST_BIN (video_bin), v_convert);
  gst_bin_add (GST_BIN (video_bin), videosink);

  gst_bin_add (GST_BIN (pipeline), video_bin);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (v_queue, "sink"), NULL);

  seekable = gst_element_get_pad (a_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 (a_decoder, "sink"));

  return pipeline;
}

static GstElement *
make_avi_msmpeg4v3_mp3_pipeline (const gchar * location)
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *a_convert, *v_decoder, *v_convert;
  GstElement *audiosink, *videosink;
  GstElement *a_queue, *v_queue;
  GstPad *seekable;

  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 ("avidemux", "demux");

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
  gst_element_link (src, demux);

  audio_bin = gst_bin_new ("a_decoder_bin");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
  a_convert = gst_element_factory_make_or_warn ("audioconvert", "a_convert");
455
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495

  gst_element_link (a_queue, a_decoder);
  gst_element_link (a_decoder, a_convert);
  gst_element_link (a_convert, audiosink);

  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
  gst_bin_add (GST_BIN (audio_bin), a_convert);
  gst_bin_add (GST_BIN (audio_bin), audiosink);

  gst_bin_add (GST_BIN (pipeline), audio_bin);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (a_queue, "sink"), NULL);

  video_bin = gst_bin_new ("v_decoder_bin");
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
  v_decoder = gst_element_factory_make_or_warn ("ffdec_msmpeg4", "v_dec");
  v_convert =
      gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_convert");
  videosink = gst_element_factory_make_or_warn ("xvimagesink", "v_sink");
  gst_element_link_many (v_queue, v_decoder, v_convert, videosink, NULL);

  gst_bin_add (GST_BIN (video_bin), v_queue);
  gst_bin_add (GST_BIN (video_bin), v_decoder);
  gst_bin_add (GST_BIN (video_bin), v_convert);
  gst_bin_add (GST_BIN (video_bin), videosink);

  gst_bin_add (GST_BIN (pipeline), video_bin);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (v_queue, "sink"), NULL);

  seekable = gst_element_get_pad (a_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 (a_decoder, "sink"));

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
496 497
static GstElement *
make_mp3_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
498 499
{
  GstElement *pipeline;
500
  GstElement *src, *decoder, *osssink, *queue;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
501
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
502

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
503 504
  pipeline = gst_pipeline_new ("app");

505 506 507
  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");
508
  osssink = gst_element_factory_make_or_warn (ASINK, "sink");
509

510
  seekable_elements = g_list_prepend (seekable_elements, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
511 512

  g_object_set (G_OBJECT (src), "location", location, NULL);
513
  g_object_set (G_OBJECT (osssink), "fragment", 0x00180008, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
514

515 516
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
517 518
  gst_bin_add (GST_BIN (pipeline), queue);
  gst_bin_add (GST_BIN (pipeline), osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
519

520 521
  gst_element_link (src, decoder);
  gst_element_link (decoder, queue);
522
  gst_element_link (queue, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
523

524 525
  seekable = gst_element_get_pad (queue, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
526 527 528 529 530 531
  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
532 533
static GstElement *
make_avi_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
534 535 536
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
537
  GstElement *a_queue = NULL, *v_queue = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
538
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
539

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
540 541
  pipeline = gst_pipeline_new ("app");

542
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
543 544
  g_object_set (G_OBJECT (src), "location", location, NULL);

545
  demux = gst_element_factory_make_or_warn ("avidemux", "demux");
546
  seekable_elements = g_list_prepend (seekable_elements, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
547 548 549

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
550
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
551 552

  audio_bin = gst_bin_new ("a_decoder_bin");
553
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
554
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
555
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
556
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
557 558
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
559
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
560 561
  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
Wim Taymans's avatar
Wim Taymans committed
562
  gst_element_set_state (audio_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
563

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
564
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
565
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
566 567

  seekable = gst_element_get_pad (a_queue, "src");
568
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
569
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
570 571
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
572 573

  video_bin = gst_bin_new ("v_decoder_bin");
574
  //v_decoder = gst_element_factory_make_or_warn ("identity", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
575
  //v_decoder = gst_element_factory_make_or_warn ("windec", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
576
  v_decoder = gst_element_factory_make_or_warn ("ffmpegdecall", "v_dec");
577
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
578
  //videosink = gst_element_factory_make_or_warn ("fakesink", "v_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
579
  //g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
580
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
Wim Taymans's avatar
Wim Taymans committed
581
  //g_object_set (G_OBJECT (v_queue), "max_level", 10, NULL);
582 583
  gst_element_link (v_decoder, v_queue);
  gst_element_link (v_queue, videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
584
  gst_bin_add (GST_BIN (video_bin), v_decoder);
585 586
  gst_bin_add (GST_BIN (video_bin), v_queue);
  gst_bin_add (GST_BIN (video_bin), videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
587

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
590
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
591
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
592 593

  seekable = gst_element_get_pad (v_queue, "src");
594
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
595
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
596 597
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
598 599 600 601

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
602 603
static GstElement *
make_mpeg_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
604 605
{
  GstElement *pipeline, *audio_bin, *video_bin;
606 607
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
608
  GstElement *a_queue, *v_queue;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
609
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
610

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
611 612
  pipeline = gst_pipeline_new ("app");

613
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
614 615
  g_object_set (G_OBJECT (src), "location", location, NULL);

616
  demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
Wim Taymans's avatar
Wim Taymans committed
617
  g_object_set (G_OBJECT (demux), "sync", FALSE, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
618

619 620
  seekable_elements = g_list_prepend (seekable_elements, demux);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
621 622
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
623
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
624 625

  audio_bin = gst_bin_new ("a_decoder_bin");
626 627
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
628
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
629
  g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
630 631
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
632
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
633 634
  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
635

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
636
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
637
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
638 639

  seekable = gst_element_get_pad (a_queue, "src");
640
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
641
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
642 643
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
644 645

  video_bin = gst_bin_new ("v_decoder_bin");
646
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
647
  //g_object_set (G_OBJECT (video_thread), "priority", 2, NULL);
648
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
649
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
650
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
651
  gst_element_link_many (v_decoder, v_queue, v_filter, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
652

653
  gst_element_link (v_filter, videosink);
654 655
  gst_bin_add_many (GST_BIN (video_bin), v_decoder, NULL);
  gst_bin_add_many (GST_BIN (video_bin), v_queue, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
656

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
657
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
658
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
659 660

  seekable = gst_element_get_pad (v_queue, "src");
661
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
662
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
663 664
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
665 666 667 668

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
669 670
static GstElement *
make_mpegnt_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
671 672 673 674
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
675
  GstElement *a_queue;
Wim Taymans's avatar
Wim Taymans committed
676
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
677

Wim Taymans's avatar
Wim Taymans committed
678 679 680 681 682 683 684 685 686 687 688 689
  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);
690
  gst_element_link (src, demux);
Wim Taymans's avatar
Wim Taymans committed
691 692 693 694

  audio_bin = gst_bin_new ("a_decoder_bin");
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
695
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
Wim Taymans's avatar
Wim Taymans committed
696 697
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
698 699
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Wim Taymans's avatar
Wim Taymans committed
700
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
701 702
  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
Wim Taymans's avatar
Wim Taymans committed
703

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
704
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
705
          "sink"), audio_bin);
Wim Taymans's avatar
Wim Taymans committed
706 707 708 709

  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
710 711
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
712 713 714

  video_bin = gst_bin_new ("v_decoder_bin");
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
715
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
716
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
717
  gst_element_link_many (v_decoder, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
718

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
721
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
722
          "sink"), video_bin);
Wim Taymans's avatar
Wim Taymans committed
723 724 725 726

  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
727 728
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
729 730 731 732

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
733 734
static GstElement *
make_playerbin_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
735
{
736
  GstElement *player;
737 738 739 740

  player = gst_element_factory_make ("playbin", "player");
  g_assert (player);

741
  g_object_set (G_OBJECT (player), "uri", location, NULL);
742 743 744 745 746 747 748

  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
749 750
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
751 752
static gchar *
format_value (GtkScale * scale, gdouble value)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
753
{
754 755 756 757 758 759 760
  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
761

762 763
  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
764 765 766 767 768 769
}

typedef struct
{
  const gchar *name;
  const GstFormat format;
770 771
}
seek_format;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
772

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
773 774 775 776 777 778
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
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
};

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
797
      if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
798
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
799
      } else {
800
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
801 802 803 804 805 806 807 808 809 810 811
      }

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

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
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) {
829
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
830 831 832 833 834 835 836 837 838 839 840 841 842
      } 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
843
{
844 845 846 847 848 849 850 851 852 853 854 855 856
  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
857
      res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
858
      if (res) {
859
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
860
      } else {
861
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
862 863
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
864
    }
865
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
866

867
    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
868 869 870 871
  }
}

G_GNUC_UNUSED static void
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
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) {
889
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
890 891 892 893 894 895 896 897 898 899 900 901 902
      } 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
903
{
904 905 906 907 908 909 910 911 912 913 914 915 916
  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
917
      res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
918
      if (res) {
919
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
920
      } else {
921
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
922 923
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
924
    }
925 926 927
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
928 929 930 931
  }
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
932
update_scale (gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
933 934
{
  GstClock *clock;
935 936
  guint64 position;
  GstFormat format = GST_FORMAT_TIME;
937
  gboolean res;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
938

939
  duration = 0;
940
  clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
941

942 943 944
  if (elem_seek) {
    if (seekable_elements) {
      GstElement *element = GST_ELEMENT (seekable_elements->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
945

946 947 948 949 950 951
      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;
952 953 954 955 956
    }
  } else {
    if (seekable_pads) {
      GstPad *pad = GST_PAD (seekable_pads->data);

957 958 959 960 961 962
      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;
963
    }
964
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
965