nas: Rework nassink a little
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 20 Apr 2012 10:09:08 +0000 (12:09 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 20 Apr 2012 10:29:36 +0000 (12:29 +0200)
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

ext/nas/nassink.c

index e4ebf8da8fff4ac1f90ece62b55e5c2b64e55bb7..afd572a27118801aad4265da44d6baf995b54a40 100644 (file)
@@ -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)
 {