Original commit message from CVS:
fixes #122272
This commit is contained in:
Thomas Vander Stichele 2003-09-14 12:30:27 +00:00
parent 796df6a931
commit d589eeb261
3 changed files with 121 additions and 23 deletions

View file

@ -50,8 +50,12 @@ typedef enum {
#define GST_CAPS_PROPERTIES(caps) ((caps)->properties)
#define GST_CAPS_NEXT(caps) ((caps)->next)
/* GST_CAPS_IS_FIXED is wrong, please use the backported function */
#define GST_CAPS_IS_FIXED(caps) (GST_CAPS_FLAGS (caps) & GST_CAPS_FIXED)
#define GST_CAPS_IS_FIXED_BP(caps) (((caps)->properties == NULL) || \
(GST_PROPS_IS_FIXED ((caps)->properties)))
#define GST_CAPS_IS_FLOATING(caps) (GST_CAPS_FLAGS (caps) & GST_CAPS_FLOATING)
#define GST_CAPS_IS_CHAINED(caps) (GST_CAPS_NEXT (caps) != NULL)
struct _GstCaps {

View file

@ -1442,7 +1442,8 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
* @pad: a #GstPad to try to set the caps on.
* @caps: the #GstCaps to set.
*
* Tries to set the caps on the given pad.
* Tries to set the caps on the given pad. Takes ownership of the caps;
* if you want to reuse these caps you need to ref them first.
*
* Returns: A #GstPadLinkReturn value indicating whether the caps
* could be set.

View file

@ -406,12 +406,44 @@ gst_props_add_entry (GstProps *props, GstPropsEntry *entry)
g_return_if_fail (props);
g_return_if_fail (entry);
/* only variable properties can change the fixed flag */
if (GST_PROPS_IS_FIXED (props) && GST_PROPS_ENTRY_IS_VARIABLE (entry)) {
GST_PROPS_FLAG_UNSET (props, GST_PROPS_FIXED);
}
props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func);
}
static void
gst_props_remove_entry_by_id (GstProps *props, GQuark propid)
{
GList *properties;
gboolean found;
/* assume fixed */
GST_PROPS_FLAG_SET (props, GST_PROPS_FIXED);
found = FALSE;
properties = props->properties;
while (properties) {
GList *current = properties;
GstPropsEntry *lentry = (GstPropsEntry *) current->data;
properties = g_list_next (properties);
if (lentry->propid == propid) {
found = TRUE;
g_list_delete_link (props->properties, current);
}
else if (GST_PROPS_ENTRY_IS_VARIABLE (lentry)) {
GST_PROPS_FLAG_UNSET (props, GST_PROPS_FIXED);
/* no need to check for further variable entries
* if we already removed the entry */
if (found)
break;
}
}
}
/**
* gst_props_remove_entry:
* @props: the property to remove the entry from
@ -425,7 +457,7 @@ gst_props_remove_entry (GstProps *props, GstPropsEntry *entry)
g_return_if_fail (props != NULL);
g_return_if_fail (entry != NULL);
props->properties = g_list_remove (props->properties, entry);
gst_props_remove_entry_by_id (props, entry->propid);
}
/**
@ -438,18 +470,13 @@ gst_props_remove_entry (GstProps *props, GstPropsEntry *entry)
void
gst_props_remove_entry_by_name (GstProps *props, const gchar *name)
{
GList *lentry;
GQuark quark;
g_return_if_fail (props != NULL);
g_return_if_fail (name != NULL);
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
gst_props_remove_entry (props, (GstPropsEntry *)lentry->data);
}
gst_props_remove_entry_by_id (props, quark);
}
/**
@ -485,7 +512,13 @@ gst_props_new (const gchar *firstname, ...)
void
gst_props_debug (GstProps *props)
{
GST_DEBUG (GST_CAT_PROPERTIES, "props %p, refcount %d, flags %d", props, props->refcount, props->flags);
if (!props) {
GST_DEBUG (GST_CAT_PROPERTIES, "props (null)");
return;
}
GST_DEBUG (GST_CAT_PROPERTIES, "props %p, refcount %d, flags %d",
props, props->refcount, props->flags);
g_list_foreach (props->properties, (GFunc) gst_props_debug_entry, NULL);
}
@ -767,26 +800,66 @@ GstProps*
gst_props_set (GstProps *props, const gchar *name, ...)
{
GQuark quark;
GList *lentry;
GList *properties;
va_list var_args;
gboolean found;
gboolean was_fixed;
g_return_val_if_fail (props != NULL, NULL);
found = FALSE;
was_fixed = GST_PROPS_IS_FIXED (props);
GST_PROPS_FLAG_SET (props, GST_PROPS_FIXED);
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
/* this looks a little complicated but the idea is to get
* out of the loop ASAP. Changing the entry to a variable
* property immediatly marks the props as non-fixed.
* changing the entry to fixed when the props was fixed
* does not change the props and we can get out of the loop
* as well.
* When changing the entry to a fixed entry, we need to
* see if all entries are fixed before we can decide the props
*/
properties = props->properties;
while (properties) {
GstPropsEntry *entry;
entry = (GstPropsEntry *)lentry->data;
entry = (GstPropsEntry *) properties->data;
va_start (var_args, name);
gst_props_entry_clean (entry);
GST_PROPS_ENTRY_FILL (entry, var_args);
va_end (var_args);
if (entry->propid == quark) {
found = TRUE;
va_start (var_args, name);
gst_props_entry_clean (entry);
GST_PROPS_ENTRY_FILL (entry, var_args);
va_end (var_args);
/* if the props was fixed and we changed this entry
* with a fixed entry, we can stop now as the global
* props flag cannot change */
if (was_fixed && !GST_PROPS_ENTRY_IS_VARIABLE (entry))
break;
/* if we already found a non fixed entry we can exit */
if (!GST_PROPS_IS_FIXED (props))
break;
/* if the entry is variable, we'll get out of the loop
* in the next statement */
/* if the entry is fixed we have to check all other
* entries before we can decide if the props are fixed */
}
if (GST_PROPS_ENTRY_IS_VARIABLE (entry)) {
/* mark the props as variable */
GST_PROPS_FLAG_UNSET (props, GST_PROPS_FIXED);
/* if we already changed the entry, we can stop now */
if (found)
break;
}
properties = g_list_next (properties);
}
else {
if (!found) {
g_warning ("gstprops: no property '%s' to change\n", name);
}
@ -1173,6 +1246,7 @@ gst_props_entry_get_safe (const GstPropsEntry *entry, ...)
static gboolean
gst_props_getv (GstProps *props, gboolean safe, gchar *first_name, va_list var_args)
{
g_print ("DEBUG: first_name: %s, var_args %p\n", first_name, var_args);
while (first_name) {
const GstPropsEntry *entry = gst_props_get_entry (props, first_name);
gboolean result;
@ -1182,6 +1256,7 @@ gst_props_getv (GstProps *props, gboolean safe, gchar *first_name, va_list var_a
if (!result) return FALSE;
first_name = va_arg (var_args, gchar *);
g_print ("DEBUG: first_name: %s, var_args %p\n", first_name, var_args);
}
return TRUE;
}
@ -1203,7 +1278,9 @@ gst_props_get (GstProps *props, gchar *first_name, ...)
va_list var_args;
gboolean ret;
g_print ("DEBUG: first_name: %s, var_args %p\n", first_name, var_args);
va_start (var_args, first_name);
g_print ("DEBUG: first_name: %s, var_args %p\n", first_name, var_args);
ret = gst_props_getv (props, FALSE, first_name, var_args);
va_end (var_args);
@ -1926,15 +2003,21 @@ gst_props_normalize (GstProps *props)
{
GList *entries;
GList *result = NULL;
gboolean fixed = TRUE;
if (!props)
return NULL;
/* warning: the property here could have a wrong FIXED flag
* but it'll be fixed at the end of the loop */
entries = props->properties;
while (entries) {
GstPropsEntry *entry = (GstPropsEntry *) entries->data;
/* be carefull with the bitmasks */
fixed &= (GST_PROPS_ENTRY_IS_VARIABLE (entry) ? FALSE : TRUE);
if (entry->propstype == GST_PROPS_LIST_TYPE) {
GList *list_entries = entry->data.list_data.entries;
@ -1944,15 +2027,18 @@ gst_props_normalize (GstProps *props)
GstProps *newprops;
GList *lentry;
/* FIXME fixed flags is probably messed up here */
newprops = gst_props_copy (props);
lentry = g_list_find_custom (newprops->properties, GINT_TO_POINTER (list_entry->propid), props_find_func);
lentry = g_list_find_custom (newprops->properties,
GINT_TO_POINTER (list_entry->propid),
props_find_func);
if (lentry) {
GList *new_list;
new_entry = (GstPropsEntry *) lentry->data;
memcpy (new_entry, list_entry, sizeof (GstPropsEntry));
/* it's possible that this property now became fixed, since we
* removed the list, we'll update the flag when everything is
* unreolled at the end of this function */
new_list = gst_props_normalize (newprops);
result = g_list_concat (new_list, result);
}
@ -1970,6 +2056,13 @@ gst_props_normalize (GstProps *props)
entries = g_list_next (entries);
}
if (!result) {
/* at this point, the props did not need any unrolling, we have scanned
* all entries and the fixed flag will hold the correct value */
if (fixed)
GST_PROPS_FLAG_SET (props, GST_PROPS_FIXED);
else
GST_PROPS_FLAG_UNSET (props, GST_PROPS_FIXED);
/* no result, create list with input props */
result = g_list_prepend (result, props);
}