wasapi: Fix some leaks, bugs, and compiler warnings
authorNirbheek Chauhan <nirbheek@centricular.com>
Wed, 24 Jan 2018 02:50:13 +0000 (08:20 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Thu, 25 Jan 2018 12:27:23 +0000 (17:57 +0530)
Also improve logging.

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

index 31d49e5..da54d8e 100644 (file)
@@ -157,14 +157,36 @@ gst_wasapi_sink_dispose (GObject * object)
     self->event_handle = NULL;
   }
 
+  if (self->client != NULL) {
+    IUnknown_Release (self->client);
+    self->client = NULL;
+  }
+
+  if (self->render_client != NULL) {
+    IUnknown_Release (self->render_client);
+    self->render_client = NULL;
+  }
+
   G_OBJECT_CLASS (gst_wasapi_sink_parent_class)->dispose (object);
 }
 
 static void
 gst_wasapi_sink_finalize (GObject * object)
 {
+  GstWasapiSink *self = GST_WASAPI_SINK (object);
+
+  g_clear_pointer (&self->mix_format, CoTaskMemFree);
+
   CoUninitialize ();
 
+  if (self->cached_caps != NULL) {
+    gst_caps_unref (self->cached_caps);
+    self->cached_caps = NULL;
+  }
+
+  g_clear_pointer (&self->device, g_free);
+  self->mute = FALSE;
+
   G_OBJECT_CLASS (gst_wasapi_sink_parent_class)->finalize (object);
 }
 
@@ -183,10 +205,10 @@ gst_wasapi_sink_set_property (GObject * object, guint prop_id,
       break;
     case PROP_DEVICE:
     {
-      gchar *device = g_value_get_string (value);
+      const gchar *device = g_value_get_string (value);
       g_free (self->device);
       self->device =
-          device ? g_utf8_to_utf16 (device, 0, NULL, NULL, NULL) : NULL;
+          device ? g_utf8_to_utf16 (device, -1, NULL, NULL, NULL) : NULL;
       break;
     }
     default:
@@ -210,7 +232,7 @@ gst_wasapi_sink_get_property (GObject * object, guint prop_id,
       break;
     case PROP_DEVICE:
       g_value_take_string (value, self->device ?
-          g_utf16_to_utf8 (self->device, 0, NULL, NULL, NULL) : NULL);
+          g_utf16_to_utf8 (self->device, -1, NULL, NULL, NULL) : NULL);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index 78ad7e6..0914d1c 100644 (file)
@@ -157,14 +157,36 @@ gst_wasapi_src_dispose (GObject * object)
     self->event_handle = NULL;
   }
 
