seek.c 64.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* GStreamer
 *
 * seek.c: seeking sample application
 *
 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
 *               2006 Stefan Kost <ensonic@users.sf.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/* FIXME: remove #if 0 code
 *
 */
26
#include <stdlib.h>
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
27
28
29
30
31
#include <glib.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <string.h>

32
GST_DEBUG_CATEGORY_STATIC (seek_debug);
33
34
#define GST_CAT_DEFAULT (seek_debug)

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* configuration */

//#define SOURCE "filesrc"
#define SOURCE "gnomevfssrc"

#define ASINK "alsasink"
//#define ASINK "osssink"

#define VSINK "xvimagesink"
//#define VSINK "sdlvideosink"
//#define VSINK "ximagesink"
//#define VSINK "aasink"
//#define VSINK "cacasink"

//#define UPDATE_INTERVAL 500
//#define UPDATE_INTERVAL 100
#define UPDATE_INTERVAL 10

/* number of milliseconds to play for after a seek */
#define SCRUB_TIME 100

/* timeout for gst_element_get_state() after a seek */
#define SEEK_TIMEOUT 40 * GST_MSECOND


60
static GList *seekable_pads = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
61
static GList *rate_pads = NULL;
62
static GList *seekable_elements = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
63

64
65
static gboolean accurate_seek = FALSE;
static gboolean keyframe_seek = FALSE;
66
static gboolean loop_seek = FALSE;
67
static gboolean flush_seek = TRUE;
68
69
static gboolean scrub = TRUE;
static gboolean play_scrub = FALSE;
70
static gdouble rate = 1.0;
71

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
72
static GstElement *pipeline;
73
74
static gint pipeline_type;
static const gchar *pipeline_spec;
75
76
static gint64 position = -1;
static gint64 duration = -1;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
77
static GtkAdjustment *adjustment;
78
static GtkWidget *hscale;
79
static gboolean stats = FALSE;
80
81
static gboolean elem_seek = FALSE;
static gboolean verbose = FALSE;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
82

83
static GstState state = GST_STATE_NULL;
84
static guint update_id = 0;
85
86
static guint seek_timeout_id = 0;
static gulong changed_id;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
87

88
static gint n_video = 0, n_audio = 0, n_text = 0;
89
static gboolean need_streams = TRUE;
90
static GtkWidget *video_combo, *audio_combo, *text_combo, *vis_combo;
91
static GtkWidget *vis_checkbox, *video_checkbox, *audio_checkbox;
92
static GtkWidget *text_checkbox, *mute_checkbox, *volume_spinbutton;
93

94
95
96
97
98
99
100
101
102
/* we keep an array of the visualisation entries so that we can easily switch
 * with the combo box index. */
typedef struct
{
  GstElementFactory *factory;
} VisEntry;

static GArray *vis_entries;

103
static void clear_streams (GstElement * pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
104

105
/* pipeline construction */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
106
107
108

typedef struct
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
109
110
111
  const gchar *padname;
  GstPad *target;
  GstElement *bin;
112
113
}
dyn_link;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
114

115
static GstElement *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
116
gst_element_factory_make_or_warn (gchar * type, gchar * name)
117
118
119
120
{
  GstElement *element = gst_element_factory_make (type, name);

  if (!element) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
121
    g_warning ("Failed to create element %s of type %s", name, type);
122
123
124
125
126
  }

  return element;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
