seek.c 27.7 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 gboolean stats = FALSE;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
15 16 17

static guint update_id;

18 19
//#define SOURCE "gnomevfssrc"
#define SOURCE "filesrc"
20

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
21 22 23
#define UPDATE_INTERVAL 500

#define THREAD
24
#define PAD_SEEK
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
25 26 27

typedef struct
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
28 29 30
  const gchar *padname;
  GstPad *target;
  GstElement *bin;
31
} dyn_link;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
32

33
static GstElement *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
34
gst_element_factory_make_or_warn (gchar * type, gchar * name)
35 36 37 38
{
  GstElement *element = gst_element_factory_make (type, name);

  if (!element) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
39
    g_warning ("Failed to create element %s of type %s", name, type);
40 41 42 43 44
  }

  return element;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
45
static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
46
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
47
{
48
  dyn_link *connect = (dyn_link *) data;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
49 50 51 52

  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);
53
    gst_pad_link (newpad, connect->target);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
54 55
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

56
    seekable_pads = g_list_prepend (seekable_pads, newpad);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
57 58 59 60 61
    rate_pads = g_list_prepend (rate_pads, newpad);
  }
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
62 63
setup_dynamic_link (GstElement * element, const gchar * padname,
    GstPad * target, GstElement * bin)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
64
{
65
  dyn_link *connect;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
66

67
  connect = g_new0 (dyn_link, 1);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
68 69 70
  connect->padname = g_strdup (padname);
  connect->target = target;
  connect->bin = bin;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
71

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
72 73
  g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
      connect);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
74 75
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
76 77
static GstElement *
make_mod_pipeline (const gchar * location)
78 79 80 81
{
  GstElement *pipeline;
  GstElement *src, *decoder, *audiosink;
  GstPad *seekable;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
82

83 84
  pipeline = gst_pipeline_new ("app");

85 86 87
  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");
88 89 90 91 92 93 94 95
  //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);

96 97
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
98 99 100 101 102 103 104 105 106

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

Wim Taymans's avatar
Wim Taymans committed
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  pipeline = gst_pipeline_new ("app");

  src = gst_element_factory_make_or_warn (SOURCE, "src");
  decoder = gst_element_factory_make_or_warn ("dvdec", "decoder");
  videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
  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);

129 130 131
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
  gst_element_link (decoder, videosink);
Wim Taymans's avatar
Wim Taymans committed
132 133 134 135 136 137 138 139 140 141 142 143

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

Wim Taymans's avatar
Wim Taymans committed
151 152
  pipeline = gst_pipeline_new ("app");

153 154 155
  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
156 157 158 159 160 161 162 163
  //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);

164 165
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
Wim Taymans's avatar
Wim Taymans committed
166 167 168 169 170 171 172 173 174

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

182 183
  pipeline = gst_pipeline_new ("app");

184 185 186
  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
187
  g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
188 189 190 191 192 193 194

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

195 196
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
197 198 199 200 201 202 203 204 205

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

213 214
  pipeline = gst_pipeline_new ("app");

215 216 217
  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");
218 219 220 221 222 223 224 225
  //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);

226 227
  gst_element_link (src, decoder);
  gst_element_link (decoder, audiosink);
228 229 230 231 232 233 234 235 236

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
244 245
  pipeline = gst_pipeline_new ("app");

246 247 248
  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
249 250
  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
251 252 253 254 255 256 257

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

258 259
  gst_element_link (src, parser);
  gst_element_link (parser, fakesink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
260 261

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

276 277
  pipeline = gst_pipeline_new ("app");

278 279 280
  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
281
  g_object_set (G_OBJECT (audiosink), "sync", TRUE, NULL);
282 283 284 285 286 287 288

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

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

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
307 308
  pipeline = gst_pipeline_new ("app");

309 310 311 312
  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");
313 314 315 316

  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
317 318 319 320

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

321 322 323 324 325
  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
326

327 328 329
  gst_element_link (src, decoder);
  gst_element_link (decoder, queue);
  gst_element_link (queue, osssink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
330

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
348 349
  pipeline = gst_pipeline_new ("app");

350
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
351 352
  g_object_set (G_OBJECT (src), "location", location, NULL);

353
  demux = gst_element_factory_make_or_warn ("avidemux", "demux");
354
  seekable_elements = g_list_prepend (seekable_elements, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
355 356 357

  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
358
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
359 360

  audio_bin = gst_bin_new ("a_decoder_bin");
361
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
362
  audio_thread = gst_thread_new ("a_decoder_thread");
363
  audiosink = gst_element_factory_make_or_warn ("osssink", "a_sink");
364
  //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
365
  a_queue = gst_element_factory_make_or_warn ("queue", "a_queue");
366 367
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
368 369 370 371
  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
372
  gst_element_set_state (audio_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
373

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
374 375
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
	  "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
376 377

  seekable = gst_element_get_pad (a_queue, "src");
378
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
379
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
380 381
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
382 383

  video_bin = gst_bin_new ("v_decoder_bin");
384
  //v_decoder = gst_element_factory_make_or_warn ("identity", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
385
  //v_decoder = gst_element_factory_make_or_warn ("windec", "v_dec");
Wim Taymans's avatar
Wim Taymans committed
386
  v_decoder = gst_element_factory_make_or_warn ("ffmpegdecall", "v_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
387
  video_thread = gst_thread_new ("v_decoder_thread");
388 389
  videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
  //videosink = gst_element_factory_make_or_warn ("fakesink", "v_sink");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
390
  //g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
391
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
Wim Taymans's avatar
Wim Taymans committed
392
  //g_object_set (G_OBJECT (v_queue), "max_level", 10, NULL);
393 394
  gst_element_link (v_decoder, v_queue);
  gst_element_link (v_queue, videosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
395 396 397 398 399
  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
400
  gst_element_set_state (video_bin, GST_STATE_PAUSED);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
401

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
402 403
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
	  "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
404 405

  seekable = gst_element_get_pad (v_queue, "src");
406
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
407
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
408 409
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
410 411 412 413

  return pipeline;
}

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
423 424
  pipeline = gst_pipeline_new ("app");

425
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
426 427
  g_object_set (G_OBJECT (src), "location", location, NULL);

428
  demux = gst_element_factory_make_or_warn ("mpegdemux", "demux");
Wim Taymans's avatar
Wim Taymans committed
429
  g_object_set (G_OBJECT (demux), "sync", FALSE, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
430

431 432
  seekable_elements = g_list_prepend (seekable_elements, demux);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
433 434
  gst_bin_add (GST_BIN (pipeline), src);
  gst_bin_add (GST_BIN (pipeline), demux);
435
  gst_element_link (src, demux);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
436 437

  audio_bin = gst_bin_new ("a_decoder_bin");
438
  a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
439
  audio_thread = gst_thread_new ("a_decoder_thread");
440 441
  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
442
  g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL);
443 444
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
445 446 447 448 449
  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
450 451
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
	  "sink"), audio_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
452 453

  seekable = gst_element_get_pad (a_queue, "src");
454
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
455
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
456 457
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
458 459

  video_bin = gst_bin_new ("v_decoder_bin");
460
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
461
  video_thread = gst_thread_new ("v_decoder_thread");
Wim Taymans's avatar
Wim Taymans committed
462
  //g_object_set (G_OBJECT (video_thread), "priority", 2, NULL);
463 464 465
  v_queue = gst_element_factory_make_or_warn ("queue", "v_queue");
  v_filter = gst_element_factory_make_or_warn ("colorspace", "v_filter");
  videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
466
  gst_element_link_many (v_decoder, v_queue, v_filter, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
467

468
  gst_element_link (v_filter, videosink);
469
  gst_bin_add_many (GST_BIN (video_bin), v_decoder, video_thread, NULL);
470
  gst_bin_add_many (GST_BIN (video_thread), v_queue, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
471

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
472 473
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
	  "sink"), video_bin);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
474 475

  seekable = gst_element_get_pad (v_queue, "src");
476
  seekable_pads = g_list_prepend (seekable_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
477
  rate_pads = g_list_prepend (rate_pads, seekable);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
478 479
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
480 481 482 483

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
484 485
static GstElement *
make_mpegnt_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
486 487 488 489 490 491
{
  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
492

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

  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);
514 515
  gst_element_link (a_decoder, a_queue);
  gst_element_link (a_queue, audiosink);
Wim Taymans's avatar
Wim Taymans committed
516 517 518 519 520
  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
521 522
  setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
	  "sink"), audio_bin);
Wim Taymans's avatar
Wim Taymans committed
523 524 525 526

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

  video_bin = gst_bin_new ("v_decoder_bin");
  v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
  v_filter = gst_element_factory_make_or_warn ("colorspace", "v_filter");
  videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
534
  gst_element_link_many (v_decoder, v_filter, videosink, NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
535

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
538 539
  setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
	  "sink"), video_bin);
Wim Taymans's avatar
Wim Taymans committed
540 541 542 543

  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
544 545
  rate_pads =
      g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
Wim Taymans's avatar
Wim Taymans committed
546 547 548 549

  return pipeline;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
550 551
static GstElement *
make_playerbin_pipeline (const gchar * location)
Wim Taymans's avatar
Wim Taymans committed
552 553 554 555
{
  return NULL;
}

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
556 557
static gchar *
format_value (GtkScale * scale, gdouble value)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
558
{
559 560 561 562 563 564 565
  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
566

567
  return g_strdup_printf ("%02lld:%02lld:%02lld",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
568
      seconds / 60, seconds % 60, subseconds % 100);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
569 570 571 572 573 574 575 576
}

typedef struct
{
  const gchar *name;
  const GstFormat format;
} seek_format;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
577 578 579 580 581 582
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
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
};

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
601 602 603 604
      if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
	g_print ("%s %13lld | ", seek_formats[i].name, value);
      } else {
	g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
605 606 607 608 609 610 611 612 613 614 615
      }

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

    walk = g_list_next (walk);
  }
}

G_GNUC_UNUSED static void
616
query_durations ()
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
617
{
618 619 620 621 622 623 624 625 626 627 628 629 630
  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
631
      res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
632
      if (res) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
633 634 635
	g_print ("%s %13lld | ", seek_formats[i].name, value);
      } else {
	g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
636 637
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
638
    }
639
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
640

641
    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
642 643 644 645
  }
}

G_GNUC_UNUSED static void
646
query_positions ()
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
647
{
648 649 650 651 652 653 654 655 656 657 658 659 660
  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
661
      res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
662
      if (res) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
663 664 665
	g_print ("%s %13lld | ", seek_formats[i].name, value);
      } else {
	g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
666 667
      }
      i++;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
668
    }
669 670 671
    g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));

    walk = g_list_next (walk);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
672 673 674 675
  }
}

static gboolean
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
676
update_scale (gpointer data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
677 678
{
  GstClock *clock;
679 680
  guint64 position;
  GstFormat format = GST_FORMAT_TIME;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
681

682
  duration = 0;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
683 684
  clock = gst_bin_get_clock (GST_BIN (pipeline));

685 686
  if (seekable_pads) {
    GstPad *pad = GST_PAD (seekable_pads->data);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
687

Wim Taymans's avatar
Wim Taymans committed
688
    gst_pad_query (pad, GST_QUERY_TOTAL, &format, &duration);
689 690
  }
  position = gst_clock_get_time (clock);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
691

692
  if (stats) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
693 694
    g_print ("clock:                  %13llu  (%s)\n", position,
	gst_object_get_name (GST_OBJECT (clock)));
695 696 697
    query_durations ();
    query_positions ();
    query_rates ();
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
  }

  if (duration > 0) {
    gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
  }

  return TRUE;
}

