c8989ced102742f7765b506e8209bc8b77019ea6
[platform/upstream/gst-plugins-base.git] / ext / alsa / gstalsasink.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
4  *
5  * gstalsasink.c:
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:element-alsasink
25  * @see_also: alsasrc
26  *
27  * This element renders raw audio samples using the ALSA audio API.
28  *
29  * <refsect2>
30  * <title>Example pipelines</title>
31  * |[
32  * gst-launch-1.0 -v uridecodebin uri=file:///path/to/audio.ogg ! audioconvert ! audioresample ! autoaudiosink
33  * ]| Play an Ogg/Vorbis file and output audio via ALSA.
34  * </refsect2>
35  */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40 #include <sys/ioctl.h>
41 #include <fcntl.h>
42 #include <errno.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <getopt.h>
46 #include <alsa/asoundlib.h>
47
48 #include "gstalsa.h"
49 #include "gstalsasink.h"
50 #include "gstalsadeviceprobe.h"
51
52 #include <gst/audio/gstaudioiec61937.h>
53 #include <gst/gst-i18n-plugin.h>
54
55 #ifndef ESTRPIPE
56 #define ESTRPIPE EPIPE
57 #endif
58
59 #define DEFAULT_DEVICE          "default"
60 #define DEFAULT_DEVICE_NAME     ""
61 #define DEFAULT_CARD_NAME       ""
62 #define SPDIF_PERIOD_SIZE 1536
63 #define SPDIF_BUFFER_SIZE 15360
64
65 enum
66 {
67   PROP_0,
68   PROP_DEVICE,
69   PROP_DEVICE_NAME,
70   PROP_CARD_NAME,
71   PROP_LAST
72 };
73
74 static void gst_alsasink_init_interfaces (GType type);
75 #define gst_alsasink_parent_class parent_class
76 G_DEFINE_TYPE_WITH_CODE (GstAlsaSink, gst_alsasink,
77     GST_TYPE_AUDIO_SINK, gst_alsasink_init_interfaces (g_define_type_id));
78
79 static void gst_alsasink_finalise (GObject * object);
80 static void gst_alsasink_set_property (GObject * object,
81     guint prop_id, const GValue * value, GParamSpec * pspec);
82 static void gst_alsasink_get_property (GObject * object,
83     guint prop_id, GValue * value, GParamSpec * pspec);
84
85 static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter);
86 static gboolean gst_alsasink_query (GstBaseSink * bsink, GstQuery * query);
87
88 static gboolean gst_alsasink_open (GstAudioSink * asink);
89 static gboolean gst_alsasink_prepare (GstAudioSink * asink,
90     GstAudioRingBufferSpec * spec);
91 static gboolean gst_alsasink_unprepare (GstAudioSink * asink);
92 static gboolean gst_alsasink_close (GstAudioSink * asink);
93 static gint gst_alsasink_write (GstAudioSink * asink, gpointer data,
94     guint length);
95 static guint gst_alsasink_delay (GstAudioSink * asink);
96 static void gst_alsasink_reset (GstAudioSink * asink);
97 static gboolean gst_alsasink_acceptcaps (GstAlsaSink * alsa, GstCaps * caps);
98 static GstBuffer *gst_alsasink_payload (GstAudioBaseSink * sink,
99     GstBuffer * buf);
100
101 static gint output_ref;         /* 0    */
102 static snd_output_t *output;    /* NULL */
103 static GMutex output_mutex;
104
105 static GstStaticPadTemplate alsasink_sink_factory =
106     GST_STATIC_PAD_TEMPLATE ("sink",
107     GST_PAD_SINK,
108     GST_PAD_ALWAYS,
109     GST_STATIC_CAPS ("audio/x-raw, "
110         "format = (string) " GST_AUDIO_FORMATS_ALL ", "
111         "layout = (string) interleaved, "
112         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]; "
113         PASSTHROUGH_CAPS)
114     );
115
116 static void
117 gst_alsasink_finalise (GObject * object)
118 {
119   GstAlsaSink *sink = GST_ALSA_SINK (object);
120
121   g_free (sink->device);
122   g_mutex_clear (&sink->alsa_lock);
123   g_mutex_clear (&sink->delay_lock);
124
125   g_mutex_lock (&output_mutex);
126   --output_ref;
127   if (output_ref == 0) {
128     snd_output_close (output);
129     output = NULL;
130   }
131   g_mutex_unlock (&output_mutex);
132
133   G_OBJECT_CLASS (parent_class)->finalize (object);
134 }
135
136 static void
137 gst_alsasink_init_interfaces (GType type)
138 {
139 #if 0
140   gst_alsa_type_add_device_property_probe_interface (type);
141 #endif
142 }
143
144 static void
145 gst_alsasink_class_init (GstAlsaSinkClass * klass)
146 {
147   GObjectClass *gobject_class;
148   GstElementClass *gstelement_class;
149   GstBaseSinkClass *gstbasesink_class;
150   GstAudioBaseSinkClass *gstbaseaudiosink_class;
151   GstAudioSinkClass *gstaudiosink_class;
152
153   gobject_class = (GObjectClass *) klass;
154   gstelement_class = (GstElementClass *) klass;
155   gstbasesink_class = (GstBaseSinkClass *) klass;
156   gstbaseaudiosink_class = (GstAudioBaseSinkClass *) klass;
157   gstaudiosink_class = (GstAudioSinkClass *) klass;
158
159   parent_class = g_type_class_peek_parent (klass);
160
161   gobject_class->finalize = gst_alsasink_finalise;
162   gobject_class->get_property = gst_alsasink_get_property;
163   gobject_class->set_property = gst_alsasink_set_property;
164
165   gst_element_class_set_static_metadata (gstelement_class,
166       "Audio sink (ALSA)", "Sink/Audio",
167       "Output to a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
168
169   gst_element_class_add_pad_template (gstelement_class,
170       gst_static_pad_template_get (&alsasink_sink_factory));
171
172   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
173   gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_alsasink_query);
174
175   gstbaseaudiosink_class->payload = GST_DEBUG_FUNCPTR (gst_alsasink_payload);
176
177   gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_alsasink_open);
178   gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_alsasink_prepare);
179   gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_alsasink_unprepare);
180   gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_alsasink_close);
181   gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_alsasink_write);
182   gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_alsasink_delay);
183   gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_alsasink_reset);
184
185   g_object_class_install_property (gobject_class, PROP_DEVICE,
186       g_param_spec_string ("device", "Device",
187           "ALSA device, as defined in an asound configuration file",
188           DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
189
190   g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
191       g_param_spec_string ("device-name", "Device name",
192           "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
193           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
194
195   g_object_class_install_property (gobject_class, PROP_CARD_NAME,
196       g_param_spec_string ("card-name", "Card name",
197           "Human-readable name of the sound card", DEFAULT_CARD_NAME,
198           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
199 }
200
201 static void
202 gst_alsasink_set_property (GObject * object, guint prop_id,
203     const GValue * value, GParamSpec * pspec)
204 {
205   GstAlsaSink *sink;
206
207   sink = GST_ALSA_SINK (object);
208
209   switch (prop_id) {
210     case PROP_DEVICE:
211       g_free (sink->device);
212       sink->device = g_value_dup_string (value);
213       /* setting NULL restores the default device */
214       if (sink->device == NULL) {
215         sink->device = g_strdup (DEFAULT_DEVICE);
216       }
217       break;
218     default:
219       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220       break;
221   }
222 }
223
224 static void
225 gst_alsasink_get_property (GObject * object, guint prop_id,
226     GValue * value, GParamSpec * pspec)
227 {
228   GstAlsaSink *sink;
229
230   sink = GST_ALSA_SINK (object);
231
232   switch (prop_id) {
233     case PROP_DEVICE:
234       g_value_set_string (value, sink->device);
235       break;
236     case PROP_DEVICE_NAME:
237       g_value_take_string (value,
238           gst_alsa_find_device_name (GST_OBJECT_CAST (sink),
239               sink->device, sink->handle, SND_PCM_STREAM_PLAYBACK));
240       break;
241     case PROP_CARD_NAME:
242       g_value_take_string (value,
243           gst_alsa_find_card_name (GST_OBJECT_CAST (sink),
244               sink->device, SND_PCM_STREAM_PLAYBACK));
245       break;
246     default:
247       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248       break;
249   }
250 }
251
252 static void
253 gst_alsasink_init (GstAlsaSink * alsasink)
254 {
255   GST_DEBUG_OBJECT (alsasink, "initializing alsasink");
256
257   alsasink->device = g_strdup (DEFAULT_DEVICE);
258   alsasink->handle = NULL;
259   alsasink->cached_caps = NULL;
260   g_mutex_init (&alsasink->alsa_lock);
261   g_mutex_init (&alsasink->delay_lock);
262
263   g_mutex_lock (&output_mutex);
264   if (output_ref == 0) {
265     snd_output_stdio_attach (&output, stdout, 0);
266     ++output_ref;
267   }
268   g_mutex_unlock (&output_mutex);
269 }
270
271 #define CHECK(call, error) \
272 G_STMT_START {             \
273   if ((err = call) < 0) {  \
274     GST_WARNING_OBJECT (alsa, "Error %d (%s) calling " #call, err, snd_strerror (err)); \
275     goto error;            \
276   }                        \
277 } G_STMT_END;
278
279 static GstCaps *
280 gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter)
281 {
282   GstElementClass *element_class;
283   GstPadTemplate *pad_template;
284   GstAlsaSink *sink = GST_ALSA_SINK (bsink);
285   GstCaps *caps, *templ_caps;
286
287   GST_OBJECT_LOCK (sink);
288   if (sink->handle == NULL) {
289     GST_OBJECT_UNLOCK (sink);
290     GST_DEBUG_OBJECT (sink, "device not open, using template caps");
291     return NULL;                /* base class will get template caps for us */
292   }
293
294   if (sink->cached_caps) {
295     if (filter) {
296       caps = gst_caps_intersect_full (filter, sink->cached_caps,
297           GST_CAPS_INTERSECT_FIRST);
298       GST_OBJECT_UNLOCK (sink);
299       GST_LOG_OBJECT (sink, "Returning cached caps %" GST_PTR_FORMAT " with "
300           "filter %" GST_PTR_FORMAT " applied: %" GST_PTR_FORMAT,
301           sink->cached_caps, filter, caps);
302       return caps;
303     } else {
304       caps = gst_caps_ref (sink->cached_caps);
305       GST_OBJECT_UNLOCK (sink);
306       GST_LOG_OBJECT (sink, "Returning cached caps %" GST_PTR_FORMAT, caps);
307       return caps;
308     }
309   }
310
311   element_class = GST_ELEMENT_GET_CLASS (sink);
312   pad_template = gst_element_class_get_pad_template (element_class, "sink");
313   if (pad_template == NULL) {
314     GST_OBJECT_UNLOCK (sink);
315     g_assert_not_reached ();
316     return NULL;
317   }
318
319   templ_caps = gst_pad_template_get_caps (pad_template);
320   caps = gst_alsa_probe_supported_formats (GST_OBJECT (sink), sink->device,
321       sink->handle, templ_caps);
322   gst_caps_unref (templ_caps);
323
324   if (caps) {
325     sink->cached_caps = gst_caps_ref (caps);
326   }
327
328   GST_OBJECT_UNLOCK (sink);
329
330   GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);
331
332   if (filter) {
333     GstCaps *intersection;
334
335     intersection =
336         gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
337     gst_caps_unref (caps);
338     return intersection;
339   } else {
340     return caps;
341   }
342 }
343
344 static gboolean
345 gst_alsasink_acceptcaps (GstAlsaSink * alsa, GstCaps * caps)
346 {
347   GstPad *pad = GST_BASE_SINK (alsa)->sinkpad;
348   GstCaps *pad_caps;
349   GstStructure *st;
350   gboolean ret = FALSE;
351   GstAudioRingBufferSpec spec = { 0 };
352
353   pad_caps = gst_pad_query_caps (pad, caps);
354   if (!pad_caps || gst_caps_is_empty (pad_caps)) {
355     if (pad_caps)
356       gst_caps_unref (pad_caps);
357     ret = FALSE;
358     goto done;
359   }
360   gst_caps_unref (pad_caps);
361
362   /* If we've not got fixed caps, creating a stream might fail, so let's just
363    * return from here with default acceptcaps behaviour */
364   if (!gst_caps_is_fixed (caps))
365     goto done;
366
367   /* parse helper expects this set, so avoid nasty warning
368    * will be set properly later on anyway  */
369   spec.latency_time = GST_SECOND;
370   if (!gst_audio_ring_buffer_parse_caps (&spec, caps))
371     goto done;
372
373   /* Make sure input is framed (one frame per buffer) and can be payloaded */
374   switch (spec.type) {
375     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3:
376     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3:
377     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
378     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG:
379     {
380       gboolean framed = FALSE, parsed = FALSE;
381       st = gst_caps_get_structure (caps, 0);
382
383       gst_structure_get_boolean (st, "framed", &framed);
384       gst_structure_get_boolean (st, "parsed", &parsed);
385       if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0)
386         goto done;
387     }
388     default:{
389     }
390   }
391   ret = TRUE;
392
393 done:
394   gst_caps_replace (&spec.caps, NULL);
395   return ret;
396 }
397
398 static gboolean
399 gst_alsasink_query (GstBaseSink * sink, GstQuery * query)
400 {
401   GstAlsaSink *alsa = GST_ALSA_SINK (sink);
402   gboolean ret;
403
404   switch (GST_QUERY_TYPE (query)) {
405     case GST_QUERY_ACCEPT_CAPS:
406     {
407       GstCaps *caps;
408
409       gst_query_parse_accept_caps (query, &caps);
410       ret = gst_alsasink_acceptcaps (alsa, caps);
411       gst_query_set_accept_caps_result (query, ret);
412       ret = TRUE;
413       break;
414     }
415     default:
416       ret = GST_BASE_SINK_CLASS (parent_class)->query (sink, query);
417       break;
418   }
419   return ret;
420 }
421
422 static int
423 set_hwparams (GstAlsaSink * alsa)
424 {
425   guint rrate;
426   gint err;
427   snd_pcm_hw_params_t *params;
428   guint period_time, buffer_time;
429
430   snd_pcm_hw_params_malloc (&params);
431
432   GST_DEBUG_OBJECT (alsa, "Negotiating to %d channels @ %d Hz (format = %s) "
433       "SPDIF (%d)", alsa->channels, alsa->rate,
434       snd_pcm_format_name (alsa->format), alsa->iec958);
435
436   /* start with requested values, if we cannot configure alsa for those values,
437    * we set these values to -1, which will leave the default alsa values */
438   buffer_time = alsa->buffer_time;
439   period_time = alsa->period_time;
440
441 retry:
442   /* choose all parameters */
443   CHECK (snd_pcm_hw_params_any (alsa->handle, params), no_config);
444   /* set the interleaved read/write format */
445   CHECK (snd_pcm_hw_params_set_access (alsa->handle, params, alsa->access),
446       wrong_access);
447   /* set the sample format */
448   if (alsa->iec958) {
449     /* Try to use big endian first else fallback to le and swap bytes */
450     if (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format) < 0) {
451       alsa->format = SND_PCM_FORMAT_S16_LE;
452       alsa->need_swap = TRUE;
453       GST_DEBUG_OBJECT (alsa, "falling back to little endian with swapping");
454     } else {
455       alsa->need_swap = FALSE;
456     }
457   }
458   CHECK (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format),
459       no_sample_format);
460   /* set the count of channels */
461   CHECK (snd_pcm_hw_params_set_channels (alsa->handle, params, alsa->channels),
462       no_channels);
463   /* set the stream rate */
464   rrate = alsa->rate;
465   CHECK (snd_pcm_hw_params_set_rate_near (alsa->handle, params, &rrate, NULL),
466       no_rate);
467
468 #ifndef GST_DISABLE_GST_DEBUG
469   /* get and dump some limits */
470   {
471     guint min, max;
472
473     snd_pcm_hw_params_get_buffer_time_min (params, &min, NULL);
474     snd_pcm_hw_params_get_buffer_time_max (params, &max, NULL);
475
476     GST_DEBUG_OBJECT (alsa, "buffer time %u, min %u, max %u",
477         alsa->buffer_time, min, max);
478
479     snd_pcm_hw_params_get_period_time_min (params, &min, NULL);
480     snd_pcm_hw_params_get_period_time_max (params, &max, NULL);
481
482     GST_DEBUG_OBJECT (alsa, "period time %u, min %u, max %u",
483         alsa->period_time, min, max);
484
485     snd_pcm_hw_params_get_periods_min (params, &min, NULL);
486     snd_pcm_hw_params_get_periods_max (params, &max, NULL);
487
488     GST_DEBUG_OBJECT (alsa, "periods min %u, max %u", min, max);
489   }
490 #endif
491
492   /* now try to configure the buffer time and period time, if one
493    * of those fail, we fall back to the defaults and emit a warning. */
494   if (buffer_time != -1 && !alsa->iec958) {
495     /* set the buffer time */
496     if ((err = snd_pcm_hw_params_set_buffer_time_near (alsa->handle, params,
497                 &buffer_time, NULL)) < 0) {
498       GST_ELEMENT_WARNING (alsa, RESOURCE, SETTINGS, (NULL),
499           ("Unable to set buffer time %i for playback: %s",
500               buffer_time, snd_strerror (err)));
501       /* disable buffer_time the next round */
502       buffer_time = -1;
503       goto retry;
504     }
505     GST_DEBUG_OBJECT (alsa, "buffer time %u", buffer_time);
506     alsa->buffer_time = buffer_time;
507   }
508   if (period_time != -1 && !alsa->iec958) {
509     /* set the period time */
510     if ((err = snd_pcm_hw_params_set_period_time_near (alsa->handle, params,
511                 &period_time, NULL)) < 0) {
512       GST_ELEMENT_WARNING (alsa, RESOURCE, SETTINGS, (NULL),
513           ("Unable to set period time %i for playback: %s",
514               period_time, snd_strerror (err)));
515       /* disable period_time the next round */
516       period_time = -1;
517       goto retry;
518     }
519     GST_DEBUG_OBJECT (alsa, "period time %u", period_time);
520     alsa->period_time = period_time;
521   }
522
523   /* Set buffer size and period size manually for SPDIF */
524   if (G_UNLIKELY (alsa->iec958)) {
525     snd_pcm_uframes_t buffer_size = SPDIF_BUFFER_SIZE;
526     snd_pcm_uframes_t period_size = SPDIF_PERIOD_SIZE;
527
528     CHECK (snd_pcm_hw_params_set_buffer_size_near (alsa->handle, params,
529             &buffer_size), buffer_size);
530     CHECK (snd_pcm_hw_params_set_period_size_near (alsa->handle, params,
531             &period_size, NULL), period_size);
532   }
533
534   /* write the parameters to device */
535   CHECK (snd_pcm_hw_params (alsa->handle, params), set_hw_params);
536
537   /* now get the configured values */
538   CHECK (snd_pcm_hw_params_get_buffer_size (params, &alsa->buffer_size),
539       buffer_size);
540   CHECK (snd_pcm_hw_params_get_period_size (params, &alsa->period_size, NULL),
541       period_size);
542
543   GST_DEBUG_OBJECT (alsa, "buffer size %lu, period size %lu", alsa->buffer_size,
544       alsa->period_size);
545
546   snd_pcm_hw_params_free (params);
547   return 0;
548
549   /* ERRORS */
550 no_config:
551   {
552     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
553         ("Broken configuration for playback: no configurations available: %s",
554             snd_strerror (err)));
555     snd_pcm_hw_params_free (params);
556     return err;
557   }
558 wrong_access:
559   {
560     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
561         ("Access type not available for playback: %s", snd_strerror (err)));
562     snd_pcm_hw_params_free (params);
563     return err;
564   }
565 no_sample_format:
566   {
567     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
568         ("Sample format not available for playback: %s", snd_strerror (err)));
569     snd_pcm_hw_params_free (params);
570     return err;
571   }
572 no_channels:
573   {
574     gchar *msg = NULL;
575
576     if ((alsa->channels) == 1)
577       msg = g_strdup (_("Could not open device for playback in mono mode."));
578     if ((alsa->channels) == 2)
579       msg = g_strdup (_("Could not open device for playback in stereo mode."));
580     if ((alsa->channels) > 2)
581       msg =
582           g_strdup_printf (_
583           ("Could not open device for playback in %d-channel mode."),
584           alsa->channels);
585     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, ("%s", msg),
586         ("%s", snd_strerror (err)));
587     g_free (msg);
588     snd_pcm_hw_params_free (params);
589     return err;
590   }
591 no_rate:
592   {
593     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
594         ("Rate %iHz not available for playback: %s",
595             alsa->rate, snd_strerror (err)));
596     return err;
597   }
598 buffer_size:
599   {
600     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
601         ("Unable to get buffer size for playback: %s", snd_strerror (err)));
602     snd_pcm_hw_params_free (params);
603     return err;
604   }
605 period_size:
606   {
607     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
608         ("Unable to get period size for playback: %s", snd_strerror (err)));
609     snd_pcm_hw_params_free (params);
610     return err;
611   }
612 set_hw_params:
613   {
614     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
615         ("Unable to set hw params for playback: %s", snd_strerror (err)));
616     snd_pcm_hw_params_free (params);
617     return err;
618   }
619 }
620
621 static int
622 set_swparams (GstAlsaSink * alsa)
623 {
624   int err;
625   snd_pcm_sw_params_t *params;
626
627   snd_pcm_sw_params_malloc (&params);
628
629   /* get the current swparams */
630   CHECK (snd_pcm_sw_params_current (alsa->handle, params), no_config);
631   /* start the transfer when the buffer is almost full: */
632   /* (buffer_size / avail_min) * avail_min */
633   CHECK (snd_pcm_sw_params_set_start_threshold (alsa->handle, params,
634           (alsa->buffer_size / alsa->period_size) * alsa->period_size),
635       start_threshold);
636
637   /* allow the transfer when at least period_size samples can be processed */
638   CHECK (snd_pcm_sw_params_set_avail_min (alsa->handle, params,
639           alsa->period_size), set_avail);
640
641 #if GST_CHECK_ALSA_VERSION(1,0,16)
642   /* snd_pcm_sw_params_set_xfer_align() is deprecated, alignment is always 1 */
643 #else
644   /* align all transfers to 1 sample */
645   CHECK (snd_pcm_sw_params_set_xfer_align (alsa->handle, params, 1), set_align);
646 #endif
647
648   /* write the parameters to the playback device */
649   CHECK (snd_pcm_sw_params (alsa->handle, params), set_sw_params);
650
651   snd_pcm_sw_params_free (params);
652   return 0;
653
654   /* ERRORS */
655 no_config:
656   {
657     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
658         ("Unable to determine current swparams for playback: %s",
659             snd_strerror (err)));
660     snd_pcm_sw_params_free (params);
661     return err;
662   }
663 start_threshold:
664   {
665     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
666         ("Unable to set start threshold mode for playback: %s",
667             snd_strerror (err)));
668     snd_pcm_sw_params_free (params);
669     return err;
670   }
671 set_avail:
672   {
673     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
674         ("Unable to set avail min for playback: %s", snd_strerror (err)));
675     snd_pcm_sw_params_free (params);
676     return err;
677   }
678 #if !GST_CHECK_ALSA_VERSION(1,0,16)
679 set_align:
680   {
681     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
682         ("Unable to set transfer align for playback: %s", snd_strerror (err)));
683     snd_pcm_sw_params_free (params);
684     return err;
685   }
686 #endif
687 set_sw_params:
688   {
689     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
690         ("Unable to set sw params for playback: %s", snd_strerror (err)));
691     snd_pcm_sw_params_free (params);
692     return err;
693   }
694 }
695
696 static gboolean
697 alsasink_parse_spec (GstAlsaSink * alsa, GstAudioRingBufferSpec * spec)
698 {
699   /* Initialize our boolean */
700   alsa->iec958 = FALSE;
701
702   switch (spec->type) {
703     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW:
704       switch (GST_AUDIO_INFO_FORMAT (&spec->info)) {
705         case GST_AUDIO_FORMAT_U8:
706           alsa->format = SND_PCM_FORMAT_U8;
707           break;
708         case GST_AUDIO_FORMAT_S8:
709           alsa->format = SND_PCM_FORMAT_S8;
710           break;
711         case GST_AUDIO_FORMAT_S16LE:
712           alsa->format = SND_PCM_FORMAT_S16_LE;
713           break;
714         case GST_AUDIO_FORMAT_S16BE:
715           alsa->format = SND_PCM_FORMAT_S16_BE;
716           break;
717         case GST_AUDIO_FORMAT_U16LE:
718           alsa->format = SND_PCM_FORMAT_U16_LE;
719           break;
720         case GST_AUDIO_FORMAT_U16BE:
721           alsa->format = SND_PCM_FORMAT_U16_BE;
722           break;
723         case GST_AUDIO_FORMAT_S24_32LE:
724           alsa->format = SND_PCM_FORMAT_S24_LE;
725           break;
726         case GST_AUDIO_FORMAT_S24_32BE:
727           alsa->format = SND_PCM_FORMAT_S24_BE;
728           break;
729         case GST_AUDIO_FORMAT_U24_32LE:
730           alsa->format = SND_PCM_FORMAT_U24_LE;
731           break;
732         case GST_AUDIO_FORMAT_U24_32BE:
733           alsa->format = SND_PCM_FORMAT_U24_BE;
734           break;
735         case GST_AUDIO_FORMAT_S32LE:
736           alsa->format = SND_PCM_FORMAT_S32_LE;
737           break;
738         case GST_AUDIO_FORMAT_S32BE:
739           alsa->format = SND_PCM_FORMAT_S32_BE;
740           break;
741         case GST_AUDIO_FORMAT_U32LE:
742           alsa->format = SND_PCM_FORMAT_U32_LE;
743           break;
744         case GST_AUDIO_FORMAT_U32BE:
745           alsa->format = SND_PCM_FORMAT_U32_BE;
746           break;
747         case GST_AUDIO_FORMAT_S24LE:
748           alsa->format = SND_PCM_FORMAT_S24_3LE;
749           break;
750         case GST_AUDIO_FORMAT_S24BE:
751           alsa->format = SND_PCM_FORMAT_S24_3BE;
752           break;
753         case GST_AUDIO_FORMAT_U24LE:
754           alsa->format = SND_PCM_FORMAT_U24_3LE;
755           break;
756         case GST_AUDIO_FORMAT_U24BE:
757           alsa->format = SND_PCM_FORMAT_U24_3BE;
758           break;
759         case GST_AUDIO_FORMAT_S20LE:
760           alsa->format = SND_PCM_FORMAT_S20_3LE;
761           break;
762         case GST_AUDIO_FORMAT_S20BE:
763           alsa->format = SND_PCM_FORMAT_S20_3BE;
764           break;
765         case GST_AUDIO_FORMAT_U20LE:
766           alsa->format = SND_PCM_FORMAT_U20_3LE;
767           break;
768         case GST_AUDIO_FORMAT_U20BE:
769           alsa->format = SND_PCM_FORMAT_U20_3BE;
770           break;
771         case GST_AUDIO_FORMAT_S18LE:
772           alsa->format = SND_PCM_FORMAT_S18_3LE;
773           break;
774         case GST_AUDIO_FORMAT_S18BE:
775           alsa->format = SND_PCM_FORMAT_S18_3BE;
776           break;
777         case GST_AUDIO_FORMAT_U18LE:
778           alsa->format = SND_PCM_FORMAT_U18_3LE;
779           break;
780         case GST_AUDIO_FORMAT_U18BE:
781           alsa->format = SND_PCM_FORMAT_U18_3BE;
782           break;
783         case GST_AUDIO_FORMAT_F32LE:
784           alsa->format = SND_PCM_FORMAT_FLOAT_LE;
785           break;
786         case GST_AUDIO_FORMAT_F32BE:
787           alsa->format = SND_PCM_FORMAT_FLOAT_BE;
788           break;
789         case GST_AUDIO_FORMAT_F64LE:
790           alsa->format = SND_PCM_FORMAT_FLOAT64_LE;
791           break;
792         case GST_AUDIO_FORMAT_F64BE:
793           alsa->format = SND_PCM_FORMAT_FLOAT64_BE;
794           break;
795         default:
796           goto error;
797       }
798       break;
799     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW:
800       alsa->format = SND_PCM_FORMAT_A_LAW;
801       break;
802     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW:
803       alsa->format = SND_PCM_FORMAT_MU_LAW;
804       break;
805     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3:
806     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3:
807     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
808     case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG:
809       alsa->format = SND_PCM_FORMAT_S16_BE;
810       alsa->iec958 = TRUE;
811       break;
812     default:
813       goto error;
814
815   }
816   alsa->rate = GST_AUDIO_INFO_RATE (&spec->info);
817   alsa->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
818   alsa->buffer_time = spec->buffer_time;
819   alsa->period_time = spec->latency_time;
820   alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED;
821
822   if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9)
823     gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
824         (alsa)->ringbuffer, alsa_position[alsa->channels - 1]);
825
826   return TRUE;
827
828   /* ERRORS */
829 error:
830   {
831     return FALSE;
832   }
833 }
834
835 static gboolean
836 gst_alsasink_open (GstAudioSink * asink)
837 {
838   GstAlsaSink *alsa;
839   gint err;
840
841   alsa = GST_ALSA_SINK (asink);
842
843   /* open in non-blocking mode, we'll use snd_pcm_wait() for space to become
844    * available. */
845   CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_PLAYBACK,
846           SND_PCM_NONBLOCK), open_error);
847   GST_LOG_OBJECT (alsa, "Opened device %s", alsa->device);
848
849   return TRUE;
850
851   /* ERRORS */
852 open_error:
853   {
854     if (err == -EBUSY) {
855       GST_ELEMENT_ERROR (alsa, RESOURCE, BUSY,
856           (_("Could not open audio device for playback. "
857                   "Device is being used by another application.")),
858           ("Device '%s' is busy", alsa->device));
859     } else {
860       GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE,
861           (_("Could not open audio device for playback.")),
862           ("Playback open error on device '%s': %s", alsa->device,
863               snd_strerror (err)));
864     }
865     return FALSE;
866   }
867 }
868
869 static gboolean
870 gst_alsasink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
871 {
872   GstAlsaSink *alsa;
873   gint err;
874
875   alsa = GST_ALSA_SINK (asink);
876
877   if (alsa->iec958) {
878     snd_pcm_close (alsa->handle);
879     alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device);
880     if (G_UNLIKELY (!alsa->handle)) {
881       goto no_iec958;
882     }
883   }
884
885   if (!alsasink_parse_spec (alsa, spec))
886     goto spec_parse;
887
888   CHECK (set_hwparams (alsa), hw_params_failed);
889   CHECK (set_swparams (alsa), sw_params_failed);
890
891   alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
892   spec->segsize = alsa->period_size * alsa->bpf;
893   spec->segtotal = alsa->buffer_size / alsa->period_size;
894
895   {
896     snd_output_t *out_buf = NULL;
897     char *msg = NULL;
898
899     snd_output_buffer_open (&out_buf);
900     snd_pcm_dump_hw_setup (alsa->handle, out_buf);
901     snd_output_buffer_string (out_buf, &msg);
902     GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
903     snd_output_close (out_buf);
904     snd_output_buffer_open (&out_buf);
905     snd_pcm_dump_sw_setup (alsa->handle, out_buf);
906     snd_output_buffer_string (out_buf, &msg);
907     GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
908     snd_output_close (out_buf);
909   }
910
911 #ifdef SND_CHMAP_API_VERSION
912   if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) {
913     snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle);
914     if (chmap && chmap->channels == alsa->channels) {
915       GstAudioChannelPosition pos[8];
916       if (alsa_chmap_to_channel_positions (chmap, pos))
917         gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
918             (alsa)->ringbuffer, pos);
919     }
920     free (chmap);
921   }
922 #endif /* SND_CHMAP_API_VERSION */
923
924   return TRUE;
925
926   /* ERRORS */
927 no_iec958:
928   {
929     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL),
930         ("Could not open IEC958 (SPDIF) device for playback"));
931     return FALSE;
932   }
933 spec_parse:
934   {
935     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
936         ("Error parsing spec"));
937     return FALSE;
938   }
939 hw_params_failed:
940   {
941     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
942         ("Setting of hwparams failed: %s", snd_strerror (err)));
943     return FALSE;
944   }
945 sw_params_failed:
946   {
947     GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
948         ("Setting of swparams failed: %s", snd_strerror (err)));
949     return FALSE;
950   }
951 }
952
953 static gboolean
954 gst_alsasink_unprepare (GstAudioSink * asink)
955 {
956   GstAlsaSink *alsa;
957
958   alsa = GST_ALSA_SINK (asink);
959
960   snd_pcm_drop (alsa->handle);
961   snd_pcm_hw_free (alsa->handle);
962
963   return TRUE;
964 }
965
966 static gboolean
967 gst_alsasink_close (GstAudioSink * asink)
968 {
969   GstAlsaSink *alsa = GST_ALSA_SINK (asink);
970
971   GST_OBJECT_LOCK (asink);
972   if (alsa->handle) {
973     snd_pcm_close (alsa->handle);
974     alsa->handle = NULL;
975   }
976   gst_caps_replace (&alsa->cached_caps, NULL);
977   GST_OBJECT_UNLOCK (asink);
978
979   return TRUE;
980 }
981
982
983 /*
984  *   Underrun and suspend recovery
985  */
986 static gint
987 xrun_recovery (GstAlsaSink * alsa, snd_pcm_t * handle, gint err)
988 {
989   GST_WARNING_OBJECT (alsa, "xrun recovery %d: %s", err, g_strerror (-err));
990
991   if (err == -EPIPE) {          /* under-run */
992     err = snd_pcm_prepare (handle);
993     if (err < 0)
994       GST_WARNING_OBJECT (alsa,
995           "Can't recover from underrun, prepare failed: %s",
996           snd_strerror (err));
997     gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa));
998     return 0;
999   } else if (err == -ESTRPIPE) {
1000     while ((err = snd_pcm_resume (handle)) == -EAGAIN)
1001       g_usleep (100);           /* wait until the suspend flag is released */
1002
1003     if (err < 0) {
1004       err = snd_pcm_prepare (handle);
1005       if (err < 0)
1006         GST_WARNING_OBJECT (alsa,
1007             "Can't recover from suspend, prepare failed: %s",
1008             snd_strerror (err));
1009     }
1010     if (err == 0)
1011       gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa));
1012     return 0;
1013   }
1014   return err;
1015 }
1016
1017 static gint
1018 gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
1019 {
1020   GstAlsaSink *alsa;
1021   gint err;
1022   gint cptr;
1023   guint8 *ptr = data;
1024
1025   alsa = GST_ALSA_SINK (asink);
1026
1027   if (alsa->iec958 && alsa->need_swap) {
1028     guint i;
1029     guint16 *ptr_tmp = (guint16 *) ptr;
1030
1031     GST_DEBUG_OBJECT (asink, "swapping bytes");
1032     for (i = 0; i < length / 2; i++) {
1033       ptr_tmp[i] = GUINT16_SWAP_LE_BE (ptr_tmp[i]);
1034     }
1035   }
1036
1037   GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length);
1038
1039   cptr = length / alsa->bpf;
1040
1041   GST_ALSA_SINK_LOCK (asink);
1042   while (cptr > 0) {
1043     /* start by doing a blocking wait for free space. Set the timeout
1044      * to 4 times the period time */
1045     err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
1046     if (err < 0) {
1047       GST_DEBUG_OBJECT (asink, "wait error, %d", err);
1048     } else {
1049       GST_DELAY_SINK_LOCK (asink);
1050       err = snd_pcm_writei (alsa->handle, ptr, cptr);
1051       GST_DELAY_SINK_UNLOCK (asink);
1052     }
1053
1054     GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
1055     if (err < 0) {
1056       GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
1057       if (err == -EAGAIN) {
1058         continue;
1059       } else if (err == -ENODEV) {
1060         goto device_disappeared;
1061       } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
1062         goto write_error;
1063       }
1064       continue;
1065     }
1066
1067     ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
1068     cptr -= err;
1069   }
1070   GST_ALSA_SINK_UNLOCK (asink);
1071
1072   return length - (cptr * alsa->bpf);
1073
1074 write_error:
1075   {
1076     GST_ALSA_SINK_UNLOCK (asink);
1077     return length;              /* skip one period */
1078   }
1079 device_disappeared:
1080   {
1081     GST_ELEMENT_ERROR (asink, RESOURCE, WRITE,
1082         (_("Error outputting to audio device. "
1083                 "The device has been disconnected.")), (NULL));
1084     goto write_error;
1085   }
1086 }
1087
1088 static guint
1089 gst_alsasink_delay (GstAudioSink * asink)
1090 {
1091   GstAlsaSink *alsa;
1092   snd_pcm_sframes_t delay;
1093   int res;
1094
1095   alsa = GST_ALSA_SINK (asink);
1096
1097   GST_DELAY_SINK_LOCK (asink);
1098   res = snd_pcm_delay (alsa->handle, &delay);
1099   GST_DELAY_SINK_UNLOCK (asink);
1100   if (G_UNLIKELY (res < 0)) {
1101     /* on errors, report 0 delay */
1102     GST_DEBUG_OBJECT (alsa, "snd_pcm_delay returned %d", res);
1103     delay = 0;
1104   }
1105   if (G_UNLIKELY (delay < 0)) {
1106     /* make sure we never return a negative delay */
1107     GST_WARNING_OBJECT (alsa, "snd_pcm_delay returned negative delay");
1108     delay = 0;
1109   }
1110
1111   return delay;
1112 }
1113
1114 static void
1115 gst_alsasink_reset (GstAudioSink * asink)
1116 {
1117   GstAlsaSink *alsa;
1118   gint err;
1119
1120   alsa = GST_ALSA_SINK (asink);
1121
1122   GST_ALSA_SINK_LOCK (asink);
1123   GST_DEBUG_OBJECT (alsa, "drop");
1124   CHECK (snd_pcm_drop (alsa->handle), drop_error);
1125   GST_DEBUG_OBJECT (alsa, "prepare");
1126   CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
1127   GST_DEBUG_OBJECT (alsa, "reset done");
1128   GST_ALSA_SINK_UNLOCK (asink);
1129
1130   return;
1131
1132   /* ERRORS */
1133 drop_error:
1134   {
1135     GST_ERROR_OBJECT (alsa, "alsa-reset: pcm drop error: %s",
1136         snd_strerror (err));
1137     GST_ALSA_SINK_UNLOCK (asink);
1138     return;
1139   }
1140 prepare_error:
1141   {
1142     GST_ERROR_OBJECT (alsa, "alsa-reset: pcm prepare error: %s",
1143         snd_strerror (err));
1144     GST_ALSA_SINK_UNLOCK (asink);
1145     return;
1146   }
1147 }
1148
1149 static GstBuffer *
1150 gst_alsasink_payload (GstAudioBaseSink * sink, GstBuffer * buf)
1151 {
1152   GstAlsaSink *alsa;
1153
1154   alsa = GST_ALSA_SINK (sink);
1155
1156   if (alsa->iec958) {
1157     GstBuffer *out;
1158     gint framesize;
1159     GstMapInfo iinfo, oinfo;
1160
1161     framesize = gst_audio_iec61937_frame_size (&sink->ringbuffer->spec);
1162     if (framesize <= 0)
1163       return NULL;
1164
1165     out = gst_buffer_new_and_alloc (framesize);
1166
1167     gst_buffer_map (buf, &iinfo, GST_MAP_READ);
1168     gst_buffer_map (out, &oinfo, GST_MAP_WRITE);
1169
1170     if (!gst_audio_iec61937_payload (iinfo.data, iinfo.size,
1171             oinfo.data, oinfo.size, &sink->ringbuffer->spec, G_BIG_ENDIAN)) {
1172       gst_buffer_unref (out);
1173       return NULL;
1174     }
1175
1176     gst_buffer_unmap (buf, &iinfo);
1177     gst_buffer_unmap (out, &oinfo);
1178
1179     gst_buffer_copy_into (out, buf, GST_BUFFER_COPY_METADATA, 0, -1);
1180     return out;
1181   }
1182
1183   return gst_buffer_ref (buf);
1184 }