summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOle André Vadla Ravnås <oravnas@cisco.com>2009-08-31 19:26:36 +0200
committerOle André Vadla Ravnås <oravnas@cisco.com>2010-10-28 17:08:31 +0200
commit2cf589b9287bddd614ff21dff8d890c4c036354c (patch)
treea9c20394bb1862387cc6e49b0012947f98ca0858
parenta54972f8069a324beffde0087a9f4a099def122f (diff)
winks: sort devices that look like cameras first
-rw-r--r--sys/winks/gstksvideosrc.c2
-rw-r--r--sys/winks/ksvideohelpers.c91
-rw-r--r--sys/winks/ksvideohelpers.h2
3 files changed, 95 insertions, 0 deletions
diff --git a/sys/winks/gstksvideosrc.c b/sys/winks/gstksvideosrc.c
index 16c19f226..3c58d74bd 100644
--- a/sys/winks/gstksvideosrc.c
+++ b/sys/winks/gstksvideosrc.c
@@ -388,6 +388,8 @@ gst_ks_video_src_open_device (GstKsVideoSrc * self)
if (devices == NULL)
goto error_no_devices;
+ devices = ks_video_device_list_sort_cameras_first (devices);
+
for (cur = devices; cur != NULL; cur = cur->next) {
KsDeviceEntry *entry = cur->data;
diff --git a/sys/winks/ksvideohelpers.c b/sys/winks/ksvideohelpers.c
index 419f2662b..e93f71b1d 100644
--- a/sys/winks/ksvideohelpers.c
+++ b/sys/winks/ksvideohelpers.c
@@ -37,6 +37,97 @@ extern const GUID MEDIASUBTYPE_I420 =
0x71}
};
+typedef struct _KsVideoDeviceEntry KsVideoDeviceEntry;
+
+struct _KsVideoDeviceEntry
+{
+ KsDeviceEntry *device;
+ gint priority;
+};
+
+static void
+ks_video_device_entry_decide_priority (KsVideoDeviceEntry * videodevice)
+{
+ HANDLE filter_handle;
+
+ videodevice->priority = 0;
+
+ filter_handle = CreateFile (videodevice->device->path,
+ GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+ if (ks_is_valid_handle (filter_handle)) {
+ GUID *propsets = NULL;
+ gulong propsets_len;
+
+ if (ks_object_get_supported_property_sets (filter_handle, &propsets,
+ &propsets_len)) {
+ gulong i;
+
+ for (i = 0; i < propsets_len; i++) {
+ if (memcmp (&propsets[i], &PROPSETID_VIDCAP_CAMERACONTROL,
+ sizeof (GUID)) == 0) {
+ videodevice->priority++;
+ break;
+ }
+ }
+
+ g_free (propsets);
+ }
+ }
+
+ CloseHandle (filter_handle);
+}
+
+static gint
+ks_video_device_entry_compare (gconstpointer a, gconstpointer b)
+{
+ const KsVideoDeviceEntry *videodevice_a = a;
+ const KsVideoDeviceEntry *videodevice_b = b;
+
+ if (videodevice_a->priority > videodevice_b->priority)
+ return -1;
+ else if (videodevice_a->priority == videodevice_b->priority)
+ return 0;
+ else
+ return 1;
+}
+
+GList *
+ks_video_device_list_sort_cameras_first (GList * devices)
+{
+ GList *videodevices = NULL, *walk;
+ guint i;
+
+ for (walk = devices; walk != NULL; walk = walk->next) {
+ KsDeviceEntry *device = walk->data;
+ KsVideoDeviceEntry *videodevice;
+
+ videodevice = g_new (KsVideoDeviceEntry, 1);
+ videodevice->device = device;
+ ks_video_device_entry_decide_priority (videodevice);
+
+ videodevices = g_list_append (videodevices, videodevice);
+ }
+
+ videodevices = g_list_sort (videodevices, ks_video_device_entry_compare);
+
+ g_list_free (devices);
+ devices = NULL;
+
+ for (walk = videodevices, i = 0; walk != NULL; walk = walk->next, i++) {
+ KsVideoDeviceEntry *videodevice = walk->data;
+
+ videodevice->device->index = i;
+ devices = g_list_append (devices, videodevice->device);
+
+ g_free (videodevice);
+ }
+
+ g_list_free (videodevices);
+
+ return devices;
+}
+
static GstStructure *
ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
{
diff --git a/sys/winks/ksvideohelpers.h b/sys/winks/ksvideohelpers.h
index 7be539ae3..0755d2356 100644
--- a/sys/winks/ksvideohelpers.h
+++ b/sys/winks/ksvideohelpers.h
@@ -51,6 +51,8 @@ struct _KsVideoMediaType
GstCaps * translated_caps;
};
+GList * ks_video_device_list_sort_cameras_first (GList * devices);
+
KsVideoMediaType * ks_video_media_type_dup (KsVideoMediaType * media_type);
void ks_video_media_type_free (KsVideoMediaType * media_type);
GList * ks_video_probe_filter_for_caps (HANDLE filter_handle);