static gboolean
iterate (gpointer data)
{
  gboolean res;

  res = gst_bin_iterate (GST_BIN (data));
  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
721
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
722 723 724 725 726 727 728 729
{
  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
730
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
731 732 733 734
{
  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
735

736 737
#ifdef PAD_SEEK
  GList *walk = seekable_pads;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
738 739 740 741

  while (walk) {
    GstPad *seekable = GST_PAD (walk->data);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
742 743 744 745 746
    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
747 748 749 750 751

    res = gst_pad_send_event (seekable, s_event);

    walk = g_list_next (walk);
  }
752 753 754 755 756 757
#else
  GList *walk = seekable_elements;

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
758 759 760 761 762
    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);
763 764 765 766 767 768

    res = gst_element_send_event (seekable, s_event);

    walk = g_list_next (walk);
  }
#endif
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
769 770 771

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  gtk_idle_add ((GtkFunction) iterate, pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
772 773
  update_id =
      gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
774 775 776 777 778 779 780

  return FALSE;
}

static void
play_cb (GtkButton * button, gpointer data)
{
781 782 783
  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
784 785
    update_id =
	gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
786
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
787 788 789 790 791
}

static void
pause_cb (GtkButton * button, gpointer data)
{
792 793 794 795
  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
796 797 798 799 800
}

static void
stop_cb (GtkButton * button, gpointer data)
{
801 802 803 804
  if (gst_element_get_state (pipeline) != GST_STATE_READY) {
    gst_element_set_state (pipeline, GST_STATE_READY);
    gtk_timeout_remove (update_id);
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
805 806
}

Wim Taymans's avatar
Wim Taymans committed
807 808 809
typedef struct
{
  gchar *name;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
810
  GstElement *(*func) (const gchar * location);
Wim Taymans's avatar
Wim Taymans committed
811 812 813
} Pipeline;

static Pipeline pipelines[] = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
814 815 816 817 818 819 820 821 822 823 824 825 826
  {"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
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
};

#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
844 845 846
int
main (int argc, char **argv)
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
847 848
  GtkWidget *window, *hbox, *vbox,
      *play_button, *pause_button, *stop_button, *hscale;
849
  struct poptOption options[] = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
850 851
    {"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
	"Show pad stats", NULL},
852 853
    POPT_TABLEEND
  };
Wim Taymans's avatar
Wim Taymans committed
854
  gint type;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
855

856
  gst_init_with_popt_table (&argc, &argv, options);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
857 858 859
  gtk_init (&argc, &argv);

  if (argc != 3) {
Wim Taymans's avatar
Wim Taymans committed
860 861 862 863 864 865 866 867
    print_usage (argc, argv);
    exit (-1);
  }

  type = atoi (argv[1]);

  if (type < 0 || type >= NUM_TYPES) {
    print_usage (argc, argv);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
868 869 870
    exit (-1);
  }

Wim Taymans's avatar
Wim Taymans committed
871 872
  pipeline = pipelines[type].func (argv[2]);
  g_assert (pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
873 874 875 876 877 878 879 880 881

  /* initialize gui elements ... */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  hbox = gtk_hbox_new (FALSE, 0);
  vbox = gtk_vbox_new (FALSE, 0);
  play_button = gtk_button_new_with_label ("play");
  pause_button = gtk_button_new_with_label ("pause");
  stop_button = gtk_button_new_with_label ("stop");

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
882 883
  adjustment =
      GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
884 885 886 887
  hscale = gtk_hscale_new (adjustment);
  gtk_scale_set_digits (GTK_SCALE (hscale), 2);
  gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
888 889 890 891 892 893
  gtk_signal_connect (GTK_OBJECT (hscale),
      "button_press_event", G_CALLBACK (start_seek), pipeline);
  gtk_signal_connect (GTK_OBJECT (hscale),
      "button_release_event", G_CALLBACK (stop_seek), pipeline);
  gtk_signal_connect (GTK_OBJECT (hscale),
      "format_value", G_CALLBACK (format_value), pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
894 895 896 897 898 899 900 901 902 903 904

  /* do the packing stuff ... */
  gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
  gtk_container_add (GTK_CONTAINER (window), vbox);
  gtk_container_add (GTK_CONTAINER (vbox), hbox);
  gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2);
  gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);

  /* connect things ... */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
905 906 907 908 909 910
  g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
      pipeline);
  g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
      pipeline);
  g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
      pipeline);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
911 912 913 914 915
  g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);

  /* show the gui. */
  gtk_widget_show_all (window);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
916 917 918 919
  g_signal_connect (pipeline, "deep_notify",
      G_CALLBACK (gst_element_default_deep_notify), NULL);
  g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
      NULL);
Wim Taymans's avatar
Wim Taymans committed
920

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
921 922
  gtk_main ();

Wim Taymans's avatar
Wim Taymans committed
923 924
  gst_element_set_state (pipeline, GST_STATE_NULL);

925 926
  //gst_object_unref (GST_OBJECT (pipeline));

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
927 928 929 930
  //g_mem_chunk_info();

  return 0;
}