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:
Benjamin Otte 2003-02-27 22:33:01 +00:00
parent 4daf140188
commit 1516bb3f58

View file

@ -453,7 +453,7 @@ gst_alsa_request_new_pad (GstElement *element, GstPadTemplate *templ,
gint channel = 0; gint channel = 0;
g_return_val_if_fail ((this = GST_ALSA (element)), NULL); 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 */ /* 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); g_return_val_if_fail (this->channels > GST_ELEMENT(this)->numpads, NULL);
@ -514,23 +514,49 @@ gst_alsa_get_format (GstCaps *caps)
"width", &width, "width", &width,
"depth", &depth, "depth", &depth,
"law", &law, "law", &law,
"endianness", &endianness,
"signed", &sign, "signed", &sign,
NULL)) NULL))
return SND_PCM_FORMAT_UNKNOWN; 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 */ /* find corresponding alsa format */
switch (law) { switch (law) {
case 0: return snd_pcm_build_linear_format (depth, width, sign ? 0 : 1, endianness == G_LITTLE_ENDIAN ? 0 : 1); 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 1:
case 2: return SND_PCM_FORMAT_MU_LAW; 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; default: return SND_PCM_FORMAT_UNKNOWN;
} }
} else if (strncmp (format_name, "float", 5) == 0) { } else if (strncmp (format_name, "float", 5) == 0) {
gchar *layout; gchar *layout;
gfloat intercept, slope;
/* get layout */ /* 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; return SND_PCM_FORMAT_UNKNOWN;
if (intercept != 0.0f || slope != 1.0f) {
return SND_PCM_FORMAT_UNKNOWN;
}
/* match layout to format wrt to endianness */ /* match layout to format wrt to endianness */
if (strncmp (layout, "gfloat", 6) == 0) { if (strncmp (layout, "gfloat", 6) == 0) {
return SND_PCM_FORMAT_FLOAT; return SND_PCM_FORMAT_FLOAT;
@ -547,14 +573,30 @@ gst_alsa_get_format (GstCaps *caps)
static GstProps * static GstProps *
gst_alsa_get_props (snd_pcm_format_t format) gst_alsa_get_props (snd_pcm_format_t format)
{ {
/* int or float */ if (format == SND_PCM_FORMAT_A_LAW) {
if (snd_pcm_format_linear (format)) { 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"), GstProps *props = gst_props_new ("format", GST_PROPS_STRING ("int"),
"width", GST_PROPS_INT(snd_pcm_format_physical_width (format)), "width", GST_PROPS_INT(snd_pcm_format_physical_width (format)),
"depth", GST_PROPS_INT(snd_pcm_format_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), "signed", GST_PROPS_BOOLEAN (snd_pcm_format_signed (format) == 1 ? TRUE : FALSE),
NULL); NULL);
/* endianness */ /* endianness */
if (snd_pcm_format_physical_width (format) > 8) {
switch (snd_pcm_format_little_endian (format)) { switch (snd_pcm_format_little_endian (format)) {
case 0: case 0:
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_BIG_ENDIAN))); 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))); gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_LITTLE_ENDIAN)));
break; break;
default: 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; 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; return props;
} else if (snd_pcm_format_float (format)) { } 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"), return gst_props_new ("format", GST_PROPS_STRING ("float"),
"layout", GST_PROPS_STRING (snd_pcm_format_width (format) == 64 ? "gdouble" : "gfloat"), "layout", GST_PROPS_STRING (snd_pcm_format_width (format) == 64 ? "gdouble" : "gfloat"),
"intercept", GST_PROPS_FLOAT (0),
"slope", GST_PROPS_FLOAT (1),
NULL); NULL);
} }
return NULL; return NULL;
@ -657,11 +692,11 @@ gst_alsa_link (GstPad *pad, GstCaps *caps)
if (!gst_alsa_open_audio (this)) if (!gst_alsa_open_audio (this))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
/* FIXME: allow changing the format here, even by retrying caps on other pads */
format = gst_alsa_get_format (caps); format = gst_alsa_get_format (caps);
GST_DEBUG (GST_CAT_CAPS, "found format %s\n", snd_pcm_format_name (format)); 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; return GST_PAD_LINK_REFUSED;
if (!gst_caps_get (caps, "rate", &rate, if (!gst_caps_get (caps, "rate", &rate,
"channels", &channels, "channels", &channels,
@ -710,8 +745,8 @@ gst_alsa_change_state (GstElement *element)
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
if (GST_FLAG_IS_SET (element, GST_ALSA_OPEN) == FALSE) if (GST_FLAG_IS_SET (element, GST_ALSA_RUNNING) == FALSE)
if (!gst_alsa_open_audio (this)) if (!gst_alsa_start_audio (this))
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
case GST_STATE_PLAYING_TO_PAUSED: 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); avail = snd_pcm_avail_update (this->handle);
if (avail < 0) { if (avail < 0) {
if (avail == -EPIPE) { if (avail == -EPIPE) {
gst_alsa_xrun_recovery (this); gst_alsa_xrun_recovery (this);
continue; goto restart;
} else { } else {
g_warning ("unknown ALSA avail_update return value (%d)", (int) avail); g_warning ("unknown ALSA avail_update return value (%d)", (int) avail);
return; return;
@ -852,16 +887,15 @@ gst_alsa_sink_loop (GstElement *element)
* under gdb, or when exiting due to a signal */ * under gdb, or when exiting due to a signal */
GST_DEBUG (GST_CAT_PLUGIN_INFO, "got interrupted while waiting"); GST_DEBUG (GST_CAT_PLUGIN_INFO, "got interrupted while waiting");
if (gst_element_interrupt (element)) if (gst_element_interrupt (element))
break; return;
else else
continue; goto restart;
} }
g_warning ("error waiting for alsa pcm: (%d: %s)", errno, strerror (errno)); g_warning ("error waiting for alsa pcm: (%d: %s)", errno, strerror (errno));
return; return;
} }
} }
} }
}
static void static void
gst_alsa_xrun_recovery (GstAlsa *this) gst_alsa_xrun_recovery (GstAlsa *this)