mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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:
parent
5caefc1e0c
commit
6c7ba14247
6 changed files with 58 additions and 9 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue