wasapi: Call _Start if the client was _Reset
authorNirbheek Chauhan <nirbheek@centricular.com>
Mon, 9 Apr 2018 23:39:42 +0000 (05:09 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Mon, 9 Apr 2018 23:46:54 +0000 (05:16 +0530)
Otherwise we will wait forever in WaitForSingleObject because we forgot
to start the client again after _Stop is called in reset().

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

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

index 6ea72e1..8267d3f 100644 (file)
@@ -175,6 +175,7 @@ gst_wasapi_sink_init (GstWasapiSink * self)
   self->low_latency = DEFAULT_LOW_LATENCY;
   self->try_audioclient3 = DEFAULT_AUDIOCLIENT3;
   self->event_handle = CreateEvent (NULL, FALSE, FALSE, NULL);
+  self->client_needs_restart = FALSE;
 
   CoInitialize (NULL);
 }
@@ -606,6 +607,14 @@ gst_wasapi_sink_write (GstAudioSink * asink, gpointer data, guint length)
   gint16 *dst = NULL;
   guint pending = length;
 
+  GST_OBJECT_LOCK (self);
+  if (self->client_needs_restart) {
+    hr = IAudioClient_Start (self->client);
+    HR_FAILED_AND (hr, IAudioClient::Start, length = 0; goto beach);
+    self->client_needs_restart = FALSE;
+  }
+  GST_OBJECT_UNLOCK (self);
+
   while (pending > 0) {
     guint can_frames, have_frames, n_frames, write_len;
 
@@ -661,12 +670,18 @@ gst_wasapi_sink_reset (GstAudioSink * asink)
   GstWasapiSink *self = GST_WASAPI_SINK (asink);
   HRESULT hr;
 
+  GST_INFO_OBJECT (self, "reset called");
+
   if (!self->client)
     return;
 
+  GST_OBJECT_LOCK (self);
   hr = IAudioClient_Stop (self->client);
-  HR_FAILED_RET (hr, IAudioClient::Stop,);
+  HR_FAILED_AND (hr, IAudioClient::Stop,);
 
   hr = IAudioClient_Reset (self->client);
-  HR_FAILED_RET (hr, IAudioClient::Reset,);
+  HR_FAILED_AND (hr, IAudioClient::Reset,);
+
+  self->client_needs_restart = TRUE;
+  GST_OBJECT_UNLOCK (self);
 }
index c178669..e3b2101 100644 (file)
@@ -45,6 +45,8 @@ struct _GstWasapiSink
   IAudioRenderClient *render_client;
   HANDLE event_handle;
   HANDLE thread_priority_handle;
+  /* Client was reset, so it needs to be started again */
+  gboolean client_needs_restart;
 
   /* Actual size of the allocated buffer */
   guint buffer_frame_count;
index 389d49a..da1e097 100644 (file)
@@ -182,6 +182,7 @@ gst_wasapi_src_init (GstWasapiSrc * self)
   self->low_latency = DEFAULT_LOW_LATENCY;
   self->try_audioclient3 = DEFAULT_AUDIOCLIENT3;
   self->event_handle = CreateEvent (NULL, FALSE, FALSE, NULL);
+  self->client_needs_restart = FALSE;
 
   CoInitialize (NULL);
 }
@@ -555,6 +556,14 @@ gst_wasapi_src_read (GstAudioSrc * asrc, gpointer data, guint length,
   guint wanted = length;
   DWORD flags;
 
+  GST_OBJECT_LOCK (self);
+  if (self->client_needs_restart) {
+    hr = IAudioClient_Start (self->client);
+    HR_FAILED_AND (hr, IAudioClient::Start, length = 0; goto beach);
+    self->client_needs_restart = FALSE;
+  }
+  GST_OBJECT_UNLOCK (self);
+
   while (wanted > 0) {
     guint have_frames, n_frames, want_frames, read_len;
 
@@ -641,11 +650,15 @@ gst_wasapi_src_reset (GstAudioSrc * asrc)
   if (!self->client)
     return;
 
+  GST_OBJECT_LOCK (self);
   hr = IAudioClient_Stop (self->client);
   HR_FAILED_RET (hr, IAudioClock::Stop,);
 
   hr = IAudioClient_Reset (self->client);
   HR_FAILED_RET (hr, IAudioClock::Reset,);
+
+  self->client_needs_restart = TRUE;
+  GST_OBJECT_UNLOCK (self);
 }
 
 static GstClockTime
index 24ed655..d6a2e20 100644 (file)
@@ -47,6 +47,8 @@ struct _GstWasapiSrc
   IAudioCaptureClient *capture_client;
   HANDLE event_handle;
   HANDLE thread_priority_handle;
+  /* Client was reset, so it needs to be started again */
+  gboolean client_needs_restart;
 
   /* Actual size of the allocated buffer */
   guint buffer_frame_count;