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
This commit is contained in:
Thibault Saunier 2019-01-30 10:41:58 -03:00
parent c164b88ac1
commit 97aa82387f
8 changed files with 144 additions and 4 deletions

View file

@ -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

View file

@ -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 =

View file

@ -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));
}

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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];

View file

@ -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];