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