alsasink: fix iec958 format detection
Add specific function that first close the current pcm device
before trying to re-open it with AES parameters.
https://bugzilla.gnome.org/show_bug.cgi?id=757258
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c
index 5aae50c..d49a2ff 100644
--- a/ext/alsa/gstalsa.c
+++ b/ext/alsa/gstalsa.c
@@ -496,7 +496,6 @@
snd_pcm_t * handle, const GstCaps * template_caps)
{
snd_pcm_hw_params_t *hw_params;
- snd_pcm_stream_t stream_type;
GstCaps *caps;
gint err;
@@ -504,8 +503,6 @@
if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0)
goto error;
- stream_type = snd_pcm_stream (handle);
-
caps = gst_alsa_detect_formats (obj, hw_params,
gst_caps_copy (template_caps), G_BYTE_ORDER);
@@ -527,17 +524,6 @@
if (!(caps = gst_alsa_detect_channels (obj, hw_params, caps)))
goto subroutine_error;
- /* Try opening IEC958 device to see if we can support that format (playback
- * only for now but we could add SPDIF capture later) */
- if (stream_type == SND_PCM_STREAM_PLAYBACK) {
- snd_pcm_t *pcm = gst_alsa_open_iec958_pcm (obj, device);
-
- if (G_LIKELY (pcm)) {
- gst_caps_append (caps, gst_caps_from_string (PASSTHROUGH_CAPS));
- snd_pcm_close (pcm);
- }
- }
-
snd_pcm_hw_params_free (hw_params);
return caps;
@@ -557,6 +543,53 @@
}
}
+/*
+ * gst_alsa_probe_supported_formats:
+ *
+ * Takes the template caps and returns the subset which is actually
+ * supported by this device.
+ */
+gboolean gst_alsa_iec958_formats_supported (GstObject * obj, gchar * device,
+ snd_pcm_t ** handle)
+{
+ snd_pcm_stream_t stream_type;
+ gboolean supported = FALSE;
+ snd_pcm_t *pcm;
+ gint err;
+
+ /* Try opening IEC958 device to see if we can support that format (playback
+ * only for now but we could add SPDIF capture later) */
+ stream_type = snd_pcm_stream (*handle);
+ if (stream_type == SND_PCM_STREAM_PLAYBACK) {
+ /* Close the exiting device to re-open it as iec958 device*/
+ err = snd_pcm_close(*handle);
+ if (G_UNLIKELY (err < 0)) {
+ GST_DEBUG_OBJECT (obj, " failed closing alsa device: %s",
+ snd_strerror (err));
+ return FALSE;
+ }
+
+ pcm = gst_alsa_open_iec958_pcm(GST_OBJECT (obj), device);
+ if (G_LIKELY (pcm)) {
+ supported = TRUE;
+ snd_pcm_close (pcm);
+ }
+
+ /* Reopen device in raw audio mode*/
+ err = snd_pcm_open (handle, device, SND_PCM_STREAM_PLAYBACK,
+ SND_PCM_NONBLOCK);
+ if (G_UNLIKELY (err < 0)) {
+ GST_DEBUG_OBJECT (obj, "failed re-opening alsa device: %s",
+ snd_strerror (err));
+ }
+ return supported;
+ }
+
+ GST_DEBUG_OBJECT (obj, "only supported for playback");
+ return FALSE;
+
+}
+
/* returns the card name when the device number is unknown or -1 */
static gchar *
gst_alsa_find_device_name_no_handle (GstObject * obj, const gchar * devcard,
diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h
index 46324a3..d9e6284 100644
--- a/ext/alsa/gstalsa.h
+++ b/ext/alsa/gstalsa.h
@@ -58,6 +58,10 @@
snd_pcm_t * handle,
const GstCaps * template_caps);
+gboolean gst_alsa_iec958_formats_supported (GstObject * obj,
+ gchar * device,
+ snd_pcm_t ** handle);
+
gchar * gst_alsa_find_device_name (GstObject * obj,
const gchar * device,
snd_pcm_t * handle,
diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c
index 282e91d..579791e 100644
--- a/ext/alsa/gstalsasink.c
+++ b/ext/alsa/gstalsasink.c
@@ -285,6 +285,9 @@
GstPadTemplate *pad_template;
GstAlsaSink *sink = GST_ALSA_SINK (bsink);
GstCaps *caps, *templ_caps;
+ snd_pcm_stream_t stream_type;
+ snd_pcm_t *pcm;
+ int res;
GST_OBJECT_LOCK (sink);
if (sink->handle == NULL) {
@@ -323,10 +326,19 @@
sink->handle, templ_caps);
gst_caps_unref (templ_caps);
+ /* Try opening IEC958 device to see if we can support that format (playback
+ * only for now but we could add SPDIF capture later)
+ */
+
+ if (gst_alsa_iec958_formats_supported(GST_OBJECT (sink), sink->device,
+ &sink->handle) == TRUE) {
+ GST_LOG_OBJECT (sink, "Add pass-through capabilities");
+ gst_caps_append (caps, gst_caps_from_string (PASSTHROUGH_CAPS));
+ }
+
if (caps) {
sink->cached_caps = gst_caps_ref (caps);
}
-
GST_OBJECT_UNLOCK (sink);
GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);