X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=gst%2Fgstdeviceprovider.c;h=c3d794e60525d4a1505620576e9e1ad99a14179b;hb=dac5966da6a0f53d0443dfa1ac239289028c415d;hp=e7972bbdf42280daf570cf6b68456b3f3e8a18e6;hpb=56b92900739c82019faaa7d75540c69db45b57aa;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstdeviceprovider.c b/gst/gstdeviceprovider.c index e7972bb..c3d794e 100644 --- a/gst/gstdeviceprovider.c +++ b/gst/gstdeviceprovider.c @@ -21,11 +21,12 @@ /** * SECTION:gstdeviceprovider + * @title: GstDeviceProvider * @short_description: A device provider * @see_also: #GstDevice, #GstDeviceMonitor * * A #GstDeviceProvider subclass is provided by a plugin that handles devices - * if there is a way to programatically list connected devices. It can also + * if there is a way to programmatically list connected devices. It can also * optionally provide updates to the list of connected devices. * * Each #GstDeviceProvider subclass is a singleton, a plugin should @@ -78,6 +79,7 @@ static void gst_device_provider_dispose (GObject * object); static void gst_device_provider_finalize (GObject * object); static gpointer gst_device_provider_parent_class = NULL; +static gint private_offset = 0; GType gst_device_provider_get_type (void) @@ -102,6 +104,9 @@ gst_device_provider_get_type (void) _type = g_type_register_static (GST_TYPE_OBJECT, "GstDeviceProvider", &element_info, G_TYPE_FLAG_ABSTRACT); + private_offset = + g_type_add_instance_private (_type, sizeof (GstDeviceProviderPrivate)); + __gst_deviceproviderclass_factory = g_quark_from_static_string ("GST_DEVICEPROVIDERCLASS_FACTORY"); g_once_init_leave (&gst_device_provider_type, _type); @@ -109,6 +114,12 @@ gst_device_provider_get_type (void) return gst_device_provider_type; } +static inline gpointer +gst_device_provider_get_instance_private (GstDeviceProvider * self) +{ + return (G_STRUCT_MEMBER_P (self, private_offset)); +} + static void gst_device_provider_base_class_init (gpointer g_class) { @@ -132,7 +143,8 @@ gst_device_provider_class_init (GstDeviceProviderClass * klass) gst_device_provider_parent_class = g_type_class_peek_parent (klass); - g_type_class_add_private (klass, sizeof (GstDeviceProviderPrivate)); + if (private_offset != 0) + g_type_class_adjust_private_offset (klass, &private_offset); gobject_class->dispose = gst_device_provider_dispose; gobject_class->finalize = gst_device_provider_finalize; @@ -151,8 +163,7 @@ gst_device_provider_class_init (GstDeviceProviderClass * klass) static void gst_device_provider_init (GstDeviceProvider * provider) { - provider->priv = G_TYPE_INSTANCE_GET_PRIVATE (provider, - GST_TYPE_DEVICE_PROVIDER, GstDeviceProviderPrivate); + provider->priv = gst_device_provider_get_instance_private (provider); g_mutex_init (&provider->priv->start_lock); @@ -252,7 +263,8 @@ gst_device_provider_class_add_static_metadata (GstDeviceProviderClass * klass, * multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>" * * Sets the detailed information for a #GstDeviceProviderClass. - * This function is for use in _class_init functions only. + * + * > This function is for use in _class_init functions only. * * Since: 1.4 */ @@ -288,7 +300,8 @@ gst_device_provider_class_set_metadata (GstDeviceProviderClass * klass, * foo.com>" * * Sets the detailed information for a #GstDeviceProviderClass. - * This function is for use in _class_init functions only. + * + * > This function is for use in _class_init functions only. * * Same as gst_device_provider_class_set_metadata(), but @longname, @classification, * @description, and @author must be static strings or inlined strings, as @@ -334,7 +347,7 @@ gst_device_provider_class_set_static_metadata (GstDeviceProviderClass * klass, * * Get metadata with @key in @klass. * - * Returns: the metadata for @key. + * Returns: (nullable): the metadata for @key. * * Since: 1.4 */ @@ -349,6 +362,29 @@ gst_device_provider_class_get_metadata (GstDeviceProviderClass * klass, } /** + * gst_device_provider_get_metadata: + * @provider: provider to get metadata for + * @key: the key to get + * + * Get metadata with @key in @provider. + * + * Returns: the metadata for @key. + * + * Since: 1.14 + */ +const gchar * +gst_device_provider_get_metadata (GstDeviceProvider * provider, + const gchar * key) +{ + g_return_val_if_fail (GST_IS_DEVICE_PROVIDER (provider), NULL); + g_return_val_if_fail (key != NULL, NULL); + + return + gst_device_provider_class_get_metadata (GST_DEVICE_PROVIDER_GET_CLASS + (provider), key); +} + +/** * gst_device_provider_get_devices: * @provider: A #GstDeviceProvider * @@ -418,6 +454,7 @@ gst_device_provider_start (GstDeviceProvider * provider) g_mutex_lock (&provider->priv->start_lock); if (provider->priv->started_count > 0) { + provider->priv->started_count++; ret = TRUE; goto started; } @@ -540,13 +577,16 @@ gst_device_provider_get_bus (GstDeviceProvider * provider) /** * gst_device_provider_device_add: * @provider: a #GstDeviceProvider - * @device: (transfer full): a #GstDevice that has been added + * @device: (transfer floating): a #GstDevice that has been added * * Posts a message on the provider's #GstBus to inform applications that * a new device has been added. * * This is for use by subclasses. * + * @device's reference count will be incremented, and any floating reference + * will be removed (see gst_object_ref_sink()). + * * Since: 1.4 */ void @@ -565,8 +605,10 @@ gst_device_provider_device_add (GstDeviceProvider * provider, } GST_OBJECT_LOCK (provider); - provider->devices = g_list_prepend (provider->devices, - gst_object_ref (device)); + /* Take an additional reference so we can be sure nobody removed it from the + * provider in the meantime and we can safely emit the message */ + gst_object_ref (device); + provider->devices = g_list_prepend (provider->devices, device); GST_OBJECT_UNLOCK (provider); message = gst_message_new_device_added (GST_OBJECT (provider), device); @@ -711,7 +753,7 @@ gst_device_provider_unhide_provider (GstDeviceProvider * provider, gchar *unhidden_name = NULL; g_return_if_fail (GST_IS_DEVICE_PROVIDER (provider)); - g_return_if_fail (unhidden_name != NULL); + g_return_if_fail (name != NULL); GST_OBJECT_LOCK (provider); find = @@ -730,3 +772,53 @@ gst_device_provider_unhide_provider (GstDeviceProvider * provider, g_free (unhidden_name); } } + +/** + * gst_device_provider_device_changed: + * @device: (transfer none): the new version of @changed_device + * @changed_device: (transfer floating): the old version of the device that has been udpated + * + * This function is used when @changed_device was modified into its new form + * @device. This will post a `DEVICE_CHANGED` message on the bus to let + * the application know that the device was modified. #GstDevice is immutable + * for MT. safety purposes so this is an "atomic" way of letting the application + * know when a device was modified. + * + * Since: 1.16 + */ +void +gst_device_provider_device_changed (GstDeviceProvider * provider, + GstDevice * device, GstDevice * changed_device) +{ + GList *dev_lst; + GstMessage *message; + + g_return_if_fail (GST_IS_DEVICE_PROVIDER (provider)); + g_return_if_fail (GST_IS_DEVICE (device)); + g_return_if_fail (GST_IS_DEVICE (changed_device)); + + GST_OBJECT_LOCK (provider); + dev_lst = g_list_find (provider->devices, changed_device); + if (!dev_lst) { + GST_ERROR_OBJECT (provider, + "Trying to update a device we do not have in our own list!"); + + GST_OBJECT_UNLOCK (provider); + return; + } + + if (!gst_object_set_parent (GST_OBJECT (device), GST_OBJECT (provider))) { + GST_OBJECT_UNLOCK (provider); + GST_WARNING_OBJECT (provider, "Could not parent device %p to provider," + " it already has a parent", device); + return; + } + dev_lst->data = device; + GST_OBJECT_UNLOCK (provider); + + message = + gst_message_new_device_changed (GST_OBJECT (provider), device, + changed_device); + gst_bus_post (provider->priv->bus, message); + gst_object_unparent (GST_OBJECT (changed_device)); +}