mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
dc4d96d54c
commit
5d1d7d95b2
4 changed files with 18 additions and 42 deletions
|
@ -356,7 +356,6 @@ gst_static_caps_get_type (void)
|
||||||
return staticcaps_type;
|
return staticcaps_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_static_caps_get:
|
* gst_static_caps_get:
|
||||||
* @static_caps: the #GstStaticCaps to convert
|
* @static_caps: the #GstStaticCaps to convert
|
||||||
|
@ -370,20 +369,19 @@ gst_static_caps_get_type (void)
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_static_caps_get (GstStaticCaps * static_caps)
|
gst_static_caps_get (GstStaticCaps * static_caps)
|
||||||
{
|
{
|
||||||
GstCaps *caps;
|
GstCaps **caps;
|
||||||
|
|
||||||
g_return_val_if_fail (static_caps != NULL, NULL);
|
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 */
|
/* 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;
|
const char *string;
|
||||||
GstCaps temp;
|
|
||||||
|
|
||||||
G_LOCK (static_caps_lock);
|
G_LOCK (static_caps_lock);
|
||||||
/* check if other thread already updated */
|
/* check if other thread already updated */
|
||||||
if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0))
|
if (G_UNLIKELY (*caps != NULL))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
string = static_caps->string;
|
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);
|
GST_CAT_TRACE (GST_CAT_CAPS, "creating %p", static_caps);
|
||||||
|
|
||||||
/* we construct the caps on the stack, then copy over the struct into our
|
*caps = gst_caps_from_string (string);
|
||||||
* 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));
|
|
||||||
|
|
||||||
/* convert to 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);
|
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);
|
GST_CAT_TRACE (GST_CAT_CAPS, "created %p", static_caps);
|
||||||
done:
|
done:
|
||||||
G_UNLOCK (static_caps_lock);
|
G_UNLOCK (static_caps_lock);
|
||||||
}
|
}
|
||||||
/* ref the caps, makes it not writable */
|
/* 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 */
|
/* ERRORS */
|
||||||
no_string:
|
no_string:
|
||||||
|
@ -427,30 +418,16 @@ no_string:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_static_caps_cleanup:
|
* 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
|
void
|
||||||
gst_static_caps_cleanup (GstStaticCaps * static_caps)
|
gst_static_caps_cleanup (GstStaticCaps * static_caps)
|
||||||
{
|
{
|
||||||
GstCaps *caps = (GstCaps *) static_caps;
|
G_LOCK (static_caps_lock);
|
||||||
|
gst_caps_replace (&static_caps->caps, NULL);
|
||||||
/* FIXME: this is not threadsafe */
|
G_UNLOCK (static_caps_lock);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* manipulation */
|
/* manipulation */
|
||||||
|
|
|
@ -129,8 +129,7 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
#define GST_STATIC_CAPS(string) \
|
#define GST_STATIC_CAPS(string) \
|
||||||
{ \
|
{ \
|
||||||
/* miniobject */ { { 0, 0, 0, 0, NULL, NULL, NULL, 0, NULL }, \
|
/* caps */ NULL, \
|
||||||
/* caps */ NULL }, \
|
|
||||||
/* string */ string, \
|
/* string */ string, \
|
||||||
GST_PADDING_INIT \
|
GST_PADDING_INIT \
|
||||||
}
|
}
|
||||||
|
@ -361,7 +360,7 @@ struct _GstCaps {
|
||||||
*/
|
*/
|
||||||
struct _GstStaticCaps {
|
struct _GstStaticCaps {
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
GstCaps caps;
|
GstCaps *caps;
|
||||||
const char *string;
|
const char *string;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
|
@ -253,7 +253,7 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
|
||||||
newt->name_template = g_intern_string (templ->name_template);
|
newt->name_template = g_intern_string (templ->name_template);
|
||||||
newt->direction = templ->direction;
|
newt->direction = templ->direction;
|
||||||
newt->presence = templ->presence;
|
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);
|
newt->static_caps.string = g_intern_string (caps_string);
|
||||||
factory->staticpadtemplates =
|
factory->staticpadtemplates =
|
||||||
g_list_append (factory->staticpadtemplates, newt);
|
g_list_append (factory->staticpadtemplates, newt);
|
||||||
|
|
|
@ -493,7 +493,7 @@ gst_registry_chunks_load_pad_template (GstElementFactory * factory, gchar ** in,
|
||||||
template = g_slice_new (GstStaticPadTemplate);
|
template = g_slice_new (GstStaticPadTemplate);
|
||||||
template->presence = pt->presence;
|
template->presence = pt->presence;
|
||||||
template->direction = (GstPadDirection) pt->direction;
|
template->direction = (GstPadDirection) pt->direction;
|
||||||
template->static_caps.caps.mini_object.refcount = 0;
|
template->static_caps.caps = NULL;
|
||||||
|
|
||||||
/* unpack pad template strings */
|
/* unpack pad template strings */
|
||||||
unpack_const_string (*in, template->name_template, end, fail);
|
unpack_const_string (*in, template->name_template, end, fail);
|
||||||
|
|
Loading…
Reference in a new issue