diff --git a/sys/dshowsrcwrapper/gstdshow.cpp b/sys/dshowsrcwrapper/gstdshow.cpp index c1eed85aec..58e33874ef 100644 --- a/sys/dshowsrcwrapper/gstdshow.cpp +++ b/sys/dshowsrcwrapper/gstdshow.cpp @@ -291,7 +291,7 @@ clean: gchar * gst_dshow_getdevice_from_devicename (const GUID * device_category, - gchar ** device_name) + gchar ** device_name, gint * device_index) { gchar *ret = NULL; ICreateDevEnum *devices_enum = NULL; @@ -300,6 +300,7 @@ gst_dshow_getdevice_from_devicename (const GUID * device_category, HRESULT hres = S_FALSE; ULONG fetched; gboolean bfound = FALSE; + gint devidx = -1; hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **) &devices_enum); @@ -333,14 +334,18 @@ gst_dshow_getdevice_from_devicename (const GUID * device_category, g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal, wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL); - if (!*device_name) { + devidx++; + GST_DEBUG ("Found device idx=%d: %s", devidx, friendly_name); + + if (!*device_name && devidx == *device_index) { *device_name = g_strdup (friendly_name); } - if (_stricmp (*device_name, friendly_name) == 0) { + if (*device_name && _stricmp (*device_name, friendly_name) == 0) { WCHAR *wszDisplayName = NULL; hres = moniker->GetDisplayName (NULL, NULL, &wszDisplayName); if (hres == S_OK && wszDisplayName) { + *device_index = devidx; ret = g_utf16_to_utf8 ((const gunichar2 *) wszDisplayName, wcslen (wszDisplayName), NULL, NULL, NULL); CoTaskMemFree (wszDisplayName); diff --git a/sys/dshowsrcwrapper/gstdshow.h b/sys/dshowsrcwrapper/gstdshow.h index 4c75f354af..aff5d0af1a 100644 --- a/sys/dshowsrcwrapper/gstdshow.h +++ b/sys/dshowsrcwrapper/gstdshow.h @@ -84,7 +84,7 @@ gboolean gst_dshow_find_filter (CLSID input_majortype, CLSID input_subtype, /* get the dshow device path from device friendly name. If friendly name is not set, it will return the first available device */ gchar *gst_dshow_getdevice_from_devicename (const GUID * device_category, - gchar ** device_name); + gchar ** device_name, gint * device_index); /* show the capture filter property page (generally used to setup the device). the page is modal*/ gboolean gst_dshow_show_propertypage (IBaseFilter * base_filter); diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp index d78f139d69..29c250bbea 100644 --- a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp @@ -48,9 +48,12 @@ enum { PROP_0, PROP_DEVICE, - PROP_DEVICE_NAME + PROP_DEVICE_NAME, + PROP_DEVICE_INDEX }; +#define DEFAULT_PROP_DEVICE_INDEX 0 + static void gst_dshowaudiosrc_dispose (GObject * gobject); static void gst_dshowaudiosrc_set_property (GObject * object, guint prop_id, @@ -122,6 +125,13 @@ gst_dshowaudiosrc_class_init (GstDshowAudioSrcClass * klass) "Human-readable name of the sound device", NULL, static_cast < GParamFlags > (G_PARAM_READWRITE))); + g_object_class_install_property + (gobject_class, PROP_DEVICE_INDEX, + g_param_spec_int ("device-index", "Device index", + "Index of the enumerated audio device", 0, G_MAXINT, + DEFAULT_PROP_DEVICE_INDEX, + static_cast < GParamFlags > (G_PARAM_READWRITE))); + gst_element_class_add_static_pad_template (gstelement_class, &src_template); gst_element_class_set_static_metadata (gstelement_class, @@ -138,6 +148,7 @@ gst_dshowaudiosrc_init (GstDshowAudioSrc * src) { src->device = NULL; src->device_name = NULL; + src->device_index = DEFAULT_PROP_DEVICE_INDEX; src->audio_cap_filter = NULL; src->dshow_fakesink = NULL; src->media_filter = NULL; @@ -224,6 +235,11 @@ gst_dshowaudiosrc_set_property (GObject * object, guint prop_id, } break; } + case PROP_DEVICE_INDEX: + { + src->device_index = g_value_get_int (value); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -254,7 +270,7 @@ gst_dshowaudiosrc_get_caps (GstBaseSrc * basesrc, GstCaps * filter) src->device = gst_dshow_getdevice_from_devicename (&CLSID_AudioInputDeviceCategory, - &src->device_name); + &src->device_name, &src->device_index); if (!src->device) { GST_ERROR ("No audio device found."); return NULL; diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.h b/sys/dshowsrcwrapper/gstdshowaudiosrc.h index dcd43423e0..d5dd2f3500 100644 --- a/sys/dshowsrcwrapper/gstdshowaudiosrc.h +++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.h @@ -48,6 +48,9 @@ struct _GstDshowAudioSrc /* device friendly name */ gchar *device_name; + /* device index */ + gint device_index; + /* list of caps created from the list of supported media types of the dshow capture filter */ GstCaps *caps; diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp index 9b478db5dd..722bb06372 100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp @@ -68,9 +68,12 @@ enum { PROP_0, PROP_DEVICE, - PROP_DEVICE_NAME + PROP_DEVICE_NAME, + PROP_DEVICE_INDEX }; +#define DEFAULT_PROP_DEVICE_INDEX 0 + static void gst_dshowvideosrc_dispose (GObject * gobject); static void gst_dshowvideosrc_set_property (GObject * object, guint prop_id, @@ -141,7 +144,14 @@ gst_dshowvideosrc_class_init (GstDshowVideoSrcClass * klass) g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, g_param_spec_string ("device-name", "Device name", - "Human-readable name of the sound device", NULL, + "Human-readable name of the video device", NULL, + static_cast < GParamFlags > (G_PARAM_READWRITE))); + + g_object_class_install_property + (gobject_class, PROP_DEVICE_INDEX, + g_param_spec_int ("device-index", "Device index", + "Index of the enumerated video device", 0, G_MAXINT, + DEFAULT_PROP_DEVICE_INDEX, static_cast < GParamFlags > (G_PARAM_READWRITE))); gst_element_class_add_static_pad_template (gstelement_class, &src_template); @@ -161,6 +171,7 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src) { src->device = NULL; src->device_name = NULL; + src->device_index = DEFAULT_PROP_DEVICE_INDEX; src->video_cap_filter = NULL; src->dshow_fakesink = NULL; src->media_filter = NULL; @@ -292,6 +303,11 @@ gst_dshowvideosrc_set_property (GObject * object, guint prop_id, } break; } + case PROP_DEVICE_INDEX: + { + src->device_index = g_value_get_int (value); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -319,16 +335,22 @@ gst_dshowvideosrc_get_caps (GstBaseSrc * basesrc, GstCaps * filter) return gst_caps_ref (src->caps); } + /* device will be used first, then device-name, then device-index */ if (!src->device) { + GST_DEBUG_OBJECT (src, "No device set, will enumerate to match device-name or device-index"); + src->device = gst_dshow_getdevice_from_devicename (&CLSID_VideoInputDeviceCategory, - &src->device_name); + &src->device_name, &src->device_index); if (!src->device) { GST_ERROR ("No video device found."); return NULL; } } + GST_DEBUG_OBJECT (src, "Opening device-index=%d, device-name='%s', device='%s'", + src->device_index, src->device_name, src->device); + unidevice = g_utf8_to_utf16 (src->device, strlen (src->device), NULL, NULL, NULL); diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.h b/sys/dshowsrcwrapper/gstdshowvideosrc.h index 684ffd6a15..c18271fb8b 100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.h +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.h @@ -55,6 +55,9 @@ struct _GstDshowVideoSrc /* device friendly name */ gchar *device_name; + /* device index */ + gint device_index; + /* list of caps created from the list of supported media types of the dshow capture filter */ GstCaps *caps;