2003-11-03 09:10:07 +00:00
|
|
|
/* GStreamer
|
|
|
|
* Copyright (C) 2003 David A. Schleef <ds@schleef.org>
|
|
|
|
*
|
|
|
|
* gststructure.c: lists of { GQuark, GValue } tuples
|
|
|
|
*
|
|
|
|
* 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
|
2012-11-03 20:44:48 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2005-10-15 16:01:57 +00:00
|
|
|
|
2005-09-02 16:17:23 +00:00
|
|
|
/**
|
|
|
|
* SECTION:gststructure
|
|
|
|
* @short_description: Generic structure containing fields of names and values
|
2005-11-09 15:10:32 +00:00
|
|
|
* @see_also: #GstCaps, #GstMessage, #GstEvent, #GstQuery
|
2005-09-02 16:17:23 +00:00
|
|
|
*
|
2006-08-14 12:35:06 +00:00
|
|
|
* A #GstStructure is a collection of key/value pairs. The keys are expressed
|
|
|
|
* as GQuarks and the values can be of any GType.
|
2005-11-09 15:10:32 +00:00
|
|
|
*
|
2007-10-16 13:58:43 +00:00
|
|
|
* In addition to the key/value pairs, a #GstStructure also has a name. The name
|
2012-03-29 11:34:50 +00:00
|
|
|
* starts with a letter and can be filled by letters, numbers and any of "/-_.:".
|
2011-03-08 08:06:23 +00:00
|
|
|
*
|
2006-08-14 12:35:06 +00:00
|
|
|
* #GstStructure is used by various GStreamer subsystems to store information
|
|
|
|
* in a flexible and extensible way. A #GstStructure does not have a refcount
|
2012-03-29 11:34:50 +00:00
|
|
|
* because it usually is part of a higher level object such as #GstCaps,
|
|
|
|
* #GstMessage, #GstEvent, #GstQuery. It provides a means to enforce mutability
|
|
|
|
* using the refcount of the parent with the gst_structure_set_parent_refcount()
|
|
|
|
* method.
|
2006-08-14 12:35:06 +00:00
|
|
|
*
|
2011-10-29 07:02:00 +00:00
|
|
|
* A #GstStructure can be created with gst_structure_new_empty() or
|
2006-08-14 12:35:06 +00:00
|
|
|
* gst_structure_new(), which both take a name and an optional set of
|
|
|
|
* key/value pairs along with the types of the values.
|
2011-03-08 08:06:23 +00:00
|
|
|
*
|
2006-08-14 12:35:06 +00:00
|
|
|
* Field values can be changed with gst_structure_set_value() or
|
|
|
|
* gst_structure_set().
|
2005-11-09 15:10:32 +00:00
|
|
|
*
|
2006-08-14 12:35:06 +00:00
|
|
|
* Field values can be retrieved with gst_structure_get_value() or the more
|
|
|
|
* convenient gst_structure_get_*() functions.
|
2005-11-09 15:10:32 +00:00
|
|
|
*
|
2006-08-14 12:35:06 +00:00
|
|
|
* Fields can be removed with gst_structure_remove_field() or
|
|
|
|
* gst_structure_remove_fields().
|
2005-11-09 15:10:32 +00:00
|
|
|
*
|
2009-06-08 23:16:05 +00:00
|
|
|
* Strings in structures must be ASCII or UTF-8 encoded. Other encodings are
|
2014-05-29 21:54:34 +00:00
|
|
|
* not allowed. Strings may be %NULL however.
|
2009-06-08 23:16:05 +00:00
|
|
|
*
|
2013-09-25 22:06:55 +00:00
|
|
|
* Be aware that the current #GstCaps / #GstStructure serialization into string
|
|
|
|
* has limited support for nested #GstCaps / #GstStructure fields. It can only
|
|
|
|
* support one level of nesting. Using more levels will lead to unexpected
|
|
|
|
* behavior when using serialization features, such as gst_caps_to_string() or
|
|
|
|
* gst_value_serialize() and their counterparts.
|
2005-09-02 16:17:23 +00:00
|
|
|
*/
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
2004-05-07 02:36:28 +00:00
|
|
|
#include "gst_private.h"
|
2009-05-30 19:50:40 +00:00
|
|
|
#include "gstquark.h"
|
2003-11-03 09:10:07 +00:00
|
|
|
#include <gst/gst.h>
|
|
|
|
#include <gobject/gvaluecollector.h>
|
|
|
|
|
2012-12-14 10:09:30 +00:00
|
|
|
GST_DEBUG_CATEGORY_STATIC (gst_structure_debug);
|
|
|
|
#define GST_CAT_DEFAULT gst_structure_debug
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
typedef struct _GstStructureField GstStructureField;
|
2004-03-12 19:35:40 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
struct _GstStructureField
|
|
|
|
{
|
2003-12-22 01:39:35 +00:00
|
|
|
GQuark name;
|
|
|
|
GValue value;
|
|
|
|
};
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GstStructure s;
|
|
|
|
|
|
|
|
/* owned by parent structure, NULL if no parent */
|
|
|
|
gint *parent_refcount;
|
|
|
|
|
|
|
|
GArray *fields;
|
|
|
|
} GstStructureImpl;
|
|
|
|
|
|
|
|
#define GST_STRUCTURE_REFCOUNT(s) (((GstStructureImpl*)(s))->parent_refcount)
|
|
|
|
#define GST_STRUCTURE_FIELDS(s) (((GstStructureImpl*)(s))->fields)
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
#define GST_STRUCTURE_FIELD(structure, index) \
|
2011-05-11 16:17:45 +00:00
|
|
|
&g_array_index(GST_STRUCTURE_FIELDS(structure), GstStructureField, (index))
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
#define IS_MUTABLE(structure) \
|
2011-05-11 16:17:45 +00:00
|
|
|
(!GST_STRUCTURE_REFCOUNT(structure) || \
|
|
|
|
g_atomic_int_get (GST_STRUCTURE_REFCOUNT(structure)) == 1)
|
2005-03-07 18:27:42 +00:00
|
|
|
|
2009-05-30 19:50:40 +00:00
|
|
|
#define IS_TAGLIST(structure) \
|
|
|
|
(structure->name == GST_QUARK (TAGLIST))
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
static void gst_structure_set_field (GstStructure * structure,
|
|
|
|
GstStructureField * field);
|
|
|
|
static GstStructureField *gst_structure_get_field (const GstStructure *
|
|
|
|
structure, const gchar * fieldname);
|
|
|
|
static GstStructureField *gst_structure_id_get_field (const GstStructure *
|
|
|
|
structure, GQuark field);
|
|
|
|
static void gst_structure_transform_to_string (const GValue * src_value,
|
|
|
|
GValue * dest_value);
|
|
|
|
static GstStructure *gst_structure_copy_conditional (const GstStructure *
|
|
|
|
structure);
|
|
|
|
static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
|
|
|
|
GValue * value, GType default_type);
|
|
|
|
static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
GType _gst_structure_type = 0;
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2011-08-29 16:50:02 +00:00
|
|
|
|
|
|
|
G_DEFINE_BOXED_TYPE (GstStructure, gst_structure,
|
|
|
|
gst_structure_copy_conditional, gst_structure_free);
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
void
|
2011-08-29 11:27:26 +00:00
|
|
|
_priv_gst_structure_initialize (void)
|
2011-05-11 16:17:45 +00:00
|
|
|
{
|
2011-08-29 16:50:02 +00:00
|
|
|
_gst_structure_type = gst_structure_get_type ();
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
g_value_register_transform_func (_gst_structure_type, G_TYPE_STRING,
|
|
|
|
gst_structure_transform_to_string);
|
2012-12-14 10:09:30 +00:00
|
|
|
|
|
|
|
GST_DEBUG_CATEGORY_INIT (gst_structure_debug, "structure", 0,
|
|
|
|
"GstStructure debug");
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2004-08-13 13:31:22 +00:00
|
|
|
static GstStructure *
|
2011-10-29 07:02:00 +00:00
|
|
|
gst_structure_new_id_empty_with_size (GQuark quark, guint prealloc)
|
2004-08-04 12:39:12 +00:00
|
|
|
{
|
2011-05-11 16:17:45 +00:00
|
|
|
GstStructureImpl *structure;
|
2004-08-04 12:39:12 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
structure = g_slice_new (GstStructureImpl);
|
|
|
|
((GstStructure *) structure)->type = _gst_structure_type;
|
|
|
|
((GstStructure *) structure)->name = quark;
|
|
|
|
GST_STRUCTURE_REFCOUNT (structure) = NULL;
|
|
|
|
GST_STRUCTURE_FIELDS (structure) =
|
gst/gstcaps.c: Callgrind micro optimisations.
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_copy), (_gst_caps_free),
(gst_caps_merge_structure), (gst_caps_get_structure),
(gst_caps_copy_nth), (gst_caps_set_simple),
(gst_caps_set_simple_valist), (gst_caps_is_fixed),
(gst_caps_is_equal_fixed), (gst_caps_intersect),
(gst_caps_subtract), (gst_caps_normalize), (gst_caps_do_simplify),
(gst_caps_to_string):
Callgrind micro optimisations.
Avoid array bounds checks and force inline of trivial function.
* gst/gstobject.c: (gst_object_set_name_default):
-1 is equivalent to letting glib to the strlen but then there is more
room for optimisations and it's not our fault.
* gst/gststructure.c: (gst_structure_id_empty_new_with_size):
no need to clear the array, we're cool.
* gst/gstvalue.c: (gst_type_is_fixed), (gst_value_is_fixed):
The most common _is_fixed() check is done on fundamental glib base
types so we check this first instead of doing a huge amount of
useless GST_TYPE_ARRAY calls.
2008-11-06 15:09:34 +00:00
|
|
|
g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc);
|
2004-08-04 12:39:12 +00:00
|
|
|
|
2012-03-11 16:22:01 +00:00
|
|
|
GST_TRACE ("created structure %p", structure);
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
return GST_STRUCTURE_CAST (structure);
|
2004-08-04 12:39:12 +00:00
|
|
|
}
|
|
|
|
|
2003-11-24 02:09:23 +00:00
|
|
|
/**
|
2011-10-29 07:02:00 +00:00
|
|
|
* gst_structure_new_id_empty:
|
2004-01-30 19:06:13 +00:00
|
|
|
* @quark: name of new structure
|
2003-11-24 02:09:23 +00:00
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Creates a new, empty #GstStructure with the given name as a GQuark.
|
2003-11-24 02:09:23 +00:00
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
|
|
|
* Returns: (transfer full): a new, empty #GstStructure
|
2003-11-24 02:09:23 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
GstStructure *
|
2011-10-29 07:02:00 +00:00
|
|
|
gst_structure_new_id_empty (GQuark quark)
|
2003-11-24 02:09:23 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (quark != 0, NULL);
|
2003-11-24 02:09:23 +00:00
|
|
|
|
2011-10-29 07:02:00 +00:00
|
|
|
return gst_structure_new_id_empty_with_size (quark, 0);
|
2003-11-24 02:09:23 +00:00
|
|
|
}
|
|
|
|
|
2009-04-04 12:35:34 +00:00
|
|
|
#ifndef G_DISABLE_CHECKS
|
2007-10-16 13:58:43 +00:00
|
|
|
static gboolean
|
|
|
|
gst_structure_validate_name (const gchar * name)
|
|
|
|
{
|
|
|
|
const gchar *s;
|
|
|
|
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
|
2011-06-02 13:38:29 +00:00
|
|
|
if (G_UNLIKELY (!g_ascii_isalpha (*name))) {
|
2007-10-16 13:58:43 +00:00
|
|
|
GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s",
|
|
|
|
*name, name);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: test name string more */
|
|
|
|
s = &name[1];
|
2011-06-03 11:25:54 +00:00
|
|
|
while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+", *s) != NULL))
|
2007-10-16 13:58:43 +00:00
|
|
|
s++;
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (*s != '\0')) {
|
2011-09-25 21:30:47 +00:00
|
|
|
GST_WARNING ("Invalid character '%c' at offset %" G_GUINTPTR_FORMAT " in"
|
|
|
|
" structure name: %s", *s, ((guintptr) s - (guintptr) name), name);
|
2007-10-16 13:58:43 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-02-29 12:41:44 +00:00
|
|
|
if (strncmp (name, "video/x-raw-", 12) == 0) {
|
|
|
|
g_warning ("0.10-style raw video caps are being created. Should be "
|
|
|
|
"video/x-raw,format=(string).. now.");
|
|
|
|
} else if (strncmp (name, "audio/x-raw-", 12) == 0) {
|
|
|
|
g_warning ("0.10-style raw audio caps are being created. Should be "
|
|
|
|
"audio/x-raw,format=(string).. now.");
|
|
|
|
}
|
|
|
|
|
2007-10-16 13:58:43 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2009-04-04 12:35:34 +00:00
|
|
|
#endif
|
2007-10-16 13:58:43 +00:00
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
2011-10-29 07:02:00 +00:00
|
|
|
* gst_structure_new_empty:
|
2003-11-03 09:10:07 +00:00
|
|
|
* @name: name of new structure
|
|
|
|
*
|
2007-10-16 13:58:43 +00:00
|
|
|
* Creates a new, empty #GstStructure with the given @name.
|
|
|
|
*
|
|
|
|
* See gst_structure_set_name() for constraints on the @name parameter.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
|
|
|
* Returns: (transfer full): a new, empty #GstStructure
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
GstStructure *
|
2011-10-29 07:02:00 +00:00
|
|
|
gst_structure_new_empty (const gchar * name)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2007-10-16 13:58:43 +00:00
|
|
|
g_return_val_if_fail (gst_structure_validate_name (name), NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-10-29 07:02:00 +00:00
|
|
|
return gst_structure_new_id_empty_with_size (g_quark_from_string (name), 0);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_new:
|
|
|
|
* @name: name of new structure
|
|
|
|
* @firstfield: name of first field to set
|
|
|
|
* @...: additional arguments
|
|
|
|
*
|
|
|
|
* Creates a new #GstStructure with the given name. Parses the
|
|
|
|
* list of variable arguments and sets fields to the values listed.
|
|
|
|
* Variable arguments should be passed as field name, field type,
|
2014-05-29 21:54:34 +00:00
|
|
|
* and value. Last variable argument should be %NULL.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
|
|
|
* Returns: (transfer full): a new #GstStructure
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-13 15:27:01 +00:00
|
|
|
GstStructure *
|
|
|
|
gst_structure_new (const gchar * name, const gchar * firstfield, ...)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructure *structure;
|
|
|
|
va_list varargs;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
va_start (varargs, firstfield);
|
|
|
|
structure = gst_structure_new_valist (name, firstfield, varargs);
|
|
|
|
va_end (varargs);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return structure;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_new_valist:
|
|
|
|
* @name: name of new structure
|
|
|
|
* @firstfield: name of first field to set
|
2004-01-30 19:06:13 +00:00
|
|
|
* @varargs: variable argument list
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2007-10-16 13:58:43 +00:00
|
|
|
* Creates a new #GstStructure with the given @name. Structure fields
|
2003-11-03 09:10:07 +00:00
|
|
|
* are set according to the varargs in a manner similar to
|
2007-10-16 13:58:43 +00:00
|
|
|
* gst_structure_new().
|
|
|
|
*
|
|
|
|
* See gst_structure_set_name() for constraints on the @name parameter.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
|
|
|
* Returns: (transfer full): a new #GstStructure
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
GstStructure *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_new_valist (const gchar * name,
|
|
|
|
const gchar * firstfield, va_list varargs)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructure *structure;
|
|
|
|
|
2011-10-29 07:02:00 +00:00
|
|
|
structure = gst_structure_new_empty (name);
|
2007-12-08 12:54:53 +00:00
|
|
|
|
|
|
|
if (structure)
|
|
|
|
gst_structure_set_valist (structure, firstfield, varargs);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return structure;
|
|
|
|
}
|
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_set_parent_refcount:
|
|
|
|
* @structure: a #GstStructure
|
2010-12-07 18:35:04 +00:00
|
|
|
* @refcount: (in): a pointer to the parent's refcount
|
2005-03-07 18:27:42 +00:00
|
|
|
*
|
|
|
|
* Sets the parent_refcount field of #GstStructure. This field is used to
|
|
|
|
* determine whether a structure is mutable or not. This function should only be
|
2005-11-09 15:10:32 +00:00
|
|
|
* called by code implementing parent objects of #GstStructure, as described in
|
2005-03-07 18:27:42 +00:00
|
|
|
* the MT Refcounting section of the design documents.
|
2011-05-11 16:17:45 +00:00
|
|
|
*
|
|
|
|
* Returns: %TRUE if the parent refcount could be set.
|
2005-03-07 18:27:42 +00:00
|
|
|
*/
|
2011-05-11 16:17:45 +00:00
|
|
|
gboolean
|
2009-06-27 13:34:36 +00:00
|
|
|
gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount)
|
2005-03-07 18:27:42 +00:00
|
|
|
{
|
2011-05-11 16:17:45 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
2005-04-21 09:33:31 +00:00
|
|
|
|
|
|
|
/* if we have a parent_refcount already, we can only clear
|
|
|
|
* if with a NULL refcount */
|
2011-05-11 16:17:45 +00:00
|
|
|
if (GST_STRUCTURE_REFCOUNT (structure)) {
|
|
|
|
if (refcount != NULL) {
|
|
|
|
g_return_val_if_fail (refcount == NULL, FALSE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (refcount == NULL) {
|
|
|
|
g_return_val_if_fail (refcount != NULL, FALSE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2005-03-07 18:27:42 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
GST_STRUCTURE_REFCOUNT (structure) = refcount;
|
|
|
|
|
|
|
|
return TRUE;
|
2005-03-07 18:27:42 +00:00
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
2003-11-04 05:54:24 +00:00
|
|
|
* gst_structure_copy:
|
2003-11-03 09:10:07 +00:00
|
|
|
* @structure: a #GstStructure to duplicate
|
|
|
|
*
|
|
|
|
* Duplicates a #GstStructure and all its fields and values.
|
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
2013-03-30 14:35:19 +00:00
|
|
|
* Returns: (transfer full): a new #GstStructure.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
GstStructure *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_copy (const GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructure *new_structure;
|
|
|
|
GstStructureField *field;
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2011-10-29 07:02:00 +00:00
|
|
|
new_structure = gst_structure_new_id_empty_with_size (structure->name, len);
|
2009-11-16 11:53:44 +00:00
|
|
|
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2003-11-03 09:10:07 +00:00
|
|
|
GstStructureField new_field = { 0 };
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
new_field.name = field->name;
|
2003-12-22 07:00:25 +00:00
|
|
|
gst_value_init_and_copy (&new_field.value, &field->value);
|
2011-05-11 16:17:45 +00:00
|
|
|
g_array_append_val (GST_STRUCTURE_FIELDS (new_structure), new_field);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
2012-03-11 16:22:01 +00:00
|
|
|
GST_CAT_TRACE (GST_CAT_PERFORMANCE, "doing copy %p -> %p",
|
|
|
|
structure, new_structure);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2003-12-30 04:59:48 +00:00
|
|
|
return new_structure;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2005-10-15 15:30:24 +00:00
|
|
|
* gst_structure_free:
|
2010-12-07 18:35:04 +00:00
|
|
|
* @structure: (in) (transfer full): the #GstStructure to free
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2005-03-07 18:27:42 +00:00
|
|
|
* Frees a #GstStructure and all its fields and values. The structure must not
|
2005-04-21 09:33:31 +00:00
|
|
|
* have a parent when this function is called.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_free (GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
2011-05-11 16:17:45 +00:00
|
|
|
g_return_if_fail (GST_STRUCTURE_REFCOUNT (structure) == NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (G_IS_VALUE (&field->value)) {
|
|
|
|
g_value_unset (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-11 16:17:45 +00:00
|
|
|
g_array_free (GST_STRUCTURE_FIELDS (structure), TRUE);
|
2003-12-22 01:39:35 +00:00
|
|
|
#ifdef USE_POISONING
|
2004-03-13 15:27:01 +00:00
|
|
|
memset (structure, 0xff, sizeof (GstStructure));
|
2003-12-22 01:39:35 +00:00
|
|
|
#endif
|
2012-03-11 16:22:01 +00:00
|
|
|
GST_TRACE ("free structure %p", structure);
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
g_slice_free1 (sizeof (GstStructureImpl), structure);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_name:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Get the name of @structure as a string.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
|
|
|
* Returns: the name of the structure.
|
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
const gchar *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_name (const GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
return g_quark_to_string (structure->name);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
gst/gstcaps.c: check for ANY caps before appending/unioning
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_append), (gst_caps_union):
check for ANY caps before appending/unioning
* gst/gstcaps.c: (gst_caps_is_subset),
(gst_caps_is_equal), (gst_caps_structure_subtract_field),
(gst_caps_structure_subtract), (gst_caps_subtract):
* gst/gstcaps.h:
add gst_caps_is_equal, gst_caps_is_subset and gst_caps_subtract to
the API. deprecate gst_caps_is_equal_fixed
* gst/gstpad.c: (gst_pad_try_set_caps):
* gst/gstqueue.c: (gst_queue_link):
s/gst_caps_is_equal_fixed/gst_caps_is_equal/
* gst/gststructure.c: (gst_structure_get_name_id):
* gst/gststructure.h:
add function gst_structure_get_name_id
* gst/gstvalue.c: (gst_value_subtract_int_int_range),
(gst_value_create_new_range), (gst_value_subtract_int_range_int),
(gst_value_subtract_int_range_int_range),
(gst_value_subtract_double_double_range),
(gst_value_subtract_double_range_double),
(gst_value_subtract_double_range_double_range),
(gst_value_subtract_from_list), (gst_value_subtract_list),
(gst_value_can_intersect), (gst_value_subtract),
(gst_value_can_subtract), (gst_value_register_subtract_func),
(_gst_value_initialize):
* gst/gstvalue.h:
add support for subtracting values from each other. Note that
subtracting means subtracting as in set theory. Required for caps
stuff above.
* testsuite/caps/.cvsignore:
* testsuite/caps/Makefile.am:
* testsuite/caps/erathostenes.c: (erathostenes), (main):
* testsuite/caps/sets.c: (check_caps), (main):
* testsuite/caps/subtract.c: (check_caps), (main):
add tests for subtraction and equality code.
2004-04-21 03:25:13 +00:00
|
|
|
/**
|
2005-07-31 11:59:33 +00:00
|
|
|
* gst_structure_has_name:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @name: structure name to check for
|
|
|
|
*
|
2005-10-20 21:08:47 +00:00
|
|
|
* Checks if the structure has the given name
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if @name matches the name of the structure.
|
2005-07-31 11:59:33 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_has_name (const GstStructure * structure, const gchar * name)
|
|
|
|
{
|
|
|
|
const gchar *structure_name;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
|
2007-10-16 13:58:43 +00:00
|
|
|
/* getting the string is cheap and comparing short strings is too
|
|
|
|
* should be faster than getting the quark for name and comparing the quarks
|
|
|
|
*/
|
2005-07-31 11:59:33 +00:00
|
|
|
structure_name = g_quark_to_string (structure->name);
|
|
|
|
|
|
|
|
return (structure_name && strcmp (structure_name, name) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_name_id:
|
gst/gstcaps.c: check for ANY caps before appending/unioning
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_append), (gst_caps_union):
check for ANY caps before appending/unioning
* gst/gstcaps.c: (gst_caps_is_subset),
(gst_caps_is_equal), (gst_caps_structure_subtract_field),
(gst_caps_structure_subtract), (gst_caps_subtract):
* gst/gstcaps.h:
add gst_caps_is_equal, gst_caps_is_subset and gst_caps_subtract to
the API. deprecate gst_caps_is_equal_fixed
* gst/gstpad.c: (gst_pad_try_set_caps):
* gst/gstqueue.c: (gst_queue_link):
s/gst_caps_is_equal_fixed/gst_caps_is_equal/
* gst/gststructure.c: (gst_structure_get_name_id):
* gst/gststructure.h:
add function gst_structure_get_name_id
* gst/gstvalue.c: (gst_value_subtract_int_int_range),
(gst_value_create_new_range), (gst_value_subtract_int_range_int),
(gst_value_subtract_int_range_int_range),
(gst_value_subtract_double_double_range),
(gst_value_subtract_double_range_double),
(gst_value_subtract_double_range_double_range),
(gst_value_subtract_from_list), (gst_value_subtract_list),
(gst_value_can_intersect), (gst_value_subtract),
(gst_value_can_subtract), (gst_value_register_subtract_func),
(_gst_value_initialize):
* gst/gstvalue.h:
add support for subtracting values from each other. Note that
subtracting means subtracting as in set theory. Required for caps
stuff above.
* testsuite/caps/.cvsignore:
* testsuite/caps/Makefile.am:
* testsuite/caps/erathostenes.c: (erathostenes), (main):
* testsuite/caps/sets.c: (check_caps), (main):
* testsuite/caps/subtract.c: (check_caps), (main):
add tests for subtraction and equality code.
2004-04-21 03:25:13 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Get the name of @structure as a GQuark.
|
gst/gstcaps.c: check for ANY caps before appending/unioning
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_append), (gst_caps_union):
check for ANY caps before appending/unioning
* gst/gstcaps.c: (gst_caps_is_subset),
(gst_caps_is_equal), (gst_caps_structure_subtract_field),
(gst_caps_structure_subtract), (gst_caps_subtract):
* gst/gstcaps.h:
add gst_caps_is_equal, gst_caps_is_subset and gst_caps_subtract to
the API. deprecate gst_caps_is_equal_fixed
* gst/gstpad.c: (gst_pad_try_set_caps):
* gst/gstqueue.c: (gst_queue_link):
s/gst_caps_is_equal_fixed/gst_caps_is_equal/
* gst/gststructure.c: (gst_structure_get_name_id):
* gst/gststructure.h:
add function gst_structure_get_name_id
* gst/gstvalue.c: (gst_value_subtract_int_int_range),
(gst_value_create_new_range), (gst_value_subtract_int_range_int),
(gst_value_subtract_int_range_int_range),
(gst_value_subtract_double_double_range),
(gst_value_subtract_double_range_double),
(gst_value_subtract_double_range_double_range),
(gst_value_subtract_from_list), (gst_value_subtract_list),
(gst_value_can_intersect), (gst_value_subtract),
(gst_value_can_subtract), (gst_value_register_subtract_func),
(_gst_value_initialize):
* gst/gstvalue.h:
add support for subtracting values from each other. Note that
subtracting means subtracting as in set theory. Required for caps
stuff above.
* testsuite/caps/.cvsignore:
* testsuite/caps/Makefile.am:
* testsuite/caps/erathostenes.c: (erathostenes), (main):
* testsuite/caps/sets.c: (check_caps), (main):
* testsuite/caps/subtract.c: (check_caps), (main):
add tests for subtraction and equality code.
2004-04-21 03:25:13 +00:00
|
|
|
*
|
|
|
|
* Returns: the quark representing the name of the structure.
|
|
|
|
*/
|
|
|
|
GQuark
|
|
|
|
gst_structure_get_name_id (const GstStructure * structure)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (structure != NULL, 0);
|
|
|
|
|
|
|
|
return structure->name;
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_set_name:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @name: the new name of the structure
|
|
|
|
*
|
2007-10-16 13:58:43 +00:00
|
|
|
* Sets the name of the structure to the given @name. The string
|
2007-10-24 13:00:58 +00:00
|
|
|
* provided is copied before being used. It must not be empty, start with a
|
|
|
|
* letter and can be followed by letters, numbers and any of "/-_.:".
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_name (GstStructure * structure, const gchar * name)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2007-10-16 13:58:43 +00:00
|
|
|
g_return_if_fail (gst_structure_validate_name (name));
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
structure->name = g_quark_from_string (name);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
static inline void
|
|
|
|
gst_structure_id_set_value_internal (GstStructure * structure, GQuark field,
|
|
|
|
const GValue * value)
|
|
|
|
{
|
|
|
|
GstStructureField gsfield = { 0, {0,} };
|
|
|
|
|
|
|
|
gsfield.name = field;
|
|
|
|
gst_value_init_and_copy (&gsfield.value, value);
|
|
|
|
|
|
|
|
gst_structure_set_field (structure, &gsfield);
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_id_set_value:
|
|
|
|
* @structure: a #GstStructure
|
2004-01-30 19:06:13 +00:00
|
|
|
* @field: a #GQuark representing a field
|
2003-11-03 09:10:07 +00:00
|
|
|
* @value: the new value of the field
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Sets the field with the given GQuark @field to @value. If the field
|
2003-11-03 09:10:07 +00:00
|
|
|
* does not exist, it is created. If the field exists, the previous
|
2005-11-09 15:10:32 +00:00
|
|
|
* value is replaced and freed.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_id_set_value (GstStructure * structure,
|
|
|
|
GQuark field, const GValue * value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (G_IS_VALUE (value));
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_id_set_value_internal (structure, field, value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_set_value:
|
|
|
|
* @structure: a #GstStructure
|
2004-01-30 19:06:13 +00:00
|
|
|
* @fieldname: the name of the field to set
|
2003-11-03 09:10:07 +00:00
|
|
|
* @value: the new value of the field
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Sets the field with the given name @field to @value. If the field
|
2003-11-03 09:10:07 +00:00
|
|
|
* does not exist, it is created. If the field exists, the previous
|
2005-11-09 15:10:32 +00:00
|
|
|
* value is replaced and freed.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_value (GstStructure * structure,
|
|
|
|
const gchar * fieldname, const GValue * value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (fieldname != NULL);
|
|
|
|
g_return_if_fail (G_IS_VALUE (value));
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_id_set_value_internal (structure,
|
|
|
|
g_quark_from_string (fieldname), value);
|
2010-09-15 22:42:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
gst_structure_id_take_value_internal (GstStructure * structure, GQuark field,
|
|
|
|
GValue * value)
|
|
|
|
{
|
|
|
|
GstStructureField gsfield = { 0, {0,} };
|
|
|
|
|
|
|
|
gsfield.name = field;
|
|
|
|
gsfield.value = *value;
|
|
|
|
|
|
|
|
gst_structure_set_field (structure, &gsfield);
|
|
|
|
|
|
|
|
/* we took ownership */
|
|
|
|
#ifdef USE_POISONING
|
|
|
|
memset (value, 0, sizeof (GValue));
|
|
|
|
#else
|
|
|
|
value->g_type = G_TYPE_INVALID;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_id_take_value:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field: a #GQuark representing a field
|
|
|
|
* @value: (transfer full): the new value of the field
|
|
|
|
*
|
|
|
|
* Sets the field with the given GQuark @field to @value. If the field
|
|
|
|
* does not exist, it is created. If the field exists, the previous
|
|
|
|
* value is replaced and freed.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_id_take_value (GstStructure * structure, GQuark field,
|
|
|
|
GValue * value)
|
|
|
|
{
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (G_IS_VALUE (value));
|
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
|
|
|
|
|
|
|
gst_structure_id_take_value_internal (structure, field, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_take_value:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to set
|
|
|
|
* @value: (transfer full): the new value of the field
|
|
|
|
*
|
|
|
|
* Sets the field with the given name @field to @value. If the field
|
|
|
|
* does not exist, it is created. If the field exists, the previous
|
|
|
|
* value is replaced and freed. The function will take ownership of @value.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_take_value (GstStructure * structure, const gchar * fieldname,
|
|
|
|
GValue * value)
|
|
|
|
{
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (fieldname != NULL);
|
|
|
|
g_return_if_fail (G_IS_VALUE (value));
|
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
|
|
|
|
|
|
|
gst_structure_id_take_value_internal (structure,
|
|
|
|
g_quark_from_string (fieldname), value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
static void
|
|
|
|
gst_structure_set_valist_internal (GstStructure * structure,
|
|
|
|
const gchar * fieldname, va_list varargs)
|
|
|
|
{
|
|
|
|
gchar *err = NULL;
|
|
|
|
GType type;
|
|
|
|
|
|
|
|
while (fieldname) {
|
|
|
|
GstStructureField field = { 0 };
|
|
|
|
|
|
|
|
field.name = g_quark_from_string (fieldname);
|
|
|
|
|
|
|
|
type = va_arg (varargs, GType);
|
|
|
|
|
|
|
|
G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
|
|
|
|
if (G_UNLIKELY (err)) {
|
|
|
|
g_critical ("%s", err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
gst_structure_set_field (structure, &field);
|
|
|
|
|
|
|
|
fieldname = va_arg (varargs, gchar *);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_set:
|
|
|
|
* @structure: a #GstStructure
|
2004-01-30 19:06:13 +00:00
|
|
|
* @fieldname: the name of the field to set
|
2003-11-03 09:10:07 +00:00
|
|
|
* @...: variable arguments
|
|
|
|
*
|
2015-05-31 23:21:42 +00:00
|
|
|
* Parses the variable arguments and sets fields accordingly. Fields that
|
|
|
|
* weren't already part of the structure are added as needed.
|
2003-11-03 09:10:07 +00:00
|
|
|
* Variable arguments should be in the form field name, field type
|
2014-05-29 21:54:34 +00:00
|
|
|
* (as a GType), value(s). The last variable argument should be %NULL.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set (GstStructure * structure, const gchar * field, ...)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
va_list varargs;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
2010-09-15 23:03:38 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure) || field == NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
va_start (varargs, field);
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_set_valist_internal (structure, field, varargs);
|
2004-03-13 15:27:01 +00:00
|
|
|
va_end (varargs);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2003-12-22 01:39:35 +00:00
|
|
|
* gst_structure_set_valist:
|
2003-11-03 09:10:07 +00:00
|
|
|
* @structure: a #GstStructure
|
2004-01-30 19:06:13 +00:00
|
|
|
* @fieldname: the name of the field to set
|
2003-11-03 09:10:07 +00:00
|
|
|
* @varargs: variable arguments
|
|
|
|
*
|
2006-01-27 22:34:51 +00:00
|
|
|
* va_list form of gst_structure_set().
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_valist (GstStructure * structure,
|
|
|
|
const gchar * fieldname, va_list varargs)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_set_valist_internal (structure, fieldname, varargs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_structure_id_set_valist_internal (GstStructure * structure,
|
|
|
|
GQuark fieldname, va_list varargs)
|
|
|
|
{
|
|
|
|
gchar *err = NULL;
|
|
|
|
GType type;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (fieldname) {
|
2003-11-03 09:10:07 +00:00
|
|
|
GstStructureField field = { 0 };
|
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
field.name = fieldname;
|
2004-03-13 15:27:01 +00:00
|
|
|
type = va_arg (varargs, GType);
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (err)) {
|
2005-05-09 06:21:10 +00:00
|
|
|
g_critical ("%s", err);
|
|
|
|
return;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_field (structure, &field);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
fieldname = va_arg (varargs, GQuark);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
gst/gststructure.*: Add API for setting values into structures without performing a quark lookup, if the appropriate ...
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set),
(gst_structure_id_set_valist):
* gst/gststructure.h:
Add API for setting values into structures without performing
a quark lookup, if the appropriate quark is already known.
API: gst_structure_id_set
API: gst_structure_id_set_valist
* gst/parse/grammar.y:
* gst/parse/parse.l:
Remove some dead code shown by the coverage information.
Don't throw a critical g_warning when encountering a syntax error,
just warn and let the normal error path handle it.
* plugins/elements/gstelements.c:
Bump the rank of filesink up to PRIMARY so that it is preferred over
gnomevfssink for file:// sink uri's
* tests/check/pipelines/parse-launch.c: (expected_fail_pipe),
(GST_START_TEST), (run_delayed_test),
(gst_parse_test_element_base_init),
(gst_parse_test_element_class_init), (gst_parse_test_element_init),
(gst_parse_test_element_change_state),
(gst_register_parse_element), (parse_suite):
Beef up the tests for parse syntax to check that more error cases
fail as they are supposed to. Increases the test coverage a bit.
2006-07-26 17:04:45 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_id_set:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the GQuark for the name of the field to set
|
|
|
|
* @...: variable arguments
|
|
|
|
*
|
|
|
|
* Identical to gst_structure_set, except that field names are
|
|
|
|
* passed using the GQuark for the field name. This allows more efficient
|
|
|
|
* setting of the structure if the caller already knows the associated
|
|
|
|
* quark values.
|
2014-05-29 21:54:34 +00:00
|
|
|
* The last variable argument must be %NULL.
|
gst/gststructure.*: Add API for setting values into structures without performing a quark lookup, if the appropriate ...
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set),
(gst_structure_id_set_valist):
* gst/gststructure.h:
Add API for setting values into structures without performing
a quark lookup, if the appropriate quark is already known.
API: gst_structure_id_set
API: gst_structure_id_set_valist
* gst/parse/grammar.y:
* gst/parse/parse.l:
Remove some dead code shown by the coverage information.
Don't throw a critical g_warning when encountering a syntax error,
just warn and let the normal error path handle it.
* plugins/elements/gstelements.c:
Bump the rank of filesink up to PRIMARY so that it is preferred over
gnomevfssink for file:// sink uri's
* tests/check/pipelines/parse-launch.c: (expected_fail_pipe),
(GST_START_TEST), (run_delayed_test),
(gst_parse_test_element_base_init),
(gst_parse_test_element_class_init), (gst_parse_test_element_init),
(gst_parse_test_element_change_state),
(gst_register_parse_element), (parse_suite):
Beef up the tests for parse syntax to check that more error cases
fail as they are supposed to. Increases the test coverage a bit.
2006-07-26 17:04:45 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_id_set (GstStructure * structure, GQuark field, ...)
|
|
|
|
{
|
|
|
|
va_list varargs;
|
|
|
|
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
|
|
|
|
va_start (varargs, field);
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_id_set_valist_internal (structure, field, varargs);
|
gst/gststructure.*: Add API for setting values into structures without performing a quark lookup, if the appropriate ...
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set),
(gst_structure_id_set_valist):
* gst/gststructure.h:
Add API for setting values into structures without performing
a quark lookup, if the appropriate quark is already known.
API: gst_structure_id_set
API: gst_structure_id_set_valist
* gst/parse/grammar.y:
* gst/parse/parse.l:
Remove some dead code shown by the coverage information.
Don't throw a critical g_warning when encountering a syntax error,
just warn and let the normal error path handle it.
* plugins/elements/gstelements.c:
Bump the rank of filesink up to PRIMARY so that it is preferred over
gnomevfssink for file:// sink uri's
* tests/check/pipelines/parse-launch.c: (expected_fail_pipe),
(GST_START_TEST), (run_delayed_test),
(gst_parse_test_element_base_init),
(gst_parse_test_element_class_init), (gst_parse_test_element_init),
(gst_parse_test_element_change_state),
(gst_register_parse_element), (parse_suite):
Beef up the tests for parse syntax to check that more error cases
fail as they are supposed to. Increases the test coverage a bit.
2006-07-26 17:04:45 +00:00
|
|
|
va_end (varargs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_id_set_valist:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to set
|
|
|
|
* @varargs: variable arguments
|
|
|
|
*
|
|
|
|
* va_list form of gst_structure_id_set().
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_id_set_valist (GstStructure * structure,
|
|
|
|
GQuark fieldname, va_list varargs)
|
|
|
|
{
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
|
|
|
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_id_set_valist_internal (structure, fieldname, varargs);
|
gst/gststructure.*: Add API for setting values into structures without performing a quark lookup, if the appropriate ...
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set),
(gst_structure_id_set_valist):
* gst/gststructure.h:
Add API for setting values into structures without performing
a quark lookup, if the appropriate quark is already known.
API: gst_structure_id_set
API: gst_structure_id_set_valist
* gst/parse/grammar.y:
* gst/parse/parse.l:
Remove some dead code shown by the coverage information.
Don't throw a critical g_warning when encountering a syntax error,
just warn and let the normal error path handle it.
* plugins/elements/gstelements.c:
Bump the rank of filesink up to PRIMARY so that it is preferred over
gnomevfssink for file:// sink uri's
* tests/check/pipelines/parse-launch.c: (expected_fail_pipe),
(GST_START_TEST), (run_delayed_test),
(gst_parse_test_element_base_init),
(gst_parse_test_element_class_init), (gst_parse_test_element_init),
(gst_parse_test_element_change_state),
(gst_register_parse_element), (parse_suite):
Beef up the tests for parse syntax to check that more error cases
fail as they are supposed to. Increases the test coverage a bit.
2006-07-26 17:04:45 +00:00
|
|
|
}
|
|
|
|
|
2009-05-29 17:22:42 +00:00
|
|
|
/**
|
2011-10-29 07:02:00 +00:00
|
|
|
* gst_structure_new_id:
|
2009-05-29 17:22:42 +00:00
|
|
|
* @name_quark: name of new structure
|
|
|
|
* @field_quark: the GQuark for the name of the field to set
|
|
|
|
* @...: variable arguments
|
|
|
|
*
|
|
|
|
* Creates a new #GstStructure with the given name as a GQuark, followed by
|
|
|
|
* fieldname quark, GType, argument(s) "triplets" in the same format as
|
|
|
|
* gst_structure_id_set(). Basically a convenience wrapper around
|
2011-10-29 07:02:00 +00:00
|
|
|
* gst_structure_new_id_empty() and gst_structure_id_set().
|
2009-05-29 17:22:42 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* The last variable argument must be %NULL (or 0).
|
2009-05-29 17:22:42 +00:00
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
|
|
|
* Returns: (transfer full): a new #GstStructure
|
2009-05-29 17:22:42 +00:00
|
|
|
*/
|
|
|
|
GstStructure *
|
2011-10-29 07:02:00 +00:00
|
|
|
gst_structure_new_id (GQuark name_quark, GQuark field_quark, ...)
|
2009-05-29 17:22:42 +00:00
|
|
|
{
|
|
|
|
GstStructure *s;
|
|
|
|
va_list varargs;
|
|
|
|
|
|
|
|
g_return_val_if_fail (name_quark != 0, NULL);
|
|
|
|
g_return_val_if_fail (field_quark != 0, NULL);
|
|
|
|
|
2011-10-29 07:02:00 +00:00
|
|
|
s = gst_structure_new_id_empty (name_quark);
|
2009-05-29 17:22:42 +00:00
|
|
|
|
|
|
|
va_start (varargs, field_quark);
|
2010-09-15 23:03:38 +00:00
|
|
|
gst_structure_id_set_valist_internal (s, field_quark, varargs);
|
2009-05-29 17:22:42 +00:00
|
|
|
va_end (varargs);
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2009-07-16 12:59:07 +00:00
|
|
|
#if GST_VERSION_NANO == 1
|
|
|
|
#define GIT_G_WARNING g_warning
|
|
|
|
#else
|
|
|
|
#define GIT_G_WARNING GST_WARNING
|
|
|
|
#endif
|
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
/* If the structure currently contains a field with the same name, it is
|
|
|
|
* replaced with the provided field. Otherwise, the field is added to the
|
|
|
|
* structure. The field's value is not deeply copied.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
static void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_field (GstStructure * structure, GstStructureField * field)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *f;
|
2014-06-18 18:06:58 +00:00
|
|
|
GType field_value_type;
|
|
|
|
guint i, len;
|
|
|
|
|
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
field_value_type = G_VALUE_TYPE (&field->value);
|
|
|
|
if (field_value_type == G_TYPE_STRING) {
|
2009-05-30 19:50:40 +00:00
|
|
|
const gchar *s;
|
|
|
|
|
|
|
|
s = g_value_get_string (&field->value);
|
|
|
|
/* only check for NULL strings in taglists, as they are allowed in message
|
|
|
|
* structs, e.g. error message debug strings */
|
2009-07-02 11:40:05 +00:00
|
|
|
if (G_UNLIKELY (IS_TAGLIST (structure) && (s == NULL || *s == '\0'))) {
|
|
|
|
if (s == NULL) {
|
2009-07-16 12:59:07 +00:00
|
|
|
GIT_G_WARNING ("Trying to set NULL string on field '%s' on taglist. "
|
2009-07-02 11:40:05 +00:00
|
|
|
"Please file a bug.", g_quark_to_string (field->name));
|
|
|
|
g_value_unset (&field->value);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
/* empty strings never make sense */
|
2009-07-16 12:59:07 +00:00
|
|
|
GIT_G_WARNING ("Trying to set empty string on taglist field '%s'. "
|
2009-07-02 11:40:05 +00:00
|
|
|
"Please file a bug.", g_quark_to_string (field->name));
|
|
|
|
g_value_unset (&field->value);
|
|
|
|
return;
|
|
|
|
}
|
2009-05-30 19:50:40 +00:00
|
|
|
} else if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) {
|
|
|
|
g_warning ("Trying to set string on %s field '%s', but string is not "
|
|
|
|
"valid UTF-8. Please file a bug.",
|
|
|
|
IS_TAGLIST (structure) ? "taglist" : "structure",
|
|
|
|
g_quark_to_string (field->name));
|
2009-06-01 09:05:32 +00:00
|
|
|
g_value_unset (&field->value);
|
2009-05-30 19:50:40 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-06-18 18:06:58 +00:00
|
|
|
} else if (G_UNLIKELY (field_value_type == G_TYPE_DATE)) {
|
2011-04-04 08:18:14 +00:00
|
|
|
const GDate *d;
|
|
|
|
|
2012-01-12 20:46:27 +00:00
|
|
|
d = g_value_get_boxed (&field->value);
|
2011-04-04 08:18:14 +00:00
|
|
|
/* only check for NULL GDates in taglists, as they might make sense
|
|
|
|
* in other, generic structs */
|
|
|
|
if (G_UNLIKELY ((IS_TAGLIST (structure) && d == NULL))) {
|
|
|
|
GIT_G_WARNING ("Trying to set NULL GDate on field '%s' on taglist. "
|
|
|
|
"Please file a bug.", g_quark_to_string (field->name));
|
|
|
|
g_value_unset (&field->value);
|
|
|
|
return;
|
|
|
|
} else if (G_UNLIKELY (d != NULL && !g_date_valid (d))) {
|
|
|
|
g_warning
|
|
|
|
("Trying to set invalid GDate on %s field '%s'. Please file a bug.",
|
|
|
|
IS_TAGLIST (structure) ? "taglist" : "structure",
|
|
|
|
g_quark_to_string (field->name));
|
|
|
|
g_value_unset (&field->value);
|
|
|
|
return;
|
|
|
|
}
|
2009-05-30 19:50:40 +00:00
|
|
|
}
|
|
|
|
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2004-03-13 15:27:01 +00:00
|
|
|
f = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (f->name == field->name)) {
|
2004-03-13 15:27:01 +00:00
|
|
|
g_value_unset (&f->value);
|
|
|
|
memcpy (f, field, sizeof (GstStructureField));
|
2003-11-03 09:10:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
g_array_append_val (GST_STRUCTURE_FIELDS (structure), *field);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
/* If there is no field with the given ID, NULL is returned.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
static GstStructureField *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (field->name == field_id))
|
2004-03-13 15:27:01 +00:00
|
|
|
return field;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
/* If there is no field with the given ID, NULL is returned.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2003-12-22 01:39:35 +00:00
|
|
|
static GstStructureField *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_field (const GstStructure * structure,
|
|
|
|
const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
return gst_structure_id_get_field (structure,
|
|
|
|
g_quark_from_string (fieldname));
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2003-11-04 05:54:24 +00:00
|
|
|
* gst_structure_get_value:
|
2003-11-03 09:10:07 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to get
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Get the value of the field with name @fieldname.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
|
|
|
* Returns: the #GValue corresponding to the field with the given name.
|
|
|
|
*/
|
|
|
|
const GValue *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_value (const GstStructure * structure,
|
|
|
|
const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
if (field == NULL)
|
|
|
|
return NULL;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return &field->value;
|
|
|
|
}
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_id_get_value:
|
|
|
|
* @structure: a #GstStructure
|
2004-01-30 19:06:13 +00:00
|
|
|
* @field: the #GQuark of the field to get
|
2003-12-22 01:39:35 +00:00
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Get the value of the field with GQuark @field.
|
2003-12-22 01:39:35 +00:00
|
|
|
*
|
2005-10-15 15:30:24 +00:00
|
|
|
* Returns: the #GValue corresponding to the field with the given name
|
2003-12-22 01:39:35 +00:00
|
|
|
* identifier.
|
|
|
|
*/
|
|
|
|
const GValue *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_id_get_value (const GstStructure * structure, GQuark field)
|
2003-12-22 01:39:35 +00:00
|
|
|
{
|
2004-01-30 19:11:50 +00:00
|
|
|
GstStructureField *gsfield;
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
gsfield = gst_structure_id_get_field (structure, field);
|
|
|
|
if (gsfield == NULL)
|
|
|
|
return NULL;
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2004-01-30 19:11:50 +00:00
|
|
|
return &gsfield->value;
|
2003-12-22 01:39:35 +00:00
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_remove_field:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to remove
|
|
|
|
*
|
|
|
|
* Removes the field with the given name. If the field with the given
|
|
|
|
* name does not exist, the structure is unchanged.
|
|
|
|
*/
|
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
GQuark id;
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (fieldname != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
id = g_quark_from_string (fieldname);
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (field->name == id) {
|
|
|
|
if (G_IS_VALUE (&field->value)) {
|
2004-03-15 19:27:17 +00:00
|
|
|
g_value_unset (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
2011-05-11 16:17:45 +00:00
|
|
|
GST_STRUCTURE_FIELDS (structure) =
|
|
|
|
g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
|
2003-11-03 09:10:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-29 02:24:52 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_remove_fields:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to remove
|
2014-05-29 21:54:34 +00:00
|
|
|
* @...: %NULL-terminated list of more fieldnames to remove
|
2004-01-29 02:24:52 +00:00
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Removes the fields with the given names. If a field does not exist, the
|
2004-01-29 02:24:52 +00:00
|
|
|
* argument is ignored.
|
|
|
|
*/
|
2004-03-13 15:27:01 +00:00
|
|
|
void
|
|
|
|
gst_structure_remove_fields (GstStructure * structure,
|
|
|
|
const gchar * fieldname, ...)
|
2004-01-29 02:24:52 +00:00
|
|
|
{
|
|
|
|
va_list varargs;
|
|
|
|
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (fieldname != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
/* mutability checked in remove_field */
|
2004-01-29 02:24:52 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
va_start (varargs, fieldname);
|
2004-01-29 02:24:52 +00:00
|
|
|
gst_structure_remove_fields_valist (structure, fieldname, varargs);
|
2004-03-13 15:27:01 +00:00
|
|
|
va_end (varargs);
|
2004-01-29 02:24:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_remove_fields_valist:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field to remove
|
2014-05-29 21:54:34 +00:00
|
|
|
* @varargs: %NULL-terminated list of more fieldnames to remove
|
2004-01-29 02:24:52 +00:00
|
|
|
*
|
2006-01-27 22:34:51 +00:00
|
|
|
* va_list form of gst_structure_remove_fields().
|
2004-01-29 02:24:52 +00:00
|
|
|
*/
|
2004-03-13 15:27:01 +00:00
|
|
|
void
|
|
|
|
gst_structure_remove_fields_valist (GstStructure * structure,
|
|
|
|
const gchar * fieldname, va_list varargs)
|
2004-01-29 02:24:52 +00:00
|
|
|
{
|
|
|
|
gchar *field = (gchar *) fieldname;
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2004-01-29 02:24:52 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (fieldname != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
/* mutability checked in remove_field */
|
2004-01-29 02:24:52 +00:00
|
|
|
|
|
|
|
while (field) {
|
|
|
|
gst_structure_remove_field (structure, field);
|
2004-03-13 15:27:01 +00:00
|
|
|
field = va_arg (varargs, char *);
|
2004-01-29 02:24:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-24 02:09:23 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_remove_all_fields:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
2005-10-15 15:30:24 +00:00
|
|
|
* Removes all fields in a GstStructure.
|
2003-11-24 02:09:23 +00:00
|
|
|
*/
|
|
|
|
void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_remove_all_fields (GstStructure * structure)
|
2003-11-24 02:09:23 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
int i;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (structure != NULL);
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
2003-11-24 02:09:23 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
for (i = GST_STRUCTURE_FIELDS (structure)->len - 1; i >= 0; i--) {
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-24 02:09:23 +00:00
|
|
|
|
|
|
|
if (G_IS_VALUE (&field->value)) {
|
2004-03-13 15:27:01 +00:00
|
|
|
g_value_unset (&field->value);
|
2003-11-24 02:09:23 +00:00
|
|
|
}
|
2011-05-11 16:17:45 +00:00
|
|
|
GST_STRUCTURE_FIELDS (structure) =
|
|
|
|
g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
|
2003-11-24 02:09:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_field_type:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of the field
|
|
|
|
*
|
|
|
|
* Finds the field with the given name, and returns the type of the
|
2003-11-29 06:31:10 +00:00
|
|
|
* value it contains. If the field is not found, G_TYPE_INVALID is
|
2003-11-03 09:10:07 +00:00
|
|
|
* returned.
|
|
|
|
*
|
|
|
|
* Returns: the #GValue of the field
|
|
|
|
*/
|
|
|
|
GType
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_field_type (const GstStructure * structure,
|
|
|
|
const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
if (field == NULL)
|
|
|
|
return G_TYPE_INVALID;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
return G_VALUE_TYPE (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_n_fields:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Get the number of fields in the structure.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
|
|
|
* Returns: the number of fields in the structure
|
|
|
|
*/
|
|
|
|
gint
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_n_fields (const GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, 0);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
return GST_STRUCTURE_FIELDS (structure)->len;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2005-06-22 19:22:34 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_nth_field_name:
|
|
|
|
* @structure: a #GstStructure
|
2005-09-23 18:08:59 +00:00
|
|
|
* @index: the index to get the name of
|
2005-06-22 19:22:34 +00:00
|
|
|
*
|
2005-10-20 21:08:47 +00:00
|
|
|
* Get the name of the given field number, counting from 0 onwards.
|
|
|
|
*
|
|
|
|
* Returns: the name of the given field number
|
2005-06-22 19:22:34 +00:00
|
|
|
*/
|
|
|
|
const gchar *
|
|
|
|
gst_structure_nth_field_name (const GstStructure * structure, guint index)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2006-07-27 11:00:21 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
2011-05-11 16:17:45 +00:00
|
|
|
g_return_val_if_fail (index < GST_STRUCTURE_FIELDS (structure)->len, NULL);
|
2006-07-27 11:00:21 +00:00
|
|
|
|
2005-06-22 19:22:34 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, index);
|
2006-07-27 11:00:21 +00:00
|
|
|
|
2005-06-22 19:22:34 +00:00
|
|
|
return g_quark_to_string (field->name);
|
|
|
|
}
|
|
|
|
|
2003-11-04 19:00:54 +00:00
|
|
|
/**
|
2003-12-22 01:39:35 +00:00
|
|
|
* gst_structure_foreach:
|
2003-11-04 19:00:54 +00:00
|
|
|
* @structure: a #GstStructure
|
2011-04-14 13:51:24 +00:00
|
|
|
* @func: (scope call): a function to call for each field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @user_data: (closure): private data
|
2003-11-04 19:00:54 +00:00
|
|
|
*
|
2005-03-07 18:27:42 +00:00
|
|
|
* Calls the provided function once for each field in the #GstStructure. The
|
2014-12-16 15:31:21 +00:00
|
|
|
* function must not modify the fields. Also see gst_structure_map_in_place()
|
|
|
|
* and gst_structure_filter_and_map_in_place().
|
2004-01-30 19:06:13 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
|
|
|
|
* %FALSE otherwise.
|
2003-11-04 19:00:54 +00:00
|
|
|
*/
|
2003-12-22 01:39:35 +00:00
|
|
|
gboolean
|
2005-03-07 18:27:42 +00:00
|
|
|
gst_structure_foreach (const GstStructure * structure,
|
2004-03-13 15:27:01 +00:00
|
|
|
GstStructureForeachFunc func, gpointer user_data)
|
2003-11-04 19:00:54 +00:00
|
|
|
{
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2003-11-04 19:00:54 +00:00
|
|
|
GstStructureField *field;
|
2003-12-22 01:39:35 +00:00
|
|
|
gboolean ret;
|
2003-11-04 19:00:54 +00:00
|
|
|
|
2005-03-07 18:27:42 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
2006-07-27 11:00:21 +00:00
|
|
|
g_return_val_if_fail (func != NULL, FALSE);
|
2005-03-07 18:27:42 +00:00
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2009-03-28 12:59:08 +00:00
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
2005-03-07 18:27:42 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
|
|
|
|
|
|
|
ret = func (field->name, &field->value, user_data);
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (!ret))
|
2005-03-07 18:27:42 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_map_in_place:
|
|
|
|
* @structure: a #GstStructure
|
2011-04-14 13:51:24 +00:00
|
|
|
* @func: (scope call): a function to call for each field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @user_data: (closure): private data
|
2005-03-07 18:27:42 +00:00
|
|
|
*
|
|
|
|
* Calls the provided function once for each field in the #GstStructure. In
|
2007-01-09 15:38:58 +00:00
|
|
|
* contrast to gst_structure_foreach(), the function may modify but not delete the
|
|
|
|
* fields. The structure must be mutable.
|
2005-03-07 18:27:42 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
|
|
|
|
* %FALSE otherwise.
|
2005-03-07 18:27:42 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_map_in_place (GstStructure * structure,
|
|
|
|
GstStructureMapFunc func, gpointer user_data)
|
|
|
|
{
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2005-03-07 18:27:42 +00:00
|
|
|
GstStructureField *field;
|
|
|
|
gboolean ret;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
2006-07-27 11:00:21 +00:00
|
|
|
g_return_val_if_fail (func != NULL, FALSE);
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2005-03-07 18:27:42 +00:00
|
|
|
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2004-03-13 15:27:01 +00:00
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
2003-11-04 19:00:54 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
ret = func (field->name, &field->value, user_data);
|
2004-03-13 15:27:01 +00:00
|
|
|
if (!ret)
|
|
|
|
return FALSE;
|
2003-11-04 19:00:54 +00:00
|
|
|
}
|
2003-12-22 01:39:35 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2003-11-04 19:00:54 +00:00
|
|
|
}
|
|
|
|
|
2014-12-16 15:31:21 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_filter_and_map_in_place:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @func: (scope call): a function to call for each field
|
|
|
|
* @user_data: (closure): private data
|
|
|
|
*
|
|
|
|
* Calls the provided function once for each field in the #GstStructure. In
|
|
|
|
* contrast to gst_structure_foreach(), the function may modify the fields.
|
|
|
|
* In contrast to gst_structure_map_in_place(), the field is removed from
|
|
|
|
* the structure if %FALSE is returned from the function.
|
|
|
|
* The structure must be mutable.
|
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_filter_and_map_in_place (GstStructure * structure,
|
|
|
|
GstStructureFilterMapFunc func, gpointer user_data)
|
|
|
|
{
|
|
|
|
guint i, len;
|
|
|
|
GstStructureField *field;
|
|
|
|
gboolean ret;
|
|
|
|
|
|
|
|
g_return_if_fail (structure != NULL);
|
|
|
|
g_return_if_fail (IS_MUTABLE (structure));
|
|
|
|
g_return_if_fail (func != NULL);
|
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
|
|
|
|
|
|
|
for (i = 0; i < len;) {
|
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
|
|
|
|
|
|
|
ret = func (field->name, &field->value, user_data);
|
|
|
|
|
|
|
|
if (!ret) {
|
|
|
|
if (G_IS_VALUE (&field->value)) {
|
|
|
|
g_value_unset (&field->value);
|
|
|
|
}
|
|
|
|
GST_STRUCTURE_FIELDS (structure) =
|
|
|
|
g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
|
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
|
|
|
} else {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-02 08:22:37 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_id_has_field:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field: #GQuark of the field name
|
|
|
|
*
|
|
|
|
* Check if @structure contains a field named @field.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure contains a field with the given name
|
2009-11-02 08:22:37 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_id_has_field (const GstStructure * structure, GQuark field)
|
|
|
|
{
|
|
|
|
GstStructureField *f;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (field != 0, FALSE);
|
|
|
|
|
|
|
|
f = gst_structure_id_get_field (structure, field);
|
|
|
|
|
|
|
|
return (f != NULL);
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_has_field:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Check if @structure contains a field named @fieldname.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure contains a field with the given name
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_has_field (const GstStructure * structure,
|
|
|
|
const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2009-11-02 08:22:37 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-11-02 08:22:37 +00:00
|
|
|
return gst_structure_id_has_field (structure,
|
|
|
|
g_quark_from_string (fieldname));
|
|
|
|
}
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-11-02 08:22:37 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_id_has_field_typed:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field: #GQuark of the field name
|
|
|
|
* @type: the type of a value
|
|
|
|
*
|
|
|
|
* Check if @structure contains a field named @field and with GType @type.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure contains a field with the given name and type
|
2009-11-02 08:22:37 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_id_has_field_typed (const GstStructure * structure,
|
|
|
|
GQuark field, GType type)
|
|
|
|
{
|
|
|
|
GstStructureField *f;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (field != 0, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-11-02 08:22:37 +00:00
|
|
|
f = gst_structure_id_get_field (structure, field);
|
|
|
|
if (f == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return (G_VALUE_TYPE (&f->value) == type);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-01-30 19:06:13 +00:00
|
|
|
* gst_structure_has_field_typed:
|
2003-11-03 09:10:07 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
|
|
|
* @type: the type of a value
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Check if @structure contains a field named @fieldname and with GType @type.
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure contains a field with the given name and type
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_has_field_typed (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, GType type)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2009-11-02 08:22:37 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-11-02 08:22:37 +00:00
|
|
|
return gst_structure_id_has_field_typed (structure,
|
|
|
|
g_quark_from_string (fieldname), type);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* utility functions */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_boolean:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to a #gboolean to set
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2004-01-30 19:06:13 +00:00
|
|
|
* Sets the boolean pointed to by @value corresponding to the value of the
|
2003-11-03 09:10:07 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2006-08-14 12:35:06 +00:00
|
|
|
* with @fieldname or the existing field did not contain a boolean, this
|
2014-05-29 21:54:34 +00:00
|
|
|
* function returns %FALSE.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_boolean (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, gboolean * value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_BOOLEAN)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-12-17 19:45:31 +00:00
|
|
|
*value = gst_g_value_get_boolean_unchecked (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_int:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to an int to set
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2004-01-30 19:06:13 +00:00
|
|
|
* Sets the int pointed to by @value corresponding to the value of the
|
2003-11-03 09:10:07 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
2006-12-21 15:00:08 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2005-11-09 15:10:32 +00:00
|
|
|
* with @fieldname or the existing field did not contain an int, this function
|
2006-12-21 15:00:08 +00:00
|
|
|
* returns %FALSE.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_int (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, gint * value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-12-17 19:45:31 +00:00
|
|
|
*value = gst_g_value_get_int_unchecked (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-08-12 16:40:59 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_uint:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to a uint to set
|
2007-08-12 16:40:59 +00:00
|
|
|
*
|
|
|
|
* Sets the uint pointed to by @value corresponding to the value of the
|
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
|
|
|
* with @fieldname or the existing field did not contain a uint, this function
|
|
|
|
* returns %FALSE.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_uint (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, guint * value)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT)
|
2007-08-12 16:40:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2009-12-17 19:45:31 +00:00
|
|
|
*value = gst_g_value_get_uint_unchecked (&field->value);
|
2007-08-12 16:40:59 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-02-25 14:41:45 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_int64:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2014-07-01 06:39:18 +00:00
|
|
|
* @value: (out): a pointer to a #gint64 to set
|
2014-02-25 14:41:45 +00:00
|
|
|
*
|
2014-07-01 06:39:18 +00:00
|
|
|
* Sets the #gint64 pointed to by @value corresponding to the value of the
|
2014-02-25 14:41:45 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2014-07-01 06:39:18 +00:00
|
|
|
* with @fieldname or the existing field did not contain a #gint64, this function
|
2014-02-25 14:41:45 +00:00
|
|
|
* returns %FALSE.
|
|
|
|
*
|
|
|
|
* Since: 1.4
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_int64 (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, gint64 * value)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT64)
|
2014-02-25 14:41:45 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*value = gst_g_value_get_int64_unchecked (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_uint64:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2014-07-01 06:39:18 +00:00
|
|
|
* @value: (out): a pointer to a #guint64 to set
|
2014-02-25 14:41:45 +00:00
|
|
|
*
|
2014-07-01 06:39:18 +00:00
|
|
|
* Sets the #guint64 pointed to by @value corresponding to the value of the
|
2014-02-25 14:41:45 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2014-07-01 06:39:18 +00:00
|
|
|
* with @fieldname or the existing field did not contain a #guint64, this function
|
2014-02-25 14:41:45 +00:00
|
|
|
* returns %FALSE.
|
|
|
|
*
|
|
|
|
* Since: 1.4
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_uint64 (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, guint64 * value)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT64)
|
2014-02-25 14:41:45 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*value = gst_g_value_get_uint64_unchecked (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_date:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out callee-allocates): a pointer to a #GDate to set
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
*
|
2005-09-23 17:46:06 +00:00
|
|
|
* Sets the date pointed to by @value corresponding to the date of the
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
2009-06-08 23:16:05 +00:00
|
|
|
* On success @value will point to a newly-allocated copy of the date which
|
|
|
|
* should be freed with g_date_free() when no longer needed (note: this is
|
|
|
|
* inconsistent with e.g. gst_structure_get_string() which doesn't return a
|
|
|
|
* copy of the string).
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2005-11-09 15:10:32 +00:00
|
|
|
* with @fieldname or the existing field did not contain a data, this function
|
2014-05-29 21:54:34 +00:00
|
|
|
* returns %FALSE.
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
|
2005-09-23 16:35:43 +00:00
|
|
|
GDate ** value)
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
2005-09-23 16:35:43 +00:00
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DATE)
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
/* FIXME: 2.0 g_value_dup_boxed() -> g_value_get_boxed() */
|
2005-09-23 16:35:43 +00:00
|
|
|
*value = g_value_dup_boxed (&field->value);
|
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual bunch of utility functions along with a hack that che...
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
2005-09-22 15:08:02 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-06-23 14:30:02 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_date_time:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out callee-allocates): a pointer to a #GstDateTime to set
|
2010-06-23 14:30:02 +00:00
|
|
|
*
|
|
|
|
* Sets the datetime pointed to by @value corresponding to the datetime of the
|
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
|
|
|
* On success @value will point to a reference of the datetime which
|
|
|
|
* should be unreffed with gst_date_time_unref() when no longer needed
|
|
|
|
* (note: this is inconsistent with e.g. gst_structure_get_string()
|
|
|
|
* which doesn't return a copy of the string).
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2010-06-23 14:30:02 +00:00
|
|
|
* with @fieldname or the existing field did not contain a data, this function
|
2014-05-29 21:54:34 +00:00
|
|
|
* returns %FALSE.
|
2010-06-23 14:30:02 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_date_time (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, GstDateTime ** value)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
|
|
|
if (field == NULL)
|
|
|
|
return FALSE;
|
|
|
|
if (!GST_VALUE_HOLDS_DATE_TIME (&field->value))
|
|
|
|
return FALSE;
|
|
|
|
|
2014-09-25 19:21:09 +00:00
|
|
|
/* FIXME 2.0: g_value_dup_boxed() -> g_value_get_boxed() */
|
2010-06-23 14:30:02 +00:00
|
|
|
*value = g_value_dup_boxed (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-09-23 17:46:06 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_clock_time:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to a #GstClockTime to set
|
2005-09-23 17:46:06 +00:00
|
|
|
*
|
|
|
|
* Sets the clock time pointed to by @value corresponding to the clock time
|
|
|
|
* of the given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2011-03-08 08:06:23 +00:00
|
|
|
* with @fieldname or the existing field did not contain a #GstClockTime, this
|
2014-05-29 21:54:34 +00:00
|
|
|
* function returns %FALSE.
|
2005-09-23 17:46:06 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_clock_time (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, GstClockTime * value)
|
|
|
|
{
|
2014-02-25 15:11:20 +00:00
|
|
|
return gst_structure_get_uint64 (structure, fieldname, value);
|
2005-09-23 17:46:06 +00:00
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_double:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to a gdouble to set
|
2003-11-03 09:10:07 +00:00
|
|
|
*
|
2004-01-30 19:06:13 +00:00
|
|
|
* Sets the double pointed to by @value corresponding to the value of the
|
2003-11-03 09:10:07 +00:00
|
|
|
* given field. Caller is responsible for making sure the field exists
|
|
|
|
* and has the correct type.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2011-03-08 08:06:23 +00:00
|
|
|
* with @fieldname or the existing field did not contain a double, this
|
2014-05-29 21:54:34 +00:00
|
|
|
* function returns %FALSE.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
2004-03-12 19:35:40 +00:00
|
|
|
gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_double (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, gdouble * value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DOUBLE)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-12-17 19:45:31 +00:00
|
|
|
*value = gst_g_value_get_double_unchecked (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_string:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
|
|
|
*
|
|
|
|
* Finds the field corresponding to @fieldname, and returns the string
|
|
|
|
* contained in the field's value. Caller is responsible for making
|
|
|
|
* sure the field exists and has the correct type.
|
|
|
|
*
|
|
|
|
* The string should not be modified, and remains valid until the next
|
|
|
|
* call to a gst_structure_*() function with the given structure.
|
|
|
|
*
|
2014-06-11 22:21:34 +00:00
|
|
|
* Returns: (nullable): a pointer to the string or %NULL when the
|
|
|
|
* field did not exist or did not contain a string.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
const gchar *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_get_string (const GstStructure * structure,
|
|
|
|
const gchar * fieldname)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_STRING)
|
2009-11-18 09:10:37 +00:00
|
|
|
return NULL;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2009-12-17 19:45:31 +00:00
|
|
|
return gst_g_value_get_string_unchecked (&field->value);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2005-09-29 02:32:37 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_enum:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
|
|
|
* @enumtype: the enum type of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value: (out): a pointer to an int to set
|
2005-09-29 02:32:37 +00:00
|
|
|
*
|
|
|
|
* Sets the int pointed to by @value corresponding to the value of the
|
|
|
|
* given field. Caller is responsible for making sure the field exists,
|
|
|
|
* has the correct type and that the enumtype is correct.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the value could be set correctly. If there was no field
|
2005-11-09 15:10:32 +00:00
|
|
|
* with @fieldname or the existing field did not contain an enum of the given
|
2014-05-29 21:54:34 +00:00
|
|
|
* type, this function returns %FALSE.
|
2005-09-29 02:32:37 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_enum (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, GType enumtype, gint * value)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
|
|
|
if (field == NULL)
|
|
|
|
return FALSE;
|
|
|
|
if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*value = g_value_get_enum (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-11-23 13:22:21 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_fraction:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
2010-12-07 18:35:04 +00:00
|
|
|
* @value_numerator: (out): a pointer to an int to set
|
|
|
|
* @value_denominator: (out): a pointer to an int to set
|
2005-11-23 13:22:21 +00:00
|
|
|
*
|
2011-03-08 08:06:23 +00:00
|
|
|
* Sets the integers pointed to by @value_numerator and @value_denominator
|
|
|
|
* corresponding to the value of the given field. Caller is responsible
|
2005-11-23 13:22:21 +00:00
|
|
|
* for making sure the field exists and has the correct type.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the values could be set correctly. If there was no field
|
2011-03-08 08:06:23 +00:00
|
|
|
* with @fieldname or the existing field did not contain a GstFraction, this
|
2014-05-29 21:54:34 +00:00
|
|
|
* function returns %FALSE.
|
2005-11-23 13:22:21 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_fraction (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, gint * value_numerator, gint * value_denominator)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value_numerator != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value_denominator != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
2014-06-18 18:06:58 +00:00
|
|
|
if (field == NULL || G_VALUE_TYPE (&field->value) != GST_TYPE_FRACTION)
|
2005-11-23 13:22:21 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*value_numerator = gst_value_get_fraction_numerator (&field->value);
|
|
|
|
*value_denominator = gst_value_get_fraction_denominator (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
gstvalue: Add GstFlagSet type
GstFlagSet is a new type designed for negotiating sets
of boolean capabilities flags, consisting of a 32-bit
flags bitfield and 32-bit mask field. The mask field
indicates which of the flags bits an element needs to have
as specific values, and which it doesn't care about.
This allows efficient negotiation of arrays of boolean
capabilities.
The standard serialisation format is FLAGS:MASK, with
flags and mask fields expressed in hexadecimal, however
GstFlagSet has a gst_register_flagset() function, which
associates a new GstFlagSet derived type with an existing
GFlags gtype. When serializing a GstFlagSet with an
associated set of GFlags, it also serializes a human-readable
form of the flags for easier debugging.
It is possible to parse a GFlags style serialisation of a
flagset, without the hex portion on the front. ie,
+flag1/flag2/flag3+flag4, to indicate that
flag1 & flag4 must be set, and flag2/flag3 must be unset,
and any other flags are don't-care.
https://bugzilla.gnome.org/show_bug.cgi?id=746373
2015-05-25 06:23:33 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_get_flagset:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @fieldname: the name of a field
|
|
|
|
* @value_flags: (out) (allow-none): a pointer to a guint for the flags field
|
|
|
|
* @value_mask: (out) (allow-none): a pointer to a guint for the mask field
|
|
|
|
*
|
|
|
|
* Read the GstFlagSet flags and mask out of the structure into the
|
|
|
|
* provided pointers.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the values could be set correctly. If there was no field
|
|
|
|
* with @fieldname or the existing field did not contain a GstFlagSet, this
|
|
|
|
* function returns %FALSE.
|
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_get_flagset (const GstStructure * structure,
|
|
|
|
const gchar * fieldname, guint * value_flags, guint * value_mask)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (fieldname != NULL, FALSE);
|
|
|
|
|
|
|
|
field = gst_structure_get_field (structure, fieldname);
|
|
|
|
|
|
|
|
if (field == NULL || !GST_VALUE_HOLDS_FLAG_SET (&field->value))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (value_flags)
|
|
|
|
*value_flags = gst_value_get_flagset_flags (&field->value);
|
|
|
|
if (value_mask)
|
|
|
|
*value_mask = gst_value_get_flagset_mask (&field->value);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
typedef struct _GstStructureAbbreviation
|
|
|
|
{
|
2010-03-03 10:45:38 +00:00
|
|
|
const gchar *type_name;
|
2003-11-29 06:31:10 +00:00
|
|
|
GType type;
|
2004-03-15 19:27:17 +00:00
|
|
|
}
|
|
|
|
GstStructureAbbreviation;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2006-05-10 14:12:14 +00:00
|
|
|
/* return a copy of an array of GstStructureAbbreviation containing all the
|
|
|
|
* known type_string, GType maps, including abbreviations for common types */
|
2004-11-02 12:39:27 +00:00
|
|
|
static GstStructureAbbreviation *
|
|
|
|
gst_structure_get_abbrs (gint * n_abbrs)
|
|
|
|
{
|
|
|
|
static GstStructureAbbreviation *abbrs = NULL;
|
2010-03-28 17:13:22 +00:00
|
|
|
static volatile gsize num = 0;
|
2004-11-02 12:39:27 +00:00
|
|
|
|
2010-03-28 17:13:22 +00:00
|
|
|
if (g_once_init_enter (&num)) {
|
2004-11-02 12:39:27 +00:00
|
|
|
/* dynamically generate the array */
|
2010-03-28 17:13:22 +00:00
|
|
|
gsize _num;
|
2004-11-02 12:39:27 +00:00
|
|
|
GstStructureAbbreviation dyn_abbrs[] = {
|
|
|
|
{"int", G_TYPE_INT}
|
|
|
|
,
|
|
|
|
{"i", G_TYPE_INT}
|
|
|
|
,
|
2010-03-23 19:23:22 +00:00
|
|
|
{"uint", G_TYPE_UINT}
|
|
|
|
,
|
|
|
|
{"u", G_TYPE_UINT}
|
|
|
|
,
|
2004-11-02 12:39:27 +00:00
|
|
|
{"float", G_TYPE_FLOAT}
|
|
|
|
,
|
|
|
|
{"f", G_TYPE_FLOAT}
|
|
|
|
,
|
|
|
|
{"double", G_TYPE_DOUBLE}
|
|
|
|
,
|
|
|
|
{"d", G_TYPE_DOUBLE}
|
|
|
|
,
|
|
|
|
{"buffer", GST_TYPE_BUFFER}
|
|
|
|
,
|
|
|
|
{"fraction", GST_TYPE_FRACTION}
|
|
|
|
,
|
|
|
|
{"boolean", G_TYPE_BOOLEAN}
|
|
|
|
,
|
|
|
|
{"bool", G_TYPE_BOOLEAN}
|
|
|
|
,
|
|
|
|
{"b", G_TYPE_BOOLEAN}
|
|
|
|
,
|
|
|
|
{"string", G_TYPE_STRING}
|
|
|
|
,
|
|
|
|
{"str", G_TYPE_STRING}
|
|
|
|
,
|
|
|
|
{"s", G_TYPE_STRING}
|
2007-10-22 08:53:26 +00:00
|
|
|
,
|
|
|
|
{"structure", GST_TYPE_STRUCTURE}
|
2010-07-22 01:04:23 +00:00
|
|
|
,
|
2012-01-12 20:46:27 +00:00
|
|
|
{"date", G_TYPE_DATE}
|
2011-04-05 12:36:43 +00:00
|
|
|
,
|
2010-07-22 01:04:23 +00:00
|
|
|
{"datetime", GST_TYPE_DATE_TIME}
|
2011-12-16 11:39:15 +00:00
|
|
|
,
|
|
|
|
{"bitmask", GST_TYPE_BITMASK}
|
2012-07-19 23:49:28 +00:00
|
|
|
,
|
2012-09-16 22:20:46 +00:00
|
|
|
{"sample", GST_TYPE_SAMPLE}
|
|
|
|
,
|
2012-07-19 23:49:28 +00:00
|
|
|
{"taglist", GST_TYPE_TAG_LIST}
|
2004-11-02 12:39:27 +00:00
|
|
|
};
|
2010-03-28 17:13:22 +00:00
|
|
|
_num = G_N_ELEMENTS (dyn_abbrs);
|
2004-11-02 12:39:27 +00:00
|
|
|
/* permanently allocate and copy the array now */
|
2010-03-28 17:13:22 +00:00
|
|
|
abbrs = g_new0 (GstStructureAbbreviation, _num);
|
|
|
|
memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * _num);
|
|
|
|
g_once_init_leave (&num, _num);
|
2004-11-02 12:39:27 +00:00
|
|
|
}
|
|
|
|
*n_abbrs = num;
|
|
|
|
|
|
|
|
return abbrs;
|
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2006-05-10 14:12:14 +00:00
|
|
|
/* given a type_name that could be a type abbreviation or a registered GType,
|
|
|
|
* return a matching GType */
|
2004-03-12 19:35:40 +00:00
|
|
|
static GType
|
2006-05-10 14:12:14 +00:00
|
|
|
gst_structure_gtype_from_abbr (const char *type_name)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
2004-02-07 15:51:39 +00:00
|
|
|
int i;
|
2004-11-02 12:39:27 +00:00
|
|
|
GstStructureAbbreviation *abbrs;
|
|
|
|
gint n_abbrs;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-11-02 12:39:27 +00:00
|
|
|
abbrs = gst_structure_get_abbrs (&n_abbrs);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-11-02 12:39:27 +00:00
|
|
|
for (i = 0; i < n_abbrs; i++) {
|
|
|
|
if (strcmp (type_name, abbrs[i].type_name) == 0) {
|
|
|
|
return abbrs[i].type;
|
|
|
|
}
|
2004-07-15 20:27:20 +00:00
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-11-02 12:39:27 +00:00
|
|
|
/* this is the fallback */
|
2003-11-29 06:31:10 +00:00
|
|
|
return g_type_from_name (type_name);
|
|
|
|
}
|
|
|
|
|
2004-03-12 19:35:40 +00:00
|
|
|
static const char *
|
|
|
|
gst_structure_to_abbr (GType type)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
2004-02-07 15:51:39 +00:00
|
|
|
int i;
|
2004-11-02 12:39:27 +00:00
|
|
|
GstStructureAbbreviation *abbrs;
|
|
|
|
gint n_abbrs;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-11-02 12:39:27 +00:00
|
|
|
abbrs = gst_structure_get_abbrs (&n_abbrs);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-11-02 12:39:27 +00:00
|
|
|
for (i = 0; i < n_abbrs; i++) {
|
|
|
|
if (type == abbrs[i].type) {
|
|
|
|
return abbrs[i].type_name;
|
|
|
|
}
|
2004-07-15 20:27:20 +00:00
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
return g_type_name (type);
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
2004-04-22 16:39:23 +00:00
|
|
|
static GType
|
2016-01-12 13:59:04 +00:00
|
|
|
gst_structure_value_get_generic_type (const GValue * val)
|
2004-04-22 16:39:23 +00:00
|
|
|
{
|
2004-05-20 17:03:02 +00:00
|
|
|
if (G_VALUE_TYPE (val) == GST_TYPE_LIST
|
GstElement::new-pad -> pad-added, GstElement::state-change -> state-changed, GstValueFixedList -> GstValueArray, add ...
Original commit message from CVS:
* docs/manual/advanced-autoplugging.xml:
* docs/manual/basics-helloworld.xml:
* docs/manual/basics-pads.xml:
* docs/random/ds/0.9-suggested-changes:
* gst/gstelement.c: (gst_element_class_init), (gst_element_seek):
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstformat.h:
* gst/gstquery.h:
* gst/gststructure.c: (gst_structure_value_get_generic_type),
(gst_structure_parse_array), (gst_structure_parse_value):
* gst/gstvalue.c: (gst_type_is_fixed),
(gst_value_list_prepend_value), (gst_value_list_append_value),
(gst_value_list_get_size), (gst_value_list_get_value),
(gst_value_transform_array_string), (gst_value_serialize_array),
(gst_value_deserialize_array), (gst_value_intersect_array),
(gst_value_is_fixed), (_gst_value_initialize):
* gst/gstvalue.h:
GstElement::new-pad -> pad-added, GstElement::state-change ->
state-changed, GstValueFixedList -> GstValueArray, add format and
flags as their own arguments in gst_element_seek() (should improve
"bindeability"), remove function generators since they don't work
under a whole bunch of compilers (they were deprecated already
anyway).
2005-07-20 17:16:44 +00:00
|
|
|
|| G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
|
2004-04-22 16:39:23 +00:00
|
|
|
GArray *array = g_value_peek_pointer (val);
|
|
|
|
|
2010-12-26 21:20:31 +00:00
|
|
|
if (array->len > 0) {
|
2004-04-22 16:39:23 +00:00
|
|
|
GValue *value = &g_array_index (array, GValue, 0);
|
|
|
|
|
|
|
|
return gst_structure_value_get_generic_type (value);
|
|
|
|
} else {
|
|
|
|
return G_TYPE_INT;
|
|
|
|
}
|
|
|
|
} else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
|
|
|
|
return G_TYPE_INT;
|
2010-08-24 10:27:30 +00:00
|
|
|
} else if (G_VALUE_TYPE (val) == GST_TYPE_INT64_RANGE) {
|
|
|
|
return G_TYPE_INT64;
|
2004-04-22 16:39:23 +00:00
|
|
|
} else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
|
|
|
|
return G_TYPE_DOUBLE;
|
2005-11-22 11:56:01 +00:00
|
|
|
} else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
|
|
|
|
return GST_TYPE_FRACTION;
|
2004-04-22 16:39:23 +00:00
|
|
|
}
|
|
|
|
return G_VALUE_TYPE (val);
|
|
|
|
}
|
|
|
|
|
2008-01-09 16:36:34 +00:00
|
|
|
gboolean
|
|
|
|
priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
|
|
|
GString * s)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
2009-03-28 12:59:08 +00:00
|
|
|
guint i, len;
|
2008-01-09 16:36:34 +00:00
|
|
|
|
|
|
|
g_return_val_if_fail (s != NULL, FALSE);
|
|
|
|
|
2011-05-11 16:17:45 +00:00
|
|
|
len = GST_STRUCTURE_FIELDS (structure)->len;
|
2009-03-28 12:59:08 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2008-01-09 16:36:34 +00:00
|
|
|
char *t;
|
|
|
|
GType type;
|
|
|
|
|
|
|
|
field = GST_STRUCTURE_FIELD (structure, i);
|
|
|
|
|
|
|
|
t = gst_value_serialize (&field->value);
|
|
|
|
type = gst_structure_value_get_generic_type (&field->value);
|
|
|
|
|
|
|
|
g_string_append_len (s, ", ", 2);
|
|
|
|
/* FIXME: do we need to escape fieldnames? */
|
|
|
|
g_string_append (s, g_quark_to_string (field->name));
|
|
|
|
g_string_append_len (s, "=(", 2);
|
|
|
|
g_string_append (s, gst_structure_to_abbr (type));
|
|
|
|
g_string_append_c (s, ')');
|
2016-01-06 20:17:16 +00:00
|
|
|
if (t) {
|
|
|
|
g_string_append (s, t);
|
|
|
|
g_free (t);
|
|
|
|
} else {
|
|
|
|
GST_WARNING ("No value transform to serialize field '%s' of type '%s'",
|
|
|
|
g_quark_to_string (field->name), gst_structure_to_abbr (type));
|
|
|
|
g_string_append (s, "NULL");
|
|
|
|
}
|
2008-01-09 16:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_string_append_c (s, ';');
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2016-01-12 13:59:04 +00:00
|
|
|
gboolean
|
|
|
|
priv__gst_structure_append_template_to_gstring (GQuark field_id,
|
|
|
|
const GValue * value, gpointer user_data)
|
|
|
|
{
|
|
|
|
GType type = gst_structure_value_get_generic_type (value);
|
|
|
|
GString *s = (GString *) user_data;
|
|
|
|
|
|
|
|
g_string_append_len (s, ", ", 2);
|
|
|
|
/* FIXME: do we need to escape fieldnames? */
|
|
|
|
g_string_append (s, g_quark_to_string (field_id));
|
|
|
|
g_string_append_len (s, "=(", 2);
|
|
|
|
g_string_append (s, gst_structure_to_abbr (type));
|
|
|
|
g_string_append_c (s, ')');
|
|
|
|
|
|
|
|
//TODO(ensonic): table like GstStructureAbbreviation (or extend it)
|
|
|
|
if (type == G_TYPE_INT) {
|
|
|
|
g_string_append_len (s, "%i", 2);
|
|
|
|
} else if (type == G_TYPE_UINT) {
|
|
|
|
g_string_append_len (s, "%u", 2);
|
|
|
|
} else if (type == G_TYPE_FLOAT) {
|
|
|
|
g_string_append_len (s, "%f", 2);
|
|
|
|
} else if (type == G_TYPE_DOUBLE) {
|
|
|
|
g_string_append_len (s, "%lf", 3);
|
|
|
|
} else if (type == G_TYPE_STRING) {
|
|
|
|
g_string_append_len (s, "%s", 2);
|
|
|
|
} else if (type == G_TYPE_BOOLEAN) {
|
|
|
|
/* we normally store this as a string, but can parse it also from an int */
|
|
|
|
g_string_append_len (s, "%i", 2);
|
|
|
|
} else if (type == G_TYPE_INT64) {
|
|
|
|
g_string_append (s, "%" G_GINT64_FORMAT);
|
|
|
|
} else if (type == G_TYPE_UINT64) {
|
|
|
|
g_string_append (s, "%" G_GUINT64_FORMAT);
|
|
|
|
} else if (type == GST_TYPE_STRUCTURE) {
|
2016-01-18 20:12:53 +00:00
|
|
|
g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
|
|
|
|
} else if (g_type_is_a (type, G_TYPE_ENUM)
|
|
|
|
|| g_type_is_a (type, G_TYPE_FLAGS)) {
|
2016-01-12 13:59:04 +00:00
|
|
|
g_string_append (s, "%i");
|
|
|
|
} else {
|
|
|
|
GST_WARNING ("unhandled type: %s", g_type_name (type));
|
2016-01-18 20:12:53 +00:00
|
|
|
g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
|
2016-01-12 13:59:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-11-03 09:10:07 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_to_string:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
2005-11-09 15:10:32 +00:00
|
|
|
* Converts @structure to a human-readable string representation.
|
2005-10-15 15:30:24 +00:00
|
|
|
*
|
2009-03-06 19:59:20 +00:00
|
|
|
* For debugging purposes its easier to do something like this:
|
2014-06-05 20:27:28 +00:00
|
|
|
* |[<!-- language="C" -->
|
2009-03-06 19:59:20 +00:00
|
|
|
* GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
|
|
|
|
* ]|
|
2013-12-07 14:38:19 +00:00
|
|
|
* This prints the structure in human readable form.
|
2009-03-06 19:59:20 +00:00
|
|
|
*
|
2013-09-25 22:06:55 +00:00
|
|
|
* The current implementation of serialization will lead to unexpected results
|
|
|
|
* when there are nested #GstCaps / #GstStructure deeper than one level.
|
|
|
|
*
|
2010-12-07 18:35:04 +00:00
|
|
|
* Free-function: g_free
|
|
|
|
*
|
2012-05-16 15:53:15 +00:00
|
|
|
* Returns: (transfer full): a pointer to string allocated by g_malloc().
|
2010-12-07 18:35:04 +00:00
|
|
|
* g_free() after usage.
|
2003-11-03 09:10:07 +00:00
|
|
|
*/
|
|
|
|
gchar *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_to_string (const GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
|
|
|
GString *s;
|
2004-03-13 15:27:01 +00:00
|
|
|
|
configure.ac: Add detection for HAVE_PRINTF_EXTENSION and
Original commit message from CVS:
* configure.ac: Add detection for HAVE_PRINTF_EXTENSION and
GST_PRINTF_EXTENSION_FORMAT_DEFINE.
* docs/random/ds/0.9-suggested-changes: Notes from Company.
* gst/gstcaps.c: (gst_caps_to_string): Add comment.
* gst/gstconfig.h.in: Add define for GST_PTR_FORMAT
* gst/gstinfo.c: (_gst_debug_init), (gst_debug_print_object),
(gst_debug_log_default), (_gst_info_printf_extension),
(_gst_info_printf_extension_arginfo): Add printf extension.
* gst/gstinfo.h: remove G_GNUC_PRINTF, because it doesn't work with %P
* gst/gststructure.c: (gst_structure_to_string),
(_gst_structure_parse_value): Use gst_value_deserialize() and
remove old code.
* gst/gstvalue.c: (gst_value_deserialize_fourcc),
(gst_value_deserialize_boolean), (gst_strtoi),
(gst_value_deserialize_int), (gst_value_deserialize_double),
(gst_value_deserialize_string), (gst_value_deserialize): Implement
a bunch of deserialize functions and gst_value_deserialize.
* gst/gstvalue.h: er, _de_serialize, not unserialize
* testsuite/caps/string-conversions.c: (main): We don't currently
handle (float) in caps, so convert these to (double).
* testsuite/debug/Makefile.am: Add new test for the printf extension
* testsuite/debug/printf_extension.c: (main): same
2004-01-29 01:20:23 +00:00
|
|
|
/* NOTE: This function is potentially called by the debug system,
|
|
|
|
* so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
|
|
|
|
* should be careful to avoid recursion. This includes any functions
|
|
|
|
* called by gst_structure_to_string. In particular, calls should
|
|
|
|
* not use the GST_PTR_FORMAT extension. */
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_val_if_fail (structure != NULL, NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2008-01-09 16:36:34 +00:00
|
|
|
/* we estimate a minimum size based on the number of fields in order to
|
|
|
|
* avoid unnecessary reallocs within GString */
|
|
|
|
s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure));
|
2013-03-30 14:35:19 +00:00
|
|
|
g_string_append (s, g_quark_to_string (structure->name));
|
2008-01-09 16:36:34 +00:00
|
|
|
priv_gst_structure_append_to_gstring (structure, s);
|
2004-03-13 15:27:01 +00:00
|
|
|
return g_string_free (s, FALSE);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2003-11-29 06:31:10 +00:00
|
|
|
/*
|
2005-10-15 15:30:24 +00:00
|
|
|
* r will still point to the string. if end == next, the string will not be
|
2003-11-29 06:31:10 +00:00
|
|
|
* null-terminated. In all other cases it will be.
|
|
|
|
* end = pointer to char behind end of string, next = pointer to start of
|
|
|
|
* unread data.
|
2005-10-15 15:30:24 +00:00
|
|
|
* THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
|
2003-11-29 06:31:10 +00:00
|
|
|
*/
|
|
|
|
static gboolean
|
2009-07-02 11:40:05 +00:00
|
|
|
gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next,
|
|
|
|
gboolean unescape)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
|
|
|
gchar *w;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (*s == 0)
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
if (*s != '"') {
|
|
|
|
int ret;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-12 19:35:40 +00:00
|
|
|
ret = gst_structure_parse_simple_string (s, end);
|
2003-12-22 01:39:35 +00:00
|
|
|
*next = *end;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2009-07-02 11:40:05 +00:00
|
|
|
if (unescape) {
|
|
|
|
w = s;
|
|
|
|
s++;
|
|
|
|
while (*s != '"') {
|
|
|
|
if (G_UNLIKELY (*s == 0))
|
|
|
|
return FALSE;
|
2014-11-20 12:34:32 +00:00
|
|
|
if (G_UNLIKELY (*s == '\\')) {
|
2009-07-02 11:40:05 +00:00
|
|
|
s++;
|
2014-11-20 12:34:32 +00:00
|
|
|
if (G_UNLIKELY (*s == 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-07-02 11:40:05 +00:00
|
|
|
*w = *s;
|
|
|
|
w++;
|
2003-12-22 01:39:35 +00:00
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
2003-12-22 01:39:35 +00:00
|
|
|
s++;
|
2009-07-02 11:40:05 +00:00
|
|
|
} else {
|
|
|
|
/* Find the closing quotes */
|
|
|
|
s++;
|
|
|
|
while (*s != '"') {
|
|
|
|
if (G_UNLIKELY (*s == 0))
|
|
|
|
return FALSE;
|
2014-11-20 12:34:32 +00:00
|
|
|
if (G_UNLIKELY (*s == '\\')) {
|
2009-07-02 11:40:05 +00:00
|
|
|
s++;
|
2014-11-20 12:34:32 +00:00
|
|
|
if (G_UNLIKELY (*s == 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-07-02 11:40:05 +00:00
|
|
|
s++;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
w = s;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*end = w;
|
2003-12-22 01:39:35 +00:00
|
|
|
*next = s;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
return TRUE;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
|
|
|
|
GType type)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
|
|
|
GValue value1 = { 0 };
|
|
|
|
GValue value2 = { 0 };
|
2011-11-30 14:45:12 +00:00
|
|
|
GValue value3 = { 0 };
|
2003-11-29 06:31:10 +00:00
|
|
|
GType range_type;
|
2011-11-30 14:45:12 +00:00
|
|
|
gboolean ret, have_step = FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (*s != '[')
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
ret = gst_structure_parse_value (s, &s, &value1, type);
|
2014-11-28 13:17:54 +00:00
|
|
|
if (!ret)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
|
|
|
|
|
|
|
if (*s != ',')
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
ret = gst_structure_parse_value (s, &s, &value2, type);
|
2014-11-28 13:17:54 +00:00
|
|
|
if (!ret)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2011-11-30 14:45:12 +00:00
|
|
|
/* optional step for int and int64 */
|
|
|
|
if (G_VALUE_TYPE (&value1) == G_TYPE_INT
|
|
|
|
|| G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
|
|
|
|
if (*s == ',') {
|
|
|
|
s++;
|
|
|
|
|
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
|
|
|
|
|
|
|
ret = gst_structure_parse_value (s, &s, &value3, type);
|
2014-11-28 13:17:54 +00:00
|
|
|
if (!ret)
|
2011-11-30 14:45:12 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
|
|
|
|
|
|
|
have_step = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (*s != ']')
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
|
|
|
|
return FALSE;
|
2011-11-30 14:45:12 +00:00
|
|
|
if (have_step && G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value3))
|
|
|
|
return FALSE;
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
|
|
|
|
range_type = GST_TYPE_DOUBLE_RANGE;
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
g_value_init (value, range_type);
|
2009-12-17 19:45:31 +00:00
|
|
|
gst_value_set_double_range (value,
|
|
|
|
gst_g_value_get_double_unchecked (&value1),
|
|
|
|
gst_g_value_get_double_unchecked (&value2));
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
} else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
|
|
|
|
range_type = GST_TYPE_INT_RANGE;
|
|
|
|
g_value_init (value, range_type);
|
2011-11-30 14:45:12 +00:00
|
|
|
if (have_step)
|
|
|
|
gst_value_set_int_range_step (value,
|
|
|
|
gst_g_value_get_int_unchecked (&value1),
|
|
|
|
gst_g_value_get_int_unchecked (&value2),
|
|
|
|
gst_g_value_get_int_unchecked (&value3));
|
|
|
|
else
|
|
|
|
gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1),
|
|
|
|
gst_g_value_get_int_unchecked (&value2));
|
2010-08-24 10:27:30 +00:00
|
|
|
} else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
|
|
|
|
range_type = GST_TYPE_INT64_RANGE;
|
|
|
|
g_value_init (value, range_type);
|
2011-11-30 14:45:12 +00:00
|
|
|
if (have_step)
|
|
|
|
gst_value_set_int64_range_step (value,
|
|
|
|
gst_g_value_get_int64_unchecked (&value1),
|
|
|
|
gst_g_value_get_int64_unchecked (&value2),
|
|
|
|
gst_g_value_get_int64_unchecked (&value3));
|
|
|
|
else
|
|
|
|
gst_value_set_int64_range (value,
|
|
|
|
gst_g_value_get_int64_unchecked (&value1),
|
|
|
|
gst_g_value_get_int64_unchecked (&value2));
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
} else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
|
|
|
|
range_type = GST_TYPE_FRACTION_RANGE;
|
|
|
|
g_value_init (value, range_type);
|
|
|
|
gst_value_set_fraction_range (value, &value1, &value2);
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*after = s;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2004-05-20 17:03:02 +00:00
|
|
|
gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
|
|
|
|
GType type, GType list_type, char begin, char end)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
|
|
|
GValue list_value = { 0 };
|
|
|
|
gboolean ret;
|
2003-12-22 01:39:35 +00:00
|
|
|
GArray *array;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-05-20 17:03:02 +00:00
|
|
|
g_value_init (value, list_type);
|
2003-12-22 01:39:35 +00:00
|
|
|
array = g_value_peek_pointer (value);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-05-20 17:03:02 +00:00
|
|
|
if (*s != begin)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2004-05-20 17:03:02 +00:00
|
|
|
if (*s == end) {
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
*after = s;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
ret = gst_structure_parse_value (s, &s, &list_value, type);
|
2014-11-28 13:17:54 +00:00
|
|
|
if (!ret)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
g_array_append_val (array, list_value);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
|
|
|
|
2004-05-20 17:03:02 +00:00
|
|
|
while (*s != end) {
|
2004-03-13 15:27:01 +00:00
|
|
|
if (*s != ',')
|
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
|
|
|
memset (&list_value, 0, sizeof (list_value));
|
2004-03-13 15:27:01 +00:00
|
|
|
ret = gst_structure_parse_value (s, &s, &list_value, type);
|
2014-11-28 13:17:54 +00:00
|
|
|
if (!ret)
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
g_array_append_val (array, list_value);
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
*after = s;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-05-20 17:03:02 +00:00
|
|
|
static gboolean
|
|
|
|
gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
|
|
|
|
{
|
|
|
|
return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
|
|
|
|
'{', '}');
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
GstElement::new-pad -> pad-added, GstElement::state-change -> state-changed, GstValueFixedList -> GstValueArray, add ...
Original commit message from CVS:
* docs/manual/advanced-autoplugging.xml:
* docs/manual/basics-helloworld.xml:
* docs/manual/basics-pads.xml:
* docs/random/ds/0.9-suggested-changes:
* gst/gstelement.c: (gst_element_class_init), (gst_element_seek):
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstformat.h:
* gst/gstquery.h:
* gst/gststructure.c: (gst_structure_value_get_generic_type),
(gst_structure_parse_array), (gst_structure_parse_value):
* gst/gstvalue.c: (gst_type_is_fixed),
(gst_value_list_prepend_value), (gst_value_list_append_value),
(gst_value_list_get_size), (gst_value_list_get_value),
(gst_value_transform_array_string), (gst_value_serialize_array),
(gst_value_deserialize_array), (gst_value_intersect_array),
(gst_value_is_fixed), (_gst_value_initialize):
* gst/gstvalue.h:
GstElement::new-pad -> pad-added, GstElement::state-change ->
state-changed, GstValueFixedList -> GstValueArray, add format and
flags as their own arguments in gst_element_seek() (should improve
"bindeability"), remove function generators since they don't work
under a whole bunch of compilers (they were deprecated already
anyway).
2005-07-20 17:16:44 +00:00
|
|
|
gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
|
2004-05-20 17:03:02 +00:00
|
|
|
GType type)
|
|
|
|
{
|
|
|
|
return gst_structure_parse_any_list (s, after, value, type,
|
GstElement::new-pad -> pad-added, GstElement::state-change -> state-changed, GstValueFixedList -> GstValueArray, add ...
Original commit message from CVS:
* docs/manual/advanced-autoplugging.xml:
* docs/manual/basics-helloworld.xml:
* docs/manual/basics-pads.xml:
* docs/random/ds/0.9-suggested-changes:
* gst/gstelement.c: (gst_element_class_init), (gst_element_seek):
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstformat.h:
* gst/gstquery.h:
* gst/gststructure.c: (gst_structure_value_get_generic_type),
(gst_structure_parse_array), (gst_structure_parse_value):
* gst/gstvalue.c: (gst_type_is_fixed),
(gst_value_list_prepend_value), (gst_value_list_append_value),
(gst_value_list_get_size), (gst_value_list_get_value),
(gst_value_transform_array_string), (gst_value_serialize_array),
(gst_value_deserialize_array), (gst_value_intersect_array),
(gst_value_is_fixed), (_gst_value_initialize):
* gst/gstvalue.h:
GstElement::new-pad -> pad-added, GstElement::state-change ->
state-changed, GstValueFixedList -> GstValueArray, add format and
flags as their own arguments in gst_element_seek() (should improve
"bindeability"), remove function generators since they don't work
under a whole bunch of compilers (they were deprecated already
anyway).
2005-07-20 17:16:44 +00:00
|
|
|
GST_TYPE_ARRAY, '<', '>');
|
2004-05-20 17:03:02 +00:00
|
|
|
}
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
static gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_parse_simple_string (gchar * str, gchar ** end)
|
2003-12-22 01:39:35 +00:00
|
|
|
{
|
|
|
|
char *s = str;
|
|
|
|
|
2009-06-29 09:23:31 +00:00
|
|
|
while (G_LIKELY (GST_ASCII_IS_STRING (*s))) {
|
2003-12-22 01:39:35 +00:00
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*end = s;
|
|
|
|
|
|
|
|
return (s != str);
|
|
|
|
}
|
|
|
|
|
2003-11-29 06:31:10 +00:00
|
|
|
static gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_parse_field (gchar * str,
|
|
|
|
gchar ** after, GstStructureField * field)
|
2003-11-29 06:31:10 +00:00
|
|
|
{
|
|
|
|
gchar *name;
|
2003-12-22 01:39:35 +00:00
|
|
|
gchar *name_end;
|
|
|
|
gchar *s;
|
|
|
|
gchar c;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
s = str;
|
|
|
|
|
2005-11-10 12:32:57 +00:00
|
|
|
while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
|
2004-03-13 15:27:01 +00:00
|
|
|
s++;
|
2003-12-22 01:39:35 +00:00
|
|
|
name = s;
|
2009-11-13 13:45:52 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &name_end))) {
|
|
|
|
GST_WARNING ("failed to parse simple string, str=%s", str);
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2009-11-13 13:45:52 +00:00
|
|
|
}
|
2003-12-22 01:39:35 +00:00
|
|
|
|
|
|
|
s = name_end;
|
2005-11-10 12:32:57 +00:00
|
|
|
while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
|
2004-03-13 15:27:01 +00:00
|
|
|
s++;
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2009-11-13 13:45:52 +00:00
|
|
|
if (G_UNLIKELY (*s != '=')) {
|
|
|
|
GST_WARNING ("missing assignment operator in the field, str=%s", str);
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2009-11-13 13:45:52 +00:00
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
|
|
|
|
2003-12-22 01:39:35 +00:00
|
|
|
c = *name_end;
|
2009-06-02 15:36:10 +00:00
|
|
|
*name_end = '\0';
|
2003-11-29 06:31:10 +00:00
|
|
|
field->name = g_quark_from_string (name);
|
2009-11-13 13:45:52 +00:00
|
|
|
GST_DEBUG ("trying field name '%s'", name);
|
2003-12-22 01:39:35 +00:00
|
|
|
*name_end = c;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_value (s, &s, &field->value,
|
2009-11-13 13:45:52 +00:00
|
|
|
G_TYPE_INVALID))) {
|
|
|
|
GST_WARNING ("failed to parse value %s", str);
|
2003-12-22 01:39:35 +00:00
|
|
|
return FALSE;
|
2009-11-13 13:45:52 +00:00
|
|
|
}
|
2003-12-22 01:39:35 +00:00
|
|
|
|
|
|
|
*after = s;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_parse_value (gchar * str,
|
|
|
|
gchar ** after, GValue * value, GType default_type)
|
2003-12-22 01:39:35 +00:00
|
|
|
{
|
|
|
|
gchar *type_name;
|
|
|
|
gchar *type_end;
|
|
|
|
gchar *value_s;
|
|
|
|
gchar *value_end;
|
|
|
|
gchar *s;
|
|
|
|
gchar c;
|
2004-01-07 13:13:03 +00:00
|
|
|
int ret = 0;
|
2003-12-22 01:39:35 +00:00
|
|
|
GType type = default_type;
|
|
|
|
|
|
|
|
s = str;
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2006-05-10 14:12:14 +00:00
|
|
|
/* check if there's a (type_name) 'cast' */
|
2003-12-22 01:39:35 +00:00
|
|
|
type_name = NULL;
|
|
|
|
if (*s == '(') {
|
|
|
|
s++;
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
type_name = s;
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &type_end)))
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-12-22 01:39:35 +00:00
|
|
|
s = type_end;
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (*s != ')'))
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2003-11-29 06:31:10 +00:00
|
|
|
s++;
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-12-22 01:39:35 +00:00
|
|
|
|
|
|
|
c = *type_end;
|
|
|
|
*type_end = 0;
|
2006-05-10 14:12:14 +00:00
|
|
|
type = gst_structure_gtype_from_abbr (type_name);
|
2009-11-13 13:45:52 +00:00
|
|
|
GST_DEBUG ("trying type name '%s'", type_name);
|
2003-12-22 01:39:35 +00:00
|
|
|
*type_end = c;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2009-11-13 13:45:52 +00:00
|
|
|
if (G_UNLIKELY (type == G_TYPE_INVALID)) {
|
|
|
|
GST_WARNING ("invalid type");
|
2004-03-13 15:27:01 +00:00
|
|
|
return FALSE;
|
2009-11-13 13:45:52 +00:00
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
while (g_ascii_isspace (*s))
|
|
|
|
s++;
|
2003-11-29 06:31:10 +00:00
|
|
|
if (*s == '[') {
|
2004-03-12 19:35:40 +00:00
|
|
|
ret = gst_structure_parse_range (s, &s, value, type);
|
2003-12-22 01:39:35 +00:00
|
|
|
} else if (*s == '{') {
|
2004-03-12 19:35:40 +00:00
|
|
|
ret = gst_structure_parse_list (s, &s, value, type);
|
2004-05-20 17:03:02 +00:00
|
|
|
} else if (*s == '<') {
|
GstElement::new-pad -> pad-added, GstElement::state-change -> state-changed, GstValueFixedList -> GstValueArray, add ...
Original commit message from CVS:
* docs/manual/advanced-autoplugging.xml:
* docs/manual/basics-helloworld.xml:
* docs/manual/basics-pads.xml:
* docs/random/ds/0.9-suggested-changes:
* gst/gstelement.c: (gst_element_class_init), (gst_element_seek):
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstformat.h:
* gst/gstquery.h:
* gst/gststructure.c: (gst_structure_value_get_generic_type),
(gst_structure_parse_array), (gst_structure_parse_value):
* gst/gstvalue.c: (gst_type_is_fixed),
(gst_value_list_prepend_value), (gst_value_list_append_value),
(gst_value_list_get_size), (gst_value_list_get_value),
(gst_value_transform_array_string), (gst_value_serialize_array),
(gst_value_deserialize_array), (gst_value_intersect_array),
(gst_value_is_fixed), (_gst_value_initialize):
* gst/gstvalue.h:
GstElement::new-pad -> pad-added, GstElement::state-change ->
state-changed, GstValueFixedList -> GstValueArray, add format and
flags as their own arguments in gst_element_seek() (should improve
"bindeability"), remove function generators since they don't work
under a whole bunch of compilers (they were deprecated already
anyway).
2005-07-20 17:16:44 +00:00
|
|
|
ret = gst_structure_parse_array (s, &s, value, type);
|
2003-11-29 06:31:10 +00:00
|
|
|
} else {
|
2003-12-22 01:39:35 +00:00
|
|
|
value_s = s;
|
|
|
|
|
2009-06-05 19:57:05 +00:00
|
|
|
if (G_UNLIKELY (type == G_TYPE_INVALID)) {
|
2005-11-22 12:35:42 +00:00
|
|
|
GType try_types[] =
|
gstvalue: Add GstFlagSet type
GstFlagSet is a new type designed for negotiating sets
of boolean capabilities flags, consisting of a 32-bit
flags bitfield and 32-bit mask field. The mask field
indicates which of the flags bits an element needs to have
as specific values, and which it doesn't care about.
This allows efficient negotiation of arrays of boolean
capabilities.
The standard serialisation format is FLAGS:MASK, with
flags and mask fields expressed in hexadecimal, however
GstFlagSet has a gst_register_flagset() function, which
associates a new GstFlagSet derived type with an existing
GFlags gtype. When serializing a GstFlagSet with an
associated set of GFlags, it also serializes a human-readable
form of the flags for easier debugging.
It is possible to parse a GFlags style serialisation of a
flagset, without the hex portion on the front. ie,
+flag1/flag2/flag3+flag4, to indicate that
flag1 & flag4 must be set, and flag2/flag3 must be unset,
and any other flags are don't-care.
https://bugzilla.gnome.org/show_bug.cgi?id=746373
2015-05-25 06:23:33 +00:00
|
|
|
{ G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, GST_TYPE_FLAG_SET,
|
|
|
|
G_TYPE_BOOLEAN, G_TYPE_STRING
|
2007-07-08 14:11:53 +00:00
|
|
|
};
|
2003-12-22 01:39:35 +00:00
|
|
|
int i;
|
|
|
|
|
2009-07-02 11:40:05 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s, TRUE)))
|
|
|
|
return FALSE;
|
|
|
|
/* Set NULL terminator for deserialization */
|
|
|
|
c = *value_end;
|
|
|
|
*value_end = '\0';
|
|
|
|
|
2007-07-08 14:11:53 +00:00
|
|
|
for (i = 0; i < G_N_ELEMENTS (try_types); i++) {
|
2004-03-15 19:27:17 +00:00
|
|
|
g_value_init (value, try_types[i]);
|
|
|
|
ret = gst_value_deserialize (value, value_s);
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
g_value_unset (value);
|
2003-12-22 01:39:35 +00:00
|
|
|
}
|
|
|
|
} else {
|
2004-03-13 15:27:01 +00:00
|
|
|
g_value_init (value, type);
|
2003-12-22 01:39:35 +00:00
|
|
|
|
2009-07-02 11:40:05 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s,
|
|
|
|
(type != G_TYPE_STRING))))
|
|
|
|
return FALSE;
|
|
|
|
/* Set NULL terminator for deserialization */
|
|
|
|
c = *value_end;
|
|
|
|
*value_end = '\0';
|
|
|
|
|
configure.ac: Add detection for HAVE_PRINTF_EXTENSION and
Original commit message from CVS:
* configure.ac: Add detection for HAVE_PRINTF_EXTENSION and
GST_PRINTF_EXTENSION_FORMAT_DEFINE.
* docs/random/ds/0.9-suggested-changes: Notes from Company.
* gst/gstcaps.c: (gst_caps_to_string): Add comment.
* gst/gstconfig.h.in: Add define for GST_PTR_FORMAT
* gst/gstinfo.c: (_gst_debug_init), (gst_debug_print_object),
(gst_debug_log_default), (_gst_info_printf_extension),
(_gst_info_printf_extension_arginfo): Add printf extension.
* gst/gstinfo.h: remove G_GNUC_PRINTF, because it doesn't work with %P
* gst/gststructure.c: (gst_structure_to_string),
(_gst_structure_parse_value): Use gst_value_deserialize() and
remove old code.
* gst/gstvalue.c: (gst_value_deserialize_fourcc),
(gst_value_deserialize_boolean), (gst_strtoi),
(gst_value_deserialize_int), (gst_value_deserialize_double),
(gst_value_deserialize_string), (gst_value_deserialize): Implement
a bunch of deserialize functions and gst_value_deserialize.
* gst/gstvalue.h: er, _de_serialize, not unserialize
* testsuite/caps/string-conversions.c: (main): We don't currently
handle (float) in caps, so convert these to (double).
* testsuite/debug/Makefile.am: Add new test for the printf extension
* testsuite/debug/printf_extension.c: (main): same
2004-01-29 01:20:23 +00:00
|
|
|
ret = gst_value_deserialize (value, value_s);
|
2009-06-05 19:57:05 +00:00
|
|
|
if (G_UNLIKELY (!ret))
|
|
|
|
g_value_unset (value);
|
2003-12-22 01:39:35 +00:00
|
|
|
}
|
|
|
|
*value_end = c;
|
2003-11-29 06:31:10 +00:00
|
|
|
}
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2003-11-29 06:31:10 +00:00
|
|
|
*after = s;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
gboolean
|
|
|
|
priv_gst_structure_parse_name (gchar * str, gchar ** start, gchar ** end,
|
|
|
|
gchar ** next)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2003-11-29 06:31:10 +00:00
|
|
|
char *w;
|
|
|
|
char *r;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
r = str;
|
2003-11-03 09:10:07 +00:00
|
|
|
|
2007-12-08 12:54:53 +00:00
|
|
|
/* skip spaces (FIXME: _isspace treats tabs and newlines as space!) */
|
2007-10-22 08:53:26 +00:00
|
|
|
while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
|
|
|
|
&& g_ascii_isspace (r[1]))))
|
|
|
|
r++;
|
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
*start = r;
|
|
|
|
|
2009-07-02 11:40:05 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_string (r, &w, &r, TRUE))) {
|
2013-03-30 14:35:19 +00:00
|
|
|
GST_WARNING ("Failed to parse structure string '%s'", str);
|
|
|
|
return FALSE;
|
2007-10-15 11:19:36 +00:00
|
|
|
}
|
2004-03-13 15:27:01 +00:00
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
*end = w;
|
|
|
|
*next = r;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
priv_gst_structure_parse_fields (gchar * str, gchar ** end,
|
|
|
|
GstStructure * structure)
|
|
|
|
{
|
|
|
|
gchar *r;
|
|
|
|
GstStructureField field;
|
|
|
|
|
|
|
|
r = str;
|
2007-12-08 12:54:53 +00:00
|
|
|
|
2007-10-22 08:53:26 +00:00
|
|
|
do {
|
|
|
|
while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
|
|
|
|
&& g_ascii_isspace (r[1]))))
|
|
|
|
r++;
|
|
|
|
if (*r == ';') {
|
|
|
|
/* end of structure, get the next char and finish */
|
|
|
|
r++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (*r == '\0') {
|
|
|
|
/* accept \0 as end delimiter */
|
|
|
|
break;
|
|
|
|
}
|
2009-06-29 09:23:31 +00:00
|
|
|
if (G_UNLIKELY (*r != ',')) {
|
2007-10-15 11:19:36 +00:00
|
|
|
GST_WARNING ("Failed to find delimiter, r=%s", r);
|
2013-03-30 14:35:19 +00:00
|
|
|
return FALSE;
|
2007-10-15 11:19:36 +00:00
|
|
|
}
|
2003-11-29 06:31:10 +00:00
|
|
|
r++;
|
2005-11-10 12:32:57 +00:00
|
|
|
while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
|
|
|
|
&& g_ascii_isspace (r[1]))))
|
2004-03-13 15:27:01 +00:00
|
|
|
r++;
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
memset (&field, 0, sizeof (field));
|
2009-11-13 13:45:52 +00:00
|
|
|
if (G_UNLIKELY (!gst_structure_parse_field (r, &r, &field))) {
|
|
|
|
GST_WARNING ("Failed to parse field, r=%s", r);
|
2013-03-30 14:35:19 +00:00
|
|
|
return FALSE;
|
2009-11-13 13:45:52 +00:00
|
|
|
}
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_set_field (structure, &field);
|
2007-10-22 08:53:26 +00:00
|
|
|
} while (TRUE);
|
2003-11-29 06:31:10 +00:00
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
*end = r;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-06-14 11:05:38 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_new_from_string:
|
|
|
|
* @string: a string representation of a #GstStructure
|
|
|
|
*
|
|
|
|
* Creates a #GstStructure from a string representation.
|
2014-05-29 21:54:34 +00:00
|
|
|
* If end is not %NULL, a pointer to the place inside the given string
|
2013-06-14 11:05:38 +00:00
|
|
|
* where parsing ended will be returned.
|
|
|
|
*
|
2013-09-25 22:06:55 +00:00
|
|
|
* The current implementation of serialization will lead to unexpected results
|
|
|
|
* when there are nested #GstCaps / #GstStructure deeper than one level.
|
|
|
|
*
|
2013-06-14 11:05:38 +00:00
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
2014-06-11 22:21:34 +00:00
|
|
|
* Returns: (transfer full) (nullable): a new #GstStructure or %NULL
|
|
|
|
* when the string could not be parsed. Free with
|
|
|
|
* gst_structure_free() after use.
|
2013-06-14 11:05:38 +00:00
|
|
|
*
|
|
|
|
* Since: 1.2
|
|
|
|
*/
|
|
|
|
GstStructure *
|
|
|
|
gst_structure_new_from_string (const gchar * string)
|
|
|
|
{
|
|
|
|
return gst_structure_from_string (string, NULL);
|
|
|
|
}
|
|
|
|
|
2013-03-30 14:35:19 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_from_string:
|
|
|
|
* @string: a string representation of a #GstStructure.
|
2013-06-14 11:05:38 +00:00
|
|
|
* @end: (out) (allow-none) (transfer none) (skip): pointer to store the end of the string in.
|
2013-03-30 14:35:19 +00:00
|
|
|
*
|
|
|
|
* Creates a #GstStructure from a string representation.
|
2014-05-29 21:54:34 +00:00
|
|
|
* If end is not %NULL, a pointer to the place inside the given string
|
2013-03-30 14:35:19 +00:00
|
|
|
* where parsing ended will be returned.
|
|
|
|
*
|
|
|
|
* Free-function: gst_structure_free
|
|
|
|
*
|
2014-06-11 22:21:34 +00:00
|
|
|
* Returns: (transfer full) (nullable): a new #GstStructure or %NULL
|
|
|
|
* when the string could not be parsed. Free with
|
|
|
|
* gst_structure_free() after use.
|
2013-03-30 14:35:19 +00:00
|
|
|
*/
|
|
|
|
GstStructure *
|
|
|
|
gst_structure_from_string (const gchar * string, gchar ** end)
|
|
|
|
{
|
|
|
|
char *name;
|
|
|
|
char *copy;
|
|
|
|
char *w;
|
|
|
|
char *r;
|
|
|
|
char save;
|
|
|
|
GstStructure *structure = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
|
|
|
|
copy = g_strdup (string);
|
|
|
|
r = copy;
|
|
|
|
|
|
|
|
if (!priv_gst_structure_parse_name (r, &name, &w, &r))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
save = *w;
|
|
|
|
*w = '\0';
|
|
|
|
structure = gst_structure_new_empty (name);
|
|
|
|
*w = save;
|
|
|
|
|
|
|
|
if (G_UNLIKELY (structure == NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!priv_gst_structure_parse_fields (r, &r, structure))
|
|
|
|
goto error;
|
|
|
|
|
2004-03-13 15:27:01 +00:00
|
|
|
if (end)
|
|
|
|
*end = (char *) string + (r - copy);
|
2008-03-03 10:07:21 +00:00
|
|
|
else if (*r)
|
|
|
|
g_warning ("gst_structure_from_string did not consume whole string,"
|
|
|
|
" but caller did not provide end pointer (\"%s\")", string);
|
2004-02-05 23:46:13 +00:00
|
|
|
|
|
|
|
g_free (copy);
|
2003-11-29 06:31:10 +00:00
|
|
|
return structure;
|
2004-02-05 23:46:13 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (structure)
|
|
|
|
gst_structure_free (structure);
|
|
|
|
g_free (copy);
|
|
|
|
return NULL;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_transform_to_string (const GValue * src_value,
|
|
|
|
GValue * dest_value)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
g_return_if_fail (src_value != NULL);
|
|
|
|
g_return_if_fail (dest_value != NULL);
|
2003-11-03 09:10:07 +00:00
|
|
|
|
|
|
|
dest_value->data[0].v_pointer =
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_to_string (src_value->data[0].v_pointer);
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
|
|
|
|
2004-03-12 19:35:40 +00:00
|
|
|
static GstStructure *
|
2004-03-13 15:27:01 +00:00
|
|
|
gst_structure_copy_conditional (const GstStructure * structure)
|
2003-11-03 09:10:07 +00:00
|
|
|
{
|
2004-03-13 15:27:01 +00:00
|
|
|
if (structure)
|
|
|
|
return gst_structure_copy (structure);
|
2004-02-18 05:26:59 +00:00
|
|
|
return NULL;
|
2003-11-03 09:10:07 +00:00
|
|
|
}
|
2005-03-07 18:27:42 +00:00
|
|
|
|
|
|
|
/* fixate utility functions */
|
|
|
|
|
|
|
|
/**
|
2005-11-21 14:28:21 +00:00
|
|
|
* gst_structure_fixate_field_nearest_int:
|
2005-03-07 18:27:42 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
|
|
|
* @target: the target value of the fixation
|
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given field to the nearest
|
|
|
|
* integer to @target that is a subset of the existing field.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure could be fixated
|
2005-03-07 18:27:42 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2005-11-21 14:28:21 +00:00
|
|
|
gst_structure_fixate_field_nearest_int (GstStructure * structure,
|
2005-03-07 18:27:42 +00:00
|
|
|
const char *field_name, int target)
|
|
|
|
{
|
|
|
|
const GValue *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
|
|
|
|
|
|
|
value = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (value) == G_TYPE_INT) {
|
|
|
|
/* already fixed */
|
|
|
|
return FALSE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
|
|
|
|
int x;
|
|
|
|
|
|
|
|
x = gst_value_get_int_range_min (value);
|
|
|
|
if (target < x)
|
|
|
|
target = x;
|
|
|
|
x = gst_value_get_int_range_max (value);
|
|
|
|
if (target > x)
|
|
|
|
target = x;
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
|
|
|
|
return TRUE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
|
|
|
|
const GValue *list_value;
|
|
|
|
int i, n;
|
|
|
|
int best = 0;
|
|
|
|
int best_index = -1;
|
|
|
|
|
|
|
|
n = gst_value_list_get_size (value);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
list_value = gst_value_list_get_value (value, i);
|
|
|
|
if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
|
2009-12-17 19:45:31 +00:00
|
|
|
int x = gst_g_value_get_int_unchecked (list_value);
|
2005-03-07 18:27:42 +00:00
|
|
|
|
|
|
|
if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
|
|
|
|
best_index = i;
|
|
|
|
best = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best_index != -1) {
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2005-11-21 14:28:21 +00:00
|
|
|
* gst_structure_fixate_field_nearest_double:
|
2005-03-07 18:27:42 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
|
|
|
* @target: the target value of the fixation
|
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given field to the nearest
|
|
|
|
* double to @target that is a subset of the existing field.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure could be fixated
|
2005-03-07 18:27:42 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2005-11-21 14:28:21 +00:00
|
|
|
gst_structure_fixate_field_nearest_double (GstStructure * structure,
|
2005-03-07 18:27:42 +00:00
|
|
|
const char *field_name, double target)
|
|
|
|
{
|
|
|
|
const GValue *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
|
|
|
|
|
|
|
value = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
|
|
|
|
/* already fixed */
|
|
|
|
return FALSE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
|
|
|
|
double x;
|
|
|
|
|
|
|
|
x = gst_value_get_double_range_min (value);
|
|
|
|
if (target < x)
|
|
|
|
target = x;
|
|
|
|
x = gst_value_get_double_range_max (value);
|
|
|
|
if (target > x)
|
|
|
|
target = x;
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
|
|
|
|
return TRUE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
|
|
|
|
const GValue *list_value;
|
|
|
|
int i, n;
|
|
|
|
double best = 0;
|
|
|
|
int best_index = -1;
|
|
|
|
|
|
|
|
n = gst_value_list_get_size (value);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
list_value = gst_value_list_get_value (value, i);
|
|
|
|
if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
|
2009-12-17 19:45:31 +00:00
|
|
|
double x = gst_g_value_get_double_unchecked (list_value);
|
2005-03-07 18:27:42 +00:00
|
|
|
|
|
|
|
if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
|
|
|
|
best_index = i;
|
|
|
|
best = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best_index != -1) {
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
2005-08-23 11:38:28 +00:00
|
|
|
|
|
|
|
/**
|
2005-11-21 14:28:21 +00:00
|
|
|
* gst_structure_fixate_field_boolean:
|
2005-08-23 11:38:28 +00:00
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
|
|
|
* @target: the target value of the fixation
|
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given @field_name field to the given
|
|
|
|
* @target boolean if that field is not fixed yet.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure could be fixated
|
2005-08-23 11:38:28 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2005-11-21 14:28:21 +00:00
|
|
|
gst_structure_fixate_field_boolean (GstStructure * structure,
|
2005-08-23 11:38:28 +00:00
|
|
|
const char *field_name, gboolean target)
|
|
|
|
{
|
|
|
|
const GValue *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
|
|
|
|
|
|
|
value = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
|
|
|
|
/* already fixed */
|
|
|
|
return FALSE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
|
|
|
|
const GValue *list_value;
|
|
|
|
int i, n;
|
|
|
|
int best = 0;
|
|
|
|
int best_index = -1;
|
|
|
|
|
|
|
|
n = gst_value_list_get_size (value);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
list_value = gst_value_list_get_value (value, i);
|
|
|
|
if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
|
2009-12-17 19:45:31 +00:00
|
|
|
gboolean x = gst_g_value_get_boolean_unchecked (list_value);
|
2005-08-23 11:38:28 +00:00
|
|
|
|
|
|
|
if (best_index == -1 || x == target) {
|
|
|
|
best_index = i;
|
|
|
|
best = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best_index != -1) {
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
|
2010-05-22 08:01:44 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_fixate_field_string:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
|
|
|
* @target: the target value of the fixation
|
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given @field_name field to the given
|
|
|
|
* @target string if that field is not fixed yet.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure could be fixated
|
2010-05-22 08:01:44 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_fixate_field_string (GstStructure * structure,
|
|
|
|
const gchar * field_name, const gchar * target)
|
|
|
|
{
|
|
|
|
const GValue *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
|
|
|
|
|
|
|
value = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
|
|
|
|
/* already fixed */
|
|
|
|
return FALSE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
|
|
|
|
const GValue *list_value;
|
|
|
|
int i, n;
|
|
|
|
const gchar *best = NULL;
|
|
|
|
int best_index = -1;
|
|
|
|
|
|
|
|
n = gst_value_list_get_size (value);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
list_value = gst_value_list_get_value (value, i);
|
|
|
|
if (G_VALUE_TYPE (list_value) == G_TYPE_STRING) {
|
|
|
|
const gchar *x = g_value_get_string (list_value);
|
|
|
|
|
|
|
|
if (best_index == -1 || g_str_equal (x, target)) {
|
|
|
|
best_index = i;
|
|
|
|
best = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best_index != -1) {
|
|
|
|
gst_structure_set (structure, field_name, G_TYPE_STRING, best, NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
/**
|
|
|
|
* gst_structure_fixate_field_nearest_fraction:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
2005-11-23 13:22:21 +00:00
|
|
|
* @target_numerator: The numerator of the target value of the fixation
|
|
|
|
* @target_denominator: The denominator of the target value of the fixation
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given field to the nearest
|
2011-03-08 08:06:23 +00:00
|
|
|
* fraction to @target_numerator/@target_denominator that is a subset
|
2005-11-23 13:22:21 +00:00
|
|
|
* of the existing field.
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure could be fixated
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
|
2005-11-23 13:22:21 +00:00
|
|
|
const char *field_name, const gint target_numerator,
|
|
|
|
const gint target_denominator)
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
{
|
|
|
|
const GValue *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
2014-04-09 16:01:01 +00:00
|
|
|
g_return_val_if_fail (target_denominator != 0, FALSE);
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
|
|
|
|
value = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
|
|
|
|
/* already fixed */
|
|
|
|
return FALSE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
|
2005-11-23 13:22:21 +00:00
|
|
|
const GValue *x, *new_value;
|
|
|
|
GValue target = { 0 };
|
|
|
|
g_value_init (&target, GST_TYPE_FRACTION);
|
|
|
|
gst_value_set_fraction (&target, target_numerator, target_denominator);
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
|
2005-11-23 13:22:21 +00:00
|
|
|
new_value = ⌖
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
x = gst_value_get_fraction_range_min (value);
|
2005-11-23 13:22:21 +00:00
|
|
|
if (gst_value_compare (&target, x) == GST_VALUE_LESS_THAN)
|
|
|
|
new_value = x;
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
x = gst_value_get_fraction_range_max (value);
|
2005-11-23 13:22:21 +00:00
|
|
|
if (gst_value_compare (&target, x) == GST_VALUE_GREATER_THAN)
|
|
|
|
new_value = x;
|
|
|
|
|
|
|
|
gst_structure_set_value (structure, field_name, new_value);
|
|
|
|
g_value_unset (&target);
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
return TRUE;
|
|
|
|
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
|
|
|
|
const GValue *list_value;
|
|
|
|
int i, n;
|
|
|
|
const GValue *best = NULL;
|
2008-08-05 15:03:27 +00:00
|
|
|
gdouble target;
|
|
|
|
gdouble cur_diff;
|
|
|
|
gdouble best_diff = G_MAXDOUBLE;
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
|
2008-08-05 15:03:27 +00:00
|
|
|
target = (gdouble) target_numerator / (gdouble) target_denominator;
|
2005-11-23 13:22:21 +00:00
|
|
|
|
2008-08-05 15:03:27 +00:00
|
|
|
GST_DEBUG ("target %g, best %g", target, best_diff);
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
|
2007-09-05 01:00:50 +00:00
|
|
|
best = NULL;
|
|
|
|
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
n = gst_value_list_get_size (value);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
list_value = gst_value_list_get_value (value, i);
|
|
|
|
if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
|
2008-08-05 15:03:27 +00:00
|
|
|
gint num, denom;
|
|
|
|
gdouble list_double;
|
|
|
|
|
|
|
|
num = gst_value_get_fraction_numerator (list_value);
|
|
|
|
denom = gst_value_get_fraction_denominator (list_value);
|
|
|
|
|
|
|
|
list_double = ((gdouble) num / (gdouble) denom);
|
|
|
|
cur_diff = target - list_double;
|
2007-09-05 01:00:50 +00:00
|
|
|
|
2008-08-05 15:03:27 +00:00
|
|
|
GST_DEBUG ("curr diff %g, list %g", cur_diff, list_double);
|
2007-09-05 01:00:50 +00:00
|
|
|
|
2008-08-05 15:03:27 +00:00
|
|
|
if (cur_diff < 0)
|
|
|
|
cur_diff = -cur_diff;
|
|
|
|
|
|
|
|
if (!best || cur_diff < best_diff) {
|
|
|
|
GST_DEBUG ("new best %g", list_double);
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
best = list_value;
|
2008-08-05 15:03:27 +00:00
|
|
|
best_diff = cur_diff;
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best != NULL) {
|
|
|
|
gst_structure_set_value (structure, field_name, best);
|
2008-08-05 15:03:27 +00:00
|
|
|
return TRUE;
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
2008-08-05 15:03:27 +00:00
|
|
|
|
Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 23:54:59 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2009-06-08 22:43:16 +00:00
|
|
|
|
2011-08-17 15:56:40 +00:00
|
|
|
static gboolean
|
|
|
|
default_fixate (GQuark field_id, const GValue * value, gpointer data)
|
|
|
|
{
|
|
|
|
GstStructure *s = data;
|
|
|
|
GValue v = { 0 };
|
|
|
|
|
|
|
|
if (gst_value_fixate (&v, value)) {
|
2012-12-22 16:50:49 +00:00
|
|
|
gst_structure_id_take_value (s, field_id, &v);
|
2011-08-17 15:56:40 +00:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_fixate_field:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @field_name: a field in @structure
|
|
|
|
*
|
|
|
|
* Fixates a #GstStructure by changing the given field with its fixated value.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the structure field could be fixated
|
2011-08-17 15:56:40 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_fixate_field (GstStructure * structure, const char *field_name)
|
|
|
|
{
|
|
|
|
GstStructureField *field;
|
|
|
|
|
|
|
|
g_return_val_if_fail (structure != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
|
|
|
|
|
|
|
if (!(field = gst_structure_get_field (structure, field_name)))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return default_fixate (field->name, &field->value, structure);
|
|
|
|
}
|
|
|
|
|
2009-06-08 22:43:16 +00:00
|
|
|
/* our very own version of G_VALUE_LCOPY that allows NULL return locations
|
|
|
|
* (useful for message parsing functions where the return location is user
|
2014-05-29 21:54:34 +00:00
|
|
|
* supplied and the user may pass %NULL if the value isn't of interest) */
|
2009-06-08 22:43:16 +00:00
|
|
|
#define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname) \
|
|
|
|
G_STMT_START { \
|
|
|
|
const GValue *_value = (value); \
|
|
|
|
guint _flags = (flags); \
|
|
|
|
GType _value_type = G_VALUE_TYPE (_value); \
|
|
|
|
GTypeValueTable *_vtable = g_type_value_table_peek (_value_type); \
|
2012-07-06 18:37:06 +00:00
|
|
|
const gchar *_lcopy_format = _vtable->lcopy_format; \
|
2009-06-08 22:43:16 +00:00
|
|
|
GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \
|
|
|
|
guint _n_values = 0; \
|
|
|
|
\
|
|
|
|
while (*_lcopy_format != '\0') { \
|
|
|
|
g_assert (*_lcopy_format == G_VALUE_COLLECT_POINTER); \
|
|
|
|
_cvalues[_n_values++].v_pointer = va_arg ((var_args), gpointer); \
|
|
|
|
_lcopy_format++; \
|
|
|
|
} \
|
|
|
|
if (_n_values == 2 && !!_cvalues[0].v_pointer != !!_cvalues[1].v_pointer) { \
|
|
|
|
*(__error) = g_strdup_printf ("either all or none of the return " \
|
|
|
|
"locations for field '%s' need to be NULL", fieldname); \
|
|
|
|
} else if (_cvalues[0].v_pointer != NULL) { \
|
|
|
|
*(__error) = _vtable->lcopy_value (_value, _n_values, _cvalues, _flags); \
|
|
|
|
} \
|
|
|
|
} G_STMT_END
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get_valist:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @first_fieldname: the name of the first field to read
|
2009-06-19 13:10:30 +00:00
|
|
|
* @args: variable arguments
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
|
|
|
* Parses the variable arguments and reads fields from @structure accordingly.
|
|
|
|
* valist-variant of gst_structure_get(). Look at the documentation of
|
|
|
|
* gst_structure_get() for more details.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
|
2009-06-08 22:43:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2010-07-16 15:33:38 +00:00
|
|
|
gst_structure_get_valist (const GstStructure * structure,
|
2009-06-08 22:43:16 +00:00
|
|
|
const char *first_fieldname, va_list args)
|
|
|
|
{
|
|
|
|
const char *field_name;
|
|
|
|
GType expected_type = G_TYPE_INVALID;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
|
|
|
|
g_return_val_if_fail (first_fieldname != NULL, FALSE);
|
|
|
|
|
|
|
|
field_name = first_fieldname;
|
|
|
|
while (field_name) {
|
|
|
|
const GValue *val = NULL;
|
|
|
|
gchar *err = NULL;
|
|
|
|
|
|
|
|
expected_type = va_arg (args, GType);
|
|
|
|
|
|
|
|
val = gst_structure_get_value (structure, field_name);
|
|
|
|
|
|
|
|
if (val == NULL)
|
|
|
|
goto no_such_field;
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (val) != expected_type)
|
|
|
|
goto wrong_type;
|
|
|
|
|
|
|
|
GST_VALUE_LCOPY (val, args, 0, &err, field_name);
|
|
|
|
if (err) {
|
|
|
|
g_warning ("%s: %s", G_STRFUNC, err);
|
|
|
|
g_free (err);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
field_name = va_arg (args, const gchar *);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* ERRORS */
|
|
|
|
no_such_field:
|
|
|
|
{
|
2012-07-06 10:45:29 +00:00
|
|
|
GST_INFO ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
|
2009-06-08 22:43:16 +00:00
|
|
|
field_name, structure);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
wrong_type:
|
|
|
|
{
|
2012-07-06 10:45:29 +00:00
|
|
|
GST_INFO ("Expected field '%s' in structure to be of type '%s', but "
|
2009-06-08 22:43:16 +00:00
|
|
|
"field was of type '%s': %" GST_PTR_FORMAT, field_name,
|
|
|
|
GST_STR_NULL (g_type_name (expected_type)),
|
|
|
|
G_VALUE_TYPE_NAME (gst_structure_get_value (structure, field_name)),
|
|
|
|
structure);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_id_get_valist:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @first_field_id: the quark of the first field to read
|
2009-06-19 13:10:30 +00:00
|
|
|
* @args: variable arguments
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
|
|
|
* Parses the variable arguments and reads fields from @structure accordingly.
|
|
|
|
* valist-variant of gst_structure_id_get(). Look at the documentation of
|
|
|
|
* gst_structure_id_get() for more details.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
|
2009-06-08 22:43:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2010-07-16 15:33:38 +00:00
|
|
|
gst_structure_id_get_valist (const GstStructure * structure,
|
|
|
|
GQuark first_field_id, va_list args)
|
2009-06-08 22:43:16 +00:00
|
|
|
{
|
|
|
|
GQuark field_id;
|
|
|
|
GType expected_type = G_TYPE_INVALID;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
|
|
|
|
g_return_val_if_fail (first_field_id != 0, FALSE);
|
|
|
|
|
|
|
|
field_id = first_field_id;
|
|
|
|
while (field_id) {
|
|
|
|
const GValue *val = NULL;
|
|
|
|
gchar *err = NULL;
|
|
|
|
|
|
|
|
expected_type = va_arg (args, GType);
|
|
|
|
|
|
|
|
val = gst_structure_id_get_value (structure, field_id);
|
|
|
|
|
|
|
|
if (val == NULL)
|
|
|
|
goto no_such_field;
|
|
|
|
|
|
|
|
if (G_VALUE_TYPE (val) != expected_type)
|
|
|
|
goto wrong_type;
|
|
|
|
|
|
|
|
GST_VALUE_LCOPY (val, args, 0, &err, g_quark_to_string (field_id));
|
|
|
|
if (err) {
|
|
|
|
g_warning ("%s: %s", G_STRFUNC, err);
|
|
|
|
g_free (err);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
field_id = va_arg (args, GQuark);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* ERRORS */
|
|
|
|
no_such_field:
|
|
|
|
{
|
2012-07-11 08:24:51 +00:00
|
|
|
GST_DEBUG ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
|
2009-06-08 22:43:16 +00:00
|
|
|
GST_STR_NULL (g_quark_to_string (field_id)), structure);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
wrong_type:
|
|
|
|
{
|
2012-07-11 08:24:51 +00:00
|
|
|
GST_DEBUG ("Expected field '%s' in structure to be of type '%s', but "
|
2009-06-08 22:43:16 +00:00
|
|
|
"field was of type '%s': %" GST_PTR_FORMAT,
|
|
|
|
g_quark_to_string (field_id),
|
|
|
|
GST_STR_NULL (g_type_name (expected_type)),
|
|
|
|
G_VALUE_TYPE_NAME (gst_structure_id_get_value (structure, field_id)),
|
|
|
|
structure);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_get:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @first_fieldname: the name of the first field to read
|
|
|
|
* @...: variable arguments
|
|
|
|
*
|
|
|
|
* Parses the variable arguments and reads fields from @structure accordingly.
|
|
|
|
* Variable arguments should be in the form field name, field type
|
|
|
|
* (as a GType), pointer(s) to a variable(s) to hold the return value(s).
|
2014-05-29 21:54:34 +00:00
|
|
|
* The last variable argument should be %NULL.
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
2012-01-11 12:19:20 +00:00
|
|
|
* For refcounted (mini)objects you will receive a new reference which
|
2009-06-08 22:43:16 +00:00
|
|
|
* you must release with a suitable _unref() when no longer needed. For
|
2012-01-11 12:19:20 +00:00
|
|
|
* strings and boxed types you will receive a copy which you will need to
|
2011-09-07 11:14:38 +00:00
|
|
|
* release with either g_free() or the suitable function for the boxed type.
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %FALSE if there was a problem reading any of the fields (e.g.
|
2009-06-08 22:43:16 +00:00
|
|
|
* because the field requested did not exist, or was of a type other
|
2014-05-29 21:54:34 +00:00
|
|
|
* than the type specified), otherwise %TRUE.
|
2009-06-08 22:43:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2010-07-16 15:33:38 +00:00
|
|
|
gst_structure_get (const GstStructure * structure, const char *first_fieldname,
|
|
|
|
...)
|
2009-06-08 22:43:16 +00:00
|
|
|
{
|
|
|
|
gboolean ret;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
|
|
|
|
g_return_val_if_fail (first_fieldname != NULL, FALSE);
|
|
|
|
|
|
|
|
va_start (args, first_fieldname);
|
|
|
|
ret = gst_structure_get_valist (structure, first_fieldname, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_id_get:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
* @first_field_id: the quark of the first field to read
|
|
|
|
* @...: variable arguments
|
|
|
|
*
|
|
|
|
* Parses the variable arguments and reads fields from @structure accordingly.
|
|
|
|
* Variable arguments should be in the form field id quark, field type
|
|
|
|
* (as a GType), pointer(s) to a variable(s) to hold the return value(s).
|
2014-05-29 21:54:34 +00:00
|
|
|
* The last variable argument should be %NULL (technically it should be a
|
|
|
|
* 0 quark, but we require %NULL so compilers that support it can check for
|
|
|
|
* the %NULL terminator and warn if it's not there).
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
|
|
|
* This function is just like gst_structure_get() only that it is slightly
|
|
|
|
* more efficient since it saves the string-to-quark lookup in the global
|
|
|
|
* quark hashtable.
|
|
|
|
*
|
2012-01-11 12:19:20 +00:00
|
|
|
* For refcounted (mini)objects you will receive a new reference which
|
2009-06-08 22:43:16 +00:00
|
|
|
* you must release with a suitable _unref() when no longer needed. For
|
2012-01-11 12:19:20 +00:00
|
|
|
* strings and boxed types you will receive a copy which you will need to
|
2011-09-07 11:14:38 +00:00
|
|
|
* release with either g_free() or the suitable function for the boxed type.
|
2009-06-08 22:43:16 +00:00
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %FALSE if there was a problem reading any of the fields (e.g.
|
2009-06-08 22:43:16 +00:00
|
|
|
* because the field requested did not exist, or was of a type other
|
2014-05-29 21:54:34 +00:00
|
|
|
* than the type specified), otherwise %TRUE.
|
2009-06-08 22:43:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
2010-07-16 15:33:38 +00:00
|
|
|
gst_structure_id_get (const GstStructure * structure, GQuark first_field_id,
|
|
|
|
...)
|
2009-06-08 22:43:16 +00:00
|
|
|
{
|
|
|
|
gboolean ret;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
|
|
|
|
g_return_val_if_fail (first_field_id != 0, FALSE);
|
|
|
|
|
|
|
|
va_start (args, first_field_id);
|
|
|
|
ret = gst_structure_id_get_valist (structure, first_field_id, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2010-09-10 16:14:05 +00:00
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2011-05-17 07:35:54 +00:00
|
|
|
const GstStructure *struct1 = (const GstStructure *) data;
|
2010-09-10 16:14:05 +00:00
|
|
|
const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (val1 == NULL))
|
|
|
|
return FALSE;
|
|
|
|
if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_is_equal:
|
|
|
|
* @structure1: a #GstStructure.
|
|
|
|
* @structure2: a #GstStructure.
|
|
|
|
*
|
|
|
|
* Tests if the two #GstStructure are equal.
|
|
|
|
*
|
2014-05-29 21:54:34 +00:00
|
|
|
* Returns: %TRUE if the two structures have the same name and field.
|
2010-09-10 16:14:05 +00:00
|
|
|
**/
|
|
|
|
gboolean
|
|
|
|
gst_structure_is_equal (const GstStructure * structure1,
|
2011-05-17 07:35:54 +00:00
|
|
|
const GstStructure * structure2)
|
2010-09-10 16:14:05 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure1), FALSE);
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (structure2), FALSE);
|
|
|
|
|
2011-10-29 22:52:22 +00:00
|
|
|
if (G_UNLIKELY (structure1 == structure2))
|
|
|
|
return TRUE;
|
|
|
|
|
2010-09-10 16:14:05 +00:00
|
|
|
if (structure1->name != structure2->name) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-05-17 09:22:58 +00:00
|
|
|
if (GST_STRUCTURE_FIELDS (structure1)->len !=
|
|
|
|
GST_STRUCTURE_FIELDS (structure2)->len) {
|
2010-09-10 16:14:05 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gst_structure_foreach (structure1, gst_structure_is_equal_foreach,
|
2011-05-17 07:35:54 +00:00
|
|
|
(gpointer) structure2);
|
2010-09-10 16:14:05 +00:00
|
|
|
}
|
2010-09-10 16:33:34 +00:00
|
|
|
|
2011-05-17 07:33:04 +00:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GstStructure *dest;
|
|
|
|
const GstStructure *intersect;
|
|
|
|
}
|
|
|
|
IntersectData;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_structure_intersect_field1 (GQuark id, const GValue * val1, gpointer data)
|
|
|
|
{
|
|
|
|
IntersectData *idata = (IntersectData *) data;
|
|
|
|
const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (val2 == NULL)) {
|
|
|
|
gst_structure_id_set_value (idata->dest, id, val1);
|
|
|
|
} else {
|
|
|
|
GValue dest_value = { 0 };
|
|
|
|
if (gst_value_intersect (&dest_value, val1, val2)) {
|
2012-12-22 16:50:49 +00:00
|
|
|
gst_structure_id_take_value (idata->dest, id, &dest_value);
|
2011-05-17 07:33:04 +00:00
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
|
|
|
|
{
|
|
|
|
IntersectData *idata = (IntersectData *) data;
|
|
|
|
const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (val2 == NULL)) {
|
|
|
|
gst_structure_id_set_value (idata->dest, id, val1);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_intersect:
|
|
|
|
* @struct1: a #GstStructure
|
|
|
|
* @struct2: a #GstStructure
|
|
|
|
*
|
2013-12-07 14:38:19 +00:00
|
|
|
* Intersects @struct1 and @struct2 and returns the intersection.
|
2011-05-17 07:33:04 +00:00
|
|
|
*
|
|
|
|
* Returns: Intersection of @struct1 and @struct2
|
|
|
|
*/
|
|
|
|
GstStructure *
|
|
|
|
gst_structure_intersect (const GstStructure * struct1,
|
|
|
|
const GstStructure * struct2)
|
|
|
|
{
|
|
|
|
IntersectData data;
|
|
|
|
|
|
|
|
g_assert (struct1 != NULL);
|
|
|
|
g_assert (struct2 != NULL);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (struct1->name != struct2->name))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* copy fields from struct1 which we have not in struct2 to target
|
|
|
|
* intersect if we have the field in both */
|
2011-10-29 07:02:00 +00:00
|
|
|
data.dest = gst_structure_new_id_empty (struct1->name);
|
2011-05-17 07:33:04 +00:00
|
|
|
data.intersect = struct2;
|
|
|
|
if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
|
|
|
|
gst_structure_intersect_field1, &data)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* copy fields from struct2 which we have not in struct1 to target */
|
|
|
|
data.intersect = struct1;
|
|
|
|
if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
|
|
|
|
gst_structure_intersect_field2, &data)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return data.dest;
|
|
|
|
|
|
|
|
error:
|
|
|
|
gst_structure_free (data.dest);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-09-10 16:33:34 +00:00
|
|
|
static gboolean
|
|
|
|
gst_caps_structure_can_intersect_field (GQuark id, const GValue * val1,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GstStructure *other = (GstStructure *) data;
|
|
|
|
const GValue *val2 = gst_structure_id_get_value (other, id);
|
|
|
|
|
|
|
|
if (G_LIKELY (val2)) {
|
|
|
|
if (!gst_value_can_intersect (val1, val2)) {
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
gint eq = gst_value_compare (val1, val2);
|
|
|
|
|
|
|
|
if (eq == GST_VALUE_UNORDERED) {
|
|
|
|
/* we need to try interseting */
|
2011-10-27 11:24:13 +00:00
|
|
|
if (!gst_value_intersect (NULL, val1, val2)) {
|
2010-09-10 16:33:34 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
} else if (eq != GST_VALUE_EQUAL) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_can_intersect:
|
|
|
|
* @struct1: a #GstStructure
|
|
|
|
* @struct2: a #GstStructure
|
|
|
|
*
|
2011-09-07 11:14:38 +00:00
|
|
|
* Tries intersecting @struct1 and @struct2 and reports whether the result
|
2010-09-10 16:33:34 +00:00
|
|
|
* would not be empty.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if intersection would not be empty
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_can_intersect (const GstStructure * struct1,
|
|
|
|
const GstStructure * struct2)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (struct1), FALSE);
|
|
|
|
g_return_val_if_fail (GST_IS_STRUCTURE (struct2), FALSE);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (struct1->name != struct2->name))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* tries to intersect if we have the field in both */
|
2011-10-27 11:02:43 +00:00
|
|
|
return gst_structure_foreach ((GstStructure *) struct1,
|
|
|
|
gst_caps_structure_can_intersect_field, (gpointer) struct2);
|
2010-09-10 16:33:34 +00:00
|
|
|
}
|
2011-05-27 11:47:11 +00:00
|
|
|
|
2013-02-13 09:46:37 +00:00
|
|
|
static gboolean
|
2013-04-04 15:59:10 +00:00
|
|
|
gst_caps_structure_is_superset_field (GQuark field_id, const GValue * value,
|
2013-02-13 09:46:37 +00:00
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GstStructure *subset = user_data;
|
2011-05-27 11:47:11 +00:00
|
|
|
const GValue *other;
|
2011-10-27 10:41:30 +00:00
|
|
|
int comparison;
|
2011-05-27 11:47:11 +00:00
|
|
|
|
2013-04-04 15:59:10 +00:00
|
|
|
if (!(other = gst_structure_id_get_value (subset, field_id)))
|
|
|
|
/* field is missing in the subset => no subset */
|
|
|
|
return FALSE;
|
2011-05-27 11:47:11 +00:00
|
|
|
|
2013-04-04 15:59:10 +00:00
|
|
|
comparison = gst_value_compare (value, other);
|
2011-10-27 10:41:30 +00:00
|
|
|
|
2011-05-27 11:47:11 +00:00
|
|
|
/* equal values are subset */
|
2011-10-27 10:41:30 +00:00
|
|
|
if (comparison == GST_VALUE_EQUAL)
|
2011-05-27 11:47:11 +00:00
|
|
|
return TRUE;
|
|
|
|
|
2011-10-27 10:41:30 +00:00
|
|
|
/* ordered, but unequal, values are not */
|
|
|
|
if (comparison != GST_VALUE_UNORDERED)
|
|
|
|
return FALSE;
|
|
|
|
|
2013-04-04 15:59:10 +00:00
|
|
|
return gst_value_is_subset (other, value);
|
2011-05-27 11:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_is_subset:
|
|
|
|
* @subset: a #GstStructure
|
|
|
|
* @superset: a potentially greater #GstStructure
|
|
|
|
*
|
|
|
|
* Checks if @subset is a subset of @superset, i.e. has the same
|
|
|
|
* structure name and for all fields that are existing in @superset,
|
|
|
|
* @subset has a value that is a subset of the value in @superset.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if @subset is a subset of @superset
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_structure_is_subset (const GstStructure * subset,
|
|
|
|
const GstStructure * superset)
|
|
|
|
{
|
|
|
|
if ((superset->name != subset->name) ||
|
|
|
|
(gst_structure_n_fields (superset) > gst_structure_n_fields (subset)))
|
|
|
|
return FALSE;
|
|
|
|
|
2013-04-04 15:59:10 +00:00
|
|
|
return gst_structure_foreach ((GstStructure *) superset,
|
|
|
|
gst_caps_structure_is_superset_field, (gpointer) subset);
|
2011-05-27 11:47:11 +00:00
|
|
|
}
|
2011-08-15 12:32:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_structure_fixate:
|
|
|
|
* @structure: a #GstStructure
|
|
|
|
*
|
|
|
|
* Fixate all values in @structure using gst_value_fixate().
|
|
|
|
* @structure will be modified in-place and should be writable.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_structure_fixate (GstStructure * structure)
|
|
|
|
{
|
2011-08-15 12:40:38 +00:00
|
|
|
g_return_if_fail (GST_IS_STRUCTURE (structure));
|
|
|
|
|
2011-08-15 12:32:17 +00:00
|
|
|
gst_structure_foreach (structure, default_fixate, structure);
|
|
|
|
}
|