Commit 97aa8238 authored by Thibault Saunier's avatar Thibault Saunier

device-provider: Allow notifying application of device changes

Thi introduces new APIs to post a `DEVICE_CHANGED` message on the
bus so the application is notifies when a device is modified. For
example, if the "defaultness" of a device was changed or any property
that can be changed at any time. Atomically changing the device
object notifying that way allow us to abtract away the internal threads.

New APIS:
  - gst_message_new_device_changed
  - gst_message_parse_device_changed
  - gst_device_provider_device_changed
parent c164b88a
......@@ -1748,8 +1748,10 @@ gst_message_parse_have_context
gst_message_new_device_added
gst_message_new_device_removed
gst_message_new_device_changed
gst_message_parse_device_added
gst_message_parse_device_removed
gst_message_parse_device_changed
gst_message_new_property_notify
gst_message_parse_property_notify
......@@ -3928,6 +3930,7 @@ gst_device_provider_class_set_metadata
gst_device_provider_class_set_static_metadata
gst_device_provider_device_add
gst_device_provider_device_remove
gst_device_provider_device_changed
gst_device_provider_get_bus
gst_device_provider_get_devices
gst_device_provider_get_factory
......
......@@ -234,15 +234,18 @@ bus_sync_message (GstBus * bus, GstMessage * message,
{
GstMessageType type = GST_MESSAGE_TYPE (message);
if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) {
if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED ||
type == GST_MESSAGE_DEVICE_CHANGED) {
gboolean matches = TRUE;
GstDevice *device;
GstDeviceProvider *provider;
if (type == GST_MESSAGE_DEVICE_ADDED)
gst_message_parse_device_added (message, &device);
else
else if (type == GST_MESSAGE_DEVICE_REMOVED)
gst_message_parse_device_removed (message, &device);
else
gst_message_parse_device_changed (message, &device, NULL);
GST_OBJECT_LOCK (monitor);
provider =
......
......@@ -772,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));
}
......@@ -162,6 +162,11 @@ GST_API
const gchar * gst_device_provider_class_get_metadata (GstDeviceProviderClass * klass,
const gchar * key);
GST_API
void gst_device_provider_device_changed (GstDeviceProvider * provider,
GstDevice *device,
GstDevice *changed_device);
/* factory management */
GST_API
......
......@@ -107,6 +107,7 @@ static GstMessageQuarks message_quarks[] = {
{GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
{GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
{GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
{GST_MESSAGE_DEVICE_CHANGED, "device-changed", 0},
{GST_MESSAGE_PROPERTY_NOTIFY, "property-notify", 0},
{GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
{GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
......@@ -2690,6 +2691,69 @@ gst_message_parse_device_removed (GstMessage * message, GstDevice ** device)
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
}
/**
* gst_message_new_device_changed:
* @src: The #GstObject that created the message
* @device: (transfer none): The newly created device representing @replaced_device
* with its new configuration.
*
* Creates a new device-changed message. The device-changed message is produced
* by #GstDeviceProvider or a #GstDeviceMonitor. They announce that a device
* properties has changed and @device represent the new modified version of @changed_device.
*
* Returns: a newly allocated #GstMessage
*
* Since: 1.16
*/
GstMessage *
gst_message_new_device_changed (GstObject * src, GstDevice * device,
GstDevice * changed_device)
{
GstMessage *message;
GstStructure *structure;
g_return_val_if_fail (device != NULL, NULL);
g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_CHANGED),
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device,
GST_QUARK (DEVICE_CHANGED), GST_TYPE_DEVICE, changed_device, NULL);
message = gst_message_new_custom (GST_MESSAGE_DEVICE_CHANGED, src, structure);
return message;
}
/**
* gst_message_parse_device_changed:
* @message: a #GstMessage of type %GST_MESSAGE_DEVICE_CHANGED
* @device: (out) (allow-none) (transfer full): A location where to store a
* pointer to the updated version of the #GstDevice, or %NULL
* @changed_device: (out) (allow-none) (transfer full): A location where to store a
* pointer to the old version of the #GstDevice, or %NULL
*
* Parses a device-changed message. The device-changed message is produced by
* #GstDeviceProvider or a #GstDeviceMonitor. It announces the
* disappearance of monitored devices. * It announce that a device properties has
* changed and @device represents the new modified version of @changed_device.
*
* Since: 1.16
*/
void
gst_message_parse_device_changed (GstMessage * message, GstDevice ** device,
GstDevice ** changed_device)
{
g_return_if_fail (GST_IS_MESSAGE (message));
g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_CHANGED);
if (device)
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
if (changed_device)
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
GST_QUARK (DEVICE_CHANGED), GST_TYPE_DEVICE, changed_device, NULL);
}
/**
* gst_message_new_property_notify:
* @src: The #GstObject whose property changed (may or may not be a #GstElement)
......
......@@ -119,6 +119,8 @@ typedef struct _GstMessage GstMessage;
* @GST_MESSAGE_REDIRECT: Message indicating to request the application to
* try to play the given URL(s). Useful if for example a HTTP 302/303
* response is received with a non-HTTP URL inside. (Since 1.10)
* @GST_MESSAGE_DEVICE_CHANGED: Message indicating a #GstDevice was changed
* a #GstDeviceProvider (Since 1.16)
* @GST_MESSAGE_ANY: mask for all of the above messages.
*
* The different message types that are available.
......@@ -171,6 +173,7 @@ typedef enum
GST_MESSAGE_STREAM_COLLECTION = GST_MESSAGE_EXTENDED + 4,
GST_MESSAGE_STREAMS_SELECTED = GST_MESSAGE_EXTENDED + 5,
GST_MESSAGE_REDIRECT = GST_MESSAGE_EXTENDED + 6,
GST_MESSAGE_DEVICE_CHANGED = GST_MESSAGE_EXTENDED + 6,
GST_MESSAGE_ANY = (gint) (0xffffffff)
} GstMessageType;
......@@ -806,6 +809,15 @@ GstMessage * gst_message_new_device_removed (GstObject * src, GstDevice *
GST_API
void gst_message_parse_device_removed (GstMessage * message, GstDevice ** device);
/* DEVICE_CHANGED */
GST_API
GstMessage * gst_message_new_device_changed (GstObject * src, GstDevice * device, GstDevice *changed_device);
GST_API
void gst_message_parse_device_changed (GstMessage * message, GstDevice ** device, GstDevice ** changed_device);
/* PROPERTY_NOTIFY */
GST_API
......
......@@ -75,7 +75,8 @@ static const gchar *_quark_strings[] = {
"GstMessageStreamCollection", "collection", "stream", "stream-collection",
"GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations",
"redirect-entry-taglists", "redirect-entry-structures",
"GstEventStreamGroupDone", "GstQueryBitrate", "nominal-bitrate"
"GstEventStreamGroupDone", "GstQueryBitrate", "nominal-bitrate",
"GstMessageDeviceChanged", "device-changed"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
......
......@@ -219,7 +219,9 @@ typedef enum _GstQuarkId
GST_QUARK_EVENT_STREAM_GROUP_DONE = 188,
GST_QUARK_QUERY_BITRATE = 189,
GST_QUARK_NOMINAL_BITRATE = 190,
GST_QUARK_MAX = 191
GST_QUARK_MESSAGE_DEVICE_CHANGED = 191,
GST_QUARK_DEVICE_CHANGED = 192,
GST_QUARK_MAX = 193
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment