From 5da5fef96030e5546fbe1ce1cefc003f79a72471 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 20 Apr 2012 12:09:08 +0200 Subject: [PATCH] nas: Rework nassink a little Based on patch from Create and destroy flow in prepare/unprepare Remove some duplicate code from close and prepare that is now in unprepare. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=674130 --- ext/nas/nassink.c | 315 +++++++++++++++++++++++------------------------------- 1 file changed, 131 insertions(+), 184 deletions(-) diff --git a/ext/nas/nassink.c b/ext/nas/nassink.c index e4ebf8d..afd572a 100644 --- a/ext/nas/nassink.c +++ b/ext/nas/nassink.c @@ -86,7 +86,6 @@ static void NAS_sendData (GstNasSink * sink, AuUint32 numBytes); static AuBool NAS_EventHandler (AuServer * aud, AuEvent * ev, AuEventHandlerRec * handler); static AuDeviceID NAS_getDevice (AuServer * aud, int numTracks); -static int NAS_createFlow (GstNasSink * sink, GstRingBufferSpec * spec); GST_BOILERPLATE (GstNasSink, gst_nas_sink, GstAudioSink, GST_TYPE_AUDIO_SINK); @@ -199,33 +198,148 @@ gst_nas_sink_getcaps (GstBaseSink * bsink) return caps; } +static gint +gst_nas_sink_sink_get_format (const GstRingBufferSpec * spec) +{ + gint result; + + switch (spec->format) { + case GST_U8: + result = AuFormatLinearUnsigned8; + break; + case GST_S8: + result = AuFormatLinearSigned8; + break; + case GST_S16_LE: + result = AuFormatLinearSigned16LSB; + break; + case GST_S16_BE: + result = AuFormatLinearSigned16MSB; + break; + case GST_U16_LE: + result = AuFormatLinearUnsigned16LSB; + break; + case GST_U16_BE: + result = AuFormatLinearUnsigned16MSB; + break; + default: + result = 0; + break; + } + return result; +} + static gboolean gst_nas_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstNasSink *sink = GST_NAS_SINK (asink); + AuElement elements[2]; + AuUint32 buf_samples; + unsigned char format; + + format = gst_nas_sink_sink_get_format (spec); + if (format == 0) { + GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL), + ("Unable to get format %d", spec->format)); + return FALSE; + } + GST_DEBUG_OBJECT (sink, "Format: %d %d\n", spec->format, format); + + sink->flow = AuGetScratchFlow (sink->audio, NULL); + if (sink->flow == 0) { + GST_DEBUG_OBJECT (sink, "couldn't get flow"); + return FALSE; + } + + buf_samples = spec->rate * NAS_SOUND_PORT_DURATION; + /* + spec->segsize = gst_util_uint64_scale (buf_samples * spec->bytes_per_sample, + spec->latency_time, GST_SECOND / GST_USECOND); + spec->segsize -= spec->segsize % spec->bytes_per_sample; + spec->segtotal = spec->buffer_time / spec->latency_time; + */ + spec->segsize = buf_samples * spec->bytes_per_sample; + spec->segtotal = 1; - /*spec->bytes_per_sample = sink->rate * NAS_SOUND_PORT_DURATION; */ - /*spec->bytes_per_sample = (spec->width / 8) * spec->channels; */ memset (spec->silence_sample, 0, spec->bytes_per_sample); - GST_DEBUG_OBJECT (sink, "Sample %d", spec->bytes_per_sample); + GST_DEBUG_OBJECT (sink, "Bytes per sample %d", spec->bytes_per_sample); - if (sink->audio == NULL) - return TRUE; + GST_DEBUG_OBJECT (sink, "Rate %d Format %d tracks %d bufs %d %d/%d w %d", + spec->rate, format, spec->channels, (gint) buf_samples, spec->segsize, + spec->segtotal, spec->width); + AuMakeElementImportClient (&elements[0], /* element */ + spec->rate, /* rate */ + format, /* format */ + spec->channels, /* number of tracks */ + AuTrue, /* discart */ + buf_samples, /* max samples */ + (AuUint32) (buf_samples / 100 * AuSoundPortLowWaterMark), + /* low water mark */ + 0, /* num actions */ + NULL); + + sink->device = NAS_getDevice (sink->audio, spec->channels); + if (sink->device == AuNone) { + GST_DEBUG_OBJECT (sink, "no device with %i tracks found", spec->channels); + return FALSE; + } + + AuMakeElementExportDevice (&elements[1], /* element */ + 0, /* input */ + sink->device, /* device */ + spec->rate, /* rate */ + AuUnlimitedSamples, /* num samples */ + 0, /* num actions */ + NULL); /* actions */ + + AuSetElements (sink->audio, /* server */ + sink->flow, /* flow ID */ + AuTrue, /* clocked */ + 2, /* num elements */ + elements, /* elements */ + NULL); + + AuRegisterEventHandler (sink->audio, /* server */ + AuEventHandlerIDMask, /* value mask */ + 0, /* type */ + sink->flow, /* flow ID */ + NAS_EventHandler, /* callback */ + (AuPointer) sink); /* data */ + + AuStartFlow (sink->audio, sink->flow, NULL); + + return TRUE; +} + +static gboolean +gst_nas_sink_unprepare (GstAudioSink * asink) +{ + GstNasSink *sink = GST_NAS_SINK (asink); if (sink->flow != AuNone) { + AuBool clocked; + int num_elements; + AuStatus status; + AuElement *oldelems; + GST_DEBUG_OBJECT (sink, "flushing buffer"); NAS_flush (sink); + + oldelems = + AuGetElements (sink->audio, sink->flow, &clocked, &num_elements, + &status); + if (num_elements > 0) { + GST_DEBUG_OBJECT (sink, "GetElements status: %i", status); + if (oldelems) + AuFreeElements (sink->audio, num_elements, oldelems); + } + AuStopFlow (sink->audio, sink->flow, NULL); AuReleaseScratchFlow (sink->audio, sink->flow, NULL); sink->flow = AuNone; } + sink->need_data = 0; - return NAS_createFlow (sink, spec); -} - -static gboolean -gst_nas_sink_unprepare (GstAudioSink * asink) -{ return TRUE; } @@ -243,7 +357,8 @@ gst_nas_sink_reset (GstAudioSink * asink) GST_DEBUG_OBJECT (sink, "reset"); - NAS_flush (sink); + if (sink->flow != AuNone) + AuStopFlow (sink->audio, sink->flow, NULL); } static guint @@ -342,22 +457,11 @@ gst_nas_sink_close (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); - if (sink->audio == NULL) - return TRUE; - - if (sink->flow != AuNone) { - NAS_flush (sink); - - AuStopFlow (sink->audio, sink->flow, NULL); - AuReleaseScratchFlow (sink->audio, sink->flow, NULL); - sink->flow = AuNone; + if (sink->audio) { + AuCloseServer (sink->audio); + sink->audio = NULL; } - sink->need_data = 0; - - AuCloseServer (sink->audio); - sink->audio = NULL; - GST_DEBUG_OBJECT (sink, "closed audio device"); return TRUE; } @@ -460,163 +564,6 @@ NAS_getDevice (AuServer * aud, int numTracks) return AuNone; } -static gint -gst_nas_sink_sink_get_format (const GstRingBufferSpec * spec) -{ - gint result; - - switch (spec->format) { - case GST_U8: - result = AuFormatLinearUnsigned8; - break; - case GST_S8: - result = AuFormatLinearSigned8; - break; - case GST_S16_LE: - result = AuFormatLinearSigned16LSB; - break; - case GST_S16_BE: - result = AuFormatLinearSigned16MSB; - break; - case GST_U16_LE: - result = AuFormatLinearUnsigned16LSB; - break; - case GST_U16_BE: - result = AuFormatLinearUnsigned16MSB; - break; - default: - result = 0; - break; - } - return result; -} - -static gboolean -NAS_createFlow (GstNasSink * sink, GstRingBufferSpec * spec) -{ - AuElement elements[2]; - AuUint32 buf_samples; - unsigned char format; - - format = gst_nas_sink_sink_get_format (spec); - if (format == 0) { - GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL), - ("Unable to get format %d", spec->format)); - return FALSE; - } - GST_DEBUG_OBJECT (sink, "Format: %d %d\n", spec->format, format); - - sink->flow = AuGetScratchFlow (sink->audio, NULL); - if (sink->flow == 0) { - GST_DEBUG_OBJECT (sink, "couldn't get flow"); - return FALSE; - } - - /* free old Elements and reconnet to server, needed to change samplerate */ - { - AuBool clocked; - int num_elements; - AuStatus status; - AuElement *oldelems; - - oldelems = - AuGetElements (sink->audio, sink->flow, &clocked, &num_elements, - &status); - if (num_elements > 0) { - GST_DEBUG_OBJECT (sink, "GetElements status: %i", status); - if (oldelems) - AuFreeElements (sink->audio, num_elements, oldelems); - gst_nas_sink_close (GST_AUDIO_SINK (sink)); - gst_nas_sink_open (GST_AUDIO_SINK (sink)); - sink->flow = AuGetScratchFlow (sink->audio, NULL); - if (sink->flow == 0) { - GST_DEBUG_OBJECT (sink, "couldn't get flow"); - return FALSE; - } - } - } - - /* free old Elements and reconnet to server, needed to change samplerate */ - { - AuBool clocked; - int num_elements; - AuStatus status; - AuElement *oldelems; - - oldelems = - AuGetElements (sink->audio, sink->flow, &clocked, &num_elements, - &status); - if (num_elements > 0) { - GST_DEBUG_OBJECT (sink, "GetElements status: %i", status); - if (oldelems) - AuFreeElements (sink->audio, num_elements, oldelems); - gst_nas_sink_close (GST_AUDIO_SINK (sink)); - gst_nas_sink_open (GST_AUDIO_SINK (sink)); - sink->flow = AuGetScratchFlow (sink->audio, NULL); - if (sink->flow == 0) { - GST_DEBUG_OBJECT (sink, "couldn't get flow"); - return FALSE; - } - } - } - - buf_samples = spec->rate * NAS_SOUND_PORT_DURATION; - /* - spec->segsize = gst_util_uint64_scale (buf_samples * spec->bytes_per_sample, - spec->latency_time, GST_SECOND / GST_USECOND); - spec->segsize -= spec->segsize % spec->bytes_per_sample; - spec->segtotal = spec->buffer_time / spec->latency_time; - */ - spec->segsize = buf_samples * spec->bytes_per_sample; - spec->segtotal = 1; - - GST_DEBUG_OBJECT (sink, "Rate %d Format %d tracks %d bufs %d %d/%d w %d", - spec->rate, format, spec->channels, (gint) buf_samples, spec->segsize, - spec->segtotal, spec->width); - AuMakeElementImportClient (&elements[0], /* element */ - spec->rate, /* rate */ - format, /* format */ - spec->channels, /* number of tracks */ - AuTrue, /* discart */ - buf_samples, /* max samples */ - (AuUint32) (buf_samples / 100 * AuSoundPortLowWaterMark), - /* low water mark */ - 0, /* num actions */ - NULL); - - sink->device = NAS_getDevice (sink->audio, spec->channels); - if (sink->device == AuNone) { - GST_DEBUG_OBJECT (sink, "no device with %i tracks found", spec->channels); - return FALSE; - } - - AuMakeElementExportDevice (&elements[1], /* element */ - 0, /* input */ - sink->device, /* device */ - spec->rate, /* rate */ - AuUnlimitedSamples, /* num samples */ - 0, /* num actions */ - NULL); /* actions */ - - AuSetElements (sink->audio, /* server */ - sink->flow, /* flow ID */ - AuTrue, /* clocked */ - 2, /* num elements */ - elements, /* elements */ - NULL); - - AuRegisterEventHandler (sink->audio, /* server */ - AuEventHandlerIDMask, /* value mask */ - 0, /* type */ - sink->flow, /* flow ID */ - NAS_EventHandler, /* callback */ - (AuPointer) sink); /* data */ - - AuStartFlow (sink->audio, sink->flow, NULL); - - return TRUE; -} - static gboolean plugin_init (GstPlugin * plugin) { -- 2.7.4