seek.c 30.9 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 20

static guint update_id;

21 22
//#define SOURCE "gnomevfssrc"
#define SOURCE "filesrc"
23

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
24 25 26
#define UPDATE_INTERVAL 500

#define THREAD
27
#define PAD_SEEK
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
28 29 30

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

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

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

  return element;
}

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

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

60
    seekable_pads = g_list_prepend (seekable_pads, newpad);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
61 62 63 64 65
    rate_pads = g_list_prepend (rate_pads, newpad);
  }
}

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

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
76 77
  g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
      connect);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
78 79
}

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

87 88
  pipeline = gst_pipeline_new ("app");

89 90 91
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("modplug", "decoder");
  audiosink = gst_element_factory_make_or_warn ("osssink", "sink");
92 93 94 95 96 97 98 99
  //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);

100 101
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
102 103 104 105 106 107 108 109 110

  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
111 112
static GstElement *
make_dv_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
113 114 115 116
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink, *videosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
117

Wim Taymans's avatar
Wim Taymans committed
118 119 120 121
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("dvdec", "decoder");
122
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
Wim Taymans's avatar
Wim Taymans committed
123 124 125 126 127 128 129 130 131 132
  audiosink = gst_element_factory_make_or_warn ("osssink", "a_sink");
  //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);

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

  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
148 149
static GstElement *
make_wav_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
150 151 152 153
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
154

Wim Taymans's avatar
Wim Taymans committed
155 156
  pipeline = gst_pipeline_new ("app");

157 158 159
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
  audiosink = gst_element_factory_make_or_warn ("osssink", "sink");
Wim Taymans's avatar
Wim Taymans committed
160 161 162 163 164 165 166 167
  //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);

168 169
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
Wim Taymans's avatar
Wim Taymans committed
170 171 172 173 174 175 176 177 178

  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
179 180
static GstElement *
make_flac_pipeline (const gchar * location)
181 182 183 184
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
185

186 187
  pipeline = gst_pipeline_new ("app");

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

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

199 200
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
201 202 203 204 205 206 207 208 209

  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
210 211
static GstElement *
make_sid_pipeline (const gchar * location)
212 213 214 215
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
216

217 218
  pipeline = gst_pipeline_new ("app");

219 220 221
  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("siddec", "decoder");
  audiosink = gst_element_factory_make_or_warn ("osssink", "sink");
222 223 224 225 226 227 228 229
  //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);

230 231
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
232 233 234 235 236 237 238 239 240

  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
