gstdecodebin.c 47.1 KB
Newer Older
1
/* GStreamer
2
 * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>
#include <gst/gst.h>

27
28
#include "gstplay-marshal.h"

29
/* generic templates */
30
static GstStaticPadTemplate decoder_bin_sink_template =
31
32
33
34
35
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

36
static GstStaticPadTemplate decoder_bin_src_template =
37
38
39
40
41
42
43
44
GST_STATIC_PAD_TEMPLATE ("src%d",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
#define GST_CAT_DEFAULT gst_decode_bin_debug

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
45
46
47
48
49
#define GST_TYPE_DECODE_BIN             (gst_decode_bin_get_type())
#define GST_DECODE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
#define GST_DECODE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
#define GST_IS_DECODE_BIN(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
#define GST_IS_DECODE_BIN_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))
50
51
52
53
54
55

typedef struct _GstDecodeBin GstDecodeBin;
typedef struct _GstDecodeBinClass GstDecodeBinClass;

struct _GstDecodeBin
{
56
  GstBin bin;                   /* we extend GstBin */
57

58
  GstElement *typefind;         /* this holds the typefind object */
59
  GstElement *fakesink;
60

61
  GList *dynamics;              /* list of dynamic connections */
62

63
64
  GList *queues;                /* list of demuxer-decoder queues */

65
66
  GList *probes;                /* list of PadProbeData */

67
  GList *factories;             /* factories we can use for selecting elements */
68
  gint numpads;
69
  gint numwaiting;
70

71
  guint have_type_id;           /* signal id for the typefind element */
72
73

  gboolean shutting_down;       /* stop pluggin if we're shutting down */
74
75

  GType queue_type;             /* store the GType of queues, to aid in recognising them */
76
77

  GMutex *cb_mutex;             /* Mutex for multi-threaded callbacks, such as removing the fakesink */
78
79
80
81
82
};

struct _GstDecodeBinClass
{
  GstBinClass parent_class;
83

84
  /* signal we fire when a new pad has been decoded into raw audio/video */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
85
  void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
86
87
  /* signal we fire when a pad has been removed */
  void (*removed_decoded_pad) (GstElement * element, GstPad * pad);
88
  /* signal fired when we found a pad that we cannot decode */
89
  void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
90
91
92
93
94
};

/* signals */
enum
{
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
95
  SIGNAL_NEW_DECODED_PAD,
96
  SIGNAL_REMOVED_DECODED_PAD,
97
  SIGNAL_UNKNOWN_TYPE,
Wim Taymans's avatar
Wim Taymans committed
98
  SIGNAL_REDIRECT,
99
100
101
  LAST_SIGNAL
};

102
103
104
105
106
107
108
109

typedef struct
{
  GstPad *pad;
  gulong sigid;
  gboolean done;
} PadProbeData;

110
111
/* this structure is created for all dynamic pads that could get created
 * at runtime */
112
113
typedef struct
{
114
  gint np_sig_id;               /* signal id of new_pad */
115
  gint unlink_sig_id;           /* signal id of unlinked */
116
117
118
  gint nmp_sig_id;              /* signal id of no_more_pads */
  GstElement *element;          /* the element sending the signal */
  GstDecodeBin *decode_bin;     /* pointer to ourself */
119
120
121
}
GstDynamic;

122
123
124
static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
static void gst_decode_bin_init (GstDecodeBin * decode_bin);
static void gst_decode_bin_dispose (GObject * object);
125
static void gst_decode_bin_finalize (GObject * object);
126

127
128
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
    GstStateChange transition);
129

130
131
132
static void add_fakesink (GstDecodeBin * decode_bin);
static void remove_fakesink (GstDecodeBin * decode_bin);

133
static void free_dynamics (GstDecodeBin * decode_bin);
134
135
static void type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstDecodeBin * decode_bin);
136
137
static GstElement *try_to_link_1 (GstDecodeBin * decode_bin,
    GstElement * origelement, GstPad * pad, GList * factories);
138
139
static void close_link (GstElement * element, GstDecodeBin * decode_bin);
static void close_pad_link (GstElement * element, GstPad * pad,
140
    GstCaps * caps, GstDecodeBin * decode_bin, gboolean more);
141
142
static void unlinked (GstPad * pad, GstPad * peerpad,
    GstDecodeBin * decode_bin);
Wim Taymans's avatar
Wim Taymans committed
143
144
static void new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic);
static void no_more_pads (GstElement * element, GstDynamic * dynamic);
145

146
static void queue_filled_cb (GstElement * queue, GstDecodeBin * decode_bin);
147
static void queue_underrun_cb (GstElement * queue, GstDecodeBin * decode_bin);
148

149
static GstElementClass *parent_class;
150
static guint gst_decode_bin_signals[LAST_SIGNAL] = { 0 };
151

Stefan Kost's avatar
Stefan Kost committed
152
static const GstElementDetails gst_decode_bin_details =
153
154
155
156
GST_ELEMENT_DETAILS ("Decoder Bin",
    "Generic/Bin/Decoder",
    "Autoplug and decode to raw media",
    "Wim Taymans <wim@fluendo.com>");
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196


