mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 16:35:40 +00:00
miniobject: work on making caps a boxed type
More work on making miniobject a simple allocated struct.
This commit is contained in:
parent
086aac764d
commit
fda9686b35
8 changed files with 223 additions and 563 deletions
|
@ -128,20 +128,15 @@
|
|||
#include "gstminiobject.h"
|
||||
#include "gstversion.h"
|
||||
|
||||
static void gst_buffer_finalize (GstBuffer * buffer);
|
||||
static GstBuffer *_gst_buffer_copy (GstBuffer * buffer);
|
||||
static GType _gst_buffer_type = 0;
|
||||
|
||||
GType
|
||||
gst_buffer_get_type (void)
|
||||
{
|
||||
static GType gst_buffer_type = 0;
|
||||
|
||||
if (G_UNLIKELY (gst_buffer_type == 0)) {
|
||||
gst_buffer_type = g_boxed_type_register_static ("GstBuffer",
|
||||
(GBoxedCopyFunc) gst_buffer_copy_conditional,
|
||||
(GBoxedFreeFunc) gst_buffer_unref);
|
||||
if (G_UNLIKELY (_gst_buffer_type == 0)) {
|
||||
_gst_buffer_type = gst_mini_object_register ("GstBuffer");
|
||||
}
|
||||
return gst_buffer_type;
|
||||
return _gst_buffer_type;
|
||||
}
|
||||
|
||||
/* buffer alignment in bytes
|
||||
|
@ -183,23 +178,6 @@ _gst_buffer_initialize (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gst_buffer_finalize (GstBuffer * buffer)
|
||||
{
|
||||
g_return_if_fail (buffer != NULL);
|
||||
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
|
||||
|
||||
/* free our data */
|
||||
if (G_LIKELY (buffer->malloc_data))
|
||||
buffer->free_func (buffer->malloc_data);
|
||||
|
||||
gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
|
||||
|
||||
if (buffer->parent)
|
||||
gst_buffer_unref (buffer->parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_copy_metadata:
|
||||
* @dest: a destination #GstBuffer
|
||||
|
@ -299,18 +277,20 @@ _gst_buffer_copy (GstBuffer * buffer)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_buffer_init (GstBuffer * buffer)
|
||||
_gst_buffer_free (GstBuffer * buffer)
|
||||
{
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "init %p", buffer);
|
||||
g_return_if_fail (buffer != NULL);
|
||||
|
||||
buffer->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_copy;
|
||||
buffer->mini_object.free = (GstMiniObjectFreeeFunction) gst_buffer_finalize;
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_FREE_FUNC (buffer) = g_free;
|
||||
/* free our data */
|
||||
if (G_LIKELY (buffer->malloc_data))
|
||||
buffer->free_func (buffer->malloc_data);
|
||||
|
||||
gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
|
||||
|
||||
if (buffer->parent)
|
||||
gst_buffer_unref (buffer->parent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,10 +307,21 @@ gst_buffer_new (void)
|
|||
{
|
||||
GstBuffer *newbuf;
|
||||
|
||||
newbuf = (GstBuffer *) gst_mini_object_new (GST_TYPE_BUFFER);
|
||||
|
||||
newbuf = g_slice_new0 (GstBuffer);
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "new %p", newbuf);
|
||||
|
||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (newbuf),
|
||||
_gst_buffer_type, sizeof (GstBuffer));
|
||||
|
||||
newbuf->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_copy;
|
||||
newbuf->mini_object.free = (GstMiniObjectFreeFunction) _gst_buffer_free;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (newbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_FREE_FUNC (newbuf) = g_free;
|
||||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
|
|
@ -145,11 +145,6 @@ struct _GstBufferList
|
|||
GList *buffers;
|
||||
};
|
||||
|
||||
struct _GstBufferListClass
|
||||
{
|
||||
GstMiniObjectClass mini_object_class;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstBufferListIterator:
|
||||
*
|
||||
|
@ -166,8 +161,6 @@ struct _GstBufferListIterator
|
|||
|
||||
static GType _gst_buffer_list_type = 0;
|
||||
|
||||
G_DEFINE_TYPE (GstBufferList, gst_buffer_list, GST_TYPE_MINI_OBJECT);
|
||||
|
||||
void
|
||||
_gst_buffer_list_initialize (void)
|
||||
{
|
||||
|
@ -177,37 +170,6 @@ _gst_buffer_list_initialize (void)
|
|||
_gst_buffer_list_type = type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_buffer_list_init (GstBufferList * list)
|
||||
{
|
||||
list->buffers = NULL;
|
||||
|
||||
GST_LOG ("init %p", list);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_buffer_list_finalize (GstBufferList * list)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
g_return_if_fail (list != NULL);
|
||||
|
||||
GST_LOG ("finalize %p", list);
|
||||
|
||||
tmp = list->buffers;
|
||||
while (tmp) {
|
||||
if (tmp->data != GROUP_START && tmp->data != STOLEN) {
|
||||
gst_buffer_unref (GST_BUFFER_CAST (tmp->data));
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_list_free (list->buffers);
|
||||
|
||||
/* Not chaining up because GstMiniObject::finalize() does nothing
|
||||
GST_MINI_OBJECT_CLASS (gst_buffer_list_parent_class)->finalize
|
||||
(GST_MINI_OBJECT_CAST (list));*/
|
||||
}
|
||||
|
||||
static GstBufferList *
|
||||
_gst_buffer_list_copy (GstBufferList * list)
|
||||
{
|
||||
|
@ -234,12 +196,24 @@ _gst_buffer_list_copy (GstBufferList * list)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_buffer_list_class_init (GstBufferListClass * list_class)
|
||||
_gst_buffer_list_free (GstBufferList * list)
|
||||
{
|
||||
list_class->mini_object_class.copy =
|
||||
(GstMiniObjectCopyFunction) _gst_buffer_list_copy;
|
||||
list_class->mini_object_class.finalize =
|
||||
(GstMiniObjectFinalizeFunction) gst_buffer_list_finalize;
|
||||
GList *tmp;
|
||||
|
||||
g_return_if_fail (list != NULL);
|
||||
|
||||
GST_LOG ("free %p", list);
|
||||
|
||||
tmp = list->buffers;
|
||||
while (tmp) {
|
||||
if (tmp->data != GROUP_START && tmp->data != STOLEN) {
|
||||
gst_buffer_unref (GST_BUFFER_CAST (tmp->data));
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_list_free (list->buffers);
|
||||
|
||||
g_slice_free (GstBufferList, list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,7 +234,13 @@ gst_buffer_list_new (void)
|
|||
{
|
||||
GstBufferList *list;
|
||||
|
||||
list = (GstBufferList *) gst_mini_object_new (_gst_buffer_list_type);
|
||||
list = g_slice_new0 (GstBufferList);
|
||||
|
||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (list), _gst_buffer_list_type,
|
||||
sizeof (GstBufferList));
|
||||
|
||||
list->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_list_copy;
|
||||
list->mini_object.free = (GstMiniObjectFreeFunction) _gst_buffer_list_free;
|
||||
|
||||
GST_LOG ("new %p", list);
|
||||
|
||||
|
@ -422,6 +402,15 @@ gst_buffer_list_get (GstBufferList * list, guint group, guint idx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_buffer_list_get_type (void)
|
||||
{
|
||||
if (G_UNLIKELY (_gst_buffer_list_type == 0)) {
|
||||
_gst_buffer_list_type = gst_mini_object_register ("GstBufferList");
|
||||
}
|
||||
return _gst_buffer_list_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_list_iterate:
|
||||
* @list: a #GstBufferList
|
||||
|
|
|
@ -28,15 +28,11 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_BUFFER_LIST (gst_buffer_list_get_type ())
|
||||
#define GST_IS_BUFFER_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BUFFER_LIST))
|
||||
#define GST_IS_BUFFER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BUFFER_LIST))
|
||||
#define GST_BUFFER_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BUFFER_LIST, GstBufferListClass))
|
||||
#define GST_BUFFER_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BUFFER_LIST, GstBufferList))
|
||||
#define GST_BUFFER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BUFFER_LIST, GstBufferListClass))
|
||||
#define GST_IS_BUFFER_LIST(obj) (GST_MINI_OBJECT_TYPE(obj) == GST_TYPE_BUFFER_LIST)
|
||||
#define GST_BUFFER_LIST_CAST(obj) ((GstBufferList *)obj)
|
||||
#define GST_BUFFER_LIST(obj) (GST_BUFFER_LIST_CAST(obj))
|
||||
|
||||
typedef struct _GstBufferList GstBufferList;
|
||||
typedef struct _GstBufferListClass GstBufferListClass;
|
||||
typedef struct _GstBufferListIterator GstBufferListIterator;
|
||||
|
||||
/**
|
||||
|
|
32
gst/gstbus.c
32
gst/gstbus.c
|
@ -106,34 +106,6 @@ struct _GstBusPrivate
|
|||
|
||||
G_DEFINE_TYPE (GstBus, gst_bus, GST_TYPE_OBJECT);
|
||||
|
||||
/* fixme: do something about this */
|
||||
static void
|
||||
marshal_VOID__MINIOBJECT (GClosure * closure, GValue * return_value,
|
||||
guint n_param_values, const GValue * param_values, gpointer invocation_hint,
|
||||
gpointer marshal_data)
|
||||
{
|
||||
typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1,
|
||||
gpointer data2);
|
||||
register marshalfunc_VOID__MINIOBJECT callback;
|
||||
register GCClosure *cc = (GCClosure *) closure;
|
||||
register gpointer data1, data2;
|
||||
|
||||
g_return_if_fail (n_param_values == 2);
|
||||
|
||||
if (G_CCLOSURE_SWAP_DATA (closure)) {
|
||||
data1 = closure->data;
|
||||
data2 = g_value_peek_pointer (param_values + 0);
|
||||
} else {
|
||||
data1 = g_value_peek_pointer (param_values + 0);
|
||||
data2 = closure->data;
|
||||
}
|
||||
callback =
|
||||
(marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data :
|
||||
cc->callback);
|
||||
|
||||
callback (data1, gst_value_get_mini_object (param_values + 1), data2);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_bus_class_init (GstBusClass * klass)
|
||||
{
|
||||
|
@ -162,7 +134,7 @@ gst_bus_class_init (GstBusClass * klass)
|
|||
g_signal_new ("sync-message", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
|
||||
G_STRUCT_OFFSET (GstBusClass, sync_message), NULL, NULL,
|
||||
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
|
||||
g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
|
||||
|
||||
/**
|
||||
* GstBus::message:
|
||||
|
@ -177,7 +149,7 @@ gst_bus_class_init (GstBusClass * klass)
|
|||
g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
|
||||
G_STRUCT_OFFSET (GstBusClass, message), NULL, NULL,
|
||||
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
|
||||
g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstBusPrivate));
|
||||
}
|
||||
|
|
|
@ -141,6 +141,32 @@ gst_caps_get_type (void)
|
|||
}
|
||||
|
||||
/* creation/deletion */
|
||||
static void
|
||||
_gst_caps_free (GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
guint i, len;
|
||||
|
||||
/* The refcount must be 0, but since we're only called by gst_caps_unref,
|
||||
* don't bother testing. */
|
||||
len = caps->structs->len;
|
||||
/* This can be used to get statistics about caps sizes */
|
||||
/*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
|
||||
for (i = 0; i < len; i++) {
|
||||
structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
|
||||
gst_structure_set_parent_refcount (structure, NULL);
|
||||
gst_structure_free (structure);
|
||||
}
|
||||
g_ptr_array_free (caps->structs, TRUE);
|
||||
#ifdef USE_POISONING
|
||||
memset (caps, 0xff, sizeof (GstCaps));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_REFCOUNT
|
||||
GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
|
||||
#endif
|
||||
g_slice_free (GstCaps, caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_new_empty:
|
||||
|
@ -156,9 +182,12 @@ gst_caps_new_empty (void)
|
|||
{
|
||||
GstCaps *caps = g_slice_new (GstCaps);
|
||||
|
||||
caps->type = GST_TYPE_CAPS;
|
||||
caps->refcount = 1;
|
||||
caps->flags = 0;
|
||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (caps),
|
||||
GST_TYPE_CAPS, sizeof (GstCaps));
|
||||
|
||||
caps->mini_object.copy = (GstMiniObjectCopyFunction) gst_caps_copy;
|
||||
caps->mini_object.free = (GstMiniObjectFreeFunction) _gst_caps_free;
|
||||
|
||||
caps->structs = g_ptr_array_new ();
|
||||
/* the 32 has been determined by logging caps sizes in _gst_caps_free
|
||||
* but g_ptr_array uses 16 anyway if it expands once, so this does not help
|
||||
|
@ -186,7 +215,7 @@ gst_caps_new_any (void)
|
|||
{
|
||||
GstCaps *caps = gst_caps_new_empty ();
|
||||
|
||||
caps->flags = GST_CAPS_FLAGS_ANY;
|
||||
GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAGS_ANY);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
@ -309,33 +338,6 @@ gst_caps_copy (const GstCaps * caps)
|
|||
return newcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_caps_free (GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
guint i, len;
|
||||
|
||||
/* The refcount must be 0, but since we're only called by gst_caps_unref,
|
||||
* don't bother testing. */
|
||||
len = caps->structs->len;
|
||||
/* This can be used to get statistics about caps sizes */
|
||||
/*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
|
||||
for (i = 0; i < len; i++) {
|
||||
structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
|
||||
gst_structure_set_parent_refcount (structure, NULL);
|
||||
gst_structure_free (structure);
|
||||
}
|
||||
g_ptr_array_free (caps->structs, TRUE);
|
||||
#ifdef USE_POISONING
|
||||
memset (caps, 0xff, sizeof (GstCaps));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_REFCOUNT
|
||||
GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
|
||||
#endif
|
||||
g_slice_free (GstCaps, caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_make_writable:
|
||||
* @caps: (transfer full): the #GstCaps to make writable
|
||||
|
|
|
@ -40,7 +40,7 @@ G_BEGIN_DECLS
|
|||
* Extra flags for a caps.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_CAPS_FLAGS_ANY = (1 << 0)
|
||||
GST_CAPS_FLAGS_ANY = (GST_MINI_OBJECT_FLAG_LAST << 0)
|
||||
} GstCapsFlags;
|
||||
|
||||
/**
|
||||
|
@ -99,6 +99,14 @@ typedef enum {
|
|||
typedef struct _GstCaps GstCaps;
|
||||
typedef struct _GstStaticCaps GstStaticCaps;
|
||||
|
||||
/**
|
||||
* GST_CAPS_FLAGS:
|
||||
* @caps: a #GstCaps.
|
||||
*
|
||||
* A flags word containing #GstCapsFlags flags set on this caps.
|
||||
*/
|
||||
#define GST_CAPS_FLAGS(caps) GST_MINI_OBJECT_FLAGS(caps)
|
||||
|
||||
/* refcount */
|
||||
/**
|
||||
* GST_CAPS_REFCOUNT:
|
||||
|
@ -106,14 +114,39 @@ typedef struct _GstStaticCaps GstStaticCaps;
|
|||
*
|
||||
* Get access to the reference count field of the caps
|
||||
*/
|
||||
#define GST_CAPS_REFCOUNT(caps) ((GST_CAPS(caps))->refcount)
|
||||
#define GST_CAPS_REFCOUNT(caps) GST_MINI_OBJECT_REFCOUNT(caps)
|
||||
/**
|
||||
* GST_CAPS_REFCOUNT_VALUE:
|
||||
* @caps: a #GstCaps
|
||||
*
|
||||
* Get the reference count value of the caps.
|
||||
*/
|
||||
#define GST_CAPS_REFCOUNT_VALUE(caps) (g_atomic_int_get (&(GST_CAPS(caps))->refcount))
|
||||
#define GST_CAPS_REFCOUNT_VALUE(caps) GST_MINI_OBJECT_REFCOUNT_VALUE(caps)
|
||||
|
||||
/**
|
||||
* GST_CAPS_FLAG_IS_SET:
|
||||
* @caps: a #GstBuffer.
|
||||
* @flag: the #GstBufferFlag to check.
|
||||
*
|
||||
* Gives the status of a specific flag on a caps.
|
||||
*/
|
||||
#define GST_CAPS_FLAG_IS_SET(caps,flag) GST_MINI_OBJECT_FLAG_IS_SET (caps, flag)
|
||||
/**
|
||||
* GST_CAPS_FLAG_SET:
|
||||
* @caps: a #GstBuffer.
|
||||
* @flag: the #GstBufferFlag to set.
|
||||
*
|
||||
* Sets a caps flag on a caps.
|
||||
*/
|
||||
#define GST_CAPS_FLAG_SET(caps,flag) GST_MINI_OBJECT_FLAG_SET (caps, flag)
|
||||
/**
|
||||
* GST_CAPS_FLAG_UNSET:
|
||||
* @caps: a #GstBuffer.
|
||||
* @flag: the #GstBufferFlag to clear.
|
||||
*
|
||||
* Clears a caps flag.
|
||||
*/
|
||||
#define GST_CAPS_FLAG_UNSET(caps,flag) GST_MINI_OBJECT_FLAG_UNSET (caps, flag)
|
||||
|
||||
/**
|
||||
* GstCaps:
|
||||
|
|
|
@ -46,153 +46,66 @@ static GstAllocTrace *_gst_mini_object_trace;
|
|||
#define GST_MINI_OBJECT_GET_CLASS_UNCHECKED(obj) \
|
||||
((GstMiniObjectClass *) (((GTypeInstance*)(obj))->g_class))
|
||||
|
||||
#if 0
|
||||
static void gst_mini_object_base_init (gpointer g_class);
|
||||
static void gst_mini_object_base_finalize (gpointer g_class);
|
||||
#endif
|
||||
static void gst_mini_object_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_mini_object_init (GTypeInstance * instance, gpointer klass);
|
||||
|
||||
static void gst_value_mini_object_init (GValue * value);
|
||||
static void gst_value_mini_object_free (GValue * value);
|
||||
static void gst_value_mini_object_copy (const GValue * src_value,
|
||||
GValue * dest_value);
|
||||
static gpointer gst_value_mini_object_peek_pointer (const GValue * value);
|
||||
static gchar *gst_value_mini_object_collect (GValue * value,
|
||||
guint n_collect_values, GTypeCValue * collect_values, guint collect_flags);
|
||||
static gchar *gst_value_mini_object_lcopy (const GValue * value,
|
||||
guint n_collect_values, GTypeCValue * collect_values, guint collect_flags);
|
||||
|
||||
static GstMiniObject *gst_mini_object_copy_default (const GstMiniObject * obj);
|
||||
static void gst_mini_object_finalize (GstMiniObject * obj);
|
||||
|
||||
GType
|
||||
gst_mini_object_get_type (void)
|
||||
{
|
||||
static volatile GType _gst_mini_object_type = 0;
|
||||
|
||||
if (g_once_init_enter (&_gst_mini_object_type)) {
|
||||
GType _type;
|
||||
static const GTypeValueTable value_table = {
|
||||
gst_value_mini_object_init,
|
||||
gst_value_mini_object_free,
|
||||
gst_value_mini_object_copy,
|
||||
gst_value_mini_object_peek_pointer,
|
||||
(char *) "p",
|
||||
gst_value_mini_object_collect,
|
||||
(char *) "p",
|
||||
gst_value_mini_object_lcopy
|
||||
};
|
||||
static const GTypeInfo mini_object_info = {
|
||||
sizeof (GstMiniObjectClass),
|
||||
#if 0
|
||||
gst_mini_object_base_init,
|
||||
gst_mini_object_base_finalize,
|
||||
#else
|
||||
NULL, NULL,
|
||||
#endif
|
||||
gst_mini_object_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstMiniObject),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_mini_object_init,
|
||||
&value_table
|
||||
};
|
||||
static const GTypeFundamentalInfo mini_object_fundamental_info = {
|
||||
(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
|
||||
G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
|
||||
};
|
||||
|
||||
_type = g_type_fundamental_next ();
|
||||
g_type_register_fundamental (_type, "GstMiniObject",
|
||||
&mini_object_info, &mini_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
|
||||
|
||||
#ifndef GST_DISABLE_TRACE
|
||||
_gst_mini_object_trace = gst_alloc_trace_register (g_type_name (_type));
|
||||
#endif
|
||||
g_once_init_leave (&_gst_mini_object_type, _type);
|
||||
}
|
||||
|
||||
return _gst_mini_object_type;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
gst_mini_object_base_init (gpointer g_class)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mini_object_base_finalize (gpointer g_class)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gst_mini_object_class_init (gpointer g_class, gpointer class_data)
|
||||
{
|
||||
GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (g_class);
|
||||
|
||||
mo_class->copy = gst_mini_object_copy_default;
|
||||
mo_class->finalize = gst_mini_object_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mini_object_init (GTypeInstance * instance, gpointer klass)
|
||||
{
|
||||
GstMiniObject *mini_object = GST_MINI_OBJECT_CAST (instance);
|
||||
|
||||
mini_object->refcount = 1;
|
||||
}
|
||||
|
||||
/* boxed copy and free functions. Don't real copy or free but simply
|
||||
* change the refcount */
|
||||
static GstMiniObject *
|
||||
gst_mini_object_copy_default (const GstMiniObject * obj)
|
||||
_gst_mini_object_boxed_copy (GstMiniObject * mini_object)
|
||||
{
|
||||
g_warning ("GstMiniObject classes must implement GstMiniObject::copy");
|
||||
return NULL;
|
||||
if (mini_object)
|
||||
return gst_mini_object_ref (mini_object);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mini_object_finalize (GstMiniObject * obj)
|
||||
_gst_mini_object_boxed_free (GstMiniObject * mini_object)
|
||||
{
|
||||
/* do nothing */
|
||||
|
||||
/* WARNING: if anything is ever put in this method, make sure that the
|
||||
* following sub-classes' finalize method chains up to this one:
|
||||
* gstbuffer
|
||||
* gstevent
|
||||
* gstmessage
|
||||
* gstquery
|
||||
*/
|
||||
if (mini_object)
|
||||
gst_mini_object_unref (mini_object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_mini_object_new:
|
||||
* @type: the #GType of the mini-object to create
|
||||
* gst_mini_object_register:
|
||||
* @name: name of the new boxed type
|
||||
*
|
||||
* Creates a new mini-object of the desired type.
|
||||
* This function creates a new G_TYPE_BOXED derived type id for a new boxed type
|
||||
* with name @name. The default miniobject refcounting copy and free function
|
||||
* are used for the boxed type.
|
||||
*
|
||||
* Returns: a new G_TYPE_BOXED derived type id for @name.
|
||||
*/
|
||||
GType
|
||||
gst_mini_object_register (const gchar * name)
|
||||
{
|
||||
GType type;
|
||||
|
||||
g_return_val_if_fail (name != NULL, 0);
|
||||
|
||||
type = g_boxed_type_register_static (name,
|
||||
(GBoxedCopyFunc) _gst_mini_object_boxed_copy,
|
||||
(GBoxedFreeFunc) _gst_mini_object_boxed_free);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_mini_object_init:
|
||||
* @mini_object: a #GstMiniObject
|
||||
* @type: the #GType of the mini-object to create
|
||||
* @size: the size of the data
|
||||
*
|
||||
* Initializes a mini-object with the desired type and size.
|
||||
*
|
||||
* MT safe
|
||||
*
|
||||
* Returns: (transfer full): the new mini-object.
|
||||
*/
|
||||
GstMiniObject *
|
||||
gst_mini_object_new (GType type)
|
||||
void
|
||||
gst_mini_object_init (GstMiniObject * mini_object, GType type, gsize size)
|
||||
{
|
||||
GstMiniObject *mini_object;
|
||||
|
||||
/* we don't support dynamic types because they really aren't useful,
|
||||
* and could cause refcount problems */
|
||||
mini_object = (GstMiniObject *) g_type_create_instance (type);
|
||||
|
||||
#ifndef GST_DISABLE_TRACE
|
||||
gst_alloc_trace_new (_gst_mini_object_trace, mini_object);
|
||||
#endif
|
||||
|
||||
return mini_object;
|
||||
mini_object->type = type;
|
||||
mini_object->refcount = 1;
|
||||
mini_object->size = size;
|
||||
}
|
||||
|
||||
/* FIXME 0.11: Current way of doing the copy makes it impossible
|
||||
|
@ -222,13 +135,16 @@ gst_mini_object_new (GType type)
|
|||
GstMiniObject *
|
||||
gst_mini_object_copy (const GstMiniObject * mini_object)
|
||||
{
|
||||
GstMiniObjectClass *mo_class;
|
||||
GstMiniObject *copy;
|
||||
|
||||
g_return_val_if_fail (mini_object != NULL, NULL);
|
||||
|
||||
mo_class = GST_MINI_OBJECT_GET_CLASS (mini_object);
|
||||
if (mini_object->copy)
|
||||
copy = mo_class->copy (mini_object);
|
||||
else
|
||||
copy = NULL;
|
||||
|
||||
return mo_class->copy (mini_object);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,33 +236,6 @@ gst_mini_object_ref (GstMiniObject * mini_object)
|
|||
return mini_object;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mini_object_free (GstMiniObject * mini_object)
|
||||
{
|
||||
GstMiniObjectClass *mo_class;
|
||||
|
||||
/* At this point, the refcount of the object is 0. We increase the refcount
|
||||
* here because if a subclass recycles the object and gives out a new
|
||||
* reference we don't want to free the instance anymore. */
|
||||
GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p ref %d->%d", mini_object,
|
||||
GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
|
||||
GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) + 1);
|
||||
|
||||
g_atomic_int_inc (&mini_object->refcount);
|
||||
|
||||
mo_class = GST_MINI_OBJECT_GET_CLASS_UNCHECKED (mini_object);
|
||||
mo_class->finalize (mini_object);
|
||||
|
||||
/* decrement the refcount again, if the subclass recycled the object we don't
|
||||
* want to free the instance anymore */
|
||||
if (G_LIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
|
||||
#ifndef GST_DISABLE_TRACE
|
||||
gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
|
||||
#endif
|
||||
g_type_free_instance ((GTypeInstance *) mini_object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_mini_object_unref:
|
||||
* @mini_object: the mini-object
|
||||
|
@ -366,7 +255,23 @@ gst_mini_object_unref (GstMiniObject * mini_object)
|
|||
GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) - 1);
|
||||
|
||||
if (G_UNLIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
|
||||
gst_mini_object_free (mini_object);
|
||||
/* At this point, the refcount of the object is 0. We increase the refcount
|
||||
* here because if a subclass recycles the object and gives out a new
|
||||
* reference we don't want to free the instance anymore. */
|
||||
gst_mini_object_ref (mini_object);
|
||||
|
||||
if (mini_object->dispose)
|
||||
mini_object->dispose (mini_object);
|
||||
|
||||
/* decrement the refcount again, if the subclass recycled the object we don't
|
||||
* want to free the instance anymore */
|
||||
if (G_LIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
|
||||
#ifndef GST_DISABLE_TRACE
|
||||
gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
|
||||
#endif
|
||||
if (mini_object->free)
|
||||
mini_object->free (mini_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,247 +312,3 @@ gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
|
|||
if (olddata_val)
|
||||
gst_mini_object_unref (olddata_val);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_value_mini_object_init (GValue * value)
|
||||
{
|
||||
value->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_value_mini_object_free (GValue * value)
|
||||
{
|
||||
if (value->data[0].v_pointer) {
|
||||
gst_mini_object_unref (GST_MINI_OBJECT_CAST (value->data[0].v_pointer));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_value_mini_object_copy (const GValue * src_value, GValue * dest_value)
|
||||
{
|
||||
if (src_value->data[0].v_pointer) {
|
||||
dest_value->data[0].v_pointer =
|
||||
gst_mini_object_ref (GST_MINI_OBJECT_CAST (src_value->data[0].
|
||||
v_pointer));
|
||||
} else {
|
||||
dest_value->data[0].v_pointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_value_mini_object_peek_pointer (const GValue * value)
|
||||
{
|
||||
return value->data[0].v_pointer;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gst_value_mini_object_collect (GValue * value, guint n_collect_values,
|
||||
GTypeCValue * collect_values, guint collect_flags)
|
||||
{
|
||||
if (collect_values[0].v_pointer) {
|
||||
value->data[0].v_pointer =
|
||||
gst_mini_object_ref (collect_values[0].v_pointer);
|
||||
} else {
|
||||
value->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gst_value_mini_object_lcopy (const GValue * value, guint n_collect_values,
|
||||
GTypeCValue * collect_values, guint collect_flags)
|
||||
{
|
||||
gpointer *mini_object_p = collect_values[0].v_pointer;
|
||||
|
||||
if (!mini_object_p) {
|
||||
return g_strdup_printf ("value location for '%s' passed as NULL",
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
}
|
||||
|
||||
if (!value->data[0].v_pointer)
|
||||
*mini_object_p = NULL;
|
||||
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
|
||||
*mini_object_p = value->data[0].v_pointer;
|
||||
else
|
||||
*mini_object_p = gst_mini_object_ref (value->data[0].v_pointer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_set_mini_object:
|
||||
* @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
|
||||
* @mini_object: (transfer none): mini object value to set
|
||||
*
|
||||
* Set the contents of a %GST_TYPE_MINI_OBJECT derived #GValue to
|
||||
* @mini_object.
|
||||
* The caller retains ownership of the reference.
|
||||
*/
|
||||
void
|
||||
gst_value_set_mini_object (GValue * value, GstMiniObject * mini_object)
|
||||
{
|
||||
gpointer *pointer_p;
|
||||
|
||||
g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value));
|
||||
g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object));
|
||||
|
||||
pointer_p = &value->data[0].v_pointer;
|
||||
gst_mini_object_replace ((GstMiniObject **) pointer_p, mini_object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_take_mini_object:
|
||||
* @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
|
||||
* @mini_object: (transfer full): mini object value to take
|
||||
*
|
||||
* Set the contents of a %GST_TYPE_MINI_OBJECT derived #GValue to
|
||||
* @mini_object.
|
||||
* Takes over the ownership of the caller's reference to @mini_object;
|
||||
* the caller doesn't have to unref it any more.
|
||||
*/
|
||||
void
|
||||
gst_value_take_mini_object (GValue * value, GstMiniObject * mini_object)
|
||||
{
|
||||
gpointer *pointer_p;
|
||||
|
||||
g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value));
|
||||
g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object));
|
||||
|
||||
pointer_p = &value->data[0].v_pointer;
|
||||
/* takes additional refcount */
|
||||
gst_mini_object_replace ((GstMiniObject **) pointer_p, mini_object);
|
||||
/* remove additional refcount */
|
||||
if (mini_object)
|
||||
gst_mini_object_unref (mini_object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_get_mini_object:
|
||||
* @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
|
||||
*
|
||||
* Get the contents of a %GST_TYPE_MINI_OBJECT derived #GValue.
|
||||
* Does not increase the refcount of the returned object.
|
||||
*
|
||||
* Returns: (transfer none): mini object contents of @value
|
||||
*/
|
||||
GstMiniObject *
|
||||
gst_value_get_mini_object (const GValue * value)
|
||||
{
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value), NULL);
|
||||
|
||||
return value->data[0].v_pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_dup_mini_object:
|
||||
* @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
|
||||
*
|
||||
* Get the contents of a %GST_TYPE_MINI_OBJECT derived #GValue,
|
||||
* increasing its reference count.
|
||||
*
|
||||
* Returns: (transfer full): mini object contents of @value
|
||||
*
|
||||
* Since: 0.10.20
|
||||
*/
|
||||
GstMiniObject *
|
||||
gst_value_dup_mini_object (const GValue * value)
|
||||
{
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value), NULL);
|
||||
|
||||
return gst_mini_object_ref (value->data[0].v_pointer);
|
||||
}
|
||||
|
||||
|
||||
/* param spec */
|
||||
|
||||
static void
|
||||
param_mini_object_init (GParamSpec * pspec)
|
||||
{
|
||||
/* GParamSpecMiniObject *ospec = G_PARAM_SPEC_MINI_OBJECT (pspec); */
|
||||
}
|
||||
|
||||
static void
|
||||
param_mini_object_set_default (GParamSpec * pspec, GValue * value)
|
||||
{
|
||||
value->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
param_mini_object_validate (GParamSpec * pspec, GValue * value)
|
||||
{
|
||||
GstMiniObject *mini_object = value->data[0].v_pointer;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
if (mini_object
|
||||
&& !g_value_type_compatible (G_OBJECT_TYPE (mini_object),
|
||||
pspec->value_type)) {
|
||||
gst_mini_object_unref (mini_object);
|
||||
value->data[0].v_pointer = NULL;
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static gint
|
||||
param_mini_object_values_cmp (GParamSpec * pspec,
|
||||
const GValue * value1, const GValue * value2)
|
||||
{
|
||||
guint8 *p1 = value1->data[0].v_pointer;
|
||||
guint8 *p2 = value2->data[0].v_pointer;
|
||||
|
||||
/* not much to compare here, try to at least provide stable lesser/greater result */
|
||||
|
||||
return p1 < p2 ? -1 : p1 > p2;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_param_spec_mini_object_get_type (void)
|
||||
{
|
||||
static GType type;
|
||||
|
||||
if (G_UNLIKELY (type) == 0) {
|
||||
static const GParamSpecTypeInfo pspec_info = {
|
||||
sizeof (GstParamSpecMiniObject), /* instance_size */
|
||||
16, /* n_preallocs */
|
||||
param_mini_object_init, /* instance_init */
|
||||
G_TYPE_OBJECT, /* value_type */
|
||||
NULL, /* finalize */
|
||||
param_mini_object_set_default, /* value_set_default */
|
||||
param_mini_object_validate, /* value_validate */
|
||||
param_mini_object_values_cmp, /* values_cmp */
|
||||
};
|
||||
/* FIXME 0.11: Should really be GstParamSpecMiniObject */
|
||||
type = g_param_type_register_static ("GParamSpecMiniObject", &pspec_info);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_param_spec_mini_object:
|
||||
* @name: the canonical name of the property
|
||||
* @nick: the nickname of the property
|
||||
* @blurb: a short description of the property
|
||||
* @object_type: the #GstMiniObject #GType for the property
|
||||
* @flags: a combination of #GParamFlags
|
||||
*
|
||||
* Creates a new #GParamSpec instance that hold #GstMiniObject references.
|
||||
*
|
||||
* Returns: (transfer full): a newly allocated #GParamSpec instance
|
||||
*/
|
||||
GParamSpec *
|
||||
gst_param_spec_mini_object (const char *name, const char *nick,
|
||||
const char *blurb, GType object_type, GParamFlags flags)
|
||||
{
|
||||
GstParamSpecMiniObject *ospec;
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (object_type, GST_TYPE_MINI_OBJECT), NULL);
|
||||
|
||||
ospec = g_param_spec_internal (GST_TYPE_PARAM_MINI_OBJECT,
|
||||
name, nick, blurb, flags);
|
||||
G_PARAM_SPEC (ospec)->value_type = object_type;
|
||||
|
||||
return G_PARAM_SPEC (ospec);
|
||||
}
|
||||
|
|
|
@ -38,20 +38,28 @@ typedef struct _GstMiniObject GstMiniObject;
|
|||
* GstMiniObjectCopyFunction:
|
||||
* @obj: MiniObject to copy
|
||||
*
|
||||
* Virtual function prototype for methods to create copies of instances.
|
||||
* Function prototype for methods to create copies of instances.
|
||||
*
|
||||
* Returns: reference to cloned instance.
|
||||
*/
|
||||
typedef GstMiniObject * (*GstMiniObjectCopyFunction) (const GstMiniObject *obj);
|
||||
/**
|
||||
* GstMiniObjectDisposeFunction:
|
||||
* @obj: MiniObject to dispose
|
||||
*
|
||||
* Function prototype for when a miniobject has lost its last refcount.
|
||||
* Implementation of the mini object are allowed to revive the
|
||||
* passed object by doing a gst_mini_object_ref(). If the object is not
|
||||
* revived after the dispose function, the memory associated with the
|
||||
* object is freed.
|
||||
*/
|
||||
typedef void (*GstMiniObjectDisposeFunction) (GstMiniObject *obj);
|
||||
/**
|
||||
* GstMiniObjectFreeFunction:
|
||||
* @obj: MiniObject to free
|
||||
*
|
||||
* Virtual function prototype for methods to free ressources used by
|
||||
* mini-objects. Subclasses of the mini object are allowed to revive the
|
||||
* passed object by doing a gst_mini_object_ref(). If the object is not
|
||||
* revived after the free function, the memory associated with the
|
||||
* object is freed.
|
||||
* mini-objects.
|
||||
*/
|
||||
typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
|
||||
|
||||
|
@ -131,6 +139,9 @@ typedef enum
|
|||
* @instance: type instance
|
||||
* @refcount: atomic refcount
|
||||
* @flags: extra flags.
|
||||
* @copy: a copy function
|
||||
* @dispose: a dispose function
|
||||
* @free: the free function
|
||||
*
|
||||
* Base class for refcounted lightweight objects.
|
||||
* Ref Func: gst_mini_object_ref
|
||||
|
@ -144,12 +155,17 @@ struct _GstMiniObject {
|
|||
/*< public >*/ /* with COW */
|
||||
gint refcount;
|
||||
guint flags;
|
||||
gsize size;
|
||||
|
||||
GstMiniObjectCopyFunction copy;
|
||||
GstMiniObjectDisposeFunction dispose;
|
||||
GstMiniObjectFreeFunction free;
|
||||
};
|
||||
|
||||
GType gst_mini_object_get_type (void);
|
||||
GType gst_mini_object_register (const gchar *name);
|
||||
|
||||
void gst_mini_object_init (GstMiniObject *mini_object,
|
||||
GType type, gsize size);
|
||||
|
||||
GstMiniObject* gst_mini_object_copy (const GstMiniObject *mini_object);
|
||||
gboolean gst_mini_object_is_writable (const GstMiniObject *mini_object);
|
||||
|
|
Loading…
Reference in a new issue