GType _gst_buffer_type = 0;
-typedef struct _GstMetaItem GstMetaItem;
-
-struct _GstMetaItem
-{
- GstMetaItem *next;
- GstMeta meta;
-};
-
/* info->size will be sizeof(FooMeta) which contains a GstMeta at the beginning
* too, and then there is again a GstMeta in GstMetaItem, so subtract one. */
#define ITEM_SIZE(info) ((info)->size + sizeof (GstMetaItem) - sizeof (GstMeta))
#define GST_BUFFER_MEM_PTR(b,i) (((GstBufferImpl *)(b))->mem[i])
#define GST_BUFFER_BUFMEM(b) (((GstBufferImpl *)(b))->bufmem)
#define GST_BUFFER_META(b) (((GstBufferImpl *)(b))->item)
+#define GST_BUFFER_TAIL_META(b) (((GstBufferImpl *)(b))->tail_item)
typedef struct
{
/* FIXME, make metadata allocation more efficient by using part of the
* GstBufferImpl */
GstMetaItem *item;
+ GstMetaItem *tail_item;
} GstBufferImpl;
+static gint64 meta_seq; /* 0 *//* ATOMIC */
+
+/* TODO: use GLib's once https://gitlab.gnome.org/GNOME/glib/issues/1076 lands */
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+static inline gint64
+gst_atomic_int64_inc (volatile gint64 * atomic)
+{
+ return __sync_fetch_and_add (atomic, 1);
+}
+#elif defined (G_PLATFORM_WIN32)
+#include <windows.h>
+static inline gint64
+gst_atomic_int64_inc (volatile gint64 * atomic)
+{
+ return InterlockedExchangeAdd64 (atomic, 1);
+}
+#else
+#warning No 64-bit atomic int defined for this platform/toolchain!
+#define NO_64BIT_ATOMIC_INT_FOR_PLATFORM
+G_LOCK_DEFINE_STATIC (meta_seq);
+static inline gint64
+gst_atomic_int64_inc (volatile gint64 * atomic)
+{
+ gint64 ret;
+
+ G_LOCK (meta_seq);
+ ret = *atomic++;
+ G_UNLOCK (meta_seq);
+
+ return ret;
+}
+#endif
static gboolean
_is_span (GstMemory ** mem, gsize len, gsize * poffset, GstMemory ** parent)
_priv_gst_buffer_initialize (void)
{
_gst_buffer_type = gst_buffer_get_type ();
+
+#ifdef NO_64BIT_ATOMIC_INT_FOR_PLATFORM
+ GST_CAT_WARNING (GST_CAT_PERFORMANCE,
+ "No 64-bit atomic int defined for this platform/toolchain!");
+#endif
}
/**
if (!info->init_func (result, params, buffer))
goto init_failed;
- /* and add to the list of metadata */
- item->next = GST_BUFFER_META (buffer);
- GST_BUFFER_META (buffer) = item;
+ item->seq_num = gst_atomic_int64_inc (&meta_seq);
+ item->next = NULL;
+
+ if (!GST_BUFFER_META (buffer)) {
+ GST_BUFFER_META (buffer) = item;
+ GST_BUFFER_TAIL_META (buffer) = item;
+ } else {
+ GST_BUFFER_TAIL_META (buffer)->next = item;
+ GST_BUFFER_TAIL_META (buffer) = item;
+ }
return result;
const GstMetaInfo *info = meta->info;
/* remove from list */
+ if (GST_BUFFER_TAIL_META (buffer) == walk) {
+ if (prev != walk)
+ GST_BUFFER_TAIL_META (buffer) = prev;
+ else
+ GST_BUFFER_TAIL_META (buffer) = NULL;
+ }
+
if (GST_BUFFER_META (buffer) == walk)
GST_BUFFER_META (buffer) = walk->next;
else
prev->next = walk->next;
+
/* call free_func if any */
if (info->free_func)
info->free_func (m, buffer);
g_return_val_if_fail (!GST_META_FLAG_IS_SET (m, GST_META_FLAG_LOCKED),
FALSE);
+ if (GST_BUFFER_TAIL_META (buffer) == walk) {
+ if (prev != walk)
+ GST_BUFFER_TAIL_META (buffer) = prev;
+ else
+ GST_BUFFER_TAIL_META (buffer) = NULL;
+ }
+
/* remove from list */
if (GST_BUFFER_META (buffer) == walk)
- GST_BUFFER_META (buffer) = next;
+ prev = GST_BUFFER_META (buffer) = next;
else
prev->next = next;
- prev = next;
-
/* call free_func if any */
if (info->free_func)
info->free_func (m, buffer);