directsoundsrc: add device property as it is done in directsoundsink
authorThomas Roos <thomas.roos@industronic.de>
Fri, 18 Dec 2015 11:26:16 +0000 (12:26 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 18 Dec 2015 11:39:03 +0000 (12:39 +0100)
This allows selection of the device by GUID instead of the name. The name is
user-given and multiple devices can have the same name.

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

sys/directsound/gstdirectsoundsrc.c
sys/directsound/gstdirectsoundsrc.h

index 2fb0483a2015a3a52255a078a6198eb5ee569f35..b88e68e10da29c8ed3715db1e40d3275c7b9d8a4 100644 (file)
@@ -45,7 +45,7 @@
  */
 
 /*
-  TODO: add device selection and check rate etc.
+  TODO: add mixer device init for selection by device-guid
 */
 
 /**
@@ -87,6 +87,7 @@ enum
 {
   PROP_0,
   PROP_DEVICE_NAME,
+  PROP_DEVICE,
   PROP_VOLUME,
   PROP_MUTE
 };
@@ -130,6 +131,11 @@ static gboolean gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc);
 static void gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc,
     gboolean mute);
 
+static const gchar *gst_directsound_src_get_device (GstDirectSoundSrc *
+    dsoundsrc);
+static void gst_directsound_src_set_device (GstDirectSoundSrc * dsoundsrc,
+    const gchar * device_id);
+
 static GstStaticPadTemplate directsound_src_src_factory =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -158,6 +164,9 @@ gst_directsound_src_finalize (GObject * object)
   g_mutex_clear (&dsoundsrc->dsound_lock);
 
   g_free (dsoundsrc->device_name);
+
+  g_free (dsoundsrc->device_id);
+
   g_free (dsoundsrc->device_guid);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -212,6 +221,12 @@ gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
       g_param_spec_string ("device-name", "Device name",
           "Human-readable name of the sound device", NULL, G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class,
+      PROP_DEVICE,
+      g_param_spec_string ("device", "Device",
+          "DirectSound playback device as a GUID string (volume and mute will not work!)",
+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property
       (gobject_class, PROP_VOLUME,
       g_param_spec_double ("volume", "Volume",
@@ -251,7 +266,6 @@ gst_directsound_src_set_property (GObject * object, guint prop_id,
       if (g_value_get_string (value)) {
         src->device_name = g_strdup (g_value_get_string (value));
       }
-
       break;
     case PROP_VOLUME:
       gst_directsound_src_set_volume (src, g_value_get_double (value));
@@ -259,6 +273,9 @@ gst_directsound_src_set_property (GObject * object, guint prop_id,
     case PROP_MUTE:
       gst_directsound_src_set_mute (src, g_value_get_boolean (value));
       break;
+    case PROP_DEVICE:
+      gst_directsound_src_set_device (src, g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -277,6 +294,9 @@ gst_directsound_src_get_property (GObject * object, guint prop_id,
     case PROP_DEVICE_NAME:
       g_value_set_string (value, src->device_name);
       break;
+    case PROP_DEVICE:
+      g_value_set_string (value, gst_directsound_src_get_device (src));
+      break;
     case PROP_VOLUME:
       g_value_set_double (value, gst_directsound_src_get_volume (src));
       break;
@@ -301,6 +321,7 @@ gst_directsound_src_init (GstDirectSoundSrc * src)
   GST_DEBUG_OBJECT (src, "initializing directsoundsrc");
   g_mutex_init (&src->dsound_lock);
   src->device_guid = NULL;
+  src->device_id = NULL;
   src->device_name = NULL;
   src->mixer = NULL;
   src->control_id_mute = -1;
@@ -335,6 +356,28 @@ gst_directsound_enum_callback (GUID * pGUID, TCHAR * strDesc,
   return TRUE;
 }
 
+static LPGUID
+string_to_guid (const gchar * str)
+{
+  HRESULT ret;
+  gunichar2 *wstr;
+  LPGUID out;
+
+  wstr = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
+  if (!wstr)
+    return NULL;
+
+  out = g_new (GUID, 1);
+  ret = CLSIDFromString ((LPOLESTR) wstr, out);
+  g_free (wstr);
+  if (ret != NOERROR) {
+    g_free (out);
+    return NULL;
+  }
+
+  return out;
+}
+
 static gboolean
 gst_directsound_src_open (GstAudioSrc * asrc)
 {
@@ -361,19 +404,37 @@ gst_directsound_src_open (GstAudioSrc * asrc)
     goto capture_function;
   }
 
-  hRes = DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)
-      gst_directsound_enum_callback, (VOID *) dsoundsrc);
-  if (FAILED (hRes)) {
-    goto capture_enumerate;
-  }
+  if (dsoundsrc->device_id) {
+    GST_DEBUG_OBJECT (asrc, "device id set to: %s ", dsoundsrc->device_id);
+    dsoundsrc->device_guid = string_to_guid (dsoundsrc->device_id);
+    if (dsoundsrc->device_guid == NULL) {
+      GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+          ("gst_directsound_src_open: device set, but guid not found: %s",
+              dsoundsrc->device_id), (NULL));
+      g_free (dsoundsrc->device_guid);
+      return FALSE;
+    }
+  } else {
 
+    hRes = DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)
+        gst_directsound_enum_callback, (VOID *) dsoundsrc);
+
+    if (FAILED (hRes)) {
+      goto capture_enumerate;
+    }
+  }
   /* Create capture object */
   hRes = pDSoundCaptureCreate (dsoundsrc->device_guid, &dsoundsrc->pDSC, NULL);
+
+
   if (FAILED (hRes)) {
     goto capture_object;
   }
+  // mixer is only supported when device-id is not set
+  if (!dsoundsrc->device_id) {
+    gst_directsound_src_mixer_init (dsoundsrc);
+  }
 
-  gst_directsound_src_mixer_init (dsoundsrc);
   return TRUE;
 
 capture_function:
@@ -936,3 +997,17 @@ gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc, gboolean mute)
   else
     dsoundsrc->mute = mute;
 }
+
+static const gchar *
+gst_directsound_src_get_device (GstDirectSoundSrc * dsoundsrc)
+{
+  return dsoundsrc->device_id;
+}
+
+static void
+gst_directsound_src_set_device (GstDirectSoundSrc * dsoundsrc,
+    const gchar * device_id)
+{
+  g_free (dsoundsrc->device_id);
+  dsoundsrc->device_id = g_strdup (device_id);
+}
index d4258cd5664bd7c75e33e6943093fd536dfd76c4..9aa225fb3cc92fd025abc761ae4201fd0ea7ff72 100644 (file)
@@ -103,7 +103,9 @@ struct _GstDirectSoundSrc
   gboolean mute;
 
   GUID *device_guid;
+
   char *device_name;
+  char *device_id;
 
   GMutex dsound_lock;