+  if (self->client_clock != NULL) {
+    IUnknown_Release (self->client_clock);
+    self->client_clock = NULL;
+  }
+
+  if (self->client != NULL) {
+    IUnknown_Release (self->client);
+    self->client = NULL;
+  }
+
+  if (self->capture_client != NULL) {
+    IUnknown_Release (self->capture_client);
+    self->capture_client = NULL;
+  }
+
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void
 gst_wasapi_src_finalize (GObject * object)
 {
+  GstWasapiSrc *self = GST_WASAPI_SRC (object);
+
+  g_clear_pointer (&self->mix_format, CoTaskMemFree);
+
   CoUninitialize ();
 
+  g_clear_pointer (&self->cached_caps, gst_caps_unref);
+  g_clear_pointer (&self->device, g_free);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -180,10 +202,10 @@ gst_wasapi_src_set_property (GObject * object, guint prop_id,
       break;
     case PROP_DEVICE:
     {
-      gchar *device = g_value_get_string (value);
+      const gchar *device = g_value_get_string (value);
       g_free (self->device);
       self->device =
-          device ? g_utf8_to_utf16 (device, 0, NULL, NULL, NULL) : NULL;
+          device ? g_utf8_to_utf16 (device, -1, NULL, NULL, NULL) : NULL;
       break;
     }
     default:
@@ -204,7 +226,7 @@ gst_wasapi_src_get_property (GObject * object, guint prop_id,
       break;
     case PROP_DEVICE:
       g_value_take_string (value, self->device ?
-          g_utf16_to_utf8 (self->device, 0, NULL, NULL, NULL) : NULL);
+          g_utf16_to_utf8 (self->device, -1, NULL, NULL, NULL) : NULL);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -275,6 +297,10 @@ gst_wasapi_src_open (GstAudioSrc * asrc)
   if (self->client)
     return TRUE;
 
+  /* FIXME: Switching the default device does not switch the stream to it,
+   * even if the old device was unplugged. We need to handle this somehow.
+   * For example, perhaps we should automatically switch to the new device if
+   * the default device is changed and a device isn't explicitly selected. */
   if (!gst_wasapi_util_get_device_client (GST_ELEMENT (self), TRUE,
           self->role, self->device, &client)) {
     if (!self->device)
@@ -344,8 +370,6 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
     goto beach;
   }
 
-  GST_INFO_OBJECT (self, "we got till here");
-
   /* Get the clock and the clock freq */
   if (!gst_wasapi_util_get_clock (GST_ELEMENT (self), self->client,
           &client_clock)) {
@@ -440,8 +464,12 @@ gst_wasapi_src_read (GstAudioSrc * asrc, gpointer data, guint length,
     hr = IAudioCaptureClient_GetBuffer (self->capture_client,
         (BYTE **) & from, &have_frames, &flags, NULL, NULL);
     if (hr != S_OK) {
-      GST_ERROR_OBJECT (self, "IAudioCaptureClient::GetBuffer () failed: %s",
-          gst_wasapi_util_hresult_to_string (hr));
+      if (hr == AUDCLNT_S_BUFFER_EMPTY)
+        GST_WARNING_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s"
+            ", retrying", gst_wasapi_util_hresult_to_string (hr));
+      else
+        GST_ERROR_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s",
+            gst_wasapi_util_hresult_to_string (hr));
       length = 0;
       goto beach;
     }
index 4bf862e..ed9f508 100644 (file)
@@ -224,8 +224,8 @@ gst_wasapi_util_get_device_client (GstElement * element,
   hr = CoCreateInstance (&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
       &IID_IMMDeviceEnumerator, (void **) &enumerator);
   if (hr != S_OK) {
-    GST_ERROR ("CoCreateInstance (MMDeviceEnumerator) failed: %s",
-        gst_wasapi_util_hresult_to_string (hr));
+    GST_ERROR_OBJECT (element, "CoCreateInstance (MMDeviceEnumerator) failed:"
+        "%s", gst_wasapi_util_hresult_to_string (hr));
     goto beach;
   }
 
@@ -233,14 +233,16 @@ gst_wasapi_util_get_device_client (GstElement * element,
     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint (enumerator,
         capture ? eCapture : eRender, role, &device);
     if (hr != S_OK) {
-      GST_ERROR ("IMMDeviceEnumerator::GetDefaultAudioEndpoint () failed: %s",
+      GST_ERROR_OBJECT (element,
+          "IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: %s",
           gst_wasapi_util_hresult_to_string (hr));
       goto beach;
     }
   } else {
     hr = IMMDeviceEnumerator_GetDevice (enumerator, device_name, &device);
     if (hr != S_OK) {
-      GST_ERROR ("IMMDeviceEnumerator::GetDevice (\"%S\") failed", device_name);
+      GST_ERROR_OBJECT (element, "IMMDeviceEnumerator::GetDevice (%S) failed"
+          ": %s", device_name, gst_wasapi_util_hresult_to_string (hr));
       goto beach;
     }
   }
@@ -248,8 +250,8 @@ gst_wasapi_util_get_device_client (GstElement * element,
   hr = IMMDevice_Activate (device, &IID_IAudioClient, CLSCTX_ALL, NULL,
       (void **) &client);
   if (hr != S_OK) {
-    GST_ERROR ("IMMDevice::Activate (IID_IAudioClient) failed: %s",
-        gst_wasapi_util_hresult_to_string (hr));
+    GST_ERROR_OBJECT (element, "IMMDevice::Activate (IID_IAudioClient) failed"
+        ": %s", gst_wasapi_util_hresult_to_string (hr));
     goto beach;
   }
 
@@ -282,7 +284,8 @@ gst_wasapi_util_get_render_client (GstElement * element, IAudioClient * client,
   hr = IAudioClient_GetService (client, &IID_IAudioRenderClient,
       (void **) &render_client);
   if (hr != S_OK) {
-    GST_ERROR ("IAudioClient::GetService (IID_IAudioRenderClient) failed: %s",
+    GST_ERROR_OBJECT (element,
+        "IAudioClient::GetService (IID_IAudioRenderClient) failed: %s",
         gst_wasapi_util_hresult_to_string (hr));
     goto beach;
   }
@@ -305,7 +308,8 @@ gst_wasapi_util_get_capture_client (GstElement * element, IAudioClient * client,
   hr = IAudioClient_GetService (client, &IID_IAudioCaptureClient,
       (void **) &capture_client);
   if (hr != S_OK) {
-    GST_ERROR ("IAudioClient::GetService (IID_IAudioCaptureClient) failed: %s",
+    GST_ERROR_OBJECT (element,
+        "IAudioClient::GetService (IID_IAudioCaptureClient) failed: %s",
         gst_wasapi_util_hresult_to_string (hr));
     goto beach;
   }
@@ -327,7 +331,8 @@ gst_wasapi_util_get_clock (GstElement * element, IAudioClient * client,
 
   hr = IAudioClient_GetService (client, &IID_IAudioClock, (void **) &clock);
   if (hr != S_OK) {
-    GST_ERROR ("IAudioClient::GetService (IID_IAudioClock) failed: %s",
+    GST_ERROR_OBJECT (element,
+        "IAudioClient::GetService (IID_IAudioClock) failed: %s",
         gst_wasapi_util_hresult_to_string (hr));
     goto beach;
   }
@@ -339,7 +344,7 @@ beach:
   return res;
 }
 
-const gchar *
+static const gchar *
 gst_waveformatex_to_audio_format (WAVEFORMATEXTENSIBLE * format)
 {
   const gchar *fmt_str = NULL;