static GType
gst_decode_bin_get_type (void)
{
  static GType gst_decode_bin_type = 0;

  if (!gst_decode_bin_type) {
    static const GTypeInfo gst_decode_bin_info = {
      sizeof (GstDecodeBinClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_decode_bin_class_init,
      NULL,
      NULL,
      sizeof (GstDecodeBin),
      0,
      (GInstanceInitFunc) gst_decode_bin_init,
      NULL
    };

    gst_decode_bin_type =
        g_type_register_static (GST_TYPE_BIN, "GstDecodeBin",
        &gst_decode_bin_info, 0);
  }

  return gst_decode_bin_type;
}

static void
gst_decode_bin_class_init (GstDecodeBinClass * klass)
{
  GObjectClass *gobject_klass;
  GstElementClass *gstelement_klass;
  GstBinClass *gstbin_klass;

  gobject_klass = (GObjectClass *) klass;
  gstelement_klass = (GstElementClass *) klass;
  gstbin_klass = (GstBinClass *) klass;

197
  parent_class = g_type_class_peek_parent (klass);
198

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
199
200
201
202
  gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] =
      g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstDecodeBinClass, new_decoded_pad), NULL, NULL,
203
      gst_play_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, GST_TYPE_PAD,
204
      G_TYPE_BOOLEAN);
205
206
207
208
209
  gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] =
      g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstDecodeBinClass, removed_decoded_pad), NULL, NULL,
      gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
210
211
212
  gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
213
      NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
214
      GST_TYPE_PAD, GST_TYPE_CAPS);
215

216
  gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
217
  gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_decode_bin_finalize);
218

219
220
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&decoder_bin_sink_template));
221
222
223
224
225
226
227
228
229
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&decoder_bin_src_template));

  gst_element_class_set_details (gstelement_klass, &gst_decode_bin_details);

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
}

230
231
232
233
234
/* check if the bin is dynamic.
 *
 * If there are no outstanding dynamic connections, the bin is 
 * considered to be non-dynamic.
 */
235
236
237
238
239
240
static gboolean
gst_decode_bin_is_dynamic (GstDecodeBin * decode_bin)
{
  return decode_bin->dynamics != NULL;
}

241
242
/* the filter function for selecting the elements we can use in
 * autoplugging */
243
244
245
246
247
static gboolean
gst_decode_bin_factory_filter (GstPluginFeature * feature,
    GstDecodeBin * decode_bin)
{
  guint rank;
248
  const gchar *klass;
249

250
  /* we only care about element factories */
251
252
253
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;

254
  klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
255
  /* only demuxers, decoders and parsers can play */
256
257
  if (strstr (klass, "Demux") == NULL &&
      strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL) {
258
259
260
    return FALSE;
  }

261
  /* only select elements with autoplugging rank */
262
  rank = gst_plugin_feature_get_rank (feature);
263
  if (rank < GST_RANK_MARGINAL)
264
265
266
267
268
    return FALSE;

  return TRUE;
}

269
/* function used to sort element features */
270
271
272
static gint
compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
{
273
  gint diff;
Wim Taymans's avatar
Wim Taymans committed
274
  const gchar *rname1, *rname2;
275
276
277
278

  diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
  if (diff != 0)
    return diff;
Wim Taymans's avatar
Wim Taymans committed
279
280
281
282
283
284
285

  rname1 = gst_plugin_feature_get_name (f1);
  rname2 = gst_plugin_feature_get_name (f2);

  diff = strcmp (rname2, rname1);

  return diff;
286
287
}

288
289
290
static void
print_feature (GstPluginFeature * feature)
{
Wim Taymans's avatar
Wim Taymans committed
291
292
293
294
295
  const gchar *rname;

  rname = gst_plugin_feature_get_name (feature);

  GST_DEBUG ("%s", rname);
296
297
}

298
299
300
301
302
static void
gst_decode_bin_init (GstDecodeBin * decode_bin)
{
  GList *factories;

303
304
  decode_bin->cb_mutex = g_mutex_new ();

305
  /* first filter out the interesting element factories */
306
  factories = gst_default_registry_feature_filter (
307
308
309
      (GstPluginFeatureFilter) gst_decode_bin_factory_filter,
      FALSE, decode_bin);

310
  /* sort them according to their ranks */
311
  decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
312
  /* do some debugging */
313
  g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL);
314

315
  /* we create the typefind element only once */
316
317
  decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
  if (!decode_bin->typefind) {
318
319
    g_warning ("can't find typefind element, decodebin will not work");
  } else {
320
321
    GstPad *pad;

322
    /* add the typefind element */
323
324
    if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind)) {
      g_warning ("Could not add typefind element, decodebin will not work");
325
      gst_object_unref (decode_bin->typefind);
326
327
      decode_bin->typefind = NULL;
    }
328
329
330
331

    /* get the sinkpad */
    pad = gst_element_get_pad (decode_bin->typefind, "sink");

332
    /* ghost the sink pad to ourself */
Andy Wingo's avatar
Andy Wingo committed
333
334
    gst_element_add_pad (GST_ELEMENT (decode_bin),
        gst_ghost_pad_new ("sink", pad));
335

336
    gst_object_unref (pad);
337
338
339
340
341
342

    /* connect a signal to find out when the typefind element found
     * a type */
    decode_bin->have_type_id =
        g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
        G_CALLBACK (type_found), decode_bin);
343
  }
344
  add_fakesink (decode_bin);
345

346
  decode_bin->dynamics = NULL;
347
  decode_bin->queues = NULL;
348
  decode_bin->probes = NULL;
349
350
}

351
352
static void dynamic_free (GstDynamic * dyn);

353
354
355
356
357
358
359
static void
gst_decode_bin_dispose (GObject * object)
{
  GstDecodeBin *decode_bin;

  decode_bin = GST_DECODE_BIN (object);

360
361
362
  if (decode_bin->factories)
    gst_plugin_feature_list_free (decode_bin->factories);
  decode_bin->factories = NULL;
363

364
  G_OBJECT_CLASS (parent_class)->dispose (object);
365
366
367
368
369

  /* our parent dispose might trigger new signals when pads are unlinked
   * etc. clean up the mess here. */
  /* FIXME do proper cleanup when going to NULL */
  free_dynamics (decode_bin);
370
371
}

372
373
374
375
376
377
378
379
380
381
static void
gst_decode_bin_finalize (GObject * object)
{
  GstDecodeBin *decode_bin = GST_DECODE_BIN (object);

  g_mutex_free (decode_bin->cb_mutex);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

Wim Taymans's avatar
Wim Taymans committed
382
383
384
385
386
static GstDynamic *
dynamic_create (GstElement * element, GstDecodeBin * decode_bin)
{
  GstDynamic *dyn;

387
388
  GST_DEBUG_OBJECT (element, "dynamic create");

Wim Taymans's avatar
Wim Taymans committed
389
  /* take refs */
390
391
  gst_object_ref (element);
  gst_object_ref (decode_bin);
Wim Taymans's avatar
Wim Taymans committed
392
393
394
395

  dyn = g_new0 (GstDynamic, 1);
  dyn->element = element;
  dyn->decode_bin = decode_bin;
396
  dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "pad-added",
Wim Taymans's avatar
Wim Taymans committed
397
398
399
400
401
402
403
404
405
406
      G_CALLBACK (new_pad), dyn);
  dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads",
      G_CALLBACK (no_more_pads), dyn);

  return dyn;
}

static void
dynamic_free (GstDynamic * dyn)
{
407
408
  GST_DEBUG_OBJECT (dyn->decode_bin, "dynamic free");

Wim Taymans's avatar
Wim Taymans committed
409
410
411
412
  /* disconnect signals */
  g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->np_sig_id);
  g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->nmp_sig_id);

413
414
  gst_object_unref (dyn->element);
  gst_object_unref (dyn->decode_bin);
Wim Taymans's avatar
Wim Taymans committed
415
416
417
418
419
  dyn->element = NULL;
  dyn->decode_bin = NULL;
  g_free (dyn);
}

420
421
422
423
424
425
426
427
428
429
430
431
432
433
static void
free_dynamics (GstDecodeBin * decode_bin)
{
  GList *dyns;

  for (dyns = decode_bin->dynamics; dyns; dyns = g_list_next (dyns)) {
    GstDynamic *dynamic = (GstDynamic *) dyns->data;

    dynamic_free (dynamic);
  }
  g_list_free (decode_bin->dynamics);
  decode_bin->dynamics = NULL;
}

434
435
436
/* this function runs through the element factories and returns a list
 * of all elements that are able to sink the given caps 
 */
437
438
439
440
441
442
static GList *
find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
{
  GList *factories;
  GList *to_try = NULL;

443
  /* loop over all the factories */
444
445
446
447
448
449
  for (factories = decode_bin->factories; factories;
      factories = g_list_next (factories)) {
    GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
    const GList *templates;
    GList *walk;

450
    /* get the templates from the element factory */
451
    templates = gst_element_factory_get_static_pad_templates (factory);
452
    for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
453
      GstStaticPadTemplate *templ = walk->data;
454

455
      /* we only care about the sink templates */
456
457
458
      if (templ->direction == GST_PAD_SINK) {
        GstCaps *intersect;

459
        /* try to intersect the caps with the caps of the template */
460
461
        intersect = gst_caps_intersect (caps,
            gst_static_caps_get (&templ->static_caps));
462
        /* check if the intersection is empty */
463
        if (!gst_caps_is_empty (intersect)) {
464
          /* non empty intersection, we can use this element */
Wim Taymans's avatar
Wim Taymans committed
465
466
          to_try = g_list_prepend (to_try, factory);
          gst_caps_unref (intersect);
467
          break;
468
        }
Wim Taymans's avatar
Wim Taymans committed
469
        gst_caps_unref (intersect);
470
471
472
      }
    }
  }
Wim Taymans's avatar
Wim Taymans committed
473
474
  to_try = g_list_reverse (to_try);

