wasapi: Unprepare when src/sink_prepare fails
authorNirbheek Chauhan <nirbheek@centricular.com>
Thu, 8 Feb 2018 08:57:43 +0000 (14:27 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Thu, 8 Feb 2018 09:00:38 +0000 (14:30 +0530)
unprepare() is not called automatically on failure.

https://bugzilla.gnome.org/show_bug.cgi?id=793289

sys/wasapi/gstwasapisink.c
sys/wasapi/gstwasapisrc.c

index bfb1192..972a827 100644 (file)
@@ -418,7 +418,6 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
   GstWasapiSink *self = GST_WASAPI_SINK (asink);
   gboolean res = FALSE;
   REFERENCE_TIME latency_rt;
-  IAudioRenderClient *render_client = NULL;
   REFERENCE_TIME default_period, min_period;
   REFERENCE_TIME device_period, device_buffer_duration;
   guint bpf, rate;
@@ -533,7 +532,7 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
 
   /* Get render sink client and start it up */
   if (!gst_wasapi_util_get_render_client (GST_ELEMENT (self), self->client,
-          &render_client)) {
+          &self->render_client)) {
     goto beach;
   }
 
@@ -555,7 +554,7 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
 
     len = n_frames * self->mix_format->nBlockAlign;
 
-    hr = IAudioRenderClient_GetBuffer (render_client, n_frames,
+    hr = IAudioRenderClient_GetBuffer (self->render_client, n_frames,
         (BYTE **) & dst);
     if (hr != S_OK) {
       gchar *msg = gst_wasapi_util_hresult_to_string (hr);
@@ -567,7 +566,7 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
 
     GST_DEBUG_OBJECT (self, "pre-wrote %i bytes of silence", len);
 
-    hr = IAudioRenderClient_ReleaseBuffer (render_client, n_frames,
+    hr = IAudioRenderClient_ReleaseBuffer (self->render_client, n_frames,
         AUDCLNT_BUFFERFLAGS_SILENT);
     if (hr != S_OK) {
       gchar *msg = gst_wasapi_util_hresult_to_string (hr);
@@ -584,9 +583,6 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
     goto beach;
   }
 
-  self->render_client = render_client;
-  render_client = NULL;
-
   gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
       (self)->ringbuffer, self->positions);
 
@@ -602,8 +598,10 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
   res = TRUE;
 
 beach:
-  if (render_client != NULL)
-    IUnknown_Release (render_client);
+  /* unprepare() is not called if prepare() fails, but we want it to be, so call
+   * it manually when needed */
+  if (!res)
+    gst_wasapi_sink_unprepare (asink);
 
   return res;
 }
index 06dadd9..87557e7 100644 (file)
@@ -380,9 +380,6 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
 {
   GstWasapiSrc *self = GST_WASAPI_SRC (asrc);
   gboolean res = FALSE;
-  IAudioClock *client_clock = NULL;
-  guint64 client_clock_freq = 0;
-  IAudioCaptureClient *capture_client = NULL;
   REFERENCE_TIME latency_rt, default_period, min_period;
   REFERENCE_TIME device_period, device_buffer_duration;
   guint bpf, rate, buffer_frames;
@@ -392,7 +389,7 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
       &min_period);
   if (hr != S_OK) {
     GST_ERROR_OBJECT (self, "IAudioClient::GetDevicePeriod failed");
-    goto beach;
+    return FALSE;
   }
   GST_INFO_OBJECT (self, "wasapi default period: %" G_GINT64_FORMAT
       ", min period: %" G_GINT64_FORMAT, default_period, min_period);
@@ -468,11 +465,11 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
 
   /* Get the clock and the clock freq */
   if (!gst_wasapi_util_get_clock (GST_ELEMENT (self), self->client,
-          &client_clock)) {
+          &self->client_clock)) {
     goto beach;
   }
 
-  hr = IAudioClock_GetFrequency (client_clock, &client_clock_freq);
+  hr = IAudioClock_GetFrequency (self->client_clock, &self->client_clock_freq);
   if (hr != S_OK) {
     GST_ERROR_OBJECT (self, "IAudioClock::GetFrequency failed");
     goto beach;
@@ -480,7 +477,7 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
 
   /* Get capture source client and start it up */
   if (!gst_wasapi_util_get_capture_client (GST_ELEMENT (self), self->client,
-          &capture_client)) {
+          &self->capture_client)) {
     goto beach;
   }
 
@@ -490,10 +487,6 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
     goto beach;
   }
 
-  self->client_clock = client_clock;
-  self->client_clock_freq = client_clock_freq;
-  self->capture_client = capture_client;
-
   gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
       (self)->ringbuffer, self->positions);
 
@@ -507,15 +500,11 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
 #endif
 
   res = TRUE;
-
 beach:
-  if (!res) {
-    if (capture_client != NULL)
-      IUnknown_Release (capture_client);
-
-    if (client_clock != NULL)
-      IUnknown_Release (client_clock);
-  }
+  /* unprepare() is not called if prepare() fails, but we want it to be, so call
+   * it manually when needed */
+  if (!res)
+    gst_wasapi_src_unprepare (asrc);
 
   return res;
 }
@@ -549,6 +538,8 @@ gst_wasapi_src_unprepare (GstAudioSrc * asrc)
     self->client_clock = NULL;
   }
 
+  self->client_clock_freq = 0;
+
   return TRUE;
 }