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