From 74eba3a61592cb5d419c68e9c16c922402348ed1 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Wed, 24 Jul 2002 18:31:12 +0000 Subject: [PATCH] add default bufferpool, clean up some code, add bufferpool testing to fakesrc Original commit message from CVS: add default bufferpool, clean up some code, add bufferpool testing to fakesrc --- gst/Makefile.am | 10 ++- gst/elements/gstfakesrc.c | 90 ++++++++++++++--------- gst/elements/gstfakesrc.h | 4 +- gst/gstbuffer.c | 36 ++++----- gst/gstbuffer.h | 7 +- gst/gstbufferpool-default.c | 165 ++++++++++++++++++++++++++++++++++++++++++ plugins/elements/gstfakesrc.c | 90 ++++++++++++++--------- plugins/elements/gstfakesrc.h | 4 +- 8 files changed, 311 insertions(+), 95 deletions(-) create mode 100644 gst/gstbufferpool-default.c diff --git a/gst/Makefile.am b/gst/Makefile.am index 8573a52..1f3003c 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -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) \ diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 2e11d61..0e5bb7d 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -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 (); diff --git a/gst/elements/gstfakesrc.h b/gst/elements/gstfakesrc.h index f4a0e67..0038589 100644 --- a/gst/elements/gstfakesrc.h +++ b/gst/elements/gstfakesrc.h @@ -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; }; diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 44fe236..9963186 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -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); } diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index 21448be..582cfa9 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -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 index 0000000..f112709 --- /dev/null +++ b/gst/gstbufferpool-default.c @@ -0,0 +1,165 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * 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); +} diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 2e11d61..0e5bb7d 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -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 (); diff --git a/plugins/elements/gstfakesrc.h b/plugins/elements/gstfakesrc.h index f4a0e67..0038589 100644 --- a/plugins/elements/gstfakesrc.h +++ b/plugins/elements/gstfakesrc.h @@ -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; }; -- 2.7.4