mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
bugfixes found while testing:
Original commit message from CVS: bugfixes found while testing: - return after 1 iteration, don't loop for ever - caps nego: only parse endianness when necessary - caps nego: make mu law and a law work - caps nego: make float work - call right function when going from PAUSED to PLAYING - stupid error in request_new_pad
This commit is contained in:
parent
4daf140188
commit
1516bb3f58
1 changed files with 80 additions and 46 deletions
|
@ -453,7 +453,7 @@ gst_alsa_request_new_pad (GstElement *element, GstPadTemplate *templ,
|
|||
gint channel = 0;
|
||||
|
||||
g_return_val_if_fail ((this = GST_ALSA (element)), NULL);
|
||||
g_return_val_if_fail (GST_FLAG_IS_SET (element, GST_ALSA_RUNNING), NULL);
|
||||
g_return_val_if_fail (!GST_FLAG_IS_SET (element, GST_ALSA_RUNNING), NULL);
|
||||
|
||||
/* you can't request a pad if the non-request pad already has more than 1 channel */
|
||||
g_return_val_if_fail (this->channels > GST_ELEMENT(this)->numpads, NULL);
|
||||
|
@ -514,23 +514,49 @@ gst_alsa_get_format (GstCaps *caps)
|
|||
"width", &width,
|
||||
"depth", &depth,
|
||||
"law", &law,
|
||||
"endianness", &endianness,
|
||||
"signed", &sign,
|
||||
NULL))
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
|
||||
/* extract endianness if needed */
|
||||
if (width > 8) {
|
||||
if (!gst_caps_get (caps,
|
||||
"endianness", &endianness,
|
||||
NULL))
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
} else {
|
||||
endianness = G_BYTE_ORDER;
|
||||
}
|
||||
|
||||
/* find corresponding alsa format */
|
||||
switch (law) {
|
||||
case 0: return snd_pcm_build_linear_format (depth, width, sign ? 0 : 1, endianness == G_LITTLE_ENDIAN ? 0 : 1);
|
||||
case 1: return SND_PCM_FORMAT_A_LAW;
|
||||
case 2: return SND_PCM_FORMAT_MU_LAW;
|
||||
case 1:
|
||||
if (width == 8 && depth == 8 && sign == FALSE) {
|
||||
return SND_PCM_FORMAT_MU_LAW;
|
||||
} else {
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
case 2:
|
||||
if (width == 8 && depth == 8 && sign == FALSE) {
|
||||
return SND_PCM_FORMAT_A_LAW;
|
||||
} else {
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
default: return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
} else if (strncmp (format_name, "float", 5) == 0) {
|
||||
gchar *layout;
|
||||
gfloat intercept, slope;
|
||||
/* get layout */
|
||||
if (!gst_caps_get_string (caps, "layout", (const gchar **) &layout))
|
||||
if (!gst_caps_get (caps, "layout", &layout,
|
||||
"intercept", &intercept,
|
||||
"slope", &slope,
|
||||
NULL))
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
if (intercept != 0.0f || slope != 1.0f) {
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
/* match layout to format wrt to endianness */
|
||||
if (strncmp (layout, "gfloat", 6) == 0) {
|
||||
return SND_PCM_FORMAT_FLOAT;
|
||||
|
@ -547,14 +573,30 @@ gst_alsa_get_format (GstCaps *caps)
|
|||
static GstProps *
|
||||
gst_alsa_get_props (snd_pcm_format_t format)
|
||||
{
|
||||
/* int or float */
|
||||
if (snd_pcm_format_linear (format)) {
|
||||
if (format == SND_PCM_FORMAT_A_LAW) {
|
||||
return gst_props_new ("format", GST_PROPS_STRING ("int"),
|
||||
"law", GST_PROPS_INT(2),
|
||||
"width", GST_PROPS_INT(8),
|
||||
"depth", GST_PROPS_INT(8),
|
||||
"signed", GST_PROPS_BOOLEAN (FALSE),
|
||||
NULL);
|
||||
} else if (format == SND_PCM_FORMAT_MU_LAW) {
|
||||
return gst_props_new ("format", GST_PROPS_STRING ("int"),
|
||||
"law", GST_PROPS_INT(1),
|
||||
"width", GST_PROPS_INT(8),
|
||||
"depth", GST_PROPS_INT(8),
|
||||
"signed", GST_PROPS_BOOLEAN (FALSE),
|
||||
NULL);
|
||||
} else if (snd_pcm_format_linear (format)) {
|
||||
/* int */
|
||||
GstProps *props = gst_props_new ("format", GST_PROPS_STRING ("int"),
|
||||
"width", GST_PROPS_INT(snd_pcm_format_physical_width (format)),
|
||||
"depth", GST_PROPS_INT(snd_pcm_format_width (format)),
|
||||
"law", GST_PROPS_INT(0),
|
||||
"signed", GST_PROPS_BOOLEAN (snd_pcm_format_signed (format) == 1 ? TRUE : FALSE),
|
||||
NULL);
|
||||
/* endianness */
|
||||
if (snd_pcm_format_physical_width (format) > 8) {
|
||||
switch (snd_pcm_format_little_endian (format)) {
|
||||
case 0:
|
||||
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_BIG_ENDIAN)));
|
||||
|
@ -563,19 +605,10 @@ gst_alsa_get_props (snd_pcm_format_t format)
|
|||
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_LITTLE_ENDIAN)));
|
||||
break;
|
||||
default:
|
||||
g_warning("ALSA: Unknown byte order in sound driver. Continuing by assuming system byte order.");
|
||||
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_BYTE_ORDER)));
|
||||
break;
|
||||
}
|
||||
/* law */
|
||||
switch (format) {
|
||||
case SND_PCM_FORMAT_A_LAW:
|
||||
gst_props_add_entry (props, gst_props_entry_new ("law", GST_PROPS_INT (1)));
|
||||
break;
|
||||
case SND_PCM_FORMAT_MU_LAW:
|
||||
gst_props_add_entry (props, gst_props_entry_new ("law", GST_PROPS_INT (2)));
|
||||
break;
|
||||
default:
|
||||
gst_props_add_entry (props, gst_props_entry_new ("law", GST_PROPS_INT (0)));
|
||||
break;
|
||||
}
|
||||
return props;
|
||||
} else if (snd_pcm_format_float (format)) {
|
||||
|
@ -585,6 +618,8 @@ gst_alsa_get_props (snd_pcm_format_t format)
|
|||
|
||||
return gst_props_new ("format", GST_PROPS_STRING ("float"),
|
||||
"layout", GST_PROPS_STRING (snd_pcm_format_width (format) == 64 ? "gdouble" : "gfloat"),
|
||||
"intercept", GST_PROPS_FLOAT (0),
|
||||
"slope", GST_PROPS_FLOAT (1),
|
||||
NULL);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -657,11 +692,11 @@ gst_alsa_link (GstPad *pad, GstCaps *caps)
|
|||
if (!gst_alsa_open_audio (this))
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
|
||||
/* FIXME: allow changing the format here, even by retrying caps on other pads */
|
||||
format = gst_alsa_get_format (caps);
|
||||
GST_DEBUG (GST_CAT_CAPS, "found format %s\n", snd_pcm_format_name (format));
|
||||
|
||||
if (this->format != SND_PCM_FORMAT_UNKNOWN && this->format != format)
|
||||
/* FIXME: allow changing the format here, even by retrying caps on other pads */
|
||||
if (format == SND_PCM_FORMAT_UNKNOWN || (this->format != SND_PCM_FORMAT_UNKNOWN && this->format != format))
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
if (!gst_caps_get (caps, "rate", &rate,
|
||||
"channels", &channels,
|
||||
|
@ -710,8 +745,8 @@ gst_alsa_change_state (GstElement *element)
|
|||
case GST_STATE_READY_TO_PAUSED:
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
if (GST_FLAG_IS_SET (element, GST_ALSA_OPEN) == FALSE)
|
||||
if (!gst_alsa_open_audio (this))
|
||||
if (GST_FLAG_IS_SET (element, GST_ALSA_RUNNING) == FALSE)
|
||||
if (!gst_alsa_start_audio (this))
|
||||
return GST_STATE_FAILURE;
|
||||
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
|
@ -763,13 +798,13 @@ gst_alsa_sink_loop (GstElement *element)
|
|||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
restart:
|
||||
|
||||
avail = snd_pcm_avail_update (this->handle);
|
||||
if (avail < 0) {
|
||||
if (avail == -EPIPE) {
|
||||
gst_alsa_xrun_recovery (this);
|
||||
continue;
|
||||
goto restart;
|
||||
} else {
|
||||
g_warning ("unknown ALSA avail_update return value (%d)", (int) avail);
|
||||
return;
|
||||
|
@ -852,16 +887,15 @@ gst_alsa_sink_loop (GstElement *element)
|
|||
* under gdb, or when exiting due to a signal */
|
||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "got interrupted while waiting");
|
||||
if (gst_element_interrupt (element))
|
||||
break;
|
||||
return;
|
||||
else
|
||||
continue;
|
||||
goto restart;
|
||||
}
|
||||
g_warning ("error waiting for alsa pcm: (%d: %s)", errno, strerror (errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_alsa_xrun_recovery (GstAlsa *this)
|
||||
|
|
Loading…
Reference in a new issue