From 26aff02c8ae8b9bfafc6a9549eacb0f523aeb4d1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 23 Mar 2006 20:12:47 +0000 Subject: [PATCH] ext/esd/esdsink.*: Fix esd choppy playback by configuring audiosink correctly. Fixes #325191 Original commit message from CVS: * ext/esd/esdsink.c: (gst_esdsink_class_init), (gst_esdsink_getcaps), (gst_esdsink_open), (gst_esdsink_close), (gst_esdsink_prepare), (gst_esdsink_unprepare), (gst_esdsink_delay), (gst_esdsink_reset): * ext/esd/esdsink.h: Fix esd choppy playback by configuring audiosink correctly. Fixes #325191 --- ChangeLog | 10 ++++++ ext/esd/esdsink.c | 88 +++++++++++++++++++++++++++++++++++++---------- ext/esd/esdsink.h | 8 +++-- 3 files changed, 85 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index af61cf6ce0..d6d075608e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-03-23 Wim Taymans + + * ext/esd/esdsink.c: (gst_esdsink_class_init), + (gst_esdsink_getcaps), (gst_esdsink_open), (gst_esdsink_close), + (gst_esdsink_prepare), (gst_esdsink_unprepare), + (gst_esdsink_delay), (gst_esdsink_reset): + * ext/esd/esdsink.h: + Fix esd choppy playback by configuring audiosink + correctly. Fixes #325191 + 2006-03-23 Tim-Philipp Müller * ext/libpng/gstpngdec.c: (gst_pngdec_change_state): diff --git a/ext/esd/esdsink.c b/ext/esd/esdsink.c index bc27516838..9d107f2a8d 100644 --- a/ext/esd/esdsink.c +++ b/ext/esd/esdsink.c @@ -186,10 +186,10 @@ gst_esdsink_getcaps (GstBaseSink * bsink) gint i; esd_server_info_t *server_info; - GST_DEBUG ("getcaps called"); - esdsink = GST_ESDSINK (bsink); + GST_DEBUG_OBJECT (esdsink, "getcaps called"); + pad_template = gst_static_pad_template_get (&sink_factory); caps = gst_caps_copy (gst_pad_template_get_caps (pad_template)); @@ -202,7 +202,7 @@ gst_esdsink_getcaps (GstBaseSink * bsink) if (!server_info) goto no_info; - GST_DEBUG ("got server info rate: %i", server_info->rate); + GST_DEBUG_OBJECT (esdsink, "got server info rate: %i", server_info->rate); for (i = 0; i < caps->structs->len; i++) { GstStructure *s; @@ -229,6 +229,8 @@ gst_esdsink_open (GstAudioSink * asink) { GstEsdSink *esdsink = GST_ESDSINK (asink); + GST_DEBUG_OBJECT (esdsink, "open"); + esdsink->ctrl_fd = esd_open_sound (esdsink->host); if (esdsink->ctrl_fd < 0) goto couldnt_connect; @@ -249,6 +251,8 @@ gst_esdsink_close (GstAudioSink * asink) { GstEsdSink *esdsink = GST_ESDSINK (asink); + GST_DEBUG_OBJECT (esdsink, "close"); + esd_close (esdsink->ctrl_fd); esdsink->ctrl_fd = -1; @@ -259,37 +263,78 @@ static gboolean gst_esdsink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstEsdSink *esdsink = GST_ESDSINK (asink); + esd_format_t esdformat; /* Name used by esound for this connection. */ const char connname[] = "GStreamer"; + guint latency; + + GST_DEBUG_OBJECT (esdsink, "prepare"); /* Bitmap describing audio format. */ - esd_format_t esdformat = ESD_STREAM | ESD_PLAY; + esdformat = ESD_STREAM | ESD_PLAY; - if (spec->depth == 16) - esdformat |= ESD_BITS16; - else if (spec->depth == 8) { - esdformat |= ESD_BITS8; + switch (spec->depth) { + case 8: + esdformat |= ESD_BITS8; + break; + case 16: + esdformat |= ESD_BITS16; + break; + default: + goto unsupported_depth; } - if (spec->channels == 2) - esdformat |= ESD_STEREO; - else if (spec->channels == 1) { - esdformat |= ESD_MONO; + switch (spec->channels) { + case 1: + esdformat |= ESD_MONO; + break; + case 2: + esdformat |= ESD_STEREO; + break; + default: + goto unsupported_channels; } - GST_INFO ("attempting to open data connection to esound server"); + GST_INFO_OBJECT (esdsink, + "attempting to open data connection to esound server"); + esdsink->fd = esd_play_stream (esdformat, spec->rate, esdsink->host, connname); if ((esdsink->fd < 0) || (esdsink->ctrl_fd < 0)) goto cannot_open; - GST_INFO ("successfully opened connection to esound server"); + esdsink->rate = spec->rate; + + latency = esd_get_latency (esdsink->ctrl_fd); + latency = latency * 44100LL / esdsink->rate; + + spec->segsize = 256 * spec->bytes_per_sample; + spec->segtotal = (latency / 256); + spec->silence_sample[0] = 0; + spec->silence_sample[1] = 0; + spec->silence_sample[2] = 0; + spec->silence_sample[3] = 0; + + GST_INFO_OBJECT (esdsink, "successfully opened connection to esound server"); return TRUE; /* ERRORS */ +unsupported_depth: + { + GST_ELEMENT_ERROR (esdsink, STREAM, WRONG_TYPE, (NULL), + ("can't handle sample depth of %d, only 8 or 16 supported", + spec->depth)); + return FALSE; + } +unsupported_channels: + { + GST_ELEMENT_ERROR (esdsink, STREAM, WRONG_TYPE, (NULL), + ("can't handle %d channels, only 1 or 2 supported", spec->channels)); + return FALSE; + } cannot_open: { GST_ELEMENT_ERROR (esdsink, RESOURCE, OPEN_WRITE, (NULL), @@ -309,7 +354,8 @@ gst_esdsink_unprepare (GstAudioSink * asink) close (esdsink->fd); esdsink->fd = -1; - GST_INFO ("esdsink: closed sound device"); + GST_INFO_OBJECT (esdsink, "closed sound device"); + return TRUE; } @@ -348,16 +394,22 @@ static guint gst_esdsink_delay (GstAudioSink * asink) { GstEsdSink *esdsink = GST_ESDSINK (asink); - guint latency = esd_get_latency (esdsink->ctrl_fd); + guint latency; + + latency = esd_get_latency (esdsink->ctrl_fd); + + /* latency is measured in samples at a rate of 44100 */ + latency = latency * 44100LL / esdsink->rate; + + GST_DEBUG_OBJECT (asink, "got latency: %u", latency); - GST_DEBUG ("got latency: %u", latency); return latency; } static void gst_esdsink_reset (GstAudioSink * asink) { - GST_DEBUG ("reset called"); + GST_DEBUG_OBJECT (asink, "reset called"); } static void diff --git a/ext/esd/esdsink.h b/ext/esd/esdsink.h index 171c1818b2..9db9afa71a 100644 --- a/ext/esd/esdsink.h +++ b/ext/esd/esdsink.h @@ -45,9 +45,11 @@ typedef struct _GstEsdSinkClass GstEsdSinkClass; struct _GstEsdSink { GstAudioSink sink; - int fd; - int ctrl_fd; - gchar *host; + int fd; + int ctrl_fd; + gchar *host; + + guint rate; }; struct _GstEsdSinkClass {