475
476
477
  return to_try;
}

Wim Taymans's avatar
Wim Taymans committed
478
479
480
481
482
static gboolean
mimetype_is_raw (const gchar * mimetype)
{
  return g_str_has_prefix (mimetype, "video/x-raw") ||
      g_str_has_prefix (mimetype, "audio/x-raw") ||
483
      g_str_has_prefix (mimetype, "text/plain") ||
484
      g_str_has_prefix (mimetype, "text/x-pango-markup");
Wim Taymans's avatar
Wim Taymans committed
485
486
}

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
static void
free_pad_probes (GstDecodeBin * decode_bin)
{
  GList *tmp;

  /* Remove pad probes */
  for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
    PadProbeData *data = (PadProbeData *) tmp->data;

    gst_pad_remove_data_probe (data->pad, data->sigid);
    g_free (data);
  }
  g_list_free (decode_bin->probes);
  decode_bin->probes = NULL;
}

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
static void
add_fakesink (GstDecodeBin * decode_bin)
{
  if (decode_bin->fakesink != NULL)
    return;

  g_mutex_lock (decode_bin->cb_mutex);

  decode_bin->fakesink = gst_element_factory_make ("fakesink", "fakesink");
  if (!decode_bin->fakesink) {
    g_warning ("can't find fakesink element, decodebin will not work");
  } else {
    GST_OBJECT_FLAG_UNSET (decode_bin->fakesink, GST_ELEMENT_IS_SINK);
    if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->fakesink)) {
      g_warning ("Could not add fakesink element, decodebin will not work");
      gst_object_unref (decode_bin->fakesink);
      decode_bin->fakesink = NULL;
    }
  }
  g_mutex_unlock (decode_bin->cb_mutex);
}

525
static void
526
remove_fakesink (GstDecodeBin * decode_bin)
527
{
528
529
530
531
532
533
  gboolean removed_fakesink = FALSE;

  if (decode_bin->fakesink == NULL)
    return;

  g_mutex_lock (decode_bin->cb_mutex);
534
  if (decode_bin->fakesink) {
535
    GST_DEBUG_OBJECT (decode_bin, "Removing fakesink and marking state dirty");
536
537
538
539
540
541
542
543
544
545
    gst_object_ref (decode_bin->fakesink);
    gst_bin_remove (GST_BIN (decode_bin), decode_bin->fakesink);

    gst_element_set_state (decode_bin->fakesink, GST_STATE_NULL);
    gst_element_get_state (decode_bin->fakesink, NULL, NULL,
        GST_CLOCK_TIME_NONE);

    gst_object_unref (decode_bin->fakesink);
    decode_bin->fakesink = NULL;

546
547
548
549
550
    removed_fakesink = TRUE;
  }
  g_mutex_unlock (decode_bin->cb_mutex);

  if (removed_fakesink) {
551
552
    free_pad_probes (decode_bin);

553
554
555
    gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
        gst_message_new_state_dirty (GST_OBJECT_CAST (decode_bin)));
  }
556
557
}

558
559
static gboolean
pad_probe (GstPad * pad, GstMiniObject * data, GstDecodeBin * decode_bin)
560
{
561
562
563
564
565
566
567
  GList *tmp;
  gboolean alldone = TRUE;

  for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
    PadProbeData *pdata = (PadProbeData *) tmp->data;

    if (pdata->pad == pad) {
568
569
570
      if (GST_IS_BUFFER (data)) {
        if (!pdata->done)
          decode_bin->numwaiting--;
571
        pdata->done = TRUE;
572
573
574
575
576
577
      } else if (GST_IS_EVENT (data) &&
          ((GST_EVENT_TYPE (data) == GST_EVENT_EOS) ||
              (GST_EVENT_TYPE (data) == GST_EVENT_TAG) ||
              (GST_EVENT_TYPE (data) == GST_EVENT_FLUSH_START))) {
        if (!pdata->done)
          decode_bin->numwaiting--;
578
        pdata->done = TRUE;
579
      }
580
581
582
583
584
    }

    if (!(pdata->done)) {
      GST_LOG_OBJECT (decode_bin, "Pad probe on pad %" GST_PTR_FORMAT
          " but pad %" GST_PTR_FORMAT " still needs data.", pad, pdata->pad);
585
      alldone = FALSE;
586
    }
587
  }
588
589
590
  if (alldone)
    remove_fakesink (decode_bin);
  return TRUE;
591
592
}

593
594
595
596
597
598
599
600
601
/* given a pad and a caps from an element, find the list of elements
 * that could connect to the pad
 *
 * If the pad has a raw format, this function will create a ghostpad
 * for the pad onto the decodebin.
 *
 * If no compatible elements could be found, this function will signal 
 * the unknown_type signal.
 */
602
603
static void
close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
604
    GstDecodeBin * decode_bin, gboolean more)
605
606
{
  GstStructure *structure;
607
  const gchar *mimetype;
Wim Taymans's avatar
Wim Taymans committed
608
609
  gchar *padname;
  gint diff;
610

Wim Taymans's avatar
Wim Taymans committed
611
612
613
614
615
616
  padname = gst_pad_get_name (pad);
  diff = strncmp (padname, "current_", 8);
  g_free (padname);

  /* hack.. ignore current pads */
  if (!diff)
617
618
    return;

619
620
  /* the caps is empty, this means the pad has no type, we can only
   * decide to fire the unknown_type signal. */
Wim Taymans's avatar
Wim Taymans committed
621
622
  if (caps == NULL || gst_caps_is_empty (caps))
    goto unknown_type;
623

624
625
  /* the caps is any, this means the pad can be anything and
   * we don't know yet */
Wim Taymans's avatar
Wim Taymans committed
626
627
  if (gst_caps_is_any (caps))
    goto dont_know_yet;
628
629
630

  GST_LOG_OBJECT (element, "trying to close %" GST_PTR_FORMAT, caps);

631
632
  /* FIXME, iterate over more structures? I guess it is possible that
   * this pad has some encoded and some raw pads. This code will fail
633
   * then if the first structure is not the raw type... */
634
635
636
  structure = gst_caps_get_structure (caps, 0);
  mimetype = gst_structure_get_name (structure);

637
638
  /* first see if this is raw. If the type is raw, we can
   * create a ghostpad for this pad. */
Wim Taymans's avatar
Wim Taymans committed
639
  if (mimetype_is_raw (mimetype)) {
640
    gchar *padname;
641
    GstPad *ghost;
642
    PadProbeData *data;
643

644
    /* make a unique name for this new pad */
645
646
647
    padname = g_strdup_printf ("src%d", decode_bin->numpads);
    decode_bin->numpads++;

648
    /* make it a ghostpad */
Andy Wingo's avatar
Andy Wingo committed
649
650
    ghost = gst_ghost_pad_new (padname, pad);
    gst_element_add_pad (GST_ELEMENT (decode_bin), ghost);
651

652
653
654
655
656
657
658
659
660
    data = g_new0 (PadProbeData, 1);
    data->pad = pad;
    data->done = FALSE;

    data->sigid = gst_pad_add_data_probe (pad, G_CALLBACK (pad_probe),
        decode_bin);
    decode_bin->numwaiting++;

    decode_bin->probes = g_list_append (decode_bin->probes, data);
661

662
663
    GST_LOG_OBJECT (element, "closed pad %s", padname);

664
    /* our own signal with an extra flag that this is the only pad */
665
    GST_DEBUG_OBJECT (decode_bin, "emitting new-decoded-pad");
666
    g_signal_emit (G_OBJECT (decode_bin),
667
        gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, ghost, !more);
668
    GST_DEBUG_OBJECT (decode_bin, "emitted new-decoded-pad");
669

670
    g_free (padname);
Wim Taymans's avatar
Wim Taymans committed
671
672
673
674
675
676
  } else {
    GList *to_try;

    /* if the caps has many types, we need to delay */
    if (gst_caps_get_size (caps) != 1)
      goto many_types;
677

Wim Taymans's avatar
Wim Taymans committed
678
    /* continue plugging, first find all compatible elements */
679
    to_try = find_compatibles (decode_bin, caps);
Wim Taymans's avatar
Wim Taymans committed
680
681
682
683
    if (to_try == NULL)
      /* no compatible elements, we cannot go on */
      goto unknown_type;

684
685
686
687
688
    if (try_to_link_1 (decode_bin, element, pad, to_try) == NULL) {
      GST_LOG_OBJECT (pad, "none of the allegedly available elements usable");
      goto unknown_type;
    }

Wim Taymans's avatar
Wim Taymans committed
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
    /* can free the list again now */
    g_list_free (to_try);
  }
  return;

unknown_type:
  {
    GST_LOG_OBJECT (pad, "unkown type found, fire signal");
    g_signal_emit (G_OBJECT (decode_bin),
        gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
    return;
  }
dont_know_yet:
  {
    GST_LOG_OBJECT (pad, "type is not known yet, waiting to close link");
    return;
  }
many_types:
  {
    GST_LOG_OBJECT (pad, "many possible types, waiting to close link");
    return;
710
711
712
  }
}

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
/* Decide whether an element is a demuxer based on the 
 * klass and number/type of src pad templates it has */
static gboolean
is_demuxer_element (GstElement * srcelement)
{
  GstElementFactory *srcfactory;
  GstElementClass *elemclass;
  GList *templates, *walk;
  const gchar *klass;
  gint potential_src_pads = 0;

  srcfactory = gst_element_get_factory (srcelement);
  klass = gst_element_factory_get_klass (srcfactory);

  /* Can't be a demuxer unless it has Demux in the klass name */
  if (!strstr (klass, "Demux"))
    return FALSE;

  /* Walk the src pad templates and count how many the element
   * might produce */
  elemclass = GST_ELEMENT_GET_CLASS (srcelement);

  walk = templates = gst_element_class_get_pad_template_list (elemclass);
  while (walk != NULL) {
    GstPadTemplate *templ;

    templ = (GstPadTemplate *) walk->data;
    if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
      switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
        case GST_PAD_ALWAYS:
        case GST_PAD_SOMETIMES:
          if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
            potential_src_pads += 2;    /* Might make multiple pads */
          else
            potential_src_pads += 1;
          break;
        case GST_PAD_REQUEST:
          potential_src_pads += 2;
          break;
      }
    }
    walk = g_list_next (walk);
  }

  if (potential_src_pads < 2)
    return FALSE;

  return TRUE;
}

