/* GStreamer * Copyright (C) 2014 Collabora * Author: Olivier Crete * * gstdevice.c: Unit test for GstDevice * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include typedef struct _GstTestDevice { GstDevice parent; } GstTestDevice; typedef struct _GstTestDeviceClass { GstDeviceClass parent_class; } GstTestDeviceClass; GType gst_test_device_get_type (void); G_DEFINE_TYPE (GstTestDevice, gst_test_device, GST_TYPE_DEVICE); static GstElement * gst_test_device_create_element (GstDevice * device, const gchar * name) { return gst_bin_new (name); } static gboolean gst_test_device_reconfigure_element (GstDevice * device, GstElement * element) { if (!strcmp (GST_ELEMENT_NAME (element), "reconfigurable")) return TRUE; else return FALSE; } static void gst_test_device_class_init (GstTestDeviceClass * klass) { GstDeviceClass *dclass = GST_DEVICE_CLASS (klass); dclass->create_element = gst_test_device_create_element; dclass->reconfigure_element = gst_test_device_reconfigure_element; } static void gst_test_device_init (GstTestDevice * self) { } #define DEVICE_CLASS "Test0/Test1/Test2/Test3/Test4/TestDev" #define DISPLAY_NAME "Test device" static GstDevice * test_device_new (void) { GstCaps *caps = gst_caps_new_empty_simple ("video/test"); GstDevice *device = g_object_new (gst_test_device_get_type (), "caps", caps, "display-name", DISPLAY_NAME, "device-class", DEVICE_CLASS, NULL); gst_caps_unref (caps); return device; } GST_START_TEST (test_device) { GstDevice *device = test_device_new (); GstCaps *caps; gchar *display_name; gchar *device_class; GstCaps *compare_caps = gst_caps_new_empty_simple ("video/test"); GstElement *element; caps = gst_device_get_caps (device); display_name = gst_device_get_display_name (device); device_class = gst_device_get_device_class (device); fail_unless_equals_string (DISPLAY_NAME, display_name); fail_unless_equals_string (DEVICE_CLASS, device_class); gst_check_caps_equal (caps, compare_caps); g_free (display_name); g_free (device_class); gst_caps_unref (caps); fail_unless (gst_device_has_classes (device, "Test1")); fail_unless (gst_device_has_classes (device, "Test2/Test1")); element = gst_device_create_element (device, "reconfigurable"); fail_unless (GST_IS_BIN (element)); fail_unless (gst_device_reconfigure_element (device, element)); gst_element_set_name (element, "no-no"); fail_unless (!gst_device_reconfigure_element (device, element)); gst_object_unref (element); gst_caps_unref (compare_caps); gst_object_unref (device); } GST_END_TEST; typedef struct _GstTestDeviceProvider { GstDeviceProvider parent; } GstTestDeviceProvider; typedef struct _GstTestDeviceProviderClass { GstDeviceProviderClass parent_class; } GstTestDeviceProviderClass; GType gst_test_device_provider_get_type (void); G_DEFINE_TYPE (GstTestDeviceProvider, gst_test_device_provider, GST_TYPE_DEVICE_PROVIDER); int num_devices = 1; static GList * gst_test_device_provider_probe (GstDeviceProvider * provider) { int i; GList *devs = NULL; for (i = 0; i < num_devices; i++) devs = g_list_prepend (devs, test_device_new ()); return devs; } static void gst_test_device_provider_class_init (GstTestDeviceProviderClass * klass) { GstDeviceProviderClass *dpclass = GST_DEVICE_PROVIDER_CLASS (klass); dpclass->probe = gst_test_device_provider_probe; gst_device_provider_class_set_static_metadata (dpclass, "Test Device Provider", "Test0/Test1/Test2/Test3/TestProvider", "List but does NOT monitor test devices", "Olivier Crete "); } static void gst_test_device_provider_init (GstTestDeviceProvider * self) { } static void register_test_device_provider (void) { gst_device_provider_register (NULL, "testdeviceprovider", 1, gst_test_device_provider_get_type ()); } GST_START_TEST (test_device_provider_factory) { GstDeviceProvider *dp, *dp2; GList *factories; GstDeviceProviderFactory *f; register_test_device_provider (); factories = gst_device_provider_factory_list_get_device_providers (1); fail_unless (factories != NULL); f = gst_device_provider_factory_find ("testdeviceprovider"); fail_unless (f != NULL); gst_plugin_feature_list_free (factories); fail_unless (gst_device_provider_factory_has_classes (f, "Test2")); fail_unless (gst_device_provider_factory_has_classes (f, "Test2/Test0")); fail_unless (!gst_device_provider_factory_has_classes (f, "Test2/TestN/Test0")); fail_unless (!gst_device_provider_factory_has_classes (f, "TestN")); fail_unless (!gst_device_provider_factory_has_classes (f, "Test")); dp = gst_device_provider_factory_get (f); gst_object_unref (f); dp2 = gst_device_provider_factory_get_by_name ("testdeviceprovider"); fail_unless_equals_pointer (dp, dp2); gst_object_unref (dp); gst_object_unref (dp2); dp2 = gst_device_provider_factory_get_by_name ("testdeviceprovider"); fail_unless_equals_pointer (dp, dp2); gst_object_unref (dp2); } GST_END_TEST; GST_START_TEST (test_device_provider) { GstDeviceProvider *dp; GList *devs; GstBus *bus; register_test_device_provider (); dp = gst_device_provider_factory_get_by_name ("testdeviceprovider"); num_devices = 0; fail_unless (dp != NULL); fail_unless (gst_device_provider_get_devices (dp) == NULL); num_devices = 1; devs = gst_device_provider_get_devices (dp); fail_unless (g_list_length (devs) == 1); fail_unless (GST_IS_DEVICE (devs->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); fail_if (gst_device_provider_can_monitor (dp)); fail_unless (gst_device_provider_start (dp)); bus = gst_device_provider_get_bus (dp); fail_unless (GST_IS_BUS (bus)); gst_object_unref (bus); gst_device_provider_stop (dp); gst_object_unref (dp); } GST_END_TEST; typedef struct _GstTestDeviceProviderMonitor { GstDeviceProvider parent; } GstTestDeviceProviderMonitor; typedef struct _GstTestDeviceProviderMonitorClass { GstDeviceProviderClass parent_class; } GstTestDeviceProviderMonitorClass; GType gst_test_device_provider_monitor_get_type (void); G_DEFINE_TYPE (GstTestDeviceProviderMonitor, gst_test_device_provider_monitor, GST_TYPE_DEVICE_PROVIDER); static gboolean gst_test_device_provider_monitor_start (GstDeviceProvider * monitor) { return TRUE; } static void gst_test_device_provider_monitor_class_init (GstTestDeviceProviderMonitorClass * klass) { GstDeviceProviderClass *dpclass = GST_DEVICE_PROVIDER_CLASS (klass); dpclass->probe = gst_test_device_provider_probe; dpclass->start = gst_test_device_provider_monitor_start; gst_device_provider_class_set_static_metadata (dpclass, "Test Device Provider Monitor", "Test0/Test1/Test2/Test4/TestProviderMonitor", "List and monitors Test devices", "Olivier Crete "); } static void gst_test_device_provider_monitor_init (GstTestDeviceProviderMonitor * self) { } static void register_test_device_provider_monitor (void) { gst_device_provider_register (NULL, "testdeviceprovidermonitor", 2, gst_test_device_provider_monitor_get_type ()); } GST_START_TEST (test_device_provider_monitor) { GstDeviceProvider *dp; GList *devs; GstBus *bus; GstDevice *mydev; GstDevice *dev; GstMessage *msg; register_test_device_provider_monitor (); dp = gst_device_provider_factory_get_by_name ("testdeviceprovidermonitor"); bus = gst_device_provider_get_bus (dp); msg = gst_bus_pop (bus); fail_unless (msg == NULL); fail_unless (gst_device_provider_can_monitor (dp)); fail_unless (gst_device_provider_start (dp)); fail_unless (gst_device_provider_get_devices (dp) == NULL); devs = gst_device_provider_get_devices (dp); fail_unless (devs == NULL); mydev = test_device_new (); fail_unless (g_object_is_floating (mydev)); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 1); gst_device_provider_device_add (dp, mydev); fail_unless (!g_object_is_floating (mydev)); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 2); devs = gst_device_provider_get_devices (dp); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 3); fail_unless_equals_int (g_list_length (devs), 1); fail_unless_equals_pointer (devs->data, mydev); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 2); msg = gst_bus_pop (bus); fail_unless (msg != NULL); fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_DEVICE_ADDED); gst_message_parse_device_added (msg, &dev); fail_unless_equals_pointer (dev, mydev); gst_object_unref (dev); gst_message_unref (msg); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 1); msg = gst_bus_pop (bus); fail_unless (msg == NULL); gst_device_provider_device_remove (dp, mydev); devs = gst_device_provider_get_devices (dp); fail_unless (devs == NULL); msg = gst_bus_pop (bus); fail_unless (msg != NULL); fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_DEVICE_REMOVED); gst_message_parse_device_removed (msg, &dev); fail_unless_equals_pointer (dev, mydev); ASSERT_OBJECT_REFCOUNT (mydev, "dev", 2); gst_object_unref (dev); gst_message_unref (msg); msg = gst_bus_pop (bus); fail_unless (msg == NULL); gst_device_provider_stop (dp); gst_object_unref (bus); ASSERT_OBJECT_REFCOUNT (dp, "monitor", 2); gst_object_unref (dp); /* Is singleton, so system keeps a ref */ ASSERT_OBJECT_REFCOUNT (dp, "monitor", 1); } GST_END_TEST; GST_START_TEST (test_device_monitor) { GstDeviceProvider *dp, *dp2; GstDeviceMonitor *mon; GList *devs; guint id, id2; GstDevice *mydev; GstMessage *msg; GstBus *bus; GstDevice *dev; register_test_device_provider (); register_test_device_provider_monitor (); dp = gst_device_provider_factory_get_by_name ("testdeviceprovider"); dp2 = gst_device_provider_factory_get_by_name ("testdeviceprovidermonitor"); mon = gst_device_monitor_new (); devs = gst_device_monitor_get_devices (mon); fail_unless (devs == NULL); id = gst_device_monitor_add_filter (mon, "TestProvider", NULL); fail_unless (id > 0); devs = gst_device_monitor_get_devices (mon); fail_unless (devs == NULL); fail_unless (gst_device_monitor_add_filter (mon, "TestDevice", NULL) == 0); ASSERT_CRITICAL (gst_device_monitor_remove_filter (mon, 0)); fail_unless (gst_device_monitor_remove_filter (mon, id)); id = gst_device_monitor_add_filter (mon, "Test3", NULL); fail_unless (id > 0); devs = gst_device_monitor_get_devices (mon); fail_unless (g_list_length (devs) == 1); fail_unless (GST_IS_DEVICE (devs->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); id2 = gst_device_monitor_add_filter (mon, "Test1", NULL); fail_unless (id2 > 0); devs = gst_device_monitor_get_devices (mon); fail_unless (g_list_length (devs) == 2); fail_unless (GST_IS_DEVICE (devs->data)); fail_unless (GST_IS_DEVICE (devs->next->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); fail_unless (gst_device_monitor_remove_filter (mon, id)); devs = gst_device_monitor_get_devices (mon); fail_unless (g_list_length (devs) == 2); fail_unless (GST_IS_DEVICE (devs->data)); fail_unless (GST_IS_DEVICE (devs->next->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); fail_unless (gst_device_monitor_start (mon)); devs = gst_device_monitor_get_devices (mon); fail_unless (g_list_length (devs) == 1); fail_unless (GST_IS_DEVICE (devs->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); gst_device_monitor_stop (mon); fail_unless (gst_device_monitor_remove_filter (mon, id2)); id = gst_device_monitor_add_filter (mon, "Test4", NULL); fail_unless (id > 0); devs = gst_device_monitor_get_devices (mon); fail_unless (g_list_length (devs) == 1); fail_unless (GST_IS_DEVICE (devs->data)); g_list_free_full (devs, (GDestroyNotify) gst_object_unref); fail_unless (gst_device_monitor_start (mon)); devs = gst_device_monitor_get_devices (mon); fail_unless (devs == NULL); bus = gst_device_monitor_get_bus (mon); msg = gst_bus_pop (bus); fail_unless (msg == NULL); mydev = test_device_new (); gst_device_provider_device_add (dp2, mydev); msg = gst_bus_pop (bus); fail_unless (msg != NULL); fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_DEVICE_ADDED); gst_message_parse_device_added (msg, &dev); fail_unless_equals_pointer (dev, mydev); gst_object_unref (dev); gst_message_unref (msg); msg = gst_bus_pop (bus); fail_unless (msg == NULL); gst_device_provider_device_remove (dp2, mydev); devs = gst_device_monitor_get_devices (mon); fail_unless (devs == NULL); msg = gst_bus_pop (bus); fail_unless (msg != NULL); fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_DEVICE_REMOVED); gst_message_parse_device_removed (msg, &dev); fail_unless_equals_pointer (dev, mydev); gst_object_unref (dev); gst_message_unref (msg); msg = gst_bus_pop (bus); fail_unless (msg == NULL); gst_device_monitor_stop (mon); gst_object_unref (bus); gst_object_unref (mon); gst_object_unref (dp); gst_object_unref (dp2); /* should work fine without any filters */ mon = gst_device_monitor_new (); fail_unless (gst_device_monitor_start (mon)); gst_device_monitor_stop (mon); gst_object_unref (mon); } GST_END_TEST; static Suite * gst_device_suite (void) { Suite *s = suite_create ("GstDevice"); TCase *tc_chain = tcase_create ("device tests"); suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_device); tcase_add_test (tc_chain, test_device_provider_factory); tcase_add_test (tc_chain, test_device_provider); tcase_add_test (tc_chain, test_device_provider_monitor); tcase_add_test (tc_chain, test_device_monitor); return s; } GST_CHECK_MAIN (gst_device);