caps: Store a pointer to GstCaps in GstStaticCaps

...instead of using hackish subclass of GstCaps, which also
had some thread-safety problems.
This commit is contained in:
Sebastian Dröge 2012-01-26 14:33:12 +01:00
parent dc4d96d54c
commit 5d1d7d95b2
4 changed files with 18 additions and 42 deletions

View file

@ -356,7 +356,6 @@ gst_static_caps_get_type (void)
return staticcaps_type;
}
/**
* gst_static_caps_get:
* @static_caps: the #GstStaticCaps to convert
@ -370,20 +369,19 @@ gst_static_caps_get_type (void)
GstCaps *
gst_static_caps_get (GstStaticCaps * static_caps)
{
GstCaps *caps;
GstCaps **caps;
g_return_val_if_fail (static_caps != NULL, NULL);
caps = (GstCaps *) static_caps;
caps = &static_caps->caps;
/* refcount is 0 when we need to convert */
if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) {
if (G_UNLIKELY (*caps == NULL)) {
const char *string;
GstCaps temp;
G_LOCK (static_caps_lock);
/* check if other thread already updated */
if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0))
if (G_UNLIKELY (*caps != NULL))
goto done;
string = static_caps->string;
@ -393,28 +391,21 @@ gst_static_caps_get (GstStaticCaps * static_caps)
GST_CAT_TRACE (GST_CAT_CAPS, "creating %p", static_caps);
/* we construct the caps on the stack, then copy over the struct into our
* real caps, refcount last. We do this because we must leave the refcount
* of the result caps to 0 so that other threads don't run away with the
* caps while we are constructing it. */
gst_caps_init (&temp, sizeof (GstCaps));
*caps = gst_caps_from_string (string);
/* convert to string */
if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
if (G_UNLIKELY (*caps == NULL))
g_critical ("Could not convert static caps \"%s\"", string);
GST_MINI_OBJECT_REFCOUNT (&temp) = 0;
memcpy (caps, &temp, sizeof (GstCaps));
gst_caps_ref (caps);
GST_CAT_TRACE (GST_CAT_CAPS, "created %p", static_caps);
done:
G_UNLOCK (static_caps_lock);
}
/* ref the caps, makes it not writable */
gst_caps_ref (caps);
if (G_LIKELY (*caps != NULL))
gst_caps_ref (*caps);
return caps;
return *caps;
/* ERRORS */
no_string:
@ -427,30 +418,16 @@ no_string:
/**
* gst_static_caps_cleanup:
* @static_caps: the #GstStaticCaps to convert
* @static_caps: the #GstStaticCaps to clean
*
* Clean up the caps contained in @static_caps when the refcount is 0.
* Clean up the cached caps contained in @static_caps.
*/
void
gst_static_caps_cleanup (GstStaticCaps * static_caps)
{
GstCaps *caps = (GstCaps *) static_caps;
/* FIXME: this is not threadsafe */
if (GST_CAPS_REFCOUNT_VALUE (caps) == 1) {
GstStructure *structure;
guint i, clen;
clen = GST_CAPS_LEN (caps);
for (i = 0; i < clen; i++) {
structure = (GstStructure *) gst_caps_get_structure (caps, i);
gst_structure_set_parent_refcount (structure, NULL);
gst_structure_free (structure);
}
g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
GST_CAPS_REFCOUNT (caps) = 0;
}
G_LOCK (static_caps_lock);
gst_caps_replace (&static_caps->caps, NULL);
G_UNLOCK (static_caps_lock);
}
/* manipulation */

View file

@ -129,8 +129,7 @@ typedef enum {
*/
#define GST_STATIC_CAPS(string) \
{ \
/* miniobject */ { { 0, 0, 0, 0, NULL, NULL, NULL, 0, NULL }, \
/* caps */ NULL }, \
/* caps */ NULL, \
/* string */ string, \
GST_PADDING_INIT \
}
@ -361,7 +360,7 @@ struct _GstCaps {
*/
struct _GstStaticCaps {
/*< public >*/
GstCaps caps;
GstCaps *caps;
const char *string;
/*< private >*/

View file

@ -253,7 +253,7 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
newt->name_template = g_intern_string (templ->name_template);
newt->direction = templ->direction;
newt->presence = templ->presence;
newt->static_caps.caps.mini_object.refcount = 0;
newt->static_caps.caps = NULL;
newt->static_caps.string = g_intern_string (caps_string);
factory->staticpadtemplates =
g_list_append (factory->staticpadtemplates, newt);

View file

@ -493,7 +493,7 @@ gst_registry_chunks_load_pad_template (GstElementFactory * factory, gchar ** in,
template = g_slice_new (GstStaticPadTemplate);
template->presence = pt->presence;
template->direction = (GstPadDirection) pt->direction;
template->static_caps.caps.mini_object.refcount = 0;
template->static_caps.caps = NULL;
/* unpack pad template strings */
unpack_const_string (*in, template->name_template, end, fail);