memory: add memory implementation
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 18 Mar 2011 18:28:17 +0000 (19:28 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 28 Mar 2011 18:08:45 +0000 (20:08 +0200)
gst/Makefile.am
gst/gst.h
gst/gstmemory.c [new file with mode: 0644]
gst/gstmemory.h

index 059f7cb..6337565 100644 (file)
@@ -73,6 +73,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
        gstatomicqueue.c        \
        gstmessage.c            \
        gstmeta.c               \
+       gstmemory.c             \
        gstminiobject.c         \
        gstpad.c                \
        gstpadtemplate.c        \
@@ -168,6 +169,7 @@ gst_headers =                       \
        gstmacros.h             \
        gstmessage.h            \
        gstmeta.h               \
+       gstmemory.h             \
        gstminiobject.h         \
        gstpad.h                \
        gstpadtemplate.h        \
index 9870f55..954fd6c 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -52,6 +52,7 @@
 #include <gst/gstiterator.h>
 #include <gst/gstmarshal.h>
 #include <gst/gstmessage.h>
+#include <gst/gstmemory.h>
 #include <gst/gstminiobject.h>
 #include <gst/gstobject.h>
 #include <gst/gstpad.h>
diff --git a/gst/gstmemory.c b/gst/gstmemory.c
new file mode 100644 (file)
index 0000000..10b6d75
--- /dev/null
@@ -0,0 +1,249 @@
+/* GStreamer
+ * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.be>
+ *
+ * gstmemory.c: memory block handling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gst_private.h"
+
+#include "gstmemory.h"
+
+struct _GstMemoryImpl
+{
+  GQuark name;
+
+  GstMemoryInfo info;
+};
+
+typedef struct
+{
+  GstMemory mem;
+
+  guint8 *data;
+  GFreeFunc free_func;
+  gsize maxsize;
+  gsize offset;
+  gsize size;
+} GstMemoryDefault;
+
+static const GstMemoryImpl *_default_memory_impl;
+
+static gsize
+_default_get_sizes (GstMemory * mem, gsize * maxsize)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+
+  if (maxsize)
+    *maxsize = def->maxsize;
+
+  return def->size;
+}
+
+static void
+_default_set_size (GstMemory * mem, gsize size)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+
+  g_return_if_fail (def->size + def->offset > def->maxsize);
+
+  def->size = size;
+}
+
+static gpointer
+_default_map (GstMemory * mem, gsize * size, gsize * maxsize, GstMapFlags flags)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+
+  if (size)
+    *size = def->size;
+  if (maxsize)
+    *maxsize = def->maxsize;
+
+  return def->data + def->offset;
+}
+
+static gboolean
+_default_unmap (GstMemory * mem, gpointer data, gsize size)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+
+  def->size = size;
+
+  return TRUE;
+}
+
+static void
+_default_free (GstMemory * mem)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+
+  if (def->free_func)
+    def->free_func (def->data);
+}
+
+static GstMemory *
+_default_copy (GstMemory * mem)
+{
+  GstMemoryDefault *def = (GstMemoryDefault *) mem;
+  GstMemoryDefault *copy;
+
+  copy = g_slice_new (GstMemoryDefault);
+  copy->mem.impl = _default_memory_impl;
+  copy->data = g_memdup (def->data, def->maxsize);
+  copy->free_func = g_free;
+  copy->maxsize = def->maxsize;
+  copy->offset = def->offset;
+  copy->size = def->size;
+
+  return (GstMemory *) copy;
+}
+
+const GstMemoryImpl *
+gst_memory_register (const gchar * name, const GstMemoryInfo * info)
+{
+  GstMemoryImpl *impl;
+
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (info != NULL, NULL);
+
+  impl = g_slice_new (GstMemoryImpl);
+  impl->name = g_quark_from_string (name);
+  impl->info = *info;
+
+  GST_DEBUG ("register \"%s\" of size %" G_GSIZE_FORMAT, name);
+
+#if 0
+  g_static_rw_lock_writer_lock (&lock);
+  g_hash_table_insert (memoryimpl, (gpointer) name, (gpointer) impl);
+  g_static_rw_lock_writer_unlock (&lock);
+#endif
+
+  return impl;
+}
+
+void
+_gst_memory_init (void)
+{
+  static const GstMemoryInfo info = {
+    _default_get_sizes,
+    _default_set_size,
+    _default_map,
+    _default_unmap,
+    _default_free,
+    _default_copy
+  };
+  _default_memory_impl = gst_memory_register ("GstMemoryDefault", &info);
+}
+
+GstMemory *
+gst_memory_ref (GstMemory * mem)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  g_atomic_int_inc (&mem->refcount);
+
+  return mem;
+}
+
+void
+gst_memory_unref (GstMemory * mem)
+{
+  g_return_if_fail (mem != NULL);
+
+  if (g_atomic_int_dec_and_test (&mem->refcount))
+    mem->impl->info.free (mem);
+}
+
+gsize
+gst_memory_get_sizes (GstMemory * mem, gsize * maxsize)
+{
+  g_return_val_if_fail (mem != NULL, 0);
+
+  return mem->impl->info.get_sizes (mem, maxsize);
+}
+
+void
+gst_memory_set_size (GstMemory * mem, gsize size)
+{
+  g_return_if_fail (mem != NULL);
+
+  mem->impl->info.set_size (mem, size);
+}
+
+gpointer
+gst_memory_map (GstMemory * mem, gsize * size, gsize * maxsize,
+    GstMapFlags flags)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  return mem->impl->info.map (mem, size, maxsize, flags);
+}
+
+gboolean
+gst_memory_unmap (GstMemory * mem, gpointer data, gsize size)
+{
+  g_return_val_if_fail (mem != NULL, FALSE);
+
+  return mem->impl->info.unmap (mem, data, size);
+}
+
+GstMemory *
+gst_memory_copy (GstMemory * mem)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  return mem->impl->info.copy (mem);
+}
+
+GstMemory *
+gst_memory_new_wrapped (gpointer data, GFreeFunc free_func,
+    gsize maxsize, gsize offset, gsize size)
+{
+  GstMemoryDefault *mem;
+
+  mem = g_slice_new (GstMemoryDefault);
+  mem->mem.impl = _default_memory_impl;
+  mem->data = data;
+  mem->free_func = free_func;
+  mem->maxsize = maxsize;
+  mem->offset = offset;
+  mem->size = size;
+
+  return (GstMemory *) mem;
+}
+
+GstMemory *
+gst_memory_new_alloc (gsize maxsize, gsize align)
+{
+  GstMemory *mem;
+  gpointer data;
+  gsize offset;
+
+  data = g_try_malloc (maxsize + align);
+  if (data == NULL)
+    return NULL;
+
+  if ((offset = ((guintptr) data & align)))
+    offset = align - offset;
+
+  mem = gst_memory_new_wrapped (data, g_free, maxsize + align, offset, maxsize);
+
+  return mem;
+}
index 97ee524..ecd54ed 100644 (file)
 #ifndef __GST_MEMORY_H__
 #define __GST_MEMORY_H__
 
+#include <gst/gst.h>
+
 G_BEGIN_DECLS
 
 typedef struct _GstMemory GstMemory;
 typedef struct _GstMemoryInfo GstMemoryInfo;
+typedef struct _GstMemoryImpl GstMemoryImpl;
 
 /**
  * GstMemory:
@@ -36,11 +39,16 @@ typedef struct _GstMemoryInfo GstMemoryInfo;
  * as the first member of their structure.
  */
 struct _GstMemory {
-  const GstMemoryInfo *info;
+  const GstMemoryImpl *impl;
 
   gint refcount;
 };
 
+typedef enum {
+  GST_MAP_READ,
+  GST_MAP_WRITE,
+} GstMapFlags;
+
 /**
  * GST_MEMORY_TRACE_NAME:
  *
@@ -51,10 +59,11 @@ struct _GstMemory {
 typedef gsize (*GstMemoryGetSizesFunction)  (GstMemory *mem, gsize *maxsize);
 
 typedef void  (*GstMemorySetSizeFunction)   (GstMemory *mem, gsize size);
-typedef gpointer (*GstMemoryMapFunction)    (GstMemory *mem, gsize offset, gsize *size,
+typedef gpointer (*GstMemoryMapFunction)    (GstMemory *mem, gsize *size, gsize *maxsize,
                                              GstMapFlags flags);
 typedef gboolean (*GstMemoryUnmapFunction)  (GstMemory *mem, gpointer data, gsize size);
 
+typedef void        (*GstMemoryFreeFunction)  (GstMemory *mem);
 typedef GstMemory * (*GstMemoryCopyFunction)  (GstMemory *mem);
 
 /**
@@ -66,13 +75,11 @@ typedef GstMemory * (*GstMemoryCopyFunction)  (GstMemory *mem);
  * structure.
  */
 struct _GstMemoryInfo {
-  GQuark                    impl;
-  gsize                     size;
-
   GstMemoryGetSizesFunction get_sizes;
   GstMemorySetSizeFunction  set_size;
   GstMemoryMapFunction      map;
   GstMemoryUnmapFunction    unmap;
+  GstMemoryFreeFunction     free;
   GstMemoryCopyFunction     copy;
 };
 
@@ -96,12 +103,9 @@ GstMemory * gst_memory_new_wrapped (gpointer data, GFreeFunc free_func,
 GstMemory * gst_memory_new_alloc   (gsize maxsize, gsize align);
 
 
+const GstMemoryImpl *  gst_memory_register    (const gchar *impl, const GstMemoryInfo *info);
+
 #if 0
-const GstMemoryInfo *  gst_memory_register    (const gchar *impl, gsize size,
-                                               GstMemoryGetSizesFunction get_sizes,
-                                               GstMemorySetSizeFunction  set_size,
-                                               GstMemoryMapFunction      map,
-                                               GstMemoryUnmapFunction    unmap);
 const GstMemoryInfo *  gst_memory_get_info    (const gchar * impl);
 #endif