From 2cf589b9287bddd614ff21dff8d890c4c036354c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Mon, 31 Aug 2009 19:26:36 +0200 Subject: [PATCH] winks: sort devices that look like cameras first --- sys/winks/gstksvideosrc.c | 2 + sys/winks/ksvideohelpers.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ sys/winks/ksvideohelpers.h | 2 + 3 files changed, 95 insertions(+) diff --git a/sys/winks/gstksvideosrc.c b/sys/winks/gstksvideosrc.c index 16c19f2..3c58d74 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 419f266..e93f71b 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 7be539a..0755d23 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); -- 2.7.4