Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / pulse / pulseaudiosink.c
1 /*-*- Mode: C; c-basic-offset: 2 -*-*/
2
3 /*  GStreamer pulseaudio plugin
4  *
5  *  Copyright (c) 2011 Intel Corporation
6  *                2011 Collabora
7  *                2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
8  *                2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
9  *
10  *  gst-pulse is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as
12  *  published by the Free Software Foundation; either version 2.1 of the
13  *  License, or (at your option) any later version.
14  *
15  *  gst-pulse is distributed in the hope that it will be useful, but
16  *  WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with gst-pulse; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  *  USA.
24  */
25
26 /**
27  * SECTION:element-pulseaudiosink
28  * @see_also: pulsesink, pulsesrc, pulsemixer
29  *
30  * This element outputs audio to a
31  * <ulink href="http://www.pulseaudio.org">PulseAudio sound server</ulink> via
32  * the @pulsesink element. It transparently takes care of passing compressed
33  * format as-is if the sink supports it, decoding if necessary, and changes
34  * to supported formats at runtime.
35  *
36  * <refsect2>
37  * <title>Example pipelines</title>
38  * |[
39  * gst-launch -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! pulseaudiosink
40  * ]| Decode and play an Ogg/Vorbis file.
41  * |[
42  * gst-launch -v filesrc location=test.mp3 ! mp3parse ! pulseaudiosink stream-properties="props,media.title=test"
43  * ]| Play an MP3 file on a sink that supports decoding directly, plug in a
44  * decoder if/when required.
45  * </refsect2>
46  */
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #ifdef HAVE_PULSE_1_0
53
54 #include <gst/pbutils/pbutils.h>
55 #include <gst/gst-i18n-plugin.h>
56
57 #include <gst/audio/gstaudioiec61937.h>
58 #include "pulsesink.h"
59
60 GST_DEBUG_CATEGORY (pulseaudiosink_debug);
61 #define GST_CAT_DEFAULT (pulseaudiosink_debug)
62
63 #define GST_PULSE_AUDIO_SINK_LOCK(obj) G_STMT_START {                    \
64     GST_LOG_OBJECT (obj,                                              \
65                     "locking from thread %p",                         \
66                     g_thread_self ());                                \
67     g_mutex_lock (GST_PULSE_AUDIO_SINK_CAST(obj)->lock);                 \
68     GST_LOG_OBJECT (obj,                                              \
69                     "locked from thread %p",                          \
70                     g_thread_self ());                                \
71 } G_STMT_END
72
73 #define GST_PULSE_AUDIO_SINK_UNLOCK(obj) G_STMT_START {                  \
74     GST_LOG_OBJECT (obj,                                              \
75                     "unlocking from thread %p",                       \
76                     g_thread_self ());                                \
77     g_mutex_unlock (GST_PULSE_AUDIO_SINK_CAST(obj)->lock);               \
78 } G_STMT_END
79
80 typedef struct
81 {
82   GstBin parent;
83   GMutex *lock;
84
85   GstPad *sinkpad;
86   GstPad *sink_proxypad;
87   GstPadEventFunction sinkpad_old_eventfunc;
88   GstPadEventFunction proxypad_old_eventfunc;
89
90   GstPulseSink *psink;
91   GstElement *dbin;
92
93   GstSegment segment;
94
95   guint event_probe_id;
96   gulong pad_added_id;
97   guint block_probe_id;
98
99   gboolean format_lost;
100 } GstPulseAudioSink;
101
102 typedef struct
103 {
104   GstBinClass parent_class;
105   guint n_prop_own;
106   guint n_prop_total;
107 } GstPulseAudioSinkClass;
108
109 static void gst_pulse_audio_sink_get_property (GObject * object, guint prop_id,
110     GValue * value, GParamSpec * pspec);
111 static void gst_pulse_audio_sink_set_property (GObject * object, guint prop_id,
112     const GValue * value, GParamSpec * pspec);
113 static void gst_pulse_audio_sink_dispose (GObject * object);
114 static gboolean gst_pulse_audio_sink_src_event (GstPad * pad, GstEvent * event);
115 static gboolean gst_pulse_audio_sink_sink_event (GstPad * pad,
116     GstEvent * event);
117 static gboolean gst_pulse_audio_sink_sink_query (GstPad * pad,
118     GstQuery * query);
119 static gboolean gst_pulse_audio_sink_sink_acceptcaps (GstPulseAudioSink * pbin,
120     GstPad * pad, GstCaps * caps);
121 static GstStateChangeReturn
122 gst_pulse_audio_sink_change_state (GstElement * element,
123     GstStateChange transition);
124 static gboolean gst_pulse_audio_sink_set_caps (GstPulseAudioSink * pbin,
125     GstCaps * caps);
126
127 #define gst_pulse_audio_sink_parent_class parent_class
128 G_DEFINE_TYPE (GstPulseAudioSink, gst_pulse_audio_sink, GST_TYPE_BIN);
129
130 static GstStaticPadTemplate sink_template =
131 GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
132     GST_STATIC_CAPS (PULSE_SINK_TEMPLATE_CAPS));
133
134 static GParamSpec *
135 param_spec_copy (GParamSpec * spec)
136 {
137   const char *name, *nick, *blurb;
138   GParamFlags flags;
139
140   name = g_param_spec_get_name (spec);
141   nick = g_param_spec_get_nick (spec);
142   blurb = g_param_spec_get_blurb (spec);
143   flags = spec->flags;
144
145   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_BOOLEAN) {
146     return g_param_spec_boolean (name, nick, blurb,
147         G_PARAM_SPEC_BOOLEAN (spec)->default_value, flags);
148   }
149
150   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_BOXED) {
151     return g_param_spec_boxed (name, nick, blurb, spec->value_type, flags);
152   }
153
154   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_CHAR) {
155     GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (spec);
156     return g_param_spec_char (name, nick, blurb, cspec->minimum,
157         cspec->maximum, cspec->default_value, flags);
158   }
159
160   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_DOUBLE) {
161     GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (spec);
162     return g_param_spec_double (name, nick, blurb, dspec->minimum,
163         dspec->maximum, dspec->default_value, flags);
164   }
165
166   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_ENUM) {
167     return g_param_spec_enum (name, nick, blurb, spec->value_type,
168         G_PARAM_SPEC_ENUM (spec)->default_value, flags);
169   }
170
171   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_FLAGS) {
172     return g_param_spec_flags (name, nick, blurb, spec->value_type,
173         G_PARAM_SPEC_ENUM (spec)->default_value, flags);
174   }
175
176   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_FLOAT) {
177     GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (spec);
178     return g_param_spec_double (name, nick, blurb, fspec->minimum,
179         fspec->maximum, fspec->default_value, flags);
180   }
181
182   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_GTYPE) {
183     return g_param_spec_gtype (name, nick, blurb,
184         G_PARAM_SPEC_GTYPE (spec)->is_a_type, flags);
185   }
186
187   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_INT) {
188     GParamSpecInt *ispec = G_PARAM_SPEC_INT (spec);
189     return g_param_spec_int (name, nick, blurb, ispec->minimum,
190         ispec->maximum, ispec->default_value, flags);
191   }
192
193   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_INT64) {
194     GParamSpecInt64 *ispec = G_PARAM_SPEC_INT64 (spec);
195     return g_param_spec_int64 (name, nick, blurb, ispec->minimum,
196         ispec->maximum, ispec->default_value, flags);
197   }
198
199   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_LONG) {
200     GParamSpecLong *lspec = G_PARAM_SPEC_LONG (spec);
201     return g_param_spec_long (name, nick, blurb, lspec->minimum,
202         lspec->maximum, lspec->default_value, flags);
203   }
204
205   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_OBJECT) {
206     return g_param_spec_object (name, nick, blurb, spec->value_type, flags);
207   }
208
209   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_PARAM) {
210     return g_param_spec_param (name, nick, blurb, spec->value_type, flags);
211   }
212
213   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_POINTER) {
214     return g_param_spec_pointer (name, nick, blurb, flags);
215   }
216
217   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_STRING) {
218     return g_param_spec_string (name, nick, blurb,
219         G_PARAM_SPEC_STRING (spec)->default_value, flags);
220   }
221
222   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_UCHAR) {
223     GParamSpecUChar *cspec = G_PARAM_SPEC_UCHAR (spec);
224     return g_param_spec_uchar (name, nick, blurb, cspec->minimum,
225         cspec->maximum, cspec->default_value, flags);
226   }
227
228   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_UINT) {
229     GParamSpecUInt *ispec = G_PARAM_SPEC_UINT (spec);
230     return g_param_spec_uint (name, nick, blurb, ispec->minimum,
231         ispec->maximum, ispec->default_value, flags);
232   }
233
234   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_UINT64) {
235     GParamSpecUInt64 *ispec = G_PARAM_SPEC_UINT64 (spec);
236     return g_param_spec_uint64 (name, nick, blurb, ispec->minimum,
237         ispec->maximum, ispec->default_value, flags);
238   }
239
240   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_ULONG) {
241     GParamSpecULong *lspec = G_PARAM_SPEC_ULONG (spec);
242     return g_param_spec_ulong (name, nick, blurb, lspec->minimum,
243         lspec->maximum, lspec->default_value, flags);
244   }
245
246   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_UNICHAR) {
247     return g_param_spec_unichar (name, nick, blurb,
248         G_PARAM_SPEC_UNICHAR (spec)->default_value, flags);
249   }
250
251   if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_PARAM_VARIANT) {
252     GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (spec);
253     return g_param_spec_variant (name, nick, blurb, vspec->type,
254         vspec->default_value, flags);
255   }
256
257   g_warning ("Unknown param type %ld for '%s'",
258       (long) G_PARAM_SPEC_TYPE (spec), name);
259   g_assert_not_reached ();
260 }
261
262 static void
263 gst_pulse_audio_sink_class_init (GstPulseAudioSinkClass * klass)
264 {
265   GObjectClass *gobject_class = (GObjectClass *) klass;
266   GstElementClass *element_class = (GstElementClass *) klass;
267   GstPulseSinkClass *psink_class =
268       GST_PULSESINK_CLASS (g_type_class_ref (GST_TYPE_PULSESINK));
269   GParamSpec **specs;
270   guint n, i, j;
271
272   GST_DEBUG_CATEGORY_INIT (pulseaudiosink_debug, "pulseaudiosink", 0,
273       "Bin that wraps pulsesink for handling compressed formats");
274
275   gst_element_class_add_pad_template (element_class,
276       gst_static_pad_template_get (&sink_template));
277
278   gst_element_class_set_details_simple (element_class,
279       "Bin wrapping pulsesink", "Sink/Audio/Bin",
280       "Correctly handles sink changes when streaming compressed formats to "
281       "pulsesink", "Arun Raghavan <arun.raghavan@collabora.co.uk>");
282
283   gobject_class->get_property = gst_pulse_audio_sink_get_property;
284   gobject_class->set_property = gst_pulse_audio_sink_set_property;
285   gobject_class->dispose = gst_pulse_audio_sink_dispose;
286   element_class->change_state =
287       GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_change_state);
288
289   /* Find out how many properties we already have */
290   specs = g_object_class_list_properties (gobject_class, &klass->n_prop_own);
291   g_free (specs);
292
293   /* Proxy pulsesink's properties */
294   specs = g_object_class_list_properties (G_OBJECT_CLASS (psink_class), &n);
295   for (i = 0, j = klass->n_prop_own; i < n; i++) {
296     if (g_object_class_find_property (gobject_class,
297             g_param_spec_get_name (specs[i]))) {
298       /* We already inherited this property from a parent, skip */
299       j--;
300     } else {
301       g_object_class_install_property (gobject_class, i + j + 1,
302           param_spec_copy (specs[i]));
303     }
304   }
305
306   klass->n_prop_total = i + j;
307
308   g_free (specs);
309   g_type_class_unref (psink_class);
310 }
311
312 static GstPad *
313 get_proxypad (GstPad * sinkpad)
314 {
315   GstIterator *iter = NULL;
316   GValue res = { 0 };
317   GstPad *proxypad = NULL;
318
319   iter = gst_pad_iterate_internal_links (sinkpad);
320   if (iter) {
321     if (gst_iterator_next (iter, &res) == GST_ITERATOR_OK) {
322       proxypad = g_value_dup_object (&res);
323       g_value_reset (&res);
324     }
325     gst_iterator_free (iter);
326   }
327
328   return proxypad;
329 }
330
331 static void
332 post_missing_element_message (GstPulseAudioSink * pbin, const gchar * name)
333 {
334   GstMessage *msg;
335
336   msg = gst_missing_element_message_new (GST_ELEMENT_CAST (pbin), name);
337   gst_element_post_message (GST_ELEMENT_CAST (pbin), msg);
338 }
339
340 static void
341 notify_cb (GObject * selector, GParamSpec * pspec, GstPulseAudioSink * pbin)
342 {
343   g_object_notify (G_OBJECT (pbin), g_param_spec_get_name (pspec));
344 }
345
346 static void
347 gst_pulse_audio_sink_init (GstPulseAudioSink * pbin)
348 {
349   GstPulseAudioSinkClass *klass =
350       GST_PULSE_AUDIO_SINK_CLASS (G_OBJECT_GET_CLASS (pbin));
351   GstPad *pad = NULL;
352   GParamSpec **specs;
353   GString *prop;
354   guint i;
355
356   pbin->lock = g_mutex_new ();
357
358   gst_segment_init (&pbin->segment, GST_FORMAT_UNDEFINED);
359
360   pbin->psink = GST_PULSESINK (gst_element_factory_make ("pulsesink",
361           "pulseaudiosink-sink"));
362   g_assert (pbin->psink != NULL);
363
364   if (!gst_bin_add (GST_BIN (pbin), GST_ELEMENT (pbin->psink))) {
365     GST_ERROR_OBJECT (pbin, "Failed to add pulsesink to bin");
366     goto error;
367   }
368
369   pad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
370   pbin->sinkpad = gst_ghost_pad_new_from_template ("sink", pad,
371       gst_static_pad_template_get (&sink_template));
372
373   pbin->sinkpad_old_eventfunc = GST_PAD_EVENTFUNC (pbin->sinkpad);
374   gst_pad_set_event_function (pbin->sinkpad,
375       GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_event));
376   gst_pad_set_query_function (pbin->sinkpad,
377       GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_query));
378
379   gst_element_add_pad (GST_ELEMENT (pbin), pbin->sinkpad);
380
381   if (!(pbin->sink_proxypad = get_proxypad (pbin->sinkpad)))
382     GST_ERROR_OBJECT (pbin, "Failed to get proxypad of srcpad");
383   else {
384     pbin->proxypad_old_eventfunc = GST_PAD_EVENTFUNC (pbin->sink_proxypad);
385     gst_pad_set_event_function (pbin->sink_proxypad,
386         GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_src_event));
387   }
388
389   /* Now proxy all the notify::* signals */
390   specs = g_object_class_list_properties (G_OBJECT_CLASS (klass), &i);
391   prop = g_string_sized_new (30);
392
393   for (i--; i >= klass->n_prop_own; i--) {
394     g_string_printf (prop, "notify::%s", g_param_spec_get_name (specs[i]));
395     g_signal_connect (pbin->psink, prop->str, G_CALLBACK (notify_cb), pbin);
396   }
397
398   g_string_free (prop, TRUE);
399   g_free (specs);
400
401   pbin->format_lost = FALSE;
402
403 out:
404   if (pad)
405     gst_object_unref (pad);
406
407   return;
408
409 error:
410   if (pbin->psink)
411     gst_object_unref (pbin->psink);
412   goto out;
413 }
414
415 static void
416 gst_pulse_audio_sink_set_property (GObject * object, guint prop_id,
417     const GValue * value, GParamSpec * pspec)
418 {
419   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (object);
420   GstPulseAudioSinkClass *klass =
421       GST_PULSE_AUDIO_SINK_CLASS (G_OBJECT_GET_CLASS (object));
422
423   g_return_if_fail (prop_id <= klass->n_prop_total);
424
425   g_object_set_property (G_OBJECT (pbin->psink), g_param_spec_get_name (pspec),
426       value);
427 }
428
429 static void
430 gst_pulse_audio_sink_get_property (GObject * object, guint prop_id,
431     GValue * value, GParamSpec * pspec)
432 {
433   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (object);
434   GstPulseAudioSinkClass *klass =
435       GST_PULSE_AUDIO_SINK_CLASS (G_OBJECT_GET_CLASS (object));
436
437   g_return_if_fail (prop_id <= klass->n_prop_total);
438
439   g_object_get_property (G_OBJECT (pbin->psink), g_param_spec_get_name (pspec),
440       value);
441 }
442
443 static void
444 gst_pulse_audio_sink_free_dbin (GstPulseAudioSink * pbin)
445 {
446   g_signal_handler_disconnect (pbin->dbin, pbin->pad_added_id);
447   gst_element_set_state (pbin->dbin, GST_STATE_NULL);
448
449   gst_bin_remove (GST_BIN (pbin), pbin->dbin);
450
451   pbin->dbin = NULL;
452 }
453
454 static void
455 gst_pulse_audio_sink_dispose (GObject * object)
456 {
457   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (object);
458
459   if (pbin->lock) {
460     g_mutex_free (pbin->lock);
461     pbin->lock = NULL;
462   }
463
464   if (pbin->sink_proxypad) {
465     gst_object_unref (pbin->sink_proxypad);
466     pbin->sink_proxypad = NULL;
467   }
468
469   if (pbin->dbin) {
470     g_signal_handler_disconnect (pbin->dbin, pbin->pad_added_id);
471     pbin->dbin = NULL;
472   }
473
474   pbin->sinkpad = NULL;
475   pbin->psink = NULL;
476
477   G_OBJECT_CLASS (parent_class)->dispose (object);
478 }
479
480 static gboolean
481 gst_pulse_audio_sink_update_sinkpad (GstPulseAudioSink * pbin, GstPad * sinkpad)
482 {
483   gboolean ret;
484
485   ret = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (pbin->sinkpad), sinkpad);
486
487   if (!ret)
488     GST_WARNING_OBJECT (pbin, "Could not update ghostpad target");
489
490   return ret;
491 }
492
493 static void
494 distribute_running_time (GstElement * element, const GstSegment * segment)
495 {
496   GstEvent *event;
497   GstPad *pad;
498
499   pad = gst_element_get_static_pad (element, "sink");
500
501   /* FIXME: Some decoders collect newsegments and send them out at once, making
502    * them lose accumulator events (and thus making dbin_event_probe() hard to
503    * do right if we're sending these as well. We can get away with not sending
504    * these at the moment, but this should be fixed! */
505 #if 0
506   if (segment->accum) {
507     event = gst_event_new_new_segment_full (FALSE, segment->rate,
508         segment->applied_rate, segment->format, 0, segment->accum, 0);
509     gst_pad_send_event (pad, event);
510   }
511 #endif
512
513   /* TODO review this copy, see if it can be avoided */
514   event = gst_event_new_segment (gst_segment_copy (segment));
515   gst_pad_send_event (pad, event);
516
517   gst_object_unref (pad);
518 }
519
520 static GstPadProbeReturn
521 dbin_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
522 {
523   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
524   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
525
526   if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
527     GST_DEBUG_OBJECT (pbin, "Got newsegment - dropping");
528     gst_pad_remove_probe (pad, pbin->event_probe_id);
529     gst_object_unref (pbin);
530     return GST_PAD_PROBE_DROP;
531   }
532
533   return GST_PAD_PROBE_OK;
534 }
535
536 static void
537 pad_added_cb (GstElement * dbin, GstPad * pad, gpointer * data)
538 {
539   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
540   GstPad *sinkpad = NULL;
541
542   pbin = GST_PULSE_AUDIO_SINK (data);
543   sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
544
545   GST_PULSE_AUDIO_SINK_LOCK (pbin);
546   if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
547     GST_ERROR_OBJECT (pbin, "Failed to link decodebin to pulsesink");
548   else
549     GST_DEBUG_OBJECT (pbin, "Linked new pad to pulsesink");
550   GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
551
552   gst_object_unref (sinkpad);
553 }
554
555 /* Called with pbin lock held */
556 static void
557 gst_pulse_audio_sink_add_dbin (GstPulseAudioSink * pbin)
558 {
559   GstPad *sinkpad = NULL;
560
561   g_assert (pbin->dbin == NULL);
562
563   pbin->dbin = gst_element_factory_make ("decodebin", "pulseaudiosink-dbin");
564
565   if (!pbin->dbin) {
566     post_missing_element_message (pbin, "decodebin");
567     GST_ELEMENT_WARNING (pbin, CORE, MISSING_PLUGIN,
568         (_("Missing element '%s' - check your GStreamer installation."),
569             "decodebin"), ("audio playback might fail"));
570     goto out;
571   }
572
573   if (!gst_bin_add (GST_BIN (pbin), pbin->dbin)) {
574     GST_ERROR_OBJECT (pbin, "Failed to add decodebin to bin");
575     goto out;
576   }
577
578   pbin->pad_added_id = g_signal_connect (pbin->dbin, "pad-added",
579       G_CALLBACK (pad_added_cb), pbin);
580
581   if (!gst_element_sync_state_with_parent (pbin->dbin)) {
582     GST_ERROR_OBJECT (pbin, "Failed to set decodebin to parent state");
583     goto out;
584   }
585
586   /* Trap the newsegment events that we feed the decodebin and discard them */
587   sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
588   pbin->event_probe_id =
589       gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
590       dbin_event_probe, gst_object_ref (pbin), NULL);
591   gst_object_unref (sinkpad);
592   sinkpad = NULL;
593
594   GST_DEBUG_OBJECT (pbin, "Distributing running time to decodebin");
595   distribute_running_time (pbin->dbin, &pbin->segment);
596
597   sinkpad = gst_element_get_static_pad (pbin->dbin, "sink");
598
599   gst_pulse_audio_sink_update_sinkpad (pbin, sinkpad);
600
601 out:
602   if (sinkpad)
603     gst_object_unref (sinkpad);
604 }
605
606 static void
607 update_eac3_alignment (GstPulseAudioSink * pbin)
608 {
609   GstCaps *caps = gst_pad_peer_get_caps (pbin->sinkpad, NULL);
610   GstStructure *st;
611
612   if (!caps)
613     return;
614
615   st = gst_caps_get_structure (caps, 0);
616
617   if (g_str_equal (gst_structure_get_name (st), "audio/x-eac3")) {
618     GstStructure *event_st = gst_structure_new ("ac3parse-set-alignment",
619         "alignment", G_TYPE_STRING, pbin->dbin ? "frame" : "iec61937", NULL);
620
621     if (!gst_pad_push_event (pbin->sinkpad,
622             gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, event_st)))
623       GST_WARNING_OBJECT (pbin->sinkpad, "Could not update alignment");
624   }
625
626   gst_caps_unref (caps);
627 }
628
629 static GstPadProbeReturn
630 proxypad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer data)
631 {
632   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
633   GstCaps *caps;
634   GstPad *sinkpad = NULL;
635
636   GST_DEBUG_OBJECT (pbin, "blocked");
637
638   GST_PULSE_AUDIO_SINK_LOCK (pbin);
639
640   if (!pbin->format_lost) {
641     sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
642
643     if (gst_pad_has_current_caps (pbin->sinkpad)) {
644       /* See if we already got caps on our sinkpad */
645       caps = gst_pad_get_current_caps (pbin->sinkpad);
646     } else {
647       /* We haven't, so get caps from upstream */
648       caps = gst_pad_get_caps (pad, NULL);
649     }
650
651     if (gst_pad_accept_caps (sinkpad, caps)) {
652       if (pbin->dbin) {
653         GST_DEBUG_OBJECT (pbin, "Removing decodebin");
654         gst_pulse_audio_sink_free_dbin (pbin);
655         gst_pulse_audio_sink_update_sinkpad (pbin, sinkpad);
656       } else {
657         GST_DEBUG_OBJECT (pbin, "Doing nothing");
658         gst_pad_send_event (sinkpad, gst_event_new_caps (caps));
659       }
660
661       gst_caps_unref (caps);
662       gst_object_unref (sinkpad);
663       goto done;
664     }
665     /* pulsesink doesn't accept the incoming caps, so add a decodebin
666      * (potentially after removing the existing once, since decodebin can't
667      * renegotiate). */
668   } else {
669     /* Format lost, proceed to try plugging a decodebin */
670     pbin->format_lost = FALSE;
671   }
672
673   if (pbin->dbin != NULL) {
674     /* decodebin doesn't support reconfiguration, so throw this one away and
675      * create a new one. */
676     gst_pulse_audio_sink_free_dbin (pbin);
677   }
678
679   GST_DEBUG_OBJECT (pbin, "Adding decodebin");
680   gst_pulse_audio_sink_add_dbin (pbin);
681
682 done:
683   update_eac3_alignment (pbin);
684
685   pbin->block_probe_id = 0;
686   GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
687
688   return GST_PAD_PROBE_REMOVE;
689 }
690
691 static gboolean
692 gst_pulse_audio_sink_src_event (GstPad * pad, GstEvent * event)
693 {
694   GstPulseAudioSink *pbin = NULL;
695   GstPad *ghostpad = NULL;
696   gboolean ret = FALSE;
697
698   ghostpad = GST_PAD_CAST (gst_pad_get_parent (pad));
699   if (G_UNLIKELY (!ghostpad)) {
700     GST_WARNING_OBJECT (pad, "Could not get ghostpad");
701     goto out;
702   }
703
704   pbin = GST_PULSE_AUDIO_SINK (gst_pad_get_parent (ghostpad));
705   if (G_UNLIKELY (!pbin)) {
706     GST_WARNING_OBJECT (pad, "Could not get pulseaudiosink");
707     goto out;
708   }
709
710   if (G_UNLIKELY (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) &&
711       (gst_event_has_name (event, "pulse-format-lost") ||
712           gst_event_has_name (event, "pulse-sink-changed"))) {
713     g_return_val_if_fail (pad->mode != GST_PAD_ACTIVATE_PULL, FALSE);
714
715     GST_PULSE_AUDIO_SINK_LOCK (pbin);
716     if (gst_event_has_name (event, "pulse-format-lost"))
717       pbin->format_lost = TRUE;
718
719     if (pbin->block_probe_id == 0)
720       pbin->block_probe_id =
721           gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
722           proxypad_blocked_cb, gst_object_ref (pbin),
723           (GDestroyNotify) gst_object_unref);
724     GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
725
726     ret = TRUE;
727   } else if (pbin->proxypad_old_eventfunc) {
728     ret = pbin->proxypad_old_eventfunc (pad, event);
729     event = NULL;
730   }
731
732 out:
733   if (ghostpad)
734     gst_object_unref (ghostpad);
735   if (pbin)
736     gst_object_unref (pbin);
737   if (event)
738     gst_event_unref (event);
739
740   return ret;
741 }
742
743 static gboolean
744 gst_pulse_audio_sink_sink_event (GstPad * pad, GstEvent * event)
745 {
746   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (gst_pad_get_parent (pad));
747   gboolean ret;
748   gboolean forward = TRUE;
749
750   switch (GST_EVENT_TYPE (event)) {
751     case GST_EVENT_CAPS:
752     {
753       GstCaps *caps;
754
755       gst_event_parse_caps (event, &caps);
756       ret = gst_pulse_audio_sink_set_caps (pbin, caps);
757       forward = FALSE;
758       break;
759     }
760     case GST_EVENT_SEGMENT:
761     {
762       const GstSegment *segment = NULL;
763
764       GST_PULSE_AUDIO_SINK_LOCK (pbin);
765       gst_event_parse_segment (event, &segment);
766
767       GST_DEBUG_OBJECT (pbin, "newsegment: %" GST_SEGMENT_FORMAT, segment);
768
769       if (segment->format == GST_FORMAT_TIME) {
770         /* Store the values for feeding to sub-elements */
771         gst_segment_copy_into (segment, &pbin->segment);
772       } else {
773         GST_WARNING_OBJECT (pbin, "Got a non-TIME format segment");
774         gst_segment_init (&pbin->segment, GST_FORMAT_TIME);
775       }
776       GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
777
778       break;
779     }
780
781     case GST_EVENT_FLUSH_STOP:
782       GST_PULSE_AUDIO_SINK_LOCK (pbin);
783       gst_segment_init (&pbin->segment, GST_FORMAT_UNDEFINED);
784       GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
785       break;
786
787     default:
788       break;
789   }
790
791   if (forward)
792     ret = pbin->sinkpad_old_eventfunc (pad, event);
793   else
794     gst_event_unref (event);
795
796   gst_object_unref (pbin);
797
798   return ret;
799 }
800
801 /* The bin's acceptcaps should be exactly equivalent to a pulsesink that is
802  * connected to a sink that supports all the formats in template caps. This
803  * means that upstream will have to have everything possibly upto a parser
804  * plugged and we plugin a decoder whenever required. */
805 static gboolean
806 gst_pulse_audio_sink_sink_acceptcaps (GstPulseAudioSink * pbin, GstPad * pad,
807     GstCaps * caps)
808 {
809   GstAudioRingBufferSpec spec = { 0 };
810   const GstStructure *st;
811   GstCaps *pad_caps = NULL;
812   gboolean ret = FALSE;
813
814   pad_caps = gst_pad_get_caps (pad, caps);
815   if (!pad_caps || gst_caps_is_empty (pad_caps))
816     goto out;
817
818   /* If we've not got fixed caps, creating a stream might fail, so let's just
819    * return from here with default acceptcaps behaviour */
820   if (!gst_caps_is_fixed (caps))
821     goto out;
822
823   spec.latency_time = GST_AUDIO_BASE_SINK (pbin->psink)->latency_time;
824   if (!gst_audio_ring_buffer_parse_caps (&spec, caps))
825     goto out;
826
827   /* Make sure non-raw input is framed (one frame per buffer) and can be
828    * payloaded */
829   st = gst_caps_get_structure (caps, 0);
830
831   if (!g_str_has_prefix (gst_structure_get_name (st), "audio/x-raw")) {
832     gboolean framed = FALSE, parsed = FALSE;
833
834     gst_structure_get_boolean (st, "framed", &framed);
835     gst_structure_get_boolean (st, "parsed", &parsed);
836     if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0)
837       goto out;
838   }
839
840   ret = TRUE;
841
842 out:
843   if (pad_caps)
844     gst_caps_unref (pad_caps);
845
846   return ret;
847 }
848
849 static gboolean
850 gst_pulse_audio_sink_sink_query (GstPad * pad, GstQuery * query)
851 {
852   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (gst_pad_get_parent (pad));
853   gboolean ret = FALSE;
854
855   switch (GST_QUERY_TYPE (query)) {
856     case GST_QUERY_ACCEPT_CAPS:
857     {
858       GstCaps *caps;
859
860       gst_query_parse_accept_caps (query, &caps);
861       ret = gst_pulse_audio_sink_sink_acceptcaps (pbin, pad, caps);
862       gst_query_set_accept_caps_result (query, ret);
863       ret = TRUE;
864       break;
865     }
866     default:
867       ret = gst_pad_query_default (pad, query);
868       break;
869   }
870
871   gst_object_unref (pbin);
872
873   return ret;
874
875 }
876
877 static gboolean
878 gst_pulse_audio_sink_set_caps (GstPulseAudioSink * pbin, GstCaps * caps)
879 {
880   gboolean ret = TRUE;
881
882   GST_PULSE_AUDIO_SINK_LOCK (pbin);
883
884   if (pbin->block_probe_id == 0)
885     pbin->block_probe_id =
886         gst_pad_add_probe (pbin->sink_proxypad,
887         GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, proxypad_blocked_cb,
888         gst_object_ref (pbin), (GDestroyNotify) gst_object_unref);
889
890   GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
891
892   return ret;
893 }
894
895 static GstStateChangeReturn
896 gst_pulse_audio_sink_change_state (GstElement * element,
897     GstStateChange transition)
898 {
899   GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (element);
900   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
901
902   /* Nothing to do for upward transitions */
903   switch (transition) {
904     case GST_STATE_CHANGE_PAUSED_TO_READY:
905       GST_PULSE_AUDIO_SINK_LOCK (pbin);
906       if (pbin->block_probe_id) {
907         gst_pad_remove_probe (pbin->sink_proxypad, pbin->block_probe_id);
908         pbin->block_probe_id = 0;
909       }
910       GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
911       break;
912
913     default:
914       break;
915   }
916
917   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
918   if (ret != GST_STATE_CHANGE_SUCCESS) {
919     GST_DEBUG_OBJECT (pbin, "Base class returned %d on state change", ret);
920     goto out;
921   }
922
923   switch (transition) {
924     case GST_STATE_CHANGE_PAUSED_TO_READY:
925       GST_PULSE_AUDIO_SINK_LOCK (pbin);
926       gst_segment_init (&pbin->segment, GST_FORMAT_UNDEFINED);
927
928       if (pbin->dbin) {
929         GstPad *pad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink),
930             "sink");
931
932         gst_pulse_audio_sink_free_dbin (pbin);
933         gst_pulse_audio_sink_update_sinkpad (pbin, pad);
934
935         gst_object_unref (pad);
936
937       }
938       GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
939
940       break;
941
942     default:
943       break;
944   }
945
946 out:
947   return ret;
948 }
949
950 #endif /* HAVE_PULSE_1_0 */