dshowsrcwrapper: add device-index property to sources

This allows users to more easily select different devices without having
to first get the device or device-name.

https://bugzilla.gnome.org/show_bug.cgi?id=797338
This commit is contained in:
Joshua M. Doe 2018-10-11 12:45:21 -04:00 committed by Nirbheek Chauhan
parent 5caefc1e0c
commit 6c7ba14247
6 changed files with 58 additions and 9 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;