Commit fda9686b authored by Wim Taymans's avatar Wim Taymans

miniobject: work on making caps a boxed type

More work on making miniobject a simple allocated struct.
parent 086aac76
......@@ -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);
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
buffer->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_copy;
buffer->mini_object.free = (GstMiniObjectFreeeFunction) gst_buffer_finalize;
/* free our data */
if (G_LIKELY (buffer->malloc_data))
buffer->free_func (buffer->malloc_data);
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;
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;
/**
......
......@@ -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)
/* boxed copy and free functions. Don't real copy or free but simply
* change the refcount */
static GstMiniObject *
_gst_mini_object_boxed_copy (GstMiniObject * mini_object)
{
/* do nothing */
if (mini_object)
return gst_mini_object_ref (mini_object);
else
return NULL;
}
#endif
static void
gst_mini_object_class_init (gpointer g_class, gpointer class_data)
_gst_mini_object_boxed_free (GstMiniObject * mini_object)
{
GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (g_class);
mo_class->copy = gst_mini_object_copy_default;
mo_class->finalize = gst_mini_object_finalize;
if (mini_object)
gst_mini_object_unref (mini_object);
}
static void
gst_mini_object_init (GTypeInstance * instance, gpointer klass)
/**
* gst_mini_object_register:
* @name: name of the new boxed 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)
{
GstMiniObject *mini_object = GST_MINI_OBJECT_CAST (instance);
GType type;
mini_object->refcount = 1;
}
g_return_val_if_fail (name != NULL, 0);
static GstMiniObject *
gst_mini_object_copy_default (const GstMiniObject * obj)
{
g_warning ("GstMiniObject classes must implement GstMiniObject::copy");
return NULL;
}
type = g_boxed_type_register_static (name,
(GBoxedCopyFunc) _gst_mini_object_boxed_copy,
(GBoxedFreeFunc) _gst_mini_object_boxed_free);
static void
gst_mini_object_finalize (GstMiniObject * obj)
{
/* 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
*/
return type;
}
/**
* gst_mini_object_new:
* gst_mini_object_init:
* @mini_object: a #GstMiniObject
* @type: the #GType of the mini-object to create
* @size: the size of the data
*
* Creates a new mini-object of the desired type.
* 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;
}