add default bufferpool, clean up some code, add bufferpool testing to fakesrc
authorAndy Wingo <wingo@pobox.com>
Wed, 24 Jul 2002 18:31:12 +0000 (18:31 +0000)
committerAndy Wingo <wingo@pobox.com>
Wed, 24 Jul 2002 18:31:12 +0000 (18:31 +0000)
Original commit message from CVS:
add default bufferpool, clean up some code, add bufferpool testing to fakesrc

gst/Makefile.am
gst/elements/gstfakesrc.c
gst/elements/gstfakesrc.h
gst/gstbuffer.c
gst/gstbuffer.h
gst/gstbufferpool-default.c [new file with mode: 0644]
plugins/elements/gstfakesrc.c
plugins/elements/gstfakesrc.h

index 8573a52..1f3003c 100644 (file)
@@ -55,6 +55,7 @@ libgstreamer_la_SOURCES =             \
        $(GST_AUTOPLUG_SRC)     \
        gstbin.c                \
        gstbuffer.c             \
+       gstbufferpool-default.c \
        gstcaps.c               \
        gstclock.c              \
        gstcpu.c                \
@@ -165,10 +166,11 @@ libgstreamerinclude_HEADERS =             \
        gstversion.h            \
        gstxml.h
 
-noinst_HEADERS =       \
-       gst_private.h   \
-       gstarch.h       \
-       cothreads.h
+noinst_HEADERS =               \
+       gst_private.h           \
+       gstarch.h               \
+       cothreads.h             \
+       gstbufferpool-default.h
 
 libgstreamer_la_CFLAGS = -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" \
        $(LIBGST_CFLAGS) \
index 2e11d61..0e5bb7d 100644 (file)
@@ -99,8 +99,9 @@ gst_fakesrc_data_get_type (void)
 {
   static GType fakesrc_data_type = 0;
   static GEnumValue fakesrc_data[] = {
-    { FAKESRC_DATA_ALLOCATE,           "2", "Allocate data"},
-    { FAKESRC_DATA_SUBBUFFER,          "3", "Subbuffer data"},
+    { FAKESRC_DATA_ALLOCATE,           "1", "Allocate data"},
+    { FAKESRC_DATA_SUBBUFFER,          "2", "Subbuffer data"},
+    { FAKESRC_DATA_BUFFERPOOL,                 "3", "Use the default buffer pool (forces sizetype=2)"},
     {0, NULL, NULL},
   };
   if (!fakesrc_data_type) {
@@ -197,43 +198,43 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
-    g_param_spec_int ("num_sources", "num_sources", "num_sources",
+    g_param_spec_int ("num-sources", "num-sources", "Number of sources",
                       1, G_MAXINT, 1, G_PARAM_READABLE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOOP_BASED,
-    g_param_spec_boolean("loop_based","loop_based","loop_based",
-                         FALSE, G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_boolean("loop-based","loop-based","Enable loop-based operation",
+                         FALSE, G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OUTPUT,
-    g_param_spec_enum("output","output","output",
-                      GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE)); /* CHECKME! */
+    g_param_spec_enum("output","output","Output method (currently unused)",
+                      GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
-    g_param_spec_enum ("data", "data", "data",
+    g_param_spec_enum ("data", "data", "Data allocation method",
                        GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
-    g_param_spec_enum ("sizetype", "sizetype", "sizetype",
+    g_param_spec_enum ("sizetype", "sizetype", "How to determine buffer sizes",
                        GST_TYPE_FAKESRC_SIZETYPE, FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
-    g_param_spec_int ("sizemin","sizemin","sizemin",
+    g_param_spec_int ("sizemin","sizemin","Minimum buffer size",
                       0, G_MAXINT, 0, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
-    g_param_spec_int ("sizemax","sizemax","sizemax",
+    g_param_spec_int ("sizemax","sizemax","Maximum buffer size",
                       0, G_MAXINT, 4096, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
-    g_param_spec_int ("parentsize","parentsize","parentsize",
+    g_param_spec_int ("parentsize","parentsize","Size of parent buffer for sub-buffered allocation",
                       0, G_MAXINT, 4096 * 10, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
-    g_param_spec_enum ("filltype", "filltype", "filltype",
+    g_param_spec_enum ("filltype", "filltype", "How to fill the buffer, if at all",
                        GST_TYPE_FAKESRC_FILLTYPE, FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PATTERN,
     g_param_spec_string("pattern","pattern","pattern",
-                        NULL, G_PARAM_READWRITE)); /* CHECKME */
+                        NULL, G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUM_BUFFERS,
-    g_param_spec_int("num_buffers","num_buffers","num_buffers",
-                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_int("num-buffers","num-buffers","Number of buffers to output before sending EOS",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_EOS,
-    g_param_spec_boolean("eos","eos","eos",
-                         TRUE,G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_boolean("eos","eos","Send out the EOS event?",
+                         TRUE,G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
-    g_param_spec_string ("last_message", "last_message", "last_message",
+    g_param_spec_string ("last-message", "last-message", "The last status message",
                          NULL, G_PARAM_READABLE)); 
 
   gst_element_class_install_std_props (
@@ -396,18 +397,28 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       break;
     case ARG_DATA:
       src->data = g_value_get_enum (value);
-      switch (src->data) {
-       case FAKESRC_DATA_ALLOCATE:
-          if (src->parent) {
-            gst_buffer_unref (src->parent);
-            src->parent = NULL;
-         }
-          break;
-       case FAKESRC_DATA_SUBBUFFER:
-         if (!src->parent)
-           gst_fakesrc_alloc_parent (src);
-       default:
-          break;
+
+      if (src->data == FAKESRC_DATA_SUBBUFFER) {
+        if (!src->parent)
+          gst_fakesrc_alloc_parent (src);
+      } else {
+        if (src->parent) {
+          gst_buffer_unref (src->parent);
+          src->parent = NULL;
+        }
+      }
+      
+      if (src->data == FAKESRC_DATA_BUFFERPOOL) {
+        if (src->sizetype != FAKESRC_SIZETYPE_FIXED)
+          g_object_set (src, "sizetype", FAKESRC_SIZETYPE_FIXED, NULL);
+        
+        if (!src->pool)
+          src->pool = gst_buffer_pool_get_default (src->sizemax, 10);
+      } else {
+        if (src->pool) {
+          gst_buffer_pool_free (src->pool);
+          src->pool = NULL;
+        }
       }
       break;
     case ARG_SIZETYPE:
@@ -630,6 +641,10 @@ gst_fakesrc_create_buffer (GstFakeSrc *src)
       }
       gst_fakesrc_prepare_buffer (src, buf);
       break;
+    case FAKESRC_DATA_BUFFERPOOL:
+      buf = gst_buffer_new_from_pool (src->pool, 0, 0);
+      gst_fakesrc_prepare_buffer (src, buf);
+      break;
     default:
       g_warning ("fakesrc: dunno how to allocate buffers !");
       buf = gst_buffer_new();
@@ -768,15 +783,20 @@ gst_fakesrc_change_state (GstElement *element)
       fakesrc->need_flush = FALSE;
       fakesrc->eos = FALSE;
       fakesrc->rt_num_buffers = fakesrc->num_buffers;
-      if (fakesrc->parent) {
-        gst_buffer_unref (fakesrc->parent);
-        fakesrc->parent = NULL;
-      }
       break;
     case GST_STATE_READY_TO_PAUSED:
     case GST_STATE_PAUSED_TO_PLAYING:
     case GST_STATE_PLAYING_TO_PAUSED:
+      break;
     case GST_STATE_READY_TO_NULL:
+      if (fakesrc->parent) {
+        gst_buffer_unref (fakesrc->parent);
+        fakesrc->parent = NULL;
+      }
+      if (fakesrc->pool) {
+        gst_buffer_pool_unref (fakesrc->pool);
+        fakesrc->pool = NULL;
+      }
       break;
     default:
       g_assert_not_reached ();
index f4a0e67..0038589 100644 (file)
@@ -44,12 +44,13 @@ typedef enum {
   FAKESRC_RANDOM,
   FAKESRC_PATTERN_LOOP,
   FAKESRC_PING_PONG_PATTERN,
-  FAKESRC_GET_ALWAYS_SUCEEDS,
+  FAKESRC_GET_ALWAYS_SUCEEDS
 } GstFakeSrcOutputType;
 
 typedef enum {
   FAKESRC_DATA_ALLOCATE = 1,
   FAKESRC_DATA_SUBBUFFER,
+  FAKESRC_DATA_BUFFERPOOL
 } GstFakeSrcDataType;
 
 typedef enum {
@@ -105,6 +106,7 @@ struct _GstFakeSrc {
   gboolean     silent;
   gboolean     dump;
   gboolean     need_flush;
+  GstBufferPool *pool;
 
   gchar                *last_message;
 };
index 44fe236..9963186 100644 (file)
@@ -28,6 +28,7 @@
 #include "gstbuffer.h"
 #include "gstmemchunk.h"
 #include "gstlog.h"
+#include "gstbufferpool-default.h"
 
 GType _gst_buffer_type;
 GType _gst_buffer_pool_type;
@@ -74,7 +75,7 @@ _gst_buffer_free_to_pool (GstBuffer *buffer)
 {
   GstBufferPool *pool = buffer->pool;
 
-  buffer->pool->buffer_free (buffer->pool, buffer, buffer->pool->user_data);
+  pool->buffer_free (pool, buffer, pool->user_data);
 
   gst_data_unref (GST_DATA (pool));
 }
@@ -97,7 +98,7 @@ _gst_buffer_sub_free (GstBuffer *buffer)
  * gst_buffer_default_free:
  * @buffer: a #GstBuffer to free
  *
- * Free the momory associated with the buffer including the buffer data,
+ * Free the memory associated with the buffer including the buffer data,
  * unless the GST_BUFFER_DONTFREE flags was set or the buffer data is NULL.
  * This function is used by bufferpools.
  */
@@ -118,6 +119,12 @@ gst_buffer_default_free (GstBuffer *buffer)
   _gst_buffer_live--;
 }
 
+static GstBuffer*
+_gst_buffer_copy_from_pool (GstBuffer *buffer)
+{
+  return buffer->pool->buffer_copy (buffer->pool, buffer, buffer->pool->user_data);
+}
+
 /**
  * gst_buffer_default_copy:
  * @buffer: a #GstBuffer to make a copy of
@@ -145,13 +152,6 @@ gst_buffer_default_copy (GstBuffer *buffer)
   return copy;
 }
 
-static GstBuffer*
-_gst_buffer_copy_to_pool (GstBuffer *buffer)
-{
-  return buffer->pool->buffer_copy (buffer->pool, buffer, buffer->pool->user_data);
-}
-
-
 /**
  * gst_buffer_new:
  *
@@ -215,6 +215,8 @@ gst_buffer_new_from_pool (GstBufferPool *pool, guint64 offset, guint size)
 {
   GstBuffer *buffer;
   
+  g_return_val_if_fail (pool != NULL, NULL);
+
   buffer = pool->buffer_new (pool, offset, size, pool->user_data);
   if (!buffer)
     return NULL;
@@ -224,9 +226,9 @@ gst_buffer_new_from_pool (GstBufferPool *pool, guint64 offset, guint size)
 
   /* override the buffer refcount functions with those from the pool (if any) */
   if (pool->buffer_free)
-    GST_DATA (buffer)->free = (GstDataFreeFunction) _gst_buffer_free_to_pool;
+    GST_DATA (buffer)->free = (GstDataFreeFunction)_gst_buffer_free_to_pool;
   if (pool->buffer_copy)
-    GST_DATA (buffer)->copy = (GstDataCopyFunction) _gst_buffer_copy_to_pool;
+    GST_DATA (buffer)->copy = (GstDataCopyFunction)_gst_buffer_copy_from_pool;
 
   return buffer;
 }
@@ -393,8 +395,8 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
   return newbuf;
 }
 
-static void
-_gst_buffer_pool_free (GstBufferPool *pool)
+void
+gst_buffer_pool_default_free (GstBufferPool *pool)
 {
   _GST_DATA_DISPOSE (GST_DATA (pool));
   g_free (pool);
@@ -429,13 +431,14 @@ gst_buffer_pool_new (GstDataFreeFunction free,
 
   pool = g_new0 (GstBufferPool, 1);
   _gst_buffer_pool_live++;
-  GST_DEBUG (GST_CAT_BUFFER,"allocating new buffer pool %p\n", pool);
+
+  GST_DEBUG (GST_CAT_BUFFER, "allocating new buffer pool %p\n", pool);
         
   /* init data struct */
   _GST_DATA_INIT (GST_DATA (pool), 
                  _gst_buffer_pool_type,
                  0,
-                 (free ? free : (GstDataFreeFunction) _gst_buffer_pool_free),
+                 (free ? free : (GstDataFreeFunction) gst_buffer_pool_default_free),
                  copy);
            
   /* set functions */
@@ -511,9 +514,8 @@ gst_buffer_pool_get_user_data (GstBufferPool *pool)
  * 
  * Returns: A new bufferpool to create buffers of the given size.
  */
-/* FIXME */
 GstBufferPool* 
 gst_buffer_pool_get_default (guint size, guint numbuffers)
 {
-  return NULL;
+  return _gst_buffer_pool_get_default (size, numbuffers);
 }
index 21448be..582cfa9 100644 (file)
@@ -110,7 +110,7 @@ struct _GstBufferPool {
 /*< private >*/
 void           _gst_buffer_initialize          (void);
 
-/* function used by subclasses and bufferpools */
+/* functions used by subclasses and bufferpools */
 void           gst_buffer_default_free         (GstBuffer *buffer);
 GstBuffer*     gst_buffer_default_copy         (GstBuffer *buffer);
 
@@ -149,6 +149,9 @@ GstBufferPool*      gst_buffer_pool_new                     (GstDataFreeFunction free,
                                                         GstBufferPoolBufferFreeFunction buffer_free,
                                                         gpointer user_data);
 
+/* function used by subclasses and bufferpools */
+void           gst_buffer_pool_default_free            (GstBufferPool *pool);
+
 gboolean       gst_buffer_pool_is_active               (GstBufferPool *pool);
 void           gst_buffer_pool_set_active              (GstBufferPool *pool, gboolean active);
 
@@ -164,7 +167,7 @@ void                gst_buffer_pool_set_active              (GstBufferPool *pool, gboolean active);
 void           gst_buffer_pool_set_user_data           (GstBufferPool *pool, gpointer user_data);
 gpointer       gst_buffer_pool_get_user_data           (GstBufferPool *pool);
 
-/* implement me */
+/* a default pool */
 GstBufferPool* gst_buffer_pool_get_default             (guint size, guint numbuffers);
 
 G_END_DECLS
diff --git a/gst/gstbufferpool-default.c b/gst/gstbufferpool-default.c
new file mode 100644 (file)
index 0000000..f112709
--- /dev/null
@@ -0,0 +1,165 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbufferpool-default.c: Private implementation of the default bufferpool
+ *
+ * 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 "gstbuffer.h"
+#include "gstinfo.h"
+#include "gstmemchunk.h"
+
+
+/* methods prefixed with underscores to avoid namespace collisions with
+ * gstbuffer.c */
+
+static GstBuffer*      _gst_buffer_pool_default_buffer_new     (GstBufferPool *pool,
+                                                                 guint64 offset,
+                                                                 guint size,
+                                                                 gpointer user_data);
+static void            _gst_buffer_pool_default_buffer_free    (GstBufferPool *pool,
+                                                                 GstBuffer *buffer,
+                                                                 gpointer user_data);
+static void            _gst_buffer_pool_default_free           (GstData *pool);
+
+
+typedef struct _GstBufferPoolDefault GstBufferPoolDefault;
+
+struct _GstBufferPoolDefault {
+  GstMemChunk *mem_chunk;
+  guint size;
+};
+
+
+static GMutex *_default_pool_lock = NULL;
+static GHashTable *_default_pools = NULL;
+
+
+/**
+ * _gst_buffer_pool_get_default:
+ * @buffer_size: the number of bytes this buffer will store
+ * @pool_size: the default number of buffers to be preallocated
+ *
+ * Returns an instance of a buffer pool using the default
+ * implementation.  If a buffer pool instance with the same buffer_size
+ * already exists this will be returned, otherwise a new instance will
+ * be created.
+ * 
+ * Returns: an instance of GstBufferPool
+ */
+GstBufferPool*
+_gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
+{
+  GstBufferPool *pool;
+  GstMemChunk *data_chunk;
+  guint real_buffer_size;
+  GstBufferPoolDefault *def;
+  
+  if (!_default_pool_lock) {
+    _default_pool_lock = g_mutex_new ();
+    _default_pools = g_hash_table_new (NULL, NULL);
+  }
+
+  /* round up to the nearest 32 bytes for cache-line and other efficiencies */
+  real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
+  
+  /* check for an existing GstBufferPool with the same real_buffer_size */
+  /* (we won't worry about the pool_size) */
+  g_mutex_lock (_default_pool_lock);
+  pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
+  g_mutex_unlock (_default_pool_lock);
+
+  if (pool != NULL){
+    gst_buffer_pool_ref (pool);
+    return pool;
+  }
+  
+  data_chunk = gst_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size, 
+                                  real_buffer_size * pool_size, G_ALLOC_AND_FREE);
+    
+  def = g_new0 (GstBufferPoolDefault, 1);
+  def->size = buffer_size;
+  def->mem_chunk = data_chunk;
+
+  pool = gst_buffer_pool_new (_gst_buffer_pool_default_free,
+                              NULL, /* pool copy */
+                              _gst_buffer_pool_default_buffer_new,
+                              NULL, /* buffer copy */
+                              _gst_buffer_pool_default_buffer_free,
+                              def);
+  
+  g_mutex_lock (_default_pool_lock);
+  g_hash_table_insert (_default_pools, GINT_TO_POINTER (real_buffer_size), pool);
+  g_mutex_unlock (_default_pool_lock);
+  
+  GST_DEBUG (GST_CAT_BUFFER,"new default buffer pool %p bytes:%d size:%d",
+             pool, real_buffer_size, pool_size);
+  
+  return pool;
+}
+
+static GstBuffer* 
+_gst_buffer_pool_default_buffer_new (GstBufferPool *pool, guint64 offset /*unused*/,
+                                    guint size /*unused*/, gpointer user_data)
+{
+  GstBuffer *buffer;
+  GstBufferPoolDefault *def = (GstBufferPoolDefault*)user_data;
+  GstMemChunk *data_chunk = def->mem_chunk;
+  
+  buffer = gst_buffer_new ();
+  GST_INFO (GST_CAT_BUFFER, "creating new buffer %p from pool %p", buffer, pool);
+  
+  GST_BUFFER_DATA (buffer) = gst_mem_chunk_alloc (data_chunk);
+  
+  GST_BUFFER_SIZE (buffer)    = def->size;
+  GST_BUFFER_MAXSIZE (buffer) = def->size;
+  
+  return buffer;
+}
+
+static void
+_gst_buffer_pool_default_buffer_free (GstBufferPool *pool, GstBuffer *buffer, gpointer user_data)
+{
+  GstBufferPoolDefault *def = (GstBufferPoolDefault*)user_data;
+  GstMemChunk *data_chunk = def->mem_chunk;
+  gpointer data = GST_BUFFER_DATA (buffer);
+  
+  gst_mem_chunk_free (data_chunk, data);
+
+  GST_BUFFER_DATA (buffer) = NULL;
+
+  gst_buffer_default_free (buffer);
+}
+
+static void
+_gst_buffer_pool_default_free (GstData *data) 
+{
+  GstBufferPool *pool = (GstBufferPool*) data;
+  GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
+  GstMemChunk *data_chunk = def->mem_chunk;
+  
+  GST_DEBUG (GST_CAT_BUFFER, "destroying default buffer pool %p", pool);
+  
+  /* this is broken right now, FIXME
+     gst_mem_chunk_destroy (data_chunk); */
+  
+  g_free (data_chunk);
+  g_free (def);
+
+  gst_buffer_pool_default_free (pool);
+}
index 2e11d61..0e5bb7d 100644 (file)
@@ -99,8 +99,9 @@ gst_fakesrc_data_get_type (void)
 {
   static GType fakesrc_data_type = 0;
   static GEnumValue fakesrc_data[] = {
-    { FAKESRC_DATA_ALLOCATE,           "2", "Allocate data"},
-    { FAKESRC_DATA_SUBBUFFER,          "3", "Subbuffer data"},
+    { FAKESRC_DATA_ALLOCATE,           "1", "Allocate data"},
+    { FAKESRC_DATA_SUBBUFFER,          "2", "Subbuffer data"},
+    { FAKESRC_DATA_BUFFERPOOL,                 "3", "Use the default buffer pool (forces sizetype=2)"},
     {0, NULL, NULL},
   };
   if (!fakesrc_data_type) {
@@ -197,43 +198,43 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
-    g_param_spec_int ("num_sources", "num_sources", "num_sources",
+    g_param_spec_int ("num-sources", "num-sources", "Number of sources",
                       1, G_MAXINT, 1, G_PARAM_READABLE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOOP_BASED,
-    g_param_spec_boolean("loop_based","loop_based","loop_based",
-                         FALSE, G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_boolean("loop-based","loop-based","Enable loop-based operation",
+                         FALSE, G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OUTPUT,
-    g_param_spec_enum("output","output","output",
-                      GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE)); /* CHECKME! */
+    g_param_spec_enum("output","output","Output method (currently unused)",
+                      GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
-    g_param_spec_enum ("data", "data", "data",
+    g_param_spec_enum ("data", "data", "Data allocation method",
                        GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
-    g_param_spec_enum ("sizetype", "sizetype", "sizetype",
+    g_param_spec_enum ("sizetype", "sizetype", "How to determine buffer sizes",
                        GST_TYPE_FAKESRC_SIZETYPE, FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
-    g_param_spec_int ("sizemin","sizemin","sizemin",
+    g_param_spec_int ("sizemin","sizemin","Minimum buffer size",
                       0, G_MAXINT, 0, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
-    g_param_spec_int ("sizemax","sizemax","sizemax",
+    g_param_spec_int ("sizemax","sizemax","Maximum buffer size",
                       0, G_MAXINT, 4096, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
-    g_param_spec_int ("parentsize","parentsize","parentsize",
+    g_param_spec_int ("parentsize","parentsize","Size of parent buffer for sub-buffered allocation",
                       0, G_MAXINT, 4096 * 10, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
-    g_param_spec_enum ("filltype", "filltype", "filltype",
+    g_param_spec_enum ("filltype", "filltype", "How to fill the buffer, if at all",
                        GST_TYPE_FAKESRC_FILLTYPE, FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PATTERN,
     g_param_spec_string("pattern","pattern","pattern",
-                        NULL, G_PARAM_READWRITE)); /* CHECKME */
+                        NULL, G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUM_BUFFERS,
-    g_param_spec_int("num_buffers","num_buffers","num_buffers",
-                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_int("num-buffers","num-buffers","Number of buffers to output before sending EOS",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_EOS,
-    g_param_spec_boolean("eos","eos","eos",
-                         TRUE,G_PARAM_READWRITE)); /* CHECKME */
+    g_param_spec_boolean("eos","eos","Send out the EOS event?",
+                         TRUE,G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
-    g_param_spec_string ("last_message", "last_message", "last_message",
+    g_param_spec_string ("last-message", "last-message", "The last status message",
                          NULL, G_PARAM_READABLE)); 
 
   gst_element_class_install_std_props (
@@ -396,18 +397,28 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       break;
     case ARG_DATA:
       src->data = g_value_get_enum (value);
-      switch (src->data) {
-       case FAKESRC_DATA_ALLOCATE:
-          if (src->parent) {
-            gst_buffer_unref (src->parent);
-            src->parent = NULL;
-         }
-          break;
-       case FAKESRC_DATA_SUBBUFFER:
-         if (!src->parent)
-           gst_fakesrc_alloc_parent (src);
-       default:
-          break;
+
+      if (src->data == FAKESRC_DATA_SUBBUFFER) {
+        if (!src->parent)
+          gst_fakesrc_alloc_parent (src);
+      } else {
+        if (src->parent) {
+          gst_buffer_unref (src->parent);
+          src->parent = NULL;
+        }
+      }
+      
+      if (src->data == FAKESRC_DATA_BUFFERPOOL) {
+        if (src->sizetype != FAKESRC_SIZETYPE_FIXED)
+          g_object_set (src, "sizetype", FAKESRC_SIZETYPE_FIXED, NULL);
+        
+        if (!src->pool)
+          src->pool = gst_buffer_pool_get_default (src->sizemax, 10);
+      } else {
+        if (src->pool) {
+          gst_buffer_pool_free (src->pool);
+          src->pool = NULL;
+        }
       }
       break;
     case ARG_SIZETYPE:
@@ -630,6 +641,10 @@ gst_fakesrc_create_buffer (GstFakeSrc *src)
       }
       gst_fakesrc_prepare_buffer (src, buf);
       break;
+    case FAKESRC_DATA_BUFFERPOOL:
+      buf = gst_buffer_new_from_pool (src->pool, 0, 0);
+      gst_fakesrc_prepare_buffer (src, buf);
+      break;
     default:
       g_warning ("fakesrc: dunno how to allocate buffers !");
       buf = gst_buffer_new();
@@ -768,15 +783,20 @@ gst_fakesrc_change_state (GstElement *element)
       fakesrc->need_flush = FALSE;
       fakesrc->eos = FALSE;
       fakesrc->rt_num_buffers = fakesrc->num_buffers;
-      if (fakesrc->parent) {
-        gst_buffer_unref (fakesrc->parent);
-        fakesrc->parent = NULL;
-      }
       break;
     case GST_STATE_READY_TO_PAUSED:
     case GST_STATE_PAUSED_TO_PLAYING:
     case GST_STATE_PLAYING_TO_PAUSED:
+      break;
     case GST_STATE_READY_TO_NULL:
+      if (fakesrc->parent) {
+        gst_buffer_unref (fakesrc->parent);
+        fakesrc->parent = NULL;
+      }
+      if (fakesrc->pool) {
+        gst_buffer_pool_unref (fakesrc->pool);
+        fakesrc->pool = NULL;
+      }
       break;
     default:
       g_assert_not_reached ();
index f4a0e67..0038589 100644 (file)
@@ -44,12 +44,13 @@ typedef enum {
   FAKESRC_RANDOM,
   FAKESRC_PATTERN_LOOP,
   FAKESRC_PING_PONG_PATTERN,
-  FAKESRC_GET_ALWAYS_SUCEEDS,
+  FAKESRC_GET_ALWAYS_SUCEEDS
 } GstFakeSrcOutputType;
 
 typedef enum {
   FAKESRC_DATA_ALLOCATE = 1,
   FAKESRC_DATA_SUBBUFFER,
+  FAKESRC_DATA_BUFFERPOOL
 } GstFakeSrcDataType;
 
 typedef enum {
@@ -105,6 +106,7 @@ struct _GstFakeSrc {
   gboolean     silent;
   gboolean     dump;
   gboolean     need_flush;
+  GstBufferPool *pool;
 
   gchar                *last_message;
 };