mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-27 11:32:51 +00:00
nas: Rework nassink a little
Based on patch from <ole.hellqvist at spray.se> 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
This commit is contained in:
parent
529f90c29d
commit
5da5fef960
1 changed files with 134 additions and 187 deletions
|
@ -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;
|
||||
|
||||
/*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);
|
||||
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);
|
||||
|
||||
if (sink->audio == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (sink->flow != AuNone) {
|
||||
GST_DEBUG_OBJECT (sink, "flushing buffer");
|
||||
NAS_flush (sink);
|
||||
AuStopFlow (sink->audio, sink->flow, NULL);
|
||||
AuReleaseScratchFlow (sink->audio, sink->flow, NULL);
|
||||
sink->flow = AuNone;
|
||||
sink->flow = AuGetScratchFlow (sink->audio, NULL);
|
||||
if (sink->flow == 0) {
|
||||
GST_DEBUG_OBJECT (sink, "couldn't get flow");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return NAS_createFlow (sink, spec);
|
||||
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;
|
||||
|
||||
memset (spec->silence_sample, 0, spec->bytes_per_sample);
|
||||
GST_DEBUG_OBJECT (sink, "Bytes per sample %d", spec->bytes_per_sample);
|
||||
|
||||
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 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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue