2 * GStreamer pulseaudio plugin
4 * Copyright (c) 2004-2008 Lennart Poettering
6 * gst-pulse is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
11 * gst-pulse is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with gst-pulse; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 * SECTION:element-pulsesrc
24 * @see_also: pulsesink
26 * This element captures audio from a
27 * <ulink href="http://www.pulseaudio.org">PulseAudio sound server</ulink>.
30 * <title>Example pipelines</title>
32 * gst-launch-1.0 -v pulsesrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
33 * ]| Record from a sound card using pulseaudio and encode to Ogg/Vorbis.
44 #include <gst/base/gstbasesrc.h>
45 #include <gst/gsttaglist.h>
46 #include <gst/audio/audio.h>
49 #include "pulseutil.h"
52 #ifdef PCM_DUMP_ENABLE
57 GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
58 #define GST_CAT_DEFAULT pulse_debug
60 #define DEFAULT_SERVER NULL
61 #define DEFAULT_DEVICE NULL
62 #define DEFAULT_CURRENT_DEVICE NULL
63 #define DEFAULT_DEVICE_NAME NULL
65 #define DEFAULT_VOLUME 1.0
66 #define DEFAULT_MUTE FALSE
67 #define MAX_VOLUME 10.0
69 #define DEFAULT_AUDIO_LATENCY "mid"
70 #endif /* __TIZEN__ */
71 /* See the pulsesink code for notes on how we interact with the PA mainloop
74 /* See the pulsesink code for notes on how we interact with the PA mainloop
85 PROP_STREAM_PROPERTIES,
86 PROP_SOURCE_OUTPUT_INDEX,
91 #endif /* __TIZEN__ */
96 #ifdef PCM_DUMP_ENABLE
97 #define GST_PULSESRC_DUMP_VCONF_KEY "memory/private/sound/pcm_dump"
98 #define GST_PULSESRC_DUMP_OUTPUT_PATH_PREFIX "/tmp/dump_pulsesrc_out"
99 #define GST_PULSESRC_DUMP_OUTPUT_FLAG 0x00200000U
103 static void gst_pulsesrc_destroy_stream (GstPulseSrc * pulsesrc);
104 static void gst_pulsesrc_destroy_context (GstPulseSrc * pulsesrc);
106 static void gst_pulsesrc_set_property (GObject * object, guint prop_id,
107 const GValue * value, GParamSpec * pspec);
108 static void gst_pulsesrc_get_property (GObject * object, guint prop_id,
109 GValue * value, GParamSpec * pspec);
110 static void gst_pulsesrc_finalize (GObject * object);
112 static gboolean gst_pulsesrc_set_corked (GstPulseSrc * psrc, gboolean corked,
114 static gboolean gst_pulsesrc_open (GstAudioSrc * asrc);
116 static gboolean gst_pulsesrc_close (GstAudioSrc * asrc);
118 static gboolean gst_pulsesrc_prepare (GstAudioSrc * asrc,
119 GstAudioRingBufferSpec * spec);
121 static gboolean gst_pulsesrc_unprepare (GstAudioSrc * asrc);
123 static guint gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data,
124 guint length, GstClockTime * timestamp);
125 static guint gst_pulsesrc_delay (GstAudioSrc * asrc);
127 static void gst_pulsesrc_reset (GstAudioSrc * src);
129 static gboolean gst_pulsesrc_negotiate (GstBaseSrc * basesrc);
130 static gboolean gst_pulsesrc_event (GstBaseSrc * basesrc, GstEvent * event);
132 static GstStateChangeReturn gst_pulsesrc_change_state (GstElement *
133 element, GstStateChange transition);
135 static GstClockTime gst_pulsesrc_get_time (GstClock * clock, GstPulseSrc * src);
137 static GstStaticPadTemplate pad_template = GST_STATIC_PAD_TEMPLATE ("src",
140 GST_STATIC_CAPS (_PULSE_CAPS_PCM)
143 #define gst_pulsesrc_parent_class parent_class
144 G_DEFINE_TYPE_WITH_CODE (GstPulseSrc, gst_pulsesrc, GST_TYPE_AUDIO_SRC,
145 G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
148 gst_pulsesrc_class_init (GstPulseSrcClass * klass)
150 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
151 GstAudioSrcClass *gstaudiosrc_class = GST_AUDIO_SRC_CLASS (klass);
152 GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
153 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
156 gobject_class->finalize = gst_pulsesrc_finalize;
157 gobject_class->set_property = gst_pulsesrc_set_property;
158 gobject_class->get_property = gst_pulsesrc_get_property;
160 gstelement_class->change_state =
161 GST_DEBUG_FUNCPTR (gst_pulsesrc_change_state);
163 gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_pulsesrc_event);
164 gstbasesrc_class->negotiate = GST_DEBUG_FUNCPTR (gst_pulsesrc_negotiate);
166 gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_pulsesrc_open);
167 gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_pulsesrc_close);
168 gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_pulsesrc_prepare);
169 gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_pulsesrc_unprepare);
170 gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_pulsesrc_read);
171 gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_pulsesrc_delay);
172 gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_pulsesrc_reset);
174 /* Overwrite GObject fields */
175 g_object_class_install_property (gobject_class,
177 g_param_spec_string ("server", "Server",
178 "The PulseAudio server to connect to", DEFAULT_SERVER,
179 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
181 g_object_class_install_property (gobject_class, PROP_DEVICE,
182 g_param_spec_string ("device", "Device",
183 "The PulseAudio source device to connect to", DEFAULT_DEVICE,
184 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
186 g_object_class_install_property (gobject_class, PROP_CURRENT_DEVICE,
187 g_param_spec_string ("current-device", "Current Device",
188 "The current PulseAudio source device", DEFAULT_CURRENT_DEVICE,
189 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
191 g_object_class_install_property (gobject_class,
193 g_param_spec_string ("device-name", "Device name",
194 "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
195 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
197 clientname = gst_pulse_client_name ();
199 * GstPulseSrc:client-name
201 * The PulseAudio client name to use.
203 g_object_class_install_property (gobject_class,
205 g_param_spec_string ("client-name", "Client Name",
206 "The PulseAudio client_name_to_use", clientname,
207 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
208 GST_PARAM_MUTABLE_READY));
212 * GstPulseSrc:stream-properties:
214 * List of pulseaudio stream properties. A list of defined properties can be
215 * found in the <ulink href="http://0pointer.de/lennart/projects/pulseaudio/doxygen/proplist_8h.html">pulseaudio api docs</ulink>.
217 * Below is an example for registering as a music application to pulseaudio.
219 * GstStructure *props;
221 * props = gst_structure_from_string ("props,media.role=music", NULL);
222 * g_object_set (pulse, "stream-properties", props, NULL);
223 * gst_structure_free (props);
226 g_object_class_install_property (gobject_class,
227 PROP_STREAM_PROPERTIES,
228 g_param_spec_boxed ("stream-properties", "stream properties",
229 "list of pulseaudio stream properties",
230 GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
232 * GstPulseSrc:source-output-index:
234 * The index of the PulseAudio source output corresponding to this element.
236 g_object_class_install_property (gobject_class,
237 PROP_SOURCE_OUTPUT_INDEX,
238 g_param_spec_uint ("source-output-index", "source output index",
239 "The index of the PulseAudio source output corresponding to this "
240 "record stream", 0, G_MAXUINT, PA_INVALID_INDEX,
241 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
243 gst_element_class_set_static_metadata (gstelement_class,
244 "PulseAudio Audio Source",
246 "Captures audio from a PulseAudio server", "Lennart Poettering");
247 gst_element_class_add_static_pad_template (gstelement_class, &pad_template);
250 * GstPulseSrc:volume:
252 * The volume of the record stream.
254 g_object_class_install_property (gobject_class,
255 PROP_VOLUME, g_param_spec_double ("volume", "Volume",
256 "Linear volume of this stream, 1.0=100%",
257 0.0, MAX_VOLUME, DEFAULT_VOLUME,
258 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
263 * Whether the stream is muted or not.
265 g_object_class_install_property (gobject_class,
266 PROP_MUTE, g_param_spec_boolean ("mute", "Mute",
267 "Mute state of this stream",
268 DEFAULT_MUTE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
271 g_object_class_install_property (gobject_class,
273 g_param_spec_string ("latency", "Audio Backend Latency",
274 "Audio Backend Latency (\"low\": Low Latency, \"mid\": Mid Latency, \"high\": High Latency)",
275 DEFAULT_AUDIO_LATENCY,
276 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
277 #endif /* __TIZEN__ */
281 #ifdef PCM_DUMP_ENABLE
282 static GstPadProbeReturn
283 gst_pulsesrc_pad_dump_probe (GstPad *pad, GstPadProbeInfo * info, gpointer data)
285 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (data);
287 GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
289 if (pulsesrc->dump_fd_output) {
290 gst_buffer_map(buffer, &in_map, GST_MAP_READ);
291 written = fwrite(in_map.data, 1, in_map.size, pulsesrc->dump_fd_output);
292 if (written != in_map.size)
293 GST_WARNING("failed to write!!! ferror=%d", ferror(pulsesrc->dump_fd_output));
294 gst_buffer_unmap(buffer, &in_map);
296 return GST_PAD_PROBE_OK;
302 gst_pulsesrc_init (GstPulseSrc * pulsesrc)
305 #ifdef PCM_DUMP_ENABLE
306 GstPad *srcpad = NULL;
310 pulsesrc->server = NULL;
311 pulsesrc->device = NULL;
312 pulsesrc->client_name = gst_pulse_client_name ();
313 pulsesrc->device_description = NULL;
315 pulsesrc->context = NULL;
316 pulsesrc->stream = NULL;
317 pulsesrc->stream_connected = FALSE;
318 pulsesrc->source_output_idx = PA_INVALID_INDEX;
320 pulsesrc->read_buffer = NULL;
321 pulsesrc->read_buffer_length = 0;
323 pa_sample_spec_init (&pulsesrc->sample_spec);
325 pulsesrc->operation_success = FALSE;
326 pulsesrc->paused = TRUE;
327 pulsesrc->in_read = FALSE;
329 pulsesrc->volume = DEFAULT_VOLUME;
330 pulsesrc->volume_set = FALSE;
332 pulsesrc->mute = DEFAULT_MUTE;
333 pulsesrc->mute_set = FALSE;
335 pulsesrc->notify = 0;
337 pulsesrc->properties = NULL;
338 pulsesrc->proplist = NULL;
340 pulsesrc->latency = g_strdup (DEFAULT_AUDIO_LATENCY);
341 pulsesrc->proplist = pa_proplist_new();
342 pa_proplist_sets(pulsesrc->proplist, PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY, pulsesrc->latency);
344 #ifdef PCM_DUMP_ENABLE
345 if (vconf_get_int(GST_PULSESRC_DUMP_VCONF_KEY, &vconf_dump)) {
346 GST_WARNING("vconf_get_int %s failed", GST_PULSESRC_DUMP_VCONF_KEY);
348 pulsesrc->need_dump_output = vconf_dump & GST_PULSESRC_DUMP_OUTPUT_FLAG ? TRUE : FALSE;
349 pulsesrc->dump_fd_output = NULL;
350 if (pulsesrc->need_dump_output) {
351 srcpad = gst_element_get_static_pad((GstElement *)pulsesrc, "src");
352 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_BUFFER, gst_pulsesrc_pad_dump_probe, pulsesrc, NULL);
354 #endif /* PCM_DUMP_ENABLE */
355 #endif /* __TIZEN__ */
356 /* this should be the default but it isn't yet */
357 gst_audio_base_src_set_slave_method (GST_AUDIO_BASE_SRC (pulsesrc),
358 GST_AUDIO_BASE_SRC_SLAVE_SKEW);
360 /* override with a custom clock */
361 if (GST_AUDIO_BASE_SRC (pulsesrc)->clock)
362 gst_object_unref (GST_AUDIO_BASE_SRC (pulsesrc)->clock);
364 GST_AUDIO_BASE_SRC (pulsesrc)->clock =
365 gst_audio_clock_new ("GstPulseSrcClock",
366 (GstAudioClockGetTimeFunc) gst_pulsesrc_get_time, pulsesrc, NULL);
370 gst_pulsesrc_destroy_stream (GstPulseSrc * pulsesrc)
372 if (pulsesrc->stream) {
373 pa_stream_disconnect (pulsesrc->stream);
374 pa_stream_unref (pulsesrc->stream);
375 pulsesrc->stream = NULL;
376 pulsesrc->stream_connected = FALSE;
377 pulsesrc->source_output_idx = PA_INVALID_INDEX;
378 g_object_notify (G_OBJECT (pulsesrc), "source-output-index");
381 g_free (pulsesrc->device_description);
382 pulsesrc->device_description = NULL;
386 gst_pulsesrc_destroy_context (GstPulseSrc * pulsesrc)
389 gst_pulsesrc_destroy_stream (pulsesrc);
391 if (pulsesrc->context) {
392 pa_context_disconnect (pulsesrc->context);
394 /* Make sure we don't get any further callbacks */
395 pa_context_set_state_callback (pulsesrc->context, NULL, NULL);
396 pa_context_set_subscribe_callback (pulsesrc->context, NULL, NULL);
398 pa_context_unref (pulsesrc->context);
400 pulsesrc->context = NULL;
405 gst_pulsesrc_finalize (GObject * object)
407 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (object);
409 g_free (pulsesrc->server);
410 g_free (pulsesrc->device);
411 g_free (pulsesrc->client_name);
412 g_free (pulsesrc->current_source_name);
414 if (pulsesrc->properties)
415 gst_structure_free (pulsesrc->properties);
416 if (pulsesrc->proplist)
417 pa_proplist_free (pulsesrc->proplist);
420 g_free (pulsesrc->latency);
421 #endif /* __TIZEN__ */
423 G_OBJECT_CLASS (parent_class)->finalize (object);
426 #define CONTEXT_OK(c) ((c) && PA_CONTEXT_IS_GOOD (pa_context_get_state ((c))))
427 #define STREAM_OK(s) ((s) && PA_STREAM_IS_GOOD (pa_stream_get_state ((s))))
430 gst_pulsesrc_is_dead (GstPulseSrc * pulsesrc, gboolean check_stream)
432 if (!pulsesrc->stream_connected)
435 if (!CONTEXT_OK (pulsesrc->context))
438 if (check_stream && !STREAM_OK (pulsesrc->stream))
445 const gchar *err_str = pulsesrc->context ?
446 pa_strerror (pa_context_errno (pulsesrc->context)) : NULL;
447 GST_ELEMENT_ERROR ((pulsesrc), RESOURCE, FAILED, ("Disconnected: %s",
454 gst_pulsesrc_source_info_cb (pa_context * c, const pa_source_info * i, int eol,
457 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (userdata);
462 g_free (pulsesrc->device_description);
463 pulsesrc->device_description = g_strdup (i->description);
466 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
470 gst_pulsesrc_device_description (GstPulseSrc * pulsesrc)
472 pa_operation *o = NULL;
475 if (!pulsesrc->mainloop)
478 pa_threaded_mainloop_lock (pulsesrc->mainloop);
480 if (!(o = pa_context_get_source_info_by_name (pulsesrc->context,
481 pulsesrc->device, gst_pulsesrc_source_info_cb, pulsesrc))) {
483 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
484 ("pa_stream_get_source_info() failed: %s",
485 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
489 while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
491 if (gst_pulsesrc_is_dead (pulsesrc, FALSE))
494 pa_threaded_mainloop_wait (pulsesrc->mainloop);
500 pa_operation_unref (o);
502 t = g_strdup (pulsesrc->device_description);
504 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
510 GST_DEBUG_OBJECT (pulsesrc, "have no mainloop");
516 gst_pulsesrc_source_output_info_cb (pa_context * c,
517 const pa_source_output_info * i, int eol, void *userdata)
521 psrc = GST_PULSESRC_CAST (userdata);
526 /* If the index doesn't match our current stream,
527 * it implies we just recreated the stream (caps change)
529 if (i->index == psrc->source_output_idx) {
530 psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume));
531 psrc->mute = i->mute;
532 psrc->current_source_idx = i->source;
534 if (G_UNLIKELY (psrc->volume > MAX_VOLUME)) {
535 GST_WARNING_OBJECT (psrc, "Clipped volume from %f to %f",
536 psrc->volume, MAX_VOLUME);
537 psrc->volume = MAX_VOLUME;
542 pa_threaded_mainloop_signal (psrc->mainloop, 0);
546 gst_pulsesrc_get_source_output_info (GstPulseSrc * pulsesrc, gdouble * volume,
549 pa_operation *o = NULL;
551 if (!pulsesrc->mainloop)
554 if (pulsesrc->source_output_idx == PA_INVALID_INDEX)
557 pa_threaded_mainloop_lock (pulsesrc->mainloop);
559 if (!(o = pa_context_get_source_output_info (pulsesrc->context,
560 pulsesrc->source_output_idx, gst_pulsesrc_source_output_info_cb,
564 while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
565 pa_threaded_mainloop_wait (pulsesrc->mainloop);
566 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
573 *volume = pulsesrc->volume;
575 *mute = pulsesrc->mute;
578 pa_operation_unref (o);
580 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
587 GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
589 *volume = pulsesrc->volume;
591 *mute = pulsesrc->mute;
596 GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
598 *volume = pulsesrc->volume;
600 *mute = pulsesrc->mute;
605 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
606 ("pa_context_get_source_output_info() failed: %s",
607 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
613 gst_pulsesrc_current_source_info_cb (pa_context * c, const pa_source_info * i,
614 int eol, void *userdata)
618 psrc = GST_PULSESRC_CAST (userdata);
623 /* If the index doesn't match our current stream,
624 * it implies we just recreated the stream (caps change)
626 if (i->index == psrc->current_source_idx) {
627 g_free (psrc->current_source_name);
628 psrc->current_source_name = g_strdup (i->name);
632 pa_threaded_mainloop_signal (psrc->mainloop, 0);
636 gst_pulsesrc_get_current_device (GstPulseSrc * pulsesrc)
638 pa_operation *o = NULL;
641 if (!pulsesrc->mainloop)
644 if (pulsesrc->source_output_idx == PA_INVALID_INDEX)
647 gst_pulsesrc_get_source_output_info (pulsesrc, NULL, NULL);
649 pa_threaded_mainloop_lock (pulsesrc->mainloop);
652 if (!(o = pa_context_get_source_info_by_index (pulsesrc->context,
653 pulsesrc->current_source_idx, gst_pulsesrc_current_source_info_cb,
657 while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
658 pa_threaded_mainloop_wait (pulsesrc->mainloop);
659 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
665 current_src = g_strdup (pulsesrc->current_source_name);
668 pa_operation_unref (o);
670 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
677 GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
682 GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
687 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
688 ("pa_context_get_source_output_info() failed: %s",
689 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
695 gst_pulsesrc_set_stream_volume (GstPulseSrc * pulsesrc, gdouble volume)
698 pa_operation *o = NULL;
700 if (!pulsesrc->mainloop)
703 if (!pulsesrc->source_output_idx)
706 pa_threaded_mainloop_lock (pulsesrc->mainloop);
708 GST_DEBUG_OBJECT (pulsesrc, "setting volume to %f", volume);
710 gst_pulse_cvolume_from_linear (&v, pulsesrc->sample_spec.channels, volume);
712 if (!(o = pa_context_set_source_output_volume (pulsesrc->context,
713 pulsesrc->source_output_idx, &v, NULL, NULL)))
716 /* We don't really care about the result of this call */
720 pa_operation_unref (o);
722 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
729 pulsesrc->volume = volume;
730 pulsesrc->volume_set = TRUE;
731 GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
736 pulsesrc->volume = volume;
737 pulsesrc->volume_set = TRUE;
738 GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
743 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
744 ("pa_stream_set_source_output_volume() failed: %s",
745 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
751 gst_pulsesrc_set_stream_mute (GstPulseSrc * pulsesrc, gboolean mute)
753 pa_operation *o = NULL;
755 if (!pulsesrc->mainloop)
758 if (!pulsesrc->source_output_idx)
761 pa_threaded_mainloop_lock (pulsesrc->mainloop);
763 GST_DEBUG_OBJECT (pulsesrc, "setting mute state to %d", mute);
765 if (!(o = pa_context_set_source_output_mute (pulsesrc->context,
766 pulsesrc->source_output_idx, mute, NULL, NULL)))
769 /* We don't really care about the result of this call */
773 pa_operation_unref (o);
775 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
782 pulsesrc->mute = mute;
783 pulsesrc->mute_set = TRUE;
784 GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
789 pulsesrc->mute = mute;
790 pulsesrc->mute_set = TRUE;
791 GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
796 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
797 ("pa_stream_set_source_output_mute() failed: %s",
798 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
804 gst_pulsesrc_set_stream_device (GstPulseSrc * pulsesrc, const gchar * device)
806 pa_operation *o = NULL;
808 if (!pulsesrc->mainloop)
811 if (!pulsesrc->source_output_idx)
814 pa_threaded_mainloop_lock (pulsesrc->mainloop);
816 GST_DEBUG_OBJECT (pulsesrc, "setting stream device to %s", device);
818 if (!(o = pa_context_move_source_output_by_name (pulsesrc->context,
819 pulsesrc->source_output_idx, device, NULL, NULL)))
825 pa_operation_unref (o);
827 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
834 GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
839 GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
844 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
845 ("pa_context_move_source_output_by_name(%s) failed: %s",
846 device, pa_strerror (pa_context_errno (pulsesrc->context))),
853 gst_pulsesrc_set_property (GObject * object,
854 guint prop_id, const GValue * value, GParamSpec * pspec)
857 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (object);
861 g_free (pulsesrc->server);
862 pulsesrc->server = g_value_dup_string (value);
865 g_free (pulsesrc->device);
866 pulsesrc->device = g_value_dup_string (value);
867 gst_pulsesrc_set_stream_device (pulsesrc, pulsesrc->device);
869 case PROP_CLIENT_NAME:
870 g_free (pulsesrc->client_name);
871 if (!g_value_get_string (value)) {
872 GST_WARNING_OBJECT (pulsesrc,
873 "Empty PulseAudio client name not allowed. Resetting to default value");
874 pulsesrc->client_name = gst_pulse_client_name ();
876 pulsesrc->client_name = g_value_dup_string (value);
878 case PROP_STREAM_PROPERTIES:
879 if (pulsesrc->properties)
880 gst_structure_free (pulsesrc->properties);
881 pulsesrc->properties =
882 gst_structure_copy (gst_value_get_structure (value));
883 if (pulsesrc->proplist)
884 pa_proplist_free (pulsesrc->proplist);
885 pulsesrc->proplist = gst_pulse_make_proplist (pulsesrc->properties);
888 gst_pulsesrc_set_stream_volume (pulsesrc, g_value_get_double (value));
891 gst_pulsesrc_set_stream_mute (pulsesrc, g_value_get_boolean (value));
894 case PROP_AUDIO_LATENCY:
895 g_free (pulsesrc->latency);
896 pulsesrc->latency = g_value_dup_string (value);
897 /* setting NULL restores the default latency */
898 if (pulsesrc->latency == NULL) {
899 pulsesrc->latency = g_strdup (DEFAULT_AUDIO_LATENCY);
901 if (!pulsesrc->proplist) {
902 pulsesrc->proplist = pa_proplist_new();
904 pa_proplist_sets(pulsesrc->proplist, PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY, pulsesrc->latency);
905 GST_DEBUG_OBJECT(pulsesrc, "latency(%s)", pulsesrc->latency);
907 #endif /* __TIZEN__ */
909 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
915 gst_pulsesrc_get_property (GObject * object,
916 guint prop_id, GValue * value, GParamSpec * pspec)
919 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (object);
923 g_value_set_string (value, pulsesrc->server);
926 g_value_set_string (value, pulsesrc->device);
928 case PROP_CURRENT_DEVICE:
930 gchar *current_device = gst_pulsesrc_get_current_device (pulsesrc);
932 g_value_take_string (value, current_device);
934 g_value_set_string (value, "");
937 case PROP_DEVICE_NAME:
938 g_value_take_string (value, gst_pulsesrc_device_description (pulsesrc));
940 case PROP_CLIENT_NAME:
941 g_value_set_string (value, pulsesrc->client_name);
943 case PROP_STREAM_PROPERTIES:
944 gst_value_set_structure (value, pulsesrc->properties);
946 case PROP_SOURCE_OUTPUT_INDEX:
947 g_value_set_uint (value, pulsesrc->source_output_idx);
952 gst_pulsesrc_get_source_output_info (pulsesrc, &volume, NULL);
953 g_value_set_double (value, volume);
959 gst_pulsesrc_get_source_output_info (pulsesrc, NULL, &mute);
960 g_value_set_boolean (value, mute);
964 case PROP_AUDIO_LATENCY:
965 g_value_set_string (value, pulsesrc->latency);
967 #endif /* __TIZEN__ */
969 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
975 gst_pulsesrc_context_state_cb (pa_context * c, void *userdata)
977 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (userdata);
979 switch (pa_context_get_state (c)) {
980 case PA_CONTEXT_READY:
981 case PA_CONTEXT_TERMINATED:
982 case PA_CONTEXT_FAILED:
983 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
986 case PA_CONTEXT_UNCONNECTED:
987 case PA_CONTEXT_CONNECTING:
988 case PA_CONTEXT_AUTHORIZING:
989 case PA_CONTEXT_SETTING_NAME:
995 gst_pulsesrc_stream_state_cb (pa_stream * s, void *userdata)
997 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (userdata);
999 switch (pa_stream_get_state (s)) {
1001 case PA_STREAM_READY:
1002 case PA_STREAM_FAILED:
1003 case PA_STREAM_TERMINATED:
1004 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
1007 case PA_STREAM_UNCONNECTED:
1008 case PA_STREAM_CREATING:
1014 gst_pulsesrc_stream_request_cb (pa_stream * s, size_t length, void *userdata)
1016 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (userdata);
1018 GST_LOG_OBJECT (pulsesrc, "got request for length %" G_GSIZE_FORMAT, length);
1020 if (pulsesrc->in_read) {
1021 /* only signal when reading */
1022 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
1027 gst_pulsesrc_stream_latency_update_cb (pa_stream * s, void *userdata)
1029 const pa_timing_info *info;
1030 pa_usec_t source_usec;
1032 info = pa_stream_get_timing_info (s);
1035 GST_LOG_OBJECT (GST_PULSESRC_CAST (userdata),
1036 "latency update (information unknown)");
1039 source_usec = info->configured_source_usec;
1041 GST_LOG_OBJECT (GST_PULSESRC_CAST (userdata),
1042 "latency_update, %" G_GUINT64_FORMAT ", %d:%" G_GINT64_FORMAT ", %d:%"
1043 G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT,
1044 GST_TIMEVAL_TO_TIME (info->timestamp), info->write_index_corrupt,
1045 info->write_index, info->read_index_corrupt, info->read_index,
1046 info->source_usec, source_usec);
1050 gst_pulsesrc_stream_underflow_cb (pa_stream * s, void *userdata)
1052 GST_WARNING_OBJECT (GST_PULSESRC_CAST (userdata), "Got underflow");
1056 gst_pulsesrc_stream_overflow_cb (pa_stream * s, void *userdata)
1058 GST_WARNING_OBJECT (GST_PULSESRC_CAST (userdata), "Got overflow");
1062 gst_pulsesrc_context_subscribe_cb (pa_context * c,
1063 pa_subscription_event_type_t t, uint32_t idx, void *userdata)
1065 GstPulseSrc *psrc = GST_PULSESRC (userdata);
1067 if (t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE)
1068 && t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_NEW))
1071 if (idx != psrc->source_output_idx)
1074 /* Actually this event is also triggered when other properties of the stream
1075 * change that are unrelated to the volume. However it is probably cheaper to
1076 * signal the change here and check for the volume when the GObject property
1077 * is read instead of querying it always. */
1079 /* inform streaming thread to notify */
1080 g_atomic_int_compare_and_exchange (&psrc->notify, 0, 1);
1084 gst_pulsesrc_open (GstAudioSrc * asrc)
1086 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1088 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1090 g_assert (!pulsesrc->context);
1091 g_assert (!pulsesrc->stream);
1093 GST_DEBUG_OBJECT (pulsesrc, "opening device");
1095 if (!(pulsesrc->context =
1096 pa_context_new (pa_threaded_mainloop_get_api (pulsesrc->mainloop),
1097 pulsesrc->client_name))) {
1098 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to create context"),
1100 goto unlock_and_fail;
1103 pa_context_set_state_callback (pulsesrc->context,
1104 gst_pulsesrc_context_state_cb, pulsesrc);
1105 pa_context_set_subscribe_callback (pulsesrc->context,
1106 gst_pulsesrc_context_subscribe_cb, pulsesrc);
1108 GST_DEBUG_OBJECT (pulsesrc, "connect to server %s",
1109 GST_STR_NULL (pulsesrc->server));
1111 if (pa_context_connect (pulsesrc->context, pulsesrc->server, 0, NULL) < 0) {
1112 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s",
1113 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1114 goto unlock_and_fail;
1118 pa_context_state_t state;
1120 state = pa_context_get_state (pulsesrc->context);
1122 if (!PA_CONTEXT_IS_GOOD (state)) {
1123 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s",
1124 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1125 goto unlock_and_fail;
1128 if (state == PA_CONTEXT_READY)
1131 /* Wait until the context is ready */
1132 pa_threaded_mainloop_wait (pulsesrc->mainloop);
1134 GST_DEBUG_OBJECT (pulsesrc, "connected");
1136 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1143 gst_pulsesrc_destroy_context (pulsesrc);
1145 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1152 gst_pulsesrc_close (GstAudioSrc * asrc)
1154 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1156 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1157 gst_pulsesrc_destroy_context (pulsesrc);
1158 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1160 #ifdef PCM_DUMP_ENABLE
1161 if (pulsesrc->dump_fd_output) {
1162 fclose(pulsesrc->dump_fd_output);
1163 pulsesrc->dump_fd_output = NULL;
1171 gst_pulsesrc_unprepare (GstAudioSrc * asrc)
1173 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1175 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1176 gst_pulsesrc_destroy_stream (pulsesrc);
1178 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1180 pulsesrc->read_buffer = NULL;
1181 pulsesrc->read_buffer_length = 0;
1187 gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length,
1188 GstClockTime * timestamp)
1190 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1193 if (g_atomic_int_compare_and_exchange (&pulsesrc->notify, 1, 0)) {
1194 g_object_notify (G_OBJECT (pulsesrc), "volume");
1195 g_object_notify (G_OBJECT (pulsesrc), "mute");
1196 g_object_notify (G_OBJECT (pulsesrc), "current-device");
1199 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1200 pulsesrc->in_read = TRUE;
1202 if (!pulsesrc->stream_connected)
1205 if (pulsesrc->paused)
1208 while (length > 0) {
1211 GST_LOG_OBJECT (pulsesrc, "reading %u bytes", length);
1213 /*check if we have a leftover buffer */
1214 if (!pulsesrc->read_buffer) {
1216 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
1217 goto unlock_and_fail;
1219 /* read all available data, we keep a pointer to the data and the length
1220 * and take from it what we need. */
1221 if (pa_stream_peek (pulsesrc->stream, &pulsesrc->read_buffer,
1222 &pulsesrc->read_buffer_length) < 0)
1225 GST_LOG_OBJECT (pulsesrc, "have data of %" G_GSIZE_FORMAT " bytes",
1226 pulsesrc->read_buffer_length);
1228 /* if we have data, process if */
1229 if (pulsesrc->read_buffer && pulsesrc->read_buffer_length)
1232 /* now wait for more data to become available */
1233 GST_LOG_OBJECT (pulsesrc, "waiting for data");
1234 pa_threaded_mainloop_wait (pulsesrc->mainloop);
1236 if (pulsesrc->paused)
1241 l = pulsesrc->read_buffer_length >
1242 length ? length : pulsesrc->read_buffer_length;
1244 memcpy (data, pulsesrc->read_buffer, l);
1246 pulsesrc->read_buffer = (const guint8 *) pulsesrc->read_buffer + l;
1247 pulsesrc->read_buffer_length -= l;
1249 data = (guint8 *) data + l;
1253 if (pulsesrc->read_buffer_length <= 0) {
1254 /* we copied all of the data, drop it now */
1255 if (pa_stream_drop (pulsesrc->stream) < 0)
1258 /* reset pointer to data */
1259 pulsesrc->read_buffer = NULL;
1260 pulsesrc->read_buffer_length = 0;
1264 pulsesrc->in_read = FALSE;
1265 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1272 GST_LOG_OBJECT (pulsesrc, "we are not connected");
1273 goto unlock_and_fail;
1277 GST_LOG_OBJECT (pulsesrc, "we are paused");
1278 goto unlock_and_fail;
1282 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1283 ("pa_stream_peek() failed: %s",
1284 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1285 goto unlock_and_fail;
1289 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1290 ("pa_stream_drop() failed: %s",
1291 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1292 goto unlock_and_fail;
1296 pulsesrc->in_read = FALSE;
1297 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1303 /* return the delay in samples */
1305 gst_pulsesrc_delay (GstAudioSrc * asrc)
1307 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1312 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1313 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
1316 /* get the latency, this can fail when we don't have a latency update yet.
1317 * We don't want to wait for latency updates here but we just return 0. */
1318 res = pa_stream_get_latency (pulsesrc->stream, &t, &negative);
1320 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1323 GST_DEBUG_OBJECT (pulsesrc, "could not get latency");
1329 result = (guint) ((t * pulsesrc->sample_spec.rate) / 1000000LL);
1336 GST_DEBUG_OBJECT (pulsesrc, "the server is dead");
1337 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1343 gst_pulsesrc_create_stream (GstPulseSrc * pulsesrc, GstCaps ** caps,
1344 GstAudioRingBufferSpec * rspec)
1346 pa_channel_map channel_map;
1347 const pa_channel_map *m;
1349 gboolean need_channel_layout = FALSE;
1350 GstAudioRingBufferSpec new_spec, *spec = NULL;
1354 /* If we already have a stream (renegotiation), free it first */
1355 if (pulsesrc->stream)
1356 gst_pulsesrc_destroy_stream (pulsesrc);
1359 /* Post-negotiation, we already have a ringbuffer spec, so we just need to
1360 * use it to create a stream. */
1363 /* At this point, we expect the channel-mask to be set in caps, so we just
1365 if (!gst_pulse_gst_to_channel_map (&channel_map, spec))
1369 /* At negotiation time, we get a fixed caps and use it to set up a stream */
1370 s = gst_caps_get_structure (*caps, 0);
1371 gst_structure_get_int (s, "channels", &new_spec.info.channels);
1372 if (!gst_structure_has_field (s, "channel-mask")) {
1373 if (new_spec.info.channels == 1) {
1374 pa_channel_map_init_mono (&channel_map);
1375 } else if (new_spec.info.channels == 2) {
1376 pa_channel_map_init_stereo (&channel_map);
1378 need_channel_layout = TRUE;
1379 gst_structure_set (s, "channel-mask", GST_TYPE_BITMASK,
1380 G_GUINT64_CONSTANT (0), NULL);
1384 memset (&new_spec, 0, sizeof (GstAudioRingBufferSpec));
1385 new_spec.latency_time = GST_SECOND;
1386 if (!gst_audio_ring_buffer_parse_caps (&new_spec, *caps))
1389 /* Keep the refcount of the caps at 1 to make them writable */
1390 gst_caps_unref (new_spec.caps);
1392 if (!need_channel_layout
1393 && !gst_pulse_gst_to_channel_map (&channel_map, &new_spec)) {
1394 need_channel_layout = TRUE;
1395 gst_structure_set (s, "channel-mask", GST_TYPE_BITMASK,
1396 G_GUINT64_CONSTANT (0), NULL);
1397 for (i = 0; i < G_N_ELEMENTS (new_spec.info.position); i++)
1398 new_spec.info.position[i] = GST_AUDIO_CHANNEL_POSITION_INVALID;
1403 /* !rspec && !caps */
1404 g_assert_not_reached ();
1407 if (!gst_pulse_fill_sample_spec (spec, &pulsesrc->sample_spec))
1410 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1412 if (!pulsesrc->context)
1415 name = "Record Stream";
1416 if (pulsesrc->proplist) {
1417 if (!(pulsesrc->stream = pa_stream_new_with_proplist (pulsesrc->context,
1418 name, &pulsesrc->sample_spec,
1419 (need_channel_layout) ? NULL : &channel_map,
1420 pulsesrc->proplist)))
1423 } else if (!(pulsesrc->stream = pa_stream_new (pulsesrc->context,
1424 name, &pulsesrc->sample_spec,
1425 (need_channel_layout) ? NULL : &channel_map)))
1429 m = pa_stream_get_channel_map (pulsesrc->stream);
1430 gst_pulse_channel_map_to_gst (m, &new_spec);
1431 gst_audio_channel_positions_to_valid_order (new_spec.info.position,
1432 new_spec.info.channels);
1433 gst_caps_unref (*caps);
1434 *caps = gst_audio_info_to_caps (&new_spec.info);
1436 GST_DEBUG_OBJECT (pulsesrc, "Caps are %" GST_PTR_FORMAT, *caps);
1440 pa_stream_set_state_callback (pulsesrc->stream, gst_pulsesrc_stream_state_cb,
1442 pa_stream_set_read_callback (pulsesrc->stream, gst_pulsesrc_stream_request_cb,
1444 pa_stream_set_underflow_callback (pulsesrc->stream,
1445 gst_pulsesrc_stream_underflow_cb, pulsesrc);
1446 pa_stream_set_overflow_callback (pulsesrc->stream,
1447 gst_pulsesrc_stream_overflow_cb, pulsesrc);
1448 pa_stream_set_latency_update_callback (pulsesrc->stream,
1449 gst_pulsesrc_stream_latency_update_cb, pulsesrc);
1451 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1458 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, SETTINGS,
1459 ("Can't parse caps."), (NULL));
1464 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, SETTINGS,
1465 ("Invalid sample specification."), (NULL));
1470 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Bad context"), (NULL));
1471 goto unlock_and_fail;
1475 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1476 ("Failed to create stream: %s",
1477 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1478 goto unlock_and_fail;
1482 gst_pulsesrc_destroy_stream (pulsesrc);
1484 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1492 gst_pulsesrc_event (GstBaseSrc * basesrc, GstEvent * event)
1494 GST_DEBUG_OBJECT (basesrc, "handle event %" GST_PTR_FORMAT, event);
1496 switch (GST_EVENT_TYPE (event)) {
1497 case GST_EVENT_RECONFIGURE:
1498 gst_pad_check_reconfigure (GST_BASE_SRC_PAD (basesrc));
1503 return GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
1506 /* This is essentially gst_base_src_negotiate_default() but the caps
1507 * are guaranteed to have a channel layout for > 2 channels
1510 gst_pulsesrc_negotiate (GstBaseSrc * basesrc)
1512 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (basesrc);
1514 GstCaps *caps = NULL;
1515 GstCaps *peercaps = NULL;
1516 gboolean result = FALSE;
1518 /* first see what is possible on our source pad */
1519 thiscaps = gst_pad_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
1520 GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
1521 /* nothing or anything is allowed, we're done */
1522 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
1523 goto no_nego_needed;
1525 /* get the peer caps */
1526 peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
1527 GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
1529 /* get intersection */
1530 caps = gst_caps_intersect (thiscaps, peercaps);
1531 GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, caps);
1532 gst_caps_unref (thiscaps);
1533 gst_caps_unref (peercaps);
1535 /* no peer, work with our own caps then */
1539 /* take first (and best, since they are sorted) possibility */
1540 caps = gst_caps_truncate (caps);
1543 if (!gst_caps_is_empty (caps)) {
1544 caps = GST_BASE_SRC_CLASS (parent_class)->fixate (basesrc, caps);
1545 GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
1547 if (gst_caps_is_any (caps)) {
1548 /* hmm, still anything, so element can do anything and
1549 * nego is not needed */
1551 } else if (gst_caps_is_fixed (caps)) {
1552 /* yay, fixed caps, use those then */
1553 result = gst_pulsesrc_create_stream (pulsesrc, &caps, NULL);
1555 result = gst_base_src_set_caps (basesrc, caps);
1558 gst_caps_unref (caps);
1564 GST_DEBUG_OBJECT (basesrc, "no negotiation needed");
1566 gst_caps_unref (thiscaps);
1572 gst_pulsesrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
1574 pa_buffer_attr wanted;
1575 const pa_buffer_attr *actual;
1576 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1577 pa_stream_flags_t flags;
1579 GstAudioClock *clock;
1581 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1583 if (!pulsesrc->stream)
1584 gst_pulsesrc_create_stream (pulsesrc, NULL, spec);
1587 GstAudioRingBufferSpec s = *spec;
1588 const pa_channel_map *m;
1590 m = pa_stream_get_channel_map (pulsesrc->stream);
1591 gst_pulse_channel_map_to_gst (m, &s);
1592 gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
1593 (pulsesrc)->ringbuffer, s.info.position);
1596 /* enable event notifications */
1597 GST_LOG_OBJECT (pulsesrc, "subscribing to context events");
1598 if (!(o = pa_context_subscribe (pulsesrc->context,
1599 PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, NULL, NULL))) {
1600 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1601 ("pa_context_subscribe() failed: %s",
1602 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1603 goto unlock_and_fail;
1606 pa_operation_unref (o);
1608 /* There's a bit of a disconnect here between the audio ringbuffer and what
1609 * PulseAudio provides. The audio ringbuffer provide a total of buffer_time
1610 * worth of buffering, divided into segments of latency_time size. We're
1611 * asking PulseAudio to provide a total latency of latency_time, which, with
1612 * PA_STREAM_ADJUST_LATENCY, effectively sets itself up as a ringbuffer with
1613 * one segment being the hardware buffer, and the other the software buffer.
1614 * This segment size is returned as the fragsize.
1616 * Since the two concepts don't map very well, what we do is keep segsize as
1617 * it is (unless fragsize is even larger, in which case we use that). We'll
1618 * get data from PulseAudio in smaller chunks than we want to pass on as an
1619 * element, and we coalesce those chunks in the ringbuffer memory and pass it
1620 * on in the expected chunk size. */
1621 wanted.maxlength = spec->segsize * spec->segtotal;
1622 wanted.tlength = -1;
1625 wanted.fragsize = spec->segsize;
1627 GST_INFO_OBJECT (pulsesrc, "maxlength: %d", wanted.maxlength);
1628 GST_INFO_OBJECT (pulsesrc, "tlength: %d", wanted.tlength);
1629 GST_INFO_OBJECT (pulsesrc, "prebuf: %d", wanted.prebuf);
1630 GST_INFO_OBJECT (pulsesrc, "minreq: %d", wanted.minreq);
1631 GST_INFO_OBJECT (pulsesrc, "fragsize: %d", wanted.fragsize);
1633 flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE |
1634 PA_STREAM_NOT_MONOTONIC | PA_STREAM_ADJUST_LATENCY |
1635 PA_STREAM_START_CORKED;
1637 if (pa_stream_connect_record (pulsesrc->stream, pulsesrc->device, &wanted,
1639 goto connect_failed;
1642 /* our clock will now start from 0 again */
1643 clock = GST_AUDIO_CLOCK (GST_AUDIO_BASE_SRC (pulsesrc)->clock);
1644 gst_audio_clock_reset (clock, 0);
1646 pulsesrc->corked = TRUE;
1649 pa_stream_state_t state;
1651 state = pa_stream_get_state (pulsesrc->stream);
1653 if (!PA_STREAM_IS_GOOD (state))
1656 if (state == PA_STREAM_READY)
1659 /* Wait until the stream is ready */
1660 pa_threaded_mainloop_wait (pulsesrc->mainloop);
1662 pulsesrc->stream_connected = TRUE;
1664 /* store the source output index so it can be accessed via a property */
1665 pulsesrc->source_output_idx = pa_stream_get_index (pulsesrc->stream);
1666 g_object_notify (G_OBJECT (pulsesrc), "source-output-index");
1668 /* Although source output stream muting is supported, there is a bug in
1669 * PulseAudio that doesn't allow us to do this at startup, so we mute
1670 * manually post-connect. This should be moved back pre-connect once things
1671 * are fixed on the PulseAudio side. */
1672 if (pulsesrc->mute_set && pulsesrc->mute) {
1673 gst_pulsesrc_set_stream_mute (pulsesrc, pulsesrc->mute);
1674 pulsesrc->mute_set = FALSE;
1677 if (pulsesrc->volume_set) {
1678 gst_pulsesrc_set_stream_volume (pulsesrc, pulsesrc->volume);
1679 pulsesrc->volume_set = FALSE;
1682 #ifdef PCM_DUMP_ENABLE
1683 if (pulsesrc->need_dump_output) {
1684 char *suffix , *dump_path;
1685 GDateTime *time = NULL;
1686 if (pulsesrc->dump_fd_output) {
1687 fclose(pulsesrc->dump_fd_output);
1688 pulsesrc->dump_fd_output = NULL;
1690 time = g_date_time_new_now_local();
1691 suffix = g_date_time_format(time, "%m%d_%H%M%S");
1692 dump_path = g_strdup_printf("%s_%dch_%dhz_%s.pcm", GST_PULSESRC_DUMP_OUTPUT_PATH_PREFIX, pulsesrc->sample_spec.channels, pulsesrc->sample_spec.rate, suffix);
1693 GST_WARNING_OBJECT(asrc,"pulse-source dumping enabled: dump path [%s]", dump_path);
1694 pulsesrc->dump_fd_output = fopen(dump_path, "w+");
1698 g_date_time_unref(time);
1700 #endif /* PCM_DUMP_ENABLE */
1703 /* get the actual buffering properties now */
1704 actual = pa_stream_get_buffer_attr (pulsesrc->stream);
1706 GST_INFO_OBJECT (pulsesrc, "maxlength: %d", actual->maxlength);
1707 GST_INFO_OBJECT (pulsesrc, "tlength: %d (wanted: %d)",
1708 actual->tlength, wanted.tlength);
1709 GST_INFO_OBJECT (pulsesrc, "prebuf: %d", actual->prebuf);
1710 GST_INFO_OBJECT (pulsesrc, "minreq: %d (wanted %d)", actual->minreq,
1712 GST_INFO_OBJECT (pulsesrc, "fragsize: %d (wanted %d)",
1713 actual->fragsize, wanted.fragsize);
1715 if (actual->fragsize >= spec->segsize) {
1716 spec->segsize = actual->fragsize;
1718 /* fragsize is smaller than what we wanted, so let the read function
1719 * coalesce the smaller chunks as they come in */
1722 /* Fix up the total ringbuffer size based on what we actually got */
1723 spec->segtotal = actual->maxlength / spec->segsize;
1724 /* Don't buffer less than 2 segments as the ringbuffer can't deal with it */
1725 if (spec->segtotal < 2)
1728 if (!pulsesrc->paused) {
1729 GST_DEBUG_OBJECT (pulsesrc, "uncorking because we are playing");
1730 gst_pulsesrc_set_corked (pulsesrc, FALSE, FALSE);
1732 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1739 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1740 ("Failed to connect stream: %s",
1741 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1742 goto unlock_and_fail;
1746 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1747 ("Failed to connect stream: %s",
1748 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1749 goto unlock_and_fail;
1753 gst_pulsesrc_destroy_stream (pulsesrc);
1755 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1761 gst_pulsesrc_success_cb (pa_stream * s, int success, void *userdata)
1763 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (userdata);
1765 pulsesrc->operation_success = ! !success;
1766 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
1770 gst_pulsesrc_reset (GstAudioSrc * asrc)
1772 GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
1773 pa_operation *o = NULL;
1775 pa_threaded_mainloop_lock (pulsesrc->mainloop);
1776 GST_DEBUG_OBJECT (pulsesrc, "reset");
1778 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
1779 goto unlock_and_fail;
1782 pa_stream_flush (pulsesrc->stream, gst_pulsesrc_success_cb,
1784 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
1785 ("pa_stream_flush() failed: %s",
1786 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1787 goto unlock_and_fail;
1790 pulsesrc->paused = TRUE;
1791 /* Inform anyone waiting in _write() call that it shall wakeup */
1792 if (pulsesrc->in_read) {
1793 pa_threaded_mainloop_signal (pulsesrc->mainloop, 0);
1796 pulsesrc->operation_success = FALSE;
1797 while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
1799 if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
1800 goto unlock_and_fail;
1802 pa_threaded_mainloop_wait (pulsesrc->mainloop);
1805 if (!pulsesrc->operation_success) {
1806 GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Flush failed: %s",
1807 pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
1808 goto unlock_and_fail;
1814 pa_operation_cancel (o);
1815 pa_operation_unref (o);
1818 pa_threaded_mainloop_unlock (pulsesrc->mainloop);
1821 /* update the corked state of a stream, must be called with the mainloop
1824 gst_pulsesrc_set_corked (GstPulseSrc * psrc, gboolean corked, gboolean wait)
1826 pa_operation *o = NULL;
1827 gboolean res = FALSE;
1829 GST_DEBUG_OBJECT (psrc, "setting corked state to %d", corked);
1830 if (!psrc->stream_connected)
1833 if (psrc->corked != corked) {
1834 if (!(o = pa_stream_cork (psrc->stream, corked,
1835 gst_pulsesrc_success_cb, psrc)))
1838 while (wait && pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
1839 pa_threaded_mainloop_wait (psrc->mainloop);
1840 if (gst_pulsesrc_is_dead (psrc, TRUE))
1843 psrc->corked = corked;
1845 GST_DEBUG_OBJECT (psrc, "skipping, already in requested state");
1851 pa_operation_unref (o);
1858 GST_DEBUG_OBJECT (psrc, "the server is dead");
1863 GST_ELEMENT_ERROR (psrc, RESOURCE, FAILED,
1864 ("pa_stream_cork() failed: %s",
1865 pa_strerror (pa_context_errno (psrc->context))), (NULL));
1870 /* start/resume playback ASAP */
1872 gst_pulsesrc_play (GstPulseSrc * psrc)
1874 pa_threaded_mainloop_lock (psrc->mainloop);
1875 GST_DEBUG_OBJECT (psrc, "playing");
1876 psrc->paused = FALSE;
1877 gst_pulsesrc_set_corked (psrc, FALSE, FALSE);
1878 pa_threaded_mainloop_unlock (psrc->mainloop);
1883 /* pause/stop playback ASAP */
1885 gst_pulsesrc_pause (GstPulseSrc * psrc)
1887 pa_threaded_mainloop_lock (psrc->mainloop);
1888 GST_DEBUG_OBJECT (psrc, "pausing");
1889 /* make sure the commit method stops writing */
1890 psrc->paused = TRUE;
1891 if (psrc->in_read) {
1892 /* we are waiting in a read, signal */
1893 GST_DEBUG_OBJECT (psrc, "signal read");
1894 pa_threaded_mainloop_signal (psrc->mainloop, 0);
1896 pa_threaded_mainloop_unlock (psrc->mainloop);
1901 static GstStateChangeReturn
1902 gst_pulsesrc_change_state (GstElement * element, GstStateChange transition)
1904 GstStateChangeReturn ret;
1905 GstPulseSrc *this = GST_PULSESRC_CAST (element);
1907 switch (transition) {
1908 case GST_STATE_CHANGE_NULL_TO_READY:
1909 if (!(this->mainloop = pa_threaded_mainloop_new ()))
1910 goto mainloop_failed;
1911 if (pa_threaded_mainloop_start (this->mainloop) < 0) {
1912 pa_threaded_mainloop_free (this->mainloop);
1913 this->mainloop = NULL;
1914 goto mainloop_start_failed;
1917 case GST_STATE_CHANGE_READY_TO_PAUSED:
1918 gst_element_post_message (element,
1919 gst_message_new_clock_provide (GST_OBJECT_CAST (element),
1920 GST_AUDIO_BASE_SRC (this)->clock, TRUE));
1922 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1923 /* uncork and start recording */
1924 gst_pulsesrc_play (this);
1926 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1927 /* stop recording ASAP by corking */
1928 pa_threaded_mainloop_lock (this->mainloop);
1929 GST_DEBUG_OBJECT (this, "corking");
1930 gst_pulsesrc_set_corked (this, TRUE, FALSE);
1931 pa_threaded_mainloop_unlock (this->mainloop);
1937 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1939 switch (transition) {
1940 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1941 /* now make sure we get out of the _read method */
1942 gst_pulsesrc_pause (this);
1944 case GST_STATE_CHANGE_READY_TO_NULL:
1946 pa_threaded_mainloop_stop (this->mainloop);
1948 gst_pulsesrc_destroy_context (this);
1950 if (this->mainloop) {
1951 pa_threaded_mainloop_free (this->mainloop);
1952 this->mainloop = NULL;
1955 case GST_STATE_CHANGE_PAUSED_TO_READY:
1956 /* format_lost is reset in release() in baseaudiosink */
1957 gst_element_post_message (element,
1958 gst_message_new_clock_lost (GST_OBJECT_CAST (element),
1959 GST_AUDIO_BASE_SRC (this)->clock));
1970 GST_ELEMENT_ERROR (this, RESOURCE, FAILED,
1971 ("pa_threaded_mainloop_new() failed"), (NULL));
1972 return GST_STATE_CHANGE_FAILURE;
1974 mainloop_start_failed:
1976 GST_ELEMENT_ERROR (this, RESOURCE, FAILED,
1977 ("pa_threaded_mainloop_start() failed"), (NULL));
1978 return GST_STATE_CHANGE_FAILURE;
1983 gst_pulsesrc_get_time (GstClock * clock, GstPulseSrc * src)
1987 if (src->mainloop == NULL)
1990 pa_threaded_mainloop_lock (src->mainloop);
1992 goto unlock_and_out;
1994 if (gst_pulsesrc_is_dead (src, TRUE))
1995 goto unlock_and_out;
1997 if (pa_stream_get_time (src->stream, &time) < 0) {
1998 GST_DEBUG_OBJECT (src, "could not get time");
1999 time = GST_CLOCK_TIME_NONE;
2006 pa_threaded_mainloop_unlock (src->mainloop);