127
static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
128
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
129
{
130
  gchar *padname;
131
  dyn_link *connect = (dyn_link *) data;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
132

133
134
135
  padname = gst_pad_get_name (newpad);

  if (connect->padname == NULL || !strcmp (padname, connect->padname)) {
136
137
    if (connect->bin)
      gst_bin_add (GST_BIN (pipeline), connect->bin);
138
    gst_pad_link (newpad, connect->target);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
139

140
    //seekable_pads = g_list_prepend (seekable_pads, newpad);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
141
142
    rate_pads = g_list_prepend (rate_pads, newpad);
  }
143
  g_free (padname);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
144
145
146
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
147
148
setup_dynamic_link (GstElement * element, const gchar * padname,
    GstPad * target, GstElement * bin)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
149
{
150
  dyn_link *connect;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
151

152
  connect = g_new0 (dyn_link, 1);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
153
154
155
  connect->padname = g_strdup (padname);
  connect->target = target;
  connect->bin = bin;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
156

157
  g_signal_connect (G_OBJECT (element), "pad-added", G_CALLBACK (dynamic_link),
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
158
      connect);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
159
160
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
161
162
static GstElement *
make_mod_pipeline (const gchar * location)
163
164
165
166
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
167

168
169
  pipeline = gst_pipeline_new ("app");

170
171
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("modplug", "decoder");
172
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
173
174
175
176
177
178
179
180
  //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);

181
182
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
183
184
185
186
187
188
189
190
191

  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
192
193
static GstElement *
make_dv_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
194
195
{
  GstElement *pipeline;
196
  GstElement *src, *demux, *decoder, *audiosink, *videosink;
197
  GstElement *a_queue, *v_queue;
Wim Taymans's avatar
Wim Taymans committed
198
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
199

Wim Taymans's avatar
Wim Taymans committed
200
201
202
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
203
  demux = gst_element_factory_make_or_warn ("dvdemux", "demuxer");
204
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
205
  decoder = gst_element_factory_make_or_warn ("ffdec_dvvideo", "decoder");
206
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
207
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
208
  audiosink = gst_element_factory_make_or_warn ("alsasink", "a_sink");
Wim Taymans's avatar
Wim Taymans committed
209
210
211
212

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

  gst_bin_add (GST_BIN (pipeline), src);
213
  gst_bin_add (GST_BIN (pipeline), demux);
214
  gst_bin_add (GST_BIN (pipeline), a_queue);
Wim Taymans's avatar
Wim Taymans committed
215
  gst_bin_add (GST_BIN (pipeline), audiosink);
216
  gst_bin_add (GST_BIN (pipeline), v_queue);
217
  gst_bin_add (GST_BIN (pipeline), decoder);
Wim Taymans's avatar
Wim Taymans committed
218
219
  gst_bin_add (GST_BIN (pipeline), videosink);

220
  gst_element_link (src, demux);
221
  gst_element_link (a_queue, audiosink);
222
223
  gst_element_link (v_queue, decoder);
  gst_element_link (decoder, videosink);
Wim Taymans's avatar
Wim Taymans committed
224

225
226
227
228
  setup_dynamic_link (demux, "video", gst_element_get_pad (v_queue, "sink"),
      NULL);
  setup_dynamic_link (demux, "audio", gst_element_get_pad (a_queue, "sink"),
      NULL);
229

230
231
  seekable = gst_element_get_pad (decoder, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Wim Taymans's avatar
Wim Taymans committed
232
233
234
235
236
  rate_pads = g_list_prepend (rate_pads, seekable);

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
237
238
static GstElement *
make_wav_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
239
240
241
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
242

Wim Taymans's avatar
Wim Taymans committed
243
244
  pipeline = gst_pipeline_new ("app");

245
246
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
247
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
248
249
250
251
252
253
254

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

255
  gst_element_link (src, decoder);
Wim Taymans's avatar
Wim Taymans committed
256

257
258
259
260
261
262
263
  setup_dynamic_link (decoder, "src", gst_element_get_pad (audiosink, "sink"),
      NULL);

  seekable_elements = g_list_prepend (seekable_elements, audiosink);

  /* force element seeking on this pipeline */
  elem_seek = TRUE;
Wim Taymans's avatar
Wim Taymans committed
264
265
266
267

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
268
269
static GstElement *
make_flac_pipeline (const gchar * location)
270
271
272
273
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
274

275
276
  pipeline = gst_pipeline_new ("app");

277
278
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("flacdec", "decoder");
279
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
280
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
281
282
283
284
285
286
287

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

288
289
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
290
291
292
293
294
295
296
297
298

  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
299
300
static GstElement *
make_sid_pipeline (const gchar * location)
301
302
303
304
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
305

306
307
  pipeline = gst_pipeline_new ("app");

308
309
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("siddec", "decoder");
310
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
311
312
313
314
315
316
317
318
  //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);

319
320
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
321
322
323
324
325
326
327
328
329

  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
330
331
static GstElement *
make_parse_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
332
333
334
335
{
  GstElement *pipeline;
  GstElement *src, *parser, *fakesink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
336

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
337
338
  pipeline = gst_pipeline_new ("app");

339
340
341
  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
342
343
  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
344
345
346
347
348
349
350

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

351
352
  gst_element_link (src, parser);
  gst_element_link (parser, fakesink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
353
354

  seekable = gst_element_get_pad (parser, "src");
355
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
356
357
358
359
360
361
  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
362
363
static GstElement *
make_vorbis_pipeline (const gchar * location)
364
{
365
366
  GstElement *pipeline, *audio_bin;
  GstElement *src, *demux, *decoder, *convert, *audiosink;
367
  GstPad *pad, *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
368

369
370
  pipeline = gst_pipeline_new ("app");

371
  src = gst_element_factory_make_or_warn (SOURCE, "src");
372
373
374
  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");
375
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Wim Taymans's avatar
Wim Taymans committed
376
  g_object_set (G_OBJECT (audiosink), "sync", TRUE, NULL);
377
378
379

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

380
381
  audio_bin = gst_bin_new ("a_decoder_bin");

382
  gst_bin_add (GST_BIN (pipeline), src);
383
384
385
386
387
  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);
388

389
390
391
392
  gst_element_link (src, demux);
  gst_element_link (decoder, convert);
  gst_element_link (convert, audiosink);

393
394
395
396
397
398
  pad = gst_element_get_pad (decoder, "sink");
  gst_element_add_pad (audio_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (audio_bin, "sink"),
      NULL);
399
400
401
402
403
404
405
406
407
408
409
410
411
412

  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;
413
  GstPad *pad, *seekable;
414
415
416
417
418
419
420

  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  demux = gst_element_factory_make_or_warn ("oggdemux", "demux");
  decoder = gst_element_factory_make_or_warn ("theoradec", "decoder");
  convert = gst_element_factory_make_or_warn ("ffmpegcolorspace", "convert");
Wim Taymans's avatar
Wim Taymans committed
421
  videosink = gst_element_factory_make_or_warn (VSINK, "sink");
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

  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 (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 (decoder, convert);
  gst_element_link (convert, videosink);

438
439
440
441
442
443
  pad = gst_element_get_pad (decoder, "sink");
  gst_element_add_pad (video_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (video_bin, "sink"),
      NULL);
444
445
446
447
448
449
450
451
452

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

453
454
455
456
457
458
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;
459
  GstElement *a_queue, *v_queue, *v_scale;
460
  GstPad *seekable;
Wim Taymans's avatar
Wim Taymans committed
461
  GstPad *pad;
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

  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");
478
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
479

480
  gst_bin_add (GST_BIN (pipeline), audio_bin);
481
482
483
484
485
486

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

487
488
489
  gst_element_link (a_queue, a_decoder);
  gst_element_link (a_decoder, a_convert);
  gst_element_link (a_convert, audiosink);
490

Wim Taymans's avatar
Wim Taymans committed
491
492
  pad = gst_element_get_pad (a_queue, "sink");
  gst_element_add_pad (audio_bin, gst_ghost_pad_new ("sink", pad));
493
  gst_object_unref (pad);
494
495
496

  setup_dynamic_link (demux, NULL, gst_element_get_pad (audio_bin, "sink"),
      NULL);
497
498
499
500
501
502

  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");
503
  v_scale = gst_element_factory_make_or_warn ("videoscale", "v_scale");
Wim Taymans's avatar
Wim Taymans committed
504
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
505
506

  gst_bin_add (GST_BIN (pipeline), video_bin);
507
508
509
510

  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);
511
  gst_bin_add (GST_BIN (video_bin), v_scale);
512
513
  gst_bin_add (GST_BIN (video_bin), videosink);

514
515
  gst_element_link_many (v_queue, v_decoder, v_convert, v_scale, videosink,
      NULL);
516

Wim Taymans's avatar
Wim Taymans committed
517
518
  pad = gst_element_get_pad (v_queue, "sink");
  gst_element_add_pad (video_bin, gst_ghost_pad_new ("sink", pad));
519
  gst_object_unref (pad);
520
521
522

  setup_dynamic_link (demux, NULL, gst_element_get_pad (video_bin, "sink"),
      NULL);
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

  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;
540
  GstPad *seekable, *pad;
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

  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");
557
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
558
559
560
561
562
563

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

564
565
566
567
  gst_element_link (a_queue, a_decoder);
  gst_element_link (a_decoder, a_convert);
  gst_element_link (a_convert, audiosink);

568
569
  gst_bin_add (GST_BIN (pipeline), audio_bin);

570
571
572
573
574
575
  pad = gst_element_get_pad (a_queue, "sink");
  gst_element_add_pad (audio_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (audio_bin, "sink"),
      NULL);
576
577
578
579
580
581

  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");
Wim Taymans's avatar
Wim Taymans committed
582
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
583
584
585
586
587
588

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

589
590
  gst_element_link_many (v_queue, v_decoder, v_convert, videosink, NULL);

591
592
  gst_bin_add (GST_BIN (pipeline), video_bin);

593
594
595
596
597
598
  pad = gst_element_get_pad (v_queue, "sink");
  gst_element_add_pad (video_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, NULL, gst_element_get_pad (video_bin, "sink"),
      NULL);
599
600
601
602
603
604
605
606
607
608

  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
609
610
static GstElement *
make_mp3_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
611
612
{
  GstElement *pipeline;
613
  GstElement *src, *decoder, *osssink, *queue;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
614
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
615

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
616
617
  pipeline = gst_pipeline_new ("app");

618
619
620
  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");
621
  osssink = gst_element_factory_make_or_warn (ASINK, "sink");
622

623
  seekable_elements = g_list_prepend (seekable_elements, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
624
625

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

628
629
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
630
631
  gst_bin_add (GST_BIN (pipeline), queue);
  gst_bin_add (GST_BIN (pipeline), osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
632

633
634
  gst_element_link (src, decoder);
  gst_element_link (decoder, queue);
635
  gst_element_link (queue, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
636

637
638
  seekable = gst_element_get_pad (queue, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
639
640
641
642
643
644
  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
645
646
static GstElement *
make_avi_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
647
648
649
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
650
  GstElement *a_queue = NULL, *v_queue = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
651
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
652

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
653
654
  pipeline = gst_pipeline_new ("app");

655
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
656
657
  g_object_set (G_OBJECT (src), "location", location, NULL);

658
  demux = gst_element_factory_make_or_warn ("avidemux", "demux");
659
  seekable_elements = g_list_prepend (seekable_elements, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
660
661
662

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
663
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
664
665

  audio_bin = gst_bin_new ("a_decoder_bin");
666
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
667
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
668
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
669
670
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
671
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
672
673
  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
Wim Taymans's avatar
Wim Taymans committed
674
  gst_element_set_state (audio_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
675

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
676
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
677
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
678
679

  seekable = gst_element_get_pad (a_queue, "src");
680
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
681
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
682
683
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
684
685

  video_bin = gst_bin_new ("v_decoder_bin");
Wim Taymans's avatar
Wim Taymans committed
686
  v_decoder = gst_element_factory_make_or_warn ("ffmpegdecall", "v_dec");
687
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
688
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
689
690
  gst_element_link (v_decoder, v_queue);
  gst_element_link (v_queue, videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
691
  gst_bin_add (GST_BIN (video_bin), v_decoder);
692
693
  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
694

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
697
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
698
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
699
700

  seekable = gst_element_get_pad (v_queue, "src");
701
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
702
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
703
704
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
705
706
707
708

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
709
710
static GstElement *
make_mpeg_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
711
712
{
  GstElement *pipeline, *audio_bin, *video_bin;
713
714
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
715
  GstElement *a_queue, *v_queue;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
716
  GstPad *seekable;
717
  GstPad *pad;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
718

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
719
720
  pipeline = gst_pipeline_new ("app");

721
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
722
723
  g_object_set (G_OBJECT (src), "location", location, NULL);

724
725
  //demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
  demux = gst_element_factory_make_or_warn ("flupsdemux", "demux");
726

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
727
728
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
729
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
730
731

  audio_bin = gst_bin_new ("a_decoder_bin");
732
733
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
734
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
735
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
736
737
  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
738

739
740
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
741

742
743
744
745
746
747
748
749
  gst_bin_add (GST_BIN (pipeline), audio_bin);

  pad = gst_element_get_pad (a_decoder, "sink");
  gst_element_add_pad (audio_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, "audio_c0", gst_element_get_pad (audio_bin,
          "sink"), NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
750
751

  video_bin = gst_bin_new ("v_decoder_bin");
752
753
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
754
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
755
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
756

757
758
759
760
761
762
763
  gst_bin_add (GST_BIN (video_bin), v_decoder);
  gst_bin_add (GST_BIN (video_bin), v_queue);
  gst_bin_add (GST_BIN (video_bin), v_filter);
  gst_bin_add (GST_BIN (video_bin), videosink);

  gst_element_link (v_decoder, v_queue);
  gst_element_link (v_queue, v_filter);
764
  gst_element_link (v_filter, videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
765

766
  gst_bin_add (GST_BIN (pipeline), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
767

768
769
770
771
772
773
774
775
  pad = gst_element_get_pad (v_decoder, "sink");
  gst_element_add_pad (video_bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (pad);

  setup_dynamic_link (demux, "video_e0", gst_element_get_pad (video_bin,
          "sink"), NULL);

  seekable = gst_element_get_pad (v_filter, "src");
776
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
777
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
778
779
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
780
781
782
783

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
784
785
static GstElement *
make_mpegnt_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
786
787
788
789
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
  GstElement *audiosink, *videosink;
790
  GstElement *a_queue;
Wim Taymans's avatar
Wim Taymans committed
791
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
792

Wim Taymans's avatar
Wim Taymans committed
793
794
795
796
797
798
799
800
801
802
803
804
  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);
805
  gst_element_link (src, demux);
Wim Taymans's avatar
Wim Taymans committed
806
807
808
809

  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");
810
  audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink");
Wim Taymans's avatar
Wim Taymans committed
811
812
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
813
814
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Wim Taymans's avatar
Wim Taymans committed
815
  gst_bin_add (GST_BIN (audio_bin), a_decoder);
816
817
  gst_bin_add (GST_BIN (audio_bin), a_queue);
  gst_bin_add (GST_BIN (audio_bin), audiosink);
Wim Taymans's avatar
Wim Taymans committed
818

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
819
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
820
          "sink"), audio_bin);
Wim Taymans's avatar
Wim Taymans committed
821
822
823
824

  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
825
826
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
827
828
829

  video_bin = gst_bin_new ("v_decoder_bin");
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
830
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
831
  videosink = gst_element_factory_make_or_warn (VSINK, "v_sink");
832
  gst_element_link_many (v_decoder, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
833

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
836
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
837
          "sink"), video_bin);
Wim Taymans's avatar
Wim Taymans committed
838
839
840
841

  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
842
843
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
844
845
846
847

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
848
849
static GstElement *
make_playerbin_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
850
{
851
  GstElement *player;
852
853
854
855

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

856
  g_object_set (G_OBJECT (player), "uri", location, NULL);
857
858
859
860
861
862
863

  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
864
865
}

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
static GstElement *
make_playerbin2_pipeline (const gchar * location)
{
  GstElement *player;

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

  g_object_set (G_OBJECT (player), "uri", location, NULL);

  seekable_elements = g_list_prepend (seekable_elements, player);

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

  return player;
}

884
#ifndef GST_DISABLE_PARSE
885
886
887
888
889
890
891
892
893
894
895
896
897
898
static GstElement *
make_parselaunch_pipeline (const gchar * description)
{
  GstElement *pipeline;
  GError *error;

  pipeline = gst_parse_launch (description, &error);

  seekable_elements = g_list_prepend (seekable_elements, pipeline);

  elem_seek = TRUE;

  return pipeline;
}
899
#endif
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
typedef struct
{
  gchar *name;
  GstElement *(*func) (const gchar * location);
}
Pipeline;

static Pipeline pipelines[] = {
  {"mp3", make_mp3_pipeline},
  {"avi", make_avi_pipeline},
  {"mpeg1", make_mpeg_pipeline},
  {"mpegparse", make_parse_pipeline},
  {"vorbis", make_vorbis_pipeline},
  {"theora", make_theora_pipeline},
  {"ogg/v/t", make_vorbis_theora_pipeline},
  {"avi/msmpeg4v3/mp3", make_avi_msmpeg4v3_mp3_pipeline},
  {"sid", make_sid_pipeline},
  {"flac", make_flac_pipeline},
  {"wav", make_wav_pipeline},
  {"mod", make_mod_pipeline},
  {"dv", make_dv_pipeline},
  {"mpeg1nothreads", make_mpegnt_pipeline},
  {"playerbin", make_playerbin_pipeline},
#ifndef GST_DISABLE_PARSE
  {"parse-launch", make_parselaunch_pipeline},
#endif
927
  {"playerbin2", make_playerbin2_pipeline},
928
929
930
931
932
933
934
  {NULL, NULL},
};

#define NUM_TYPES       ((sizeof (pipelines) / sizeof (Pipeline)) - 1)

/* ui callbacks and helpers */

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
935
936
static gchar *
format_value (GtkScale * scale, gdouble value)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
937
{
938
939
940
941
942
943
944
  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
945

946
947
  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
948
949
950
951
952
953
}

typedef struct
{
  const gchar *name;
  const GstFormat format;
954
955
}
seek_format;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
956

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
957
958
959
960
961
962
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
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
};

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;

Wim Taymans's avatar
Wim Taymans committed
981
982
      if (gst_pad_query_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format,
              &value)) {
983
        g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
984
      } else {
985
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
986
987
988
989
990
991
992
993
994
995
996
      }

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

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
997
query_positions_elems (void)
998
999
1000
1001
1002
1003
1004
1005
1006
{
  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) {
Wim Taymans's avatar
Wim Taymans committed
1007
      gint64 position, total;
1008
1009
1010
      GstFormat format;

      format = seek_formats[i].format;
Wim Taymans's avatar
Wim Taymans committed
1011

Wim Taymans's avatar
Wim Taymans committed
1012
1013
      if (gst_element_query_position (element, &format, &position) &&
          gst_element_query_duration (element, &format, &total)) {
Wim Taymans's avatar
Wim Taymans committed
1014
1015
        g_print ("%s %13" G_GINT64_FORMAT " / %13" G_GINT64_FORMAT " | ",
            seek_formats[i].name, position, total);
1016
      } else {
Wim Taymans's avatar
Wim Taymans committed
1017
1018
        g_print ("%s %13.13s / %13.13s | ", seek_formats[i].name, "*NA*",
            "*NA*");
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
      }
      i++;
    }
    g_print (" %s\n", GST_ELEMENT_NAME (element));

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
1029
query_positions_pads (void)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1030
{
1031
1032
1033
1034
1035
1036
1037
1038
1039
  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) {
      GstFormat format;
Wim Taymans's avatar
Wim Taymans committed
1040
      gint64 position, total;
1041
1042

      format = seek_formats[i].format;
Wim Taymans's avatar
Wim Taymans committed
1043

Wim Taymans's avatar
Wim Taymans committed
1044
1045
      if (gst_pad_query_position (pad, &format, &position) &&
          gst_pad_query_duration (pad, &format, &total)) {
Wim Taymans's avatar
Wim Taymans committed
1046
1047
        g_print ("%s %13" G_GINT64_FORMAT " / %13" G_GINT64_FORMAT " | ",
            seek_formats[i].name, position, total);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1048
      } else {
Wim Taymans's avatar
Wim Taymans committed
1049
1050
        g_print ("%s %13.13s / %13.13s | ", seek_formats[i].name, "*NA*",
            "*NA*");
1051
      }
Wim Taymans's avatar
Wim Taymans committed
1052

1053
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1054
    }
1055
1056
1057
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1058
1059
1060
  }
}

1061
1062
1063
1064
static gboolean start_seek (GtkWidget * widget, GdkEventButton * event,
    gpointer user_data);
static gboolean stop_seek (GtkWidget * widget, GdkEventButton * event,
    gpointer user_data);
1065
static void seek_cb (GtkWidget * widget);
1066
1067
1068
1069

static void
set_scale (gdouble value)
{
1070
1071
1072
1073
  g_signal_handlers_block_by_func (hscale, (void *) start_seek,
      (void *) pipeline);
  g_signal_handlers_block_by_func (hscale, (void *) stop_seek,
      (void *) pipeline);
1074
  g_signal_handlers_block_by_func (hscale, (void *) seek_cb, (void *) pipeline);
1075
  gtk_adjustment_set_value (adjustment, value);
1076
1077
1078
1079
  g_signal_handlers_unblock_by_func (hscale, (void *) start_seek,
      (void *) pipeline);
  g_signal_handlers_unblock_by_func (hscale, (void *) stop_seek,
      (void *) pipeline);
1080
1081
  g_signal_handlers_unblock_by_func (hscale, (void *) seek_cb,
      (void *) pipeline);
1082
1083
1084
  gtk_widget_queue_draw (hscale);
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1085
static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1086
update_scale (gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1087
{
1088
  GstFormat format = GST_FORMAT_TIME;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1089

1090
1091
  //position = 0;
  //duration = 0;