763
/*
Wim Taymans's avatar
Wim Taymans committed
764
765
766
 * given a list of element factories, try to link one of the factories
 * to the given pad.
 *
767
 * The function returns the element that was successfully linked to the
Wim Taymans's avatar
Wim Taymans committed
768
769
 * pad.
 */
770
static GstElement *
771
772
try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
    GList * factories)
773
774
{
  GList *walk;
775
  GstElement *result = NULL;
776
  gboolean isdemux = FALSE;
777
778
779
  GstPad *queuesinkpad = NULL, *queuesrcpad = NULL;
  GstElement *queue = NULL;
  GstPad *usedsrcpad = pad;
780
781

  /* Check if the parent of the src pad is a demuxer */
782
783
784
  isdemux = is_demuxer_element (srcelement);

  if (isdemux && factories != NULL) {
785
786
    GstPadLinkReturn dqlink;

787
788
789
790
791
792
793
794
    /* Insert a queue between demuxer and decoder */
    GST_DEBUG_OBJECT (decode_bin,
        "Element %s is a demuxer, inserting a queue",
        GST_OBJECT_NAME (srcelement));
    queue = gst_element_factory_make ("queue", NULL);
    decode_bin->queue_type = G_OBJECT_TYPE (queue);

    g_object_set (G_OBJECT (queue), "max-size-buffers", 0, NULL);
795
796
    g_object_set (G_OBJECT (queue), "max-size-time", G_GINT64_CONSTANT (0),
        NULL);
797
798
799
800
801
802
    g_object_set (G_OBJECT (queue), "max-size-bytes", 8192, NULL);
    gst_bin_add (GST_BIN (decode_bin), queue);
    gst_element_set_state (queue, GST_STATE_READY);
    queuesinkpad = gst_element_get_pad (queue, "sink");
    usedsrcpad = queuesrcpad = gst_element_get_pad (queue, "src");

803
804
    dqlink = gst_pad_link (pad, queuesinkpad);
    g_return_val_if_fail (dqlink == GST_PAD_LINK_OK, NULL);
805
  }
806

807
  /* loop over the factories */
808
809
810
  for (walk = factories; walk; walk = g_list_next (walk)) {
    GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
    GstElement *element;
Wim Taymans's avatar
Wim Taymans committed
811
    GstPadLinkReturn ret;
812
    GstPad *sinkpad;
813

814
    GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
815
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
816

817
    /* make an element from the factory first */
818
    if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
819
820
      /* hmm, strange. Like with all things in life, let's move on.. */
      GST_WARNING_OBJECT (decode_bin, "could not create an element from %s",
821
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
822
      continue;
823
    }
824

825
826
827
828
829
830
831
832
833
    /* try to link the given pad to a sinkpad */
    /* FIXME, find the sinkpad by looping over the pads instead of 
     * looking it up by name */
    if ((sinkpad = gst_element_get_pad (element, "sink")) == NULL) {
      /* if no pad is found we can't do anything */
      GST_WARNING_OBJECT (decode_bin, "could not find sinkpad in element");
      continue;
    }

834
    /* now add the element to the bin first */
835
    GST_DEBUG_OBJECT (decode_bin, "adding %s", GST_OBJECT_NAME (element));
836
    gst_bin_add (GST_BIN (decode_bin), element);
837

Wim Taymans's avatar
Wim Taymans committed
838
    /* set to ready first so it is ready */
839
    gst_element_set_state (element, GST_STATE_READY);
840

841
    if ((ret = gst_pad_link (usedsrcpad, sinkpad)) != GST_PAD_LINK_OK) {
842
843
844
      GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
          GST_DEBUG_PAD_NAME (pad), ret);
      /* get rid of the sinkpad */
845
      gst_object_unref (sinkpad);
846
847
      /* this element did not work, remove it again and continue trying
       * other elements, the element will be disposed. */
848
      gst_element_set_state (element, GST_STATE_NULL);
849
      gst_bin_remove (GST_BIN (decode_bin), element);
850

851
    } else {
852
853
854
      guint sig;

      GST_DEBUG_OBJECT (decode_bin, "linked on pad %s:%s",
855
          GST_DEBUG_PAD_NAME (usedsrcpad));
856

857
      if (queue != NULL) {
858
859
860
        decode_bin->queues = g_list_append (decode_bin->queues, queue);
        g_signal_connect (G_OBJECT (queue),
            "overrun", G_CALLBACK (queue_filled_cb), decode_bin);
861
862
        g_signal_connect (G_OBJECT (queue),
            "underrun", G_CALLBACK (queue_underrun_cb), decode_bin);
863
864
      }

865
      /* The link worked, now figure out what it was that we connected */
Wim Taymans's avatar
Wim Taymans committed
866

867
      /* make sure we catch unlink signals */
868
      sig = g_signal_connect (G_OBJECT (pad), "unlinked",
869
          G_CALLBACK (unlinked), decode_bin);
870

871
872
      /* now that we added the element we can try to continue autoplugging
       * on it until we have a raw type */
873
      close_link (element, decode_bin);
874
      /* change the state of the element to that of the parent */
875
      gst_element_set_state (element, GST_STATE_PAUSED);
876
877
878
879

      result = element;

      /* get rid of the sinkpad now */
880
      gst_object_unref (sinkpad);
881
882
883
884

      /* Set the queue to paused and set the pointer to NULL so we don't 
       * remove it below */
      if (queue != NULL) {
885
        gst_element_set_state (queue, GST_STATE_PAUSED);
886
        queue = NULL;
887
888
889
        gst_object_unref (queuesrcpad);
        gst_object_unref (queuesinkpad);
      }
890
891
892

      /* and exit */
      goto done;
893
894
    }
  }