241 242
static GstElement *
make_parse_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
243 244 245 246
{
  GstElement *pipeline;
  GstElement *src, *parser, *fakesink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
247

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
248 249
  pipeline = gst_pipeline_new ("app");

250 251 252
  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
253 254
  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
255 256 257 258 259 260 261

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

262 263
  gst_element_link (src, parser);
  gst_element_link (parser, fakesink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
264 265

  seekable = gst_element_get_pad (parser, "src");
266
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
267 268 269 270 271 272
  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
273 274
static GstElement *
make_vorbis_pipeline (const gchar * location)
275 276 277 278
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
279

280 281
  pipeline = gst_pipeline_new ("app");

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

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

293 294
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
295 296 297 298 299 300 301 302 303

  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
304 305
static GstElement *
make_mp3_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
306 307
{
  GstElement *pipeline;
308
  GstElement *src, *decoder, *osssink, *queue, *audio_thread;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
309
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
310

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
311 312
  pipeline = gst_pipeline_new ("app");

313 314 315 316
  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");
  osssink = gst_element_factory_make_or_warn ("osssink", "sink");
317 318 319 320

  audio_thread = gst_thread_new ("a_decoder_thread");

  seekable_elements = g_list_prepend (seekable_elements, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
321 322 323 324

  g_object_set (G_OBJECT (src), "location", location, NULL);
  g_object_set (G_OBJECT (osssink), "fragment", 0x00180008, NULL);

325 326 327 328 329
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), decoder);
  gst_bin_add (GST_BIN (audio_thread), queue);
  gst_bin_add (GST_BIN (audio_thread), osssink);
  gst_bin_add (GST_BIN (pipeline), audio_thread);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
330

331 332 333
  gst_element_link (src, decoder);
  gst_element_link (decoder, queue);
  gst_element_link (queue, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
334

335 336
  seekable = gst_element_get_pad (queue, "src");
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
337 338 339 340 341 342
  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
343 344
static GstElement *
make_avi_pipeline (const gchar * location)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
345 346 347
{
  GstElement *pipeline, *audio_bin, *video_bin;
  GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
348 349
  GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue =
      NULL, *video_thread = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
350
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
351

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
352 353
  pipeline = gst_pipeline_new ("app");

354
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
355 356
  g_object_set (G_OBJECT (src), "location", location, NULL);

357
  demux = gst_element_factory_make_or_warn ("avidemux", "demux");
358
  seekable_elements = g_list_prepend (seekable_elements, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
359 360 361

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
362
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
363 364

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
378
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
379
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
380 381

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

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

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
406
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
407
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
408 409

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

  return pipeline;
}

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
427 428
  pipeline = gst_pipeline_new ("app");

429
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
430 431
  g_object_set (G_OBJECT (src), "location", location, NULL);

432
  demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
Wim Taymans's avatar
Wim Taymans committed
433
  g_object_set (G_OBJECT (demux), "sync", FALSE, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
434

435 436
  seekable_elements = g_list_prepend (seekable_elements, demux);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
437 438
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
439
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
440 441

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
454
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
455
          "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
456 457

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

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

472
  gst_element_link (v_filter, videosink);
473
  gst_bin_add_many (GST_BIN (video_bin), v_decoder, video_thread, NULL);
474
  gst_bin_add_many (GST_BIN (video_thread), v_queue, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
475

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
476
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
477
          "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
478 479

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

  return pipeline;
}

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

Wim Taymans's avatar
Wim Taymans committed
497 498 499 500 501 502 503 504 505 506 507 508
  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);
509
  gst_element_link (src, demux);
Wim Taymans's avatar
Wim Taymans committed
510 511 512 513 514 515 516 517

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

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

  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
531 532
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
533 534 535

  video_bin = gst_bin_new ("v_decoder_bin");
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
536 537
  v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter");
  videosink = gst_element_factory_make_or_warn ("ximagesink", "v_sink");
538
  gst_element_link_many (v_decoder, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
539

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

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

  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
548 549
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
550 551 552 553

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
554 555
static GstElement *
make_playerbin_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
556
{
557 558 559 560 561 562 563 564 565 566 567 568 569
  GstElement *player;

  player = gst_element_factory_make ("playbin", "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;
Wim Taymans's avatar
Wim Taymans committed
570 571
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
572 573
static gchar *
format_value (GtkScale * scale, gdouble value)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
574
{
575 576 577 578 579 580 581
  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
582

583
  return g_strdup_printf ("%02lld:%02lld:%02lld",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
584
      seconds / 60, seconds % 60, subseconds % 100);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
585 586 587 588 589 590
}

typedef struct
{
  const gchar *name;
  const GstFormat format;
591 592
}
seek_format;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
593

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
594 595 596 597 598 599
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
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
};

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
618
      if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
619
        g_print ("%s %13lld | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
620
      } else {
621
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
622 623 624 625 626 627 628 629 630 631 632
      }

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

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
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) {
        g_print ("%s %13lld | ", seek_formats[i].name, value);
      } 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
664
{
665 666 667 668 669 670 671 672 673 674 675 676 677
  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
678
      res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
679
      if (res) {
680
        g_print ("%s %13lld | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
681
      } else {
682
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
683 684
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
685
    }
686
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
687

688
    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
689 690 691 692
  }
}

G_GNUC_UNUSED static void
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
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) {
        g_print ("%s %13lld | ", seek_formats[i].name, value);
      } 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
724
{
725 726 727 728 729 730 731 732 733 734 735 736 737
  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
738
      res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
739
      if (res) {
740
        g_print ("%s %13lld | ", seek_formats[i].name, value);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
741
      } else {
742
        g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
743 744
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
745
    }
746 747 748
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
749 750 751 752
  }
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
753
update_scale (gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
754 755
{
  GstClock *clock;
756 757
  guint64 position;
  GstFormat format = GST_FORMAT_TIME;
758
  gboolean res;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
759

760
  duration = 0;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
761 762
  clock = gst_bin_get_clock (GST_BIN (pipeline));

763 764 765
  if (elem_seek) {
    if (seekable_elements) {
      GstElement *element = GST_ELEMENT (seekable_elements->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
766

767 768 769 770 771 772
      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;
773 774 775 776 777
    }
  } else {
    if (seekable_pads) {
      GstPad *pad = GST_PAD (seekable_pads->data);

778 779 780 781 782 783
      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;
784
    }
785
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
786

787
  if (stats) {
788 789 790 791 792 793 794 795 796 797 798 799
    if (clock) {
      g_print ("clock:                  %13llu  (%s)\n", position,
          gst_object_get_name (GST_OBJECT (clock)));
    }

    if (elem_seek) {
      query_durations_elems ();
      query_positions_elems ();
    } else {
      query_durations_pads ();
      query_positions_pads ();
    }
800
    query_rates ();
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
801
  }
802 803
  if (position >= duration)
    duration = position;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
804 805 806

  if (duration > 0) {
    gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
807
    gtk_widget_queue_draw (hscale);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
808 809 810 811 812 813 814 815 816 817
  }

  return TRUE;
}

static gboolean
iterate (gpointer data)
{
  gboolean res;

818 819 820
  if (!GST_FLAG_IS_SET (GST_OBJECT (data), GST_BIN_SELF_SCHEDULABLE)) {
    res = gst_bin_iterate (GST_BIN (data));
  } else {
821
    g_usleep (500);
822 823 824
    res = gst_element_get_state (GST_ELEMENT (data)) == GST_STATE_PLAYING;
  }

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
825 826 827 828 829 830 831 832
  if (!res) {
    gtk_timeout_remove (update_id);
    g_print ("stopping iterations\n");
  }
  return res;
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
833
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
834 835 836 837 838 839 840 841
{
  gst_element_set_state (pipeline, GST_STATE_PAUSED);
  gtk_timeout_remove (update_id);

  return FALSE;
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
842
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
843 844 845 846
{
  gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
  gboolean res;
  GstEvent *s_event;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
847

848 849
  if (!elem_seek) {
    GList *walk = seekable_pads;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
850

851 852
    while (walk) {
      GstPad *seekable = GST_PAD (walk->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
853

854 855 856 857 858
      g_print ("seek to %lld on pad %s:%s\n", real,
          GST_DEBUG_PAD_NAME (seekable));
      s_event =
          gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
          GST_SEEK_FLAG_FLUSH, real);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
859

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

862 863 864 865
      walk = g_list_next (walk);
    }
  } else {
    GList *walk = seekable_elements;
866

867 868
    while (walk) {
      GstElement *seekable = GST_ELEMENT (walk->data);
869

870 871 872 873 874
      g_print ("seek to %lld on element %s\n", real,
          gst_element_get_name (seekable));
      s_event =
          gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
          GST_SEEK_FLAG_FLUSH, real);
875

876
      res = gst_element_send_event (seekable, s_event);
877

878 879
      walk = g_list_next (walk);
    }
880
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
881 882 883

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  gtk_idle_add ((GtkFunction) iterate, pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
884 885
  update_id =
      gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
886 887 888 889 890 891 892

  return FALSE;
}

static void
play_cb (GtkButton * button, gpointer data)
{
893 894 895
  if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) {
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
    gtk_idle_add ((GtkFunction) iterate, pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
896
    update_id =
897
        gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
898
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
899 900 901 902 903
}

static void
pause_cb (GtkButton * button, gpointer data)
{
904 905 906 907
  if (gst_element_get_state (pipeline) != GST_STATE_PAUSED) {
    gst_element_set_state (pipeline, GST_STATE_PAUSED);
    gtk_timeout_remove (update_id);
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
908 909 910 911 912
}

static void
stop_cb (GtkButton * button, gpointer data)
{
913 914
  if (gst_element_get_state (pipeline) != GST_STATE_READY) {
    gst_element_set_state (pipeline, GST_STATE_READY);
Wim Taymans's avatar
Wim Taymans committed
915
    gtk_adjustment_set_value (adjustment, 0.0);
916 917
    gtk_timeout_remove (update_id);
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
918 919
}

Wim Taymans's avatar
Wim Taymans committed
920 921 922
typedef struct
{
  gchar *name;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
923
  GstElement *(*func) (const gchar * location);
924 925
}
Pipeline;
Wim Taymans's avatar
Wim Taymans committed
926 927

static Pipeline pipelines[] = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
928 929 930 931 932 933 934 935 936 937 938 939 940
  {"mp3", make_mp3_pipeline},
  {"avi", make_avi_pipeline},
  {"mpeg1", make_mpeg_pipeline},
  {"mpegparse", make_parse_pipeline},
  {"vorbis", make_vorbis_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},
  {NULL, NULL},
Wim Taymans's avatar
Wim Taymans committed
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
};

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

static void
print_usage (int argc, char **argv)
{
  gint i;

  g_print ("usage: %s <type> <filename>\n", argv[0]);
  g_print ("   possible types:\n");

  for (i = 0; i < NUM_TYPES; i++) {
    g_print ("     %d = %s\n", i, pipelines[i].name);
  }
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
958 959 960
int
main (int argc, char **argv)
{