mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
891 lines
27 KiB
C
891 lines
27 KiB
C
#include <glib-object.h>
|
|
#include <gst/gst.h>
|
|
|
|
#include "ges-meta-container.h"
|
|
|
|
/**
|
|
* SECTION: ges-meta-container
|
|
* @short_description: An interface for storing meta
|
|
*
|
|
* Interface that allows reading and writing meta
|
|
*/
|
|
|
|
static GQuark ges_meta_key;
|
|
|
|
G_DEFINE_INTERFACE_WITH_CODE (GESMetaContainer, ges_meta_container,
|
|
G_TYPE_OBJECT, ges_meta_key =
|
|
g_quark_from_static_string ("ges-meta-container-data"););
|
|
|
|
enum
|
|
{
|
|
NOTIFY_SIGNAL,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint _signals[LAST_SIGNAL] = { 0 };
|
|
|
|
typedef struct RegisteredMeta
|
|
{
|
|
GType item_type;
|
|
GESMetaFlag flags;
|
|
} RegisteredMeta;
|
|
|
|
typedef struct ContainerData
|
|
{
|
|
GstStructure *structure;
|
|
GHashTable *static_items;
|
|
} ContainerData;
|
|
|
|
static void
|
|
ges_meta_container_default_init (GESMetaContainerInterface * iface)
|
|
{
|
|
|
|
/**
|
|
* GESMetaContainer::notify:
|
|
* @container: a #GESMetaContainer
|
|
* @prop: the key of the value that changed
|
|
* @value: the #GValue containing the new value
|
|
*
|
|
* The notify signal is used to be notify of changes of values
|
|
* of some metadatas
|
|
*/
|
|
_signals[NOTIFY_SIGNAL] =
|
|
g_signal_new ("notify-meta", G_TYPE_FROM_INTERFACE (iface),
|
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
|
|
G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
|
|
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE);
|
|
}
|
|
|
|
static void
|
|
_free_meta_container_data (ContainerData * data)
|
|
{
|
|
gst_structure_free (data->structure);
|
|
g_hash_table_unref (data->static_items);
|
|
|
|
g_slice_free (ContainerData, data);
|
|
}
|
|
|
|
static void
|
|
_free_static_item (RegisteredMeta * item)
|
|
{
|
|
g_slice_free (RegisteredMeta, item);
|
|
}
|
|
|
|
static ContainerData *
|
|
_create_container_data (GESMetaContainer * container)
|
|
{
|
|
ContainerData *data = g_slice_new (ContainerData);
|
|
data->structure = gst_structure_new_empty ("metadatas");
|
|
data->static_items = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
g_free, (GDestroyNotify) (GDestroyNotify) _free_static_item);
|
|
g_object_set_qdata_full (G_OBJECT (container), ges_meta_key, data,
|
|
(GDestroyNotify) _free_meta_container_data);
|
|
|
|
return data;
|
|
}
|
|
|
|
static GstStructure *
|
|
_meta_container_get_structure (GESMetaContainer * container)
|
|
{
|
|
ContainerData *data;
|
|
|
|
data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
|
|
if (!data)
|
|
data = _create_container_data (container);
|
|
|
|
return data->structure;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
GESMetaForeachFunc func;
|
|
const GESMetaContainer *container;
|
|
gpointer data;
|
|
} MetadataForeachData;
|
|
|
|
static void
|
|
structure_foreach_wrapper (GQuark field_id, const GValue * value,
|
|
gpointer user_data)
|
|
{
|
|
MetadataForeachData *data = (MetadataForeachData *) user_data;
|
|
|
|
data->func (data->container, g_quark_to_string (field_id), value, data->data);
|
|
}
|
|
|
|
static gboolean
|
|
_append_foreach (GQuark field_id, const GValue * value, GESMetaContainer * self)
|
|
{
|
|
ges_meta_container_set_meta (self, g_quark_to_string (field_id), value);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_foreach:
|
|
* @container: container to iterate over
|
|
* @func: (scope call): function to be called for each metadata
|
|
* @user_data: (closure): user specified data
|
|
*
|
|
* Calls the given function for each metadata inside the meta container. Note
|
|
* that if there is no metadata, the function won't be called at all.
|
|
*/
|
|
void
|
|
ges_meta_container_foreach (GESMetaContainer * container,
|
|
GESMetaForeachFunc func, gpointer user_data)
|
|
{
|
|
GstStructure *structure;
|
|
MetadataForeachData foreach_data;
|
|
|
|
g_return_if_fail (GES_IS_META_CONTAINER (container));
|
|
g_return_if_fail (func != NULL);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
foreach_data.func = func;
|
|
foreach_data.container = container;
|
|
foreach_data.data = user_data;
|
|
|
|
gst_structure_foreach (structure,
|
|
(GstStructureForeachFunc) structure_foreach_wrapper, &foreach_data);
|
|
}
|
|
|
|
/* _can_write_value should have been checked before calling */
|
|
static gboolean
|
|
_register_meta (GESMetaContainer * container, GESMetaFlag flags,
|
|
const gchar * meta_item, GType type)
|
|
{
|
|
ContainerData *data;
|
|
RegisteredMeta *static_item;
|
|
|
|
data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
|
|
if (!data)
|
|
data = _create_container_data (container);
|
|
else if (g_hash_table_lookup (data->static_items, meta_item)) {
|
|
GST_WARNING_OBJECT (container, "Static meta %s already registered",
|
|
meta_item);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static_item = g_slice_new0 (RegisteredMeta);
|
|
static_item->item_type = type;
|
|
static_item->flags = flags;
|
|
g_hash_table_insert (data->static_items, g_strdup (meta_item), static_item);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_set_value (GESMetaContainer * container, const gchar * meta_item,
|
|
const GValue * value)
|
|
{
|
|
GstStructure *structure;
|
|
gchar *val = gst_value_serialize (value);
|
|
|
|
if (val == NULL) {
|
|
GST_WARNING_OBJECT (container, "Could not set value on item: %s",
|
|
meta_item);
|
|
|
|
g_free (val);
|
|
return FALSE;
|
|
}
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
GST_DEBUG_OBJECT (container, "Setting meta_item %s value: %s::%s",
|
|
meta_item, G_VALUE_TYPE_NAME (value), val);
|
|
|
|
gst_structure_set_value (structure, meta_item, value);
|
|
g_signal_emit (container, _signals[NOTIFY_SIGNAL], 0, meta_item, value);
|
|
|
|
g_free (val);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_can_write_value (GESMetaContainer * container, const gchar * item_name,
|
|
GType type)
|
|
{
|
|
ContainerData *data;
|
|
RegisteredMeta *static_item = NULL;
|
|
|
|
data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
|
|
if (!data) {
|
|
data = _create_container_data (container);
|
|
return TRUE;
|
|
}
|
|
|
|
static_item = g_hash_table_lookup (data->static_items, item_name);
|
|
|
|
if (static_item == NULL)
|
|
return TRUE;
|
|
|
|
if ((static_item->flags & GES_META_WRITABLE) == FALSE) {
|
|
GST_WARNING_OBJECT (container, "Can not write %s", item_name);
|
|
return FALSE;
|
|
}
|
|
|
|
if (static_item->item_type != type) {
|
|
GST_WARNING_OBJECT (container, "Can not set value of type %s on %s "
|
|
"its type is: %s", g_type_name (static_item->item_type), item_name,
|
|
g_type_name (type));
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define CREATE_SETTER(name, value_ctype, value_gtype, setter_name) \
|
|
gboolean \
|
|
ges_meta_container_set_ ## name (GESMetaContainer *container, \
|
|
const gchar *meta_item, value_ctype value) \
|
|
{ \
|
|
GValue gval = { 0 }; \
|
|
\
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE); \
|
|
g_return_val_if_fail (meta_item != NULL, FALSE); \
|
|
\
|
|
if (_can_write_value (container, meta_item, value_gtype) == FALSE) \
|
|
return FALSE; \
|
|
\
|
|
g_value_init (&gval, value_gtype); \
|
|
g_value_set_ ##setter_name (&gval, value); \
|
|
\
|
|
return _set_value (container, meta_item, &gval); \
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_set_boolean:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (boolean, gboolean, G_TYPE_BOOLEAN, boolean)
|
|
|
|
/**
|
|
* ges_meta_container_set_int:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (int, gint, G_TYPE_INT, int)
|
|
|
|
/**
|
|
* ges_meta_container_set_uint:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (uint, guint, G_TYPE_UINT, uint)
|
|
|
|
/**
|
|
* ges_meta_container_set_int64:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (int64, gint64, G_TYPE_INT64, int64)
|
|
|
|
/**
|
|
* ges_meta_container_set_uint64:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (uint64, guint64, G_TYPE_UINT64, uint64)
|
|
|
|
/**
|
|
* ges_meta_container_set_float:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (float, float, G_TYPE_FLOAT, float)
|
|
|
|
/**
|
|
* ges_meta_container_set_double:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (double, double, G_TYPE_DOUBLE, double)
|
|
|
|
/**
|
|
* ges_meta_container_set_date:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (date, const GDate *, G_TYPE_DATE, boxed)
|
|
|
|
/**
|
|
* ges_meta_container_set_date_time:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (date_time, const GstDateTime *, GST_TYPE_DATE_TIME, boxed)
|
|
|
|
/**
|
|
* ges_meta_container_set_string:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
CREATE_SETTER (string, const gchar *, G_TYPE_STRING, string)
|
|
|
|
/**
|
|
* ges_meta_container_set_meta:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
* Sets the value of a given meta item
|
|
*
|
|
* Return: %TRUE if the meta could be added, %FALSE otherwize
|
|
*/
|
|
gboolean
|
|
ges_meta_container_set_meta (GESMetaContainer * container,
|
|
const gchar * meta_item, const GValue * value)
|
|
{
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
|
|
if (_can_write_value (container, meta_item, G_VALUE_TYPE (value)) == FALSE)
|
|
return FALSE;
|
|
|
|
_set_value (container, meta_item, value);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_metas_to_string:
|
|
* @container: a #GESMetaContainer
|
|
*
|
|
* Serializes a meta container to a string.
|
|
*
|
|
* Returns: a newly-allocated string, or NULL in case of an error. The
|
|
* string must be freed with g_free() when no longer needed.
|
|
*/
|
|
gchar *
|
|
ges_meta_container_metas_to_string (GESMetaContainer * container)
|
|
{
|
|
GstStructure *structure;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), NULL);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
return gst_structure_to_string (structure);
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_add_metas_from_string:
|
|
* @str: a string created with ges_meta_container_metas_to_string()
|
|
*
|
|
* Deserializes a meta container.
|
|
*
|
|
* Returns: (transfer full): a new #GESMetaContainer, or NULL in case of an
|
|
* error.
|
|
*/
|
|
gboolean
|
|
ges_meta_container_add_metas_from_string (GESMetaContainer * container,
|
|
const gchar * str)
|
|
{
|
|
GstStructure *n_structure;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
|
|
n_structure = gst_structure_from_string (str, NULL);
|
|
if (n_structure == NULL) {
|
|
GST_WARNING_OBJECT (container, "Could not add metas: %s", str);
|
|
return FALSE;
|
|
}
|
|
|
|
gst_structure_foreach (n_structure, (GstStructureForeachFunc) _append_foreach,
|
|
container);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define CREATE_REGISTER_STATIC(name, value_ctype, value_gtype, setter_name) \
|
|
gboolean \
|
|
ges_meta_container_register_meta_ ## name (GESMetaContainer *container,\
|
|
GESMetaFlag flags, const gchar *meta_item, value_ctype value) \
|
|
{ \
|
|
GValue gval = { 0 }; \
|
|
\
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE); \
|
|
g_return_val_if_fail (meta_item != NULL, FALSE); \
|
|
\
|
|
if (!_register_meta (container, flags, meta_item, value_gtype)) \
|
|
return FALSE; \
|
|
\
|
|
g_value_init (&gval, value_gtype); \
|
|
g_value_set_ ##setter_name (&gval, value); \
|
|
\
|
|
return _set_value (container, meta_item, &gval); \
|
|
}
|
|
|
|
/**
|
|
* register_meta_:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (boolean, gboolean, G_TYPE_BOOLEAN, boolean)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_int:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (int, gint, G_TYPE_INT, int)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_uint:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (uint, guint, G_TYPE_UINT, uint)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_int64:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (int64, gint64, G_TYPE_INT64, int64)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_uint64:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (uint64, guint64, G_TYPE_UINT64, uint64)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_float:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (float, float, G_TYPE_FLOAT, float)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_double:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (double, double, G_TYPE_DOUBLE, double)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_date:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (date, const GDate *, G_TYPE_DATE, boxed)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_date_time:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (date_time, const GstDateTime *, GST_TYPE_DATE_TIME,
|
|
boxed)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta_string:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: (allow-none): Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the meta could be register, %FALSE otherwize
|
|
*/
|
|
CREATE_REGISTER_STATIC (string, const gchar *, G_TYPE_STRING, string)
|
|
|
|
/**
|
|
* ges_meta_container_register_meta:
|
|
* @container: Target container
|
|
* @flags: The #GESMetaFlag to be used
|
|
* @meta_item: Name of the meta item to set
|
|
* @value: Value to set
|
|
*
|
|
* Sets a static meta on @container. This method lets you define static
|
|
* metadatas, which means that the type of the registered will be the only
|
|
* type accepted for this meta on that particular @container.
|
|
*
|
|
* Return: %TRUE if the static meta could be added, %FALSE otherwize
|
|
*/
|
|
gboolean
|
|
ges_meta_container_register_meta (GESMetaContainer * container,
|
|
GESMetaFlag flags, const gchar * meta_item, const GValue * value)
|
|
{
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
|
|
if (!_register_meta (container, flags, meta_item, G_VALUE_TYPE (value)))
|
|
return FALSE;
|
|
|
|
return _set_value (container, meta_item, value);
|
|
}
|
|
|
|
gboolean
|
|
ges_meta_container_check_meta_registered (GESMetaContainer * container,
|
|
const gchar * meta_item, GESMetaFlag * flags, GType * type)
|
|
{
|
|
ContainerData *data;
|
|
RegisteredMeta *static_item;
|
|
|
|
data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
|
|
if (!data)
|
|
return FALSE;
|
|
|
|
static_item = g_hash_table_lookup (data->static_items, meta_item);
|
|
if (static_item == NULL) {
|
|
GST_WARNING_OBJECT (container, "Static meta %s already registered",
|
|
meta_item);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (type)
|
|
*type = static_item->item_type;
|
|
|
|
if (flags)
|
|
*flags = static_item->flags;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* Copied from gsttaglist.c */
|
|
/***** evil macros to get all the *_get_* functions right *****/
|
|
|
|
#define CREATE_GETTER(name,type) \
|
|
gboolean \
|
|
ges_meta_container_get_ ## name (GESMetaContainer *container, \
|
|
const gchar *meta_item, type value) \
|
|
{ \
|
|
GstStructure *structure; \
|
|
\
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE); \
|
|
g_return_val_if_fail (meta_item != NULL, FALSE); \
|
|
g_return_val_if_fail (value != NULL, FALSE); \
|
|
\
|
|
structure = _meta_container_get_structure (container); \
|
|
\
|
|
return gst_structure_get_ ## name (structure, meta_item, value); \
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_boolean:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (boolean, gboolean *);
|
|
/**
|
|
* ges_meta_container_get_int:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (int, gint *);
|
|
/**
|
|
* ges_meta_container_get_uint:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (uint, guint *);
|
|
/**
|
|
* ges_meta_container_get_double:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (double, gdouble *);
|
|
|
|
/**
|
|
* ges_meta_container_get_int64:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns %FALSE if @meta_item
|
|
* can not be found.
|
|
*/
|
|
gboolean
|
|
ges_meta_container_get_int64 (GESMetaContainer * container,
|
|
const gchar * meta_item, gint64 * dest)
|
|
{
|
|
GstStructure *structure;
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
g_return_val_if_fail (dest != NULL, FALSE);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
value = gst_structure_get_value (structure, meta_item);
|
|
if (!value || G_VALUE_TYPE (value) != G_TYPE_INT64)
|
|
return FALSE;
|
|
|
|
*dest = g_value_get_int64 (value);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_uint64:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
gboolean
|
|
ges_meta_container_get_uint64 (GESMetaContainer * container,
|
|
const gchar * meta_item, guint64 * dest)
|
|
{
|
|
GstStructure *structure;
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
g_return_val_if_fail (dest != NULL, FALSE);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
value = gst_structure_get_value (structure, meta_item);
|
|
if (!value || G_VALUE_TYPE (value) != G_TYPE_UINT64)
|
|
return FALSE;
|
|
|
|
*dest = g_value_get_uint64 (value);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_float:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns FALSE if @meta_item
|
|
* can not be found.
|
|
*/
|
|
gboolean
|
|
ges_meta_container_get_float (GESMetaContainer * container,
|
|
const gchar * meta_item, gfloat * dest)
|
|
{
|
|
GstStructure *structure;
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
g_return_val_if_fail (dest != NULL, FALSE);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
value = gst_structure_get_value (structure, meta_item);
|
|
if (!value || G_VALUE_TYPE (value) != G_TYPE_FLOAT)
|
|
return FALSE;
|
|
|
|
*dest = g_value_get_float (value);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gchar *
|
|
_gst_strdup0 (const gchar * s)
|
|
{
|
|
if (s == NULL || *s == '\0')
|
|
return NULL;
|
|
|
|
return g_strdup (s);
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_string:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
const gchar *
|
|
ges_meta_container_get_string (GESMetaContainer * container,
|
|
const gchar * meta_item)
|
|
{
|
|
GstStructure *structure;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (meta_item != NULL, FALSE);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
return gst_structure_get_string (structure, meta_item);
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_meta:
|
|
* @container: Target container
|
|
*
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*
|
|
* Returns: %TRUE if the vale could be optained %FALSE otherwize
|
|
*/
|
|
const GValue *
|
|
ges_meta_container_get_meta (GESMetaContainer * container, const gchar * key)
|
|
{
|
|
GstStructure *structure;
|
|
|
|
g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
|
|
g_return_val_if_fail (key != NULL, FALSE);
|
|
|
|
structure = _meta_container_get_structure (container);
|
|
|
|
return gst_structure_get_value (structure, key);
|
|
}
|
|
|
|
/**
|
|
* ges_meta_container_get_date:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (date, GDate **);
|
|
|
|
/**
|
|
* ges_meta_container_get_date_time:
|
|
* @container: Target container
|
|
* @meta_item: Name of the meta item to get
|
|
* @dest: (out): Destination to which value of meta item will be copied
|
|
* Gets the value of a given meta item, returns NULL if @meta_item
|
|
* can not be found.
|
|
*/
|
|
CREATE_GETTER (date_time, GstDateTime **);
|