895
done:
896
897
  if (queue != NULL) {
    /* We didn't successfully connect to the queue */
898
    gst_pad_unlink (pad, queuesinkpad);
899
900
901
902
903
    gst_element_set_state (queue, GST_STATE_NULL);
    gst_object_unref (queuesrcpad);
    gst_object_unref (queuesinkpad);
    gst_bin_remove (GST_BIN (decode_bin), queue);
  }
904
  return result;
905
906
}

907
908
909
static GstPad *
get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
{
910
911
912
  GstIterator *pad_it = NULL;
  GstPad *db_pad = NULL;
  gboolean done = FALSE;
913
914
915
916
917
918

  if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
    GST_DEBUG_OBJECT (decode_bin, "pad NULL or not SRC pad");
    return NULL;
  }

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
  pad_it = gst_element_iterate_pads (GST_ELEMENT (decode_bin));
  while (!done) {
    switch (gst_iterator_next (pad_it, (gpointer) & db_pad)) {
      case GST_ITERATOR_OK:
        GST_DEBUG_OBJECT (decode_bin, "looking at pad %s:%s",
            GST_DEBUG_PAD_NAME (db_pad));
        if (GST_IS_GHOST_PAD (db_pad) && GST_PAD_IS_SRC (db_pad)) {
          GstPad *target_pad = NULL;

          target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (db_pad));

          if (target_pad == pad) {      /* Found our ghost pad */
            GST_DEBUG_OBJECT (decode_bin, "found ghostpad %s:%s for pad %s:%s",
                GST_DEBUG_PAD_NAME (db_pad), GST_DEBUG_PAD_NAME (pad));
            done = TRUE;
            break;
          } else {              /* Not the right one */
            gst_object_unref (db_pad);
            db_pad = NULL;
          }
        } else {
          gst_object_unref (db_pad);
          db_pad = NULL;
        }
Wim Taymans's avatar
Wim Taymans committed
943

944
945
946
947
948
949
950
951
952
953
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (pad_it);
        break;
      case GST_ITERATOR_ERROR:
        done = TRUE;
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
954
955
    }
  }
956
  gst_iterator_free (pad_it);
957

958
  return db_pad;
959
960
961
962
963
964
965
966
967
}

/* remove all downstream elements starting from the given pad.
 * Also make sure to remove the ghostpad we created for the raw 
 * decoded stream.
 */
static void
remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
{
968
  GList *int_links, *walk;
969
  GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
970

Wim Taymans's avatar
Wim Taymans committed
971
972
973
974
  while (GST_OBJECT_PARENT (elem) &&
      GST_OBJECT_PARENT (elem) != GST_OBJECT (decode_bin))
    elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));

975
976
977
978
979
980
  if (G_OBJECT_TYPE (elem) == decode_bin->queue_type) {
    GST_DEBUG_OBJECT (decode_bin,
        "Encountered demuxer output queue while removing element chain");
    decode_bin->queues = g_list_remove (decode_bin->queues, elem);
  }

981
  GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
982
  int_links = gst_pad_get_internal_links (pad);
983
984
985

  /* remove all elements linked to this pad up to the ghostpad 
   * that we created for this stream */
986
  for (walk = int_links; walk; walk = g_list_next (walk)) {
987
988
989
990
    GstPad *pad;
    GstPad *ghostpad;
    GstPad *peer;

991
    pad = GST_PAD (walk->data);
992
993
994
995
996
997
998
999
1000
1001
1002
1003
    GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
        GST_DEBUG_PAD_NAME (pad));

    ghostpad = get_our_ghost_pad (decode_bin, pad);
    if (ghostpad) {
      GST_DEBUG_OBJECT (decode_bin, "found our ghost pad %s:%s for %s:%s",
          GST_DEBUG_PAD_NAME (ghostpad), GST_DEBUG_PAD_NAME (pad));

      g_signal_emit (G_OBJECT (decode_bin),
          gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, ghostpad);

      gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
1004
      gst_object_unref (ghostpad);
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
      continue;
    } else {
      GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
    }

    peer = gst_pad_get_peer (pad);
    if (peer == NULL)
      continue;

    GST_DEBUG_OBJECT (decode_bin, "internal pad %s:%s linked to pad %s:%s",
        GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));

1017
    {
1018
      GstObject *parent = gst_pad_get_parent (peer);
1019

Andy Wingo's avatar
Andy Wingo committed
1020
      if (parent) {
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
        GstElement *grandparent = GST_ELEMENT (gst_object_get_parent (parent));

        if (grandparent) {
          if (grandparent != GST_ELEMENT (decode_bin)) {
            GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s parent %s",
                GST_DEBUG_PAD_NAME (peer), GST_OBJECT_NAME (grandparent));
          } else {
            GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
                GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
            remove_element_chain (decode_bin, peer);
          }
          gst_object_unref (grandparent);
Andy Wingo's avatar
Andy Wingo committed
1033
        }
1034
        gst_object_unref (parent);
1035
      }
1036
    }
1037
    gst_object_unref (peer);
1038
  }
1039
1040
1041
1042
  GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));

  g_list_free (int_links);

1043
1044
  gst_element_set_state (elem, GST_STATE_NULL);

1045
1046
1047
  gst_bin_remove (GST_BIN (decode_bin), elem);
}

1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
/* there are @bytes bytes in @queue, enlarge it 
 *
 * Returns: new max number of bytes in @queue
 */
static guint
queue_enlarge (GstElement * queue, guint bytes, GstDecodeBin * decode_bin)
{
  /* Increase the queue size by 1Mbyte if it is over 1Mb, else double its current limit
   */
  if (bytes > 1024 * 1024)
    bytes += 1024 * 1024;
  else
    bytes *= 2;

  GST_DEBUG_OBJECT (decode_bin,
      "increasing queue %s max-size-bytes to %d", GST_ELEMENT_NAME (queue),
      bytes);
  g_object_set (G_OBJECT (queue), "max-size-bytes", bytes, NULL);

  return bytes;
}

/* this callback is called when our queues fills up or are empty
 * We then check the status of all other queues to make sure we
 * never have an empty and full queue at the same time since that
 * would block dataflow. In the case of a filled queue, we make
 * it larger.
 */
static void
queue_underrun_cb (GstElement * queue, GstDecodeBin * decode_bin)
{
  /* FIXME: we don't really do anything here for now. Ideally we should
   * see if some of the queues are filled and increase their values
   * in that case. 
   * Note: be very carefull with thread safety here as this underrun
   * signal is done from the streaming thread of queue srcpad which
   * is different from the pad_added (where we add the queue to the
   * list) and the overrun signals that are signalled from the
   * demuxer thread.
   */
}

1090
1091
1092
1093
1094
1095
1096
1097
/* Make sure we don't have a full queue and empty queue situation */
static void
queue_filled_cb (GstElement * queue, GstDecodeBin * decode_bin)
{
  GList *tmp;
  gboolean increase = FALSE;
  guint bytes;

1098
  /* get current byte level from the queue that is filled */
1099
1100
1101
  g_object_get (G_OBJECT (queue), "current-level-bytes", &bytes, NULL);
  GST_DEBUG_OBJECT (decode_bin, "One of the queues is full at %d bytes", bytes);

1102
1103
1104
  /* we do not buffer more than 20Mb */
  if (bytes > (20 * 1024 * 1024))
    goto too_large;
1105

1106
1107
  /* check all other queue to see if one is empty, in that case
   * we need to enlarge @queue */
1108
1109
1110
1111
1112
  for (tmp = decode_bin->queues; tmp; tmp = g_list_next (tmp)) {
    GstElement *aqueue = GST_ELEMENT (tmp->data);
    guint levelbytes = -1;

    if (aqueue != queue) {
1113
1114
      g_object_get (G_OBJECT (aqueue), "current-level-bytes", &levelbytes,
          NULL);
1115
      if (levelbytes == 0) {
1116
1117
        /* yup, found an empty queue, we can stop the search and
         * need to enlarge the queue */
1118
        increase = TRUE;
1119
        break;
1120
1121
1122
1123
1124
      }
    }
  }

  if (increase) {
1125
1126
1127
    /* enlarge @queue */
    queue_enlarge (queue, bytes, decode_bin);
  } else {
1128
1129
    GST_DEBUG_OBJECT (decode_bin,
        "Queue is full but other queues are not empty, not doing anything");
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
  }
  return;

  /* errors */
too_large:
  {
    GST_WARNING_OBJECT (decode_bin,
        "Queue is bigger than 20Mbytes, something else is going wrong");
    return;
  }
1140
1141
}

1142
1143
/* This function will be called when a dynamic pad is created on an element.
 * We try to continue autoplugging on this new pad. */
1144
static void
1145
new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic)
1146
{
1147
  GstDecodeBin *decode_bin = dynamic->decode_bin;
1148
  GstCaps *caps;
1149
  gboolean more;
1150

Andy Wingo's avatar