diff options
author | Benjamin Otte <otte@gnome.org> | 2002-03-15 23:41:18 +0000 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2002-03-15 23:41:18 +0000 |
commit | df68257f9499fdaafbc57a0a09585a66458182e9 (patch) | |
tree | 28891df881ceea4cf9bf320a174e3ae002ea5bc6 | |
parent | 6f099dfb0ca8a8d9ef7235249d8da6bc634ffaa3 (diff) | |
download | gstreamer-df68257f9499fdaafbc57a0a09585a66458182e9.tar.gz |
EVENTS2 BRANCH: rewrote the buffer API
Original commit message from CVS:
EVENTS2 BRANCH:
rewrote the buffer API
28 files changed, 449 insertions, 671 deletions
diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 6f07bb0bd7..41e8a05de6 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -370,9 +370,7 @@ gst_fakesrc_alloc_parent (GstFakeSrc *src) { GstBuffer *buf; - buf = gst_buffer_new (); - GST_BUFFER_DATA (buf) = g_malloc (src->parentsize); - GST_BUFFER_SIZE (buf) = src->parentsize; + buf = gst_buffer_new (NULL, src->parentsize); src->parent = buf; src->parentoffset = 0; @@ -546,26 +544,23 @@ gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf) } static GstBuffer* -gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size) +gst_fakesrc_alloc_buffer (GstPad *pad, guint size) { - GstBuffer *buf; - - buf = gst_buffer_new (); - GST_BUFFER_SIZE(buf) = size; + GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad)); + GstBuffer *buf = gst_pad_new_buffer (pad, size); if (size != 0) { switch (src->filltype) { case FAKESRC_FILLTYPE_NOTHING: - GST_BUFFER_DATA(buf) = g_malloc (size); break; case FAKESRC_FILLTYPE_NULL: + memset (buf->data, 0, buf->size); GST_BUFFER_DATA(buf) = g_malloc0 (size); break; case FAKESRC_FILLTYPE_RANDOM: case FAKESRC_FILLTYPE_PATTERN: case FAKESRC_FILLTYPE_PATTERN_CONT: default: - GST_BUFFER_DATA(buf) = g_malloc (size); gst_fakesrc_prepare_buffer (src, buf); break; } @@ -596,19 +591,20 @@ gst_fakesrc_get_size (GstFakeSrc *src) } static GstBuffer * -gst_fakesrc_create_buffer (GstFakeSrc *src) +gst_fakesrc_create_buffer (GstPad *pad) { GstBuffer *buf; guint size; + GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad)); gboolean dump = src->dump; size = gst_fakesrc_get_size (src); if (size == 0) - return gst_buffer_new(); + return gst_pad_new_buffer (pad, 0); switch (src->data) { case FAKESRC_DATA_ALLOCATE: - buf = gst_fakesrc_alloc_buffer (src, size); + buf = gst_fakesrc_alloc_buffer (pad, size); break; case FAKESRC_DATA_SUBBUFFER: /* see if we have a parent to subbuffer */ @@ -626,13 +622,13 @@ gst_fakesrc_create_buffer (GstFakeSrc *src) gst_data_unref (GST_DATA (src->parent)); src->parent = NULL; /* try again (this will allocate a new parent) */ - return gst_fakesrc_create_buffer (src); + return gst_fakesrc_create_buffer (pad); } gst_fakesrc_prepare_buffer (src, buf); break; default: g_warning ("fakesrc: dunno how to allocate buffers !"); - buf = gst_buffer_new(); + buf = gst_pad_new_buffer (pad, 0); break; } if (dump) { @@ -673,7 +669,7 @@ gst_fakesrc_get(GstPad *pad) return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } - buf = gst_fakesrc_create_buffer (src); + buf = gst_fakesrc_create_buffer (pad); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; if (!src->silent) { @@ -730,7 +726,7 @@ gst_fakesrc_loop(GstElement *element) return; } - buf = gst_fakesrc_create_buffer (src); + buf = gst_fakesrc_create_buffer (pad); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; if (!src->silent) { diff --git a/gst/elements/gstfdsrc.c b/gst/elements/gstfdsrc.c index 5ec4d10cdd..8e1745fdf4 100644 --- a/gst/elements/gstfdsrc.c +++ b/gst/elements/gstfdsrc.c @@ -190,12 +190,9 @@ gst_fdsrc_get(GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this*/ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, src->bytes_per_read); g_return_val_if_fail (buf, NULL); - - /* allocate the space for the buffer data */ - GST_BUFFER_DATA(buf) = g_malloc(src->bytes_per_read); - g_return_val_if_fail(GST_BUFFER_DATA(buf) != NULL, NULL); + g_return_val_if_fail (GST_BUFFER_DATA(buf) != NULL, NULL); /* read it in from the file */ readbytes = read(src->fd,GST_BUFFER_DATA(buf),src->bytes_per_read); diff --git a/gst/elements/gstfilesrc.c b/gst/elements/gstfilesrc.c index 1301e70eb2..b2fbe81b32 100644 --- a/gst/elements/gstfilesrc.c +++ b/gst/elements/gstfilesrc.c @@ -98,20 +98,23 @@ enum { ARG_TOUCH, }; - -static void gst_filesrc_class_init (GstFileSrcClass *klass); -static void gst_filesrc_init (GstFileSrc *filesrc); -static void gst_filesrc_dispose (GObject *object); - -static void gst_filesrc_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void gst_filesrc_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - -static GstData * gst_filesrc_get (GstPad *pad); -static gpointer gst_filesrc_srcpad_event (GstPad *pad, GstData *event); - +/* standard GObject stuff */ +static void gst_filesrc_class_init (GstFileSrcClass *klass); +static void gst_filesrc_init (GstFileSrc *filesrc); +static void gst_filesrc_dispose (GObject *object); +/* properties */ +static void gst_filesrc_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_filesrc_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); +/* buffer handling */ +static GstData * gst_filesrc_get (GstPad *pad); +static gpointer gst_filesrc_srcpad_event (GstPad *pad, GstData *event); +/* state change */ static GstElementStateReturn gst_filesrc_change_state (GstElement *element); +/* bufferpool */ +static GstBuffer * gst_filesrc_buffer_new (GstBufferPool *pool, guint size); +static void gst_filesrc_buffer_dispose (GstData *buffer); static GstElementClass *parent_class = NULL; @@ -201,6 +204,11 @@ gst_filesrc_init (GstFileSrc *src) src->mapbuf = NULL; src->mapsize = 4 * 1024 * 1024; /* default is 4MB */ + src->pool = gst_buffer_pool_new (); + gst_buffer_pool_set_buffer_new_function (src->pool, gst_filesrc_buffer_new); + gst_buffer_pool_set_buffer_dispose_function (src->pool, gst_filesrc_buffer_dispose); + gst_buffer_pool_set_user_data (src->pool, src); + src->map_regions = g_tree_new(gst_filesrc_bufcmp); src->map_regions_lock = g_mutex_new(); @@ -316,9 +324,9 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS static void gst_filesrc_free_parent_mmap (GstBuffer *buf) { - GstFileSrc *src = GST_FILESRC(GST_BUFFER_POOL_PRIVATE(buf)); + GstFileSrc *src = GST_FILESRC(gst_buffer_pool_get_user_data (buf->pool)); - fs_print ("freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf)); + fs_print ("freeing mmap()d buffer at %d+%d\n", GST_BUFFER_OFFSET_BYTES(buf), GST_BUFFER_SIZE(buf)); /* remove the buffer from the list of available mmap'd regions */ g_mutex_lock(src->map_regions_lock); @@ -334,7 +342,7 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf) madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_DONTNEED); #endif /* now unmap the memory */ - munmap(GST_BUFFER_DATA(buf),GST_BUFFER_MAXSIZE(buf)); + munmap(GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); } static GstBuffer * @@ -348,7 +356,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) fs_print ("mapping region %08lx+%08lx from file into memory\n",offset,size); /* time to allocate a new mapbuf */ - buf = gst_buffer_new(); + buf = gst_buffer_new(src->pool, 0); /* mmap() the data into this new buffer */ GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset); if (GST_BUFFER_DATA(buf) == NULL) { @@ -362,16 +370,12 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL); #endif /* fill in the rest of the fields */ - GST_BUFFER_FLAGS(buf) = GST_BUFFER_READONLY | GST_BUFFER_ORIGINAL; + GST_DATA_FLAGS(buf) |= GST_DATA_READONLY; GST_BUFFER_SIZE(buf) = size; - GST_BUFFER_MAXSIZE(buf) = size; - GST_BUFFER_OFFSET(buf) = offset; - GST_BUFFER_TIMESTAMP(buf) = -1LL; - GST_BUFFER_POOL_PRIVATE(buf) = src; - GST_BUFFER_FREE_FUNC(buf) = gst_filesrc_free_parent_mmap; + GST_DATA_OFFSET_BYTES(buf) = offset; g_mutex_lock(src->map_regions_lock); - g_tree_insert(src->map_regions,buf,buf); + g_tree_insert(src->map_regions, buf, buf); g_mutex_unlock(src->map_regions_lock); return buf; @@ -715,3 +719,27 @@ gst_filesrc_srcpad_event (GstPad *pad, GstData *event) gst_data_unref (event); return ret; } +static GstBuffer * +gst_filesrc_buffer_new (GstBufferPool *pool, guint size) +{ + GstBuffer *buffer; + + if (size > 0) + g_warning("filesrc: ignoring size request when creating buffer"); + + g_return_val_if_fail((buffer = gst_buffer_alloc()), NULL); + gst_buffer_init (buffer, pool); + + return buffer; +} +static void +gst_filesrc_buffer_dispose (GstData *buffer) +{ + GstBuffer *buf = GST_BUFFER (buffer); + + gst_buffer_dispose (buffer); + if (buf->data) + gst_filesrc_free_parent_mmap (GST_BUFFER (buffer)); + buf->data = NULL; + buf->size = 0; +} diff --git a/gst/elements/gstfilesrc.h b/gst/elements/gstfilesrc.h index dd94c1e362..9bc67e30ec 100644 --- a/gst/elements/gstfilesrc.h +++ b/gst/elements/gstfilesrc.h @@ -74,6 +74,7 @@ struct _GstFileSrc { off_t block_size; /* bytes per read */ gboolean touch; /* whether to touch every page */ + GstBufferPool *pool; /* the pool creating the buffers */ GstBuffer *mapbuf; size_t mapsize; diff --git a/gst/elements/gstmultidisksrc.c b/gst/elements/gstmultidisksrc.c index 07554837e8..24cb27ff8b 100644 --- a/gst/elements/gstmultidisksrc.c +++ b/gst/elements/gstmultidisksrc.c @@ -218,14 +218,13 @@ gst_multidisksrc_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, 0); g_return_val_if_fail (buf != NULL, NULL); /* simply set the buffer to point to the correct region of the file */ GST_BUFFER_DATA (buf) = src->map; GST_BUFFER_OFFSET (buf) = 0; - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if (src->new_seek) { /* fixme, do something here */ diff --git a/gst/elements/gstmultifilesrc.c b/gst/elements/gstmultifilesrc.c index 07554837e8..24cb27ff8b 100644 --- a/gst/elements/gstmultifilesrc.c +++ b/gst/elements/gstmultifilesrc.c @@ -218,14 +218,13 @@ gst_multidisksrc_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, 0); g_return_val_if_fail (buf != NULL, NULL); /* simply set the buffer to point to the correct region of the file */ GST_BUFFER_DATA (buf) = src->map; GST_BUFFER_OFFSET (buf) = 0; - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if (src->new_seek) { /* fixme, do something here */ diff --git a/gst/elements/gstpipefilter.c b/gst/elements/gstpipefilter.c index cff2bfbf47..6902e67f98 100644 --- a/gst/elements/gstpipefilter.c +++ b/gst/elements/gstpipefilter.c @@ -64,7 +64,7 @@ static void gst_pipefilter_get_property (GObject *object, guint prop_id, GVal static GstData * gst_pipefilter_get (GstPad *pad); static void gst_pipefilter_chain (GstPad *pad, GstData *buf); -static gboolean gst_pipefilter_handle_event (GstPad *pad, GstData *event); +static gpointer gst_pipefilter_handle_event (GstPad *pad, GstData *event); static GstElementStateReturn gst_pipefilter_change_state (GstElement *element); @@ -133,7 +133,7 @@ gst_pipefilter_init (GstPipefilter *pipefilter) pipefilter->seq = 0; } -static gboolean +static gpointer gst_pipefilter_handle_event (GstPad *pad, GstData *event) { GstPipefilter *pipefilter; @@ -148,7 +148,7 @@ gst_pipefilter_handle_event (GstPad *pad, GstData *event) GST_FLAG_SET (pad, GST_PAD_EOS); - return TRUE; + return (gpointer) TRUE; } static GstData * @@ -162,11 +162,8 @@ gst_pipefilter_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - newbuf = gst_buffer_new(); + newbuf = gst_pad_new_buffer (pad, pipefilter->bytes_per_read); g_return_val_if_fail(newbuf, NULL); - - /* allocate the space for the buffer data */ - GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read); g_return_val_if_fail(GST_BUFFER_DATA(newbuf) != NULL, NULL); /* read it in from the file */ diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 0d972a72ed..9a50e5a08e 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -27,135 +27,167 @@ #include "gstbuffer.h" #include "gstobject.h" -static void gst_buffer_free (GstData *data); - -static GMemChunk *buffer_chunk = NULL; +static GMemChunk *_buffer_chunk = NULL; void _gst_buffer_initialize (void) { gint buffersize = sizeof (GstBuffer); - if (buffer_chunk == NULL) + if (_buffer_chunk == NULL) { - buffer_chunk = g_mem_chunk_new ("GstBufferChunk", buffersize, buffersize * 128, G_ALLOC_AND_FREE); + _buffer_chunk = g_mem_chunk_new ("GstBufferChunk", buffersize, buffersize * 128, G_ALLOC_AND_FREE); GST_INFO (GST_CAT_BUFFER, "Buffers are initialized now"); } } - +/** + * gst_buffer_alloc: + * + * Allocate space for a new buffer. Works the same way + * as g_malloc. + * Buffers allocated with gst_buffer_alloc must be freed + * with gst_buffer_free. + * + * Returns: A new buffer or NULL on failure + */ +GstBuffer * +gst_buffer_alloc (void) +{ + return g_mem_chunk_alloc (_buffer_chunk); +} +/** + * gst_buffer_free: + * @buffer: The buffer to free. + * + * Frees a buffer that wa previously allocated with gst_buffer_alloc. + */ +void +gst_buffer_free (GstBuffer *buffer) +{ + g_mem_chunk_free (_buffer_chunk, buffer); +} /** * gst_buffer_init: * @buffer: The buffer to be initialized + * @pool: The bufferpool to initialize from * - * Initializes a buffer. - * This function should be called by the init routine of a subtype - * of a buffer. + * Initializes a buffer from a given bufferpool. + * This function is a convenience function to be used in buffer_new + * routines of bufferpools. */ void -gst_buffer_init (GstBuffer *buffer) +gst_buffer_init (GstBuffer *buffer, GstBufferPool *pool) { - GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer); + GST_DEBUG (GST_CAT_BUFFER, "initializing new buffer %p", buffer); + gst_data_ref (GST_DATA (pool)); gst_data_init (GST_DATA (buffer)); - GST_DATA (buffer)->type = GST_BUFFER; - GST_DATA (buffer)->dispose = gst_buffer_dispose; - GST_DATA (buffer)->free = gst_buffer_free; + GST_DATA (buffer)->type = GST_DATA_BUFFER; + GST_DATA (buffer)->dispose = pool->buffer_dispose; + GST_DATA (buffer)->free = pool->buffer_free; - buffer->flags = 0; buffer->data = NULL; buffer->size = 0; - buffer->maxsize = 0; buffer->parent = NULL; - buffer->pool = NULL; + buffer->pool = pool; buffer->pool_private = NULL; - - buffer->free = NULL; - buffer->copy = NULL; -} -static void -gst_buffer_free (GstData *data) -{ - g_mem_chunk_free (buffer_chunk, data); } /** * gst_buffer_dispose: * @buffer: The buffer to be disposed * - * Destroys a buffer. - * This function should be called by the dispose routine of a subtype - * of a buffer. + * Disposes a buffer. + * This function is a convenience function to be used in buffer_dispose + * routines of bufferpools. */ void -gst_buffer_dispose (GstData *data) +gst_buffer_dispose (GstData *buffer) { - GstBuffer *buffer = (GstBuffer *) data; - - GST_INFO (GST_CAT_BUFFER, "freeing %sbuffer %p", - (buffer->parent?"sub":""), - buffer); - - /* free the data only if there is some, DONTFREE isn't set, and not sub */ - if (GST_BUFFER_DATA (buffer) && - !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE) && - (buffer->parent == NULL)) { - /* if there's a free function, use it */ - if (buffer->free != NULL) { - (buffer->free)(buffer); - } else { - g_free (GST_BUFFER_DATA (buffer)); - } - } - /* unreference the parent if there is one */ - if (buffer->parent != NULL) - gst_data_unref (GST_DATA (buffer->parent)); - - gst_data_dispose (data); + gst_buffer_unparent (GST_BUFFER (buffer)); + + gst_data_unref (GST_DATA (GST_BUFFER (buffer)->pool)); + gst_data_dispose (buffer); } /** * gst_buffer_new: + * @pool: bufferpool to create the buffer from + * @size: size of the data, 0 if no data initialization * - * Create a new buffer. + * Create a new buffer from the given bufferpool. If the bufferpool + * is set to NULL, the default pool is used. * - * Returns: new buffer + * Returns: new buffer or NULL, if buffer couldn't be created. */ GstBuffer* -gst_buffer_new (void) +gst_buffer_new (GstBufferPool *pool, guint size) { - GstBuffer *buf; - buf = g_mem_chunk_alloc (buffer_chunk); - gst_buffer_init (buf); - - return buf; + if (pool == NULL) + { + GstBufferPool *def = gst_buffer_pool_default (); + return def->buffer_new (def, size); + } else { + return pool->buffer_new (pool, size); + } } /** - * gst_buffer_new_from_pool: - * @pool: the buffer pool to use - * @offset: the offset of the new buffer - * @size: the size of the new buffer - * - * Create a new buffer using the specified bufferpool, offset and size. + * gst_buffer_set_parent: + * @buffer: buffer to set the parent for + * @parent: parent to set * - * Returns: new buffer + * Sets the buffers parent to the given one. */ -GstBuffer* -gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size) +void +gst_buffer_set_parent (GstBuffer *buffer, GstBuffer *parent, guint offset, guint size) { - GstBuffer *buffer; - - g_return_val_if_fail (pool != NULL, NULL); - g_return_val_if_fail (pool->buffer_new != NULL, NULL); + /* make sure we get valid data */ + g_return_if_fail (buffer != NULL); + g_return_if_fail (parent != NULL); + g_return_if_fail (buffer != parent); + /* make sure we can get the data from the parent */ + g_return_if_fail (parent->size >= offset + size); + /* do not reset the parent */ + if (buffer->parent == parent) + return; + /* if we have a parent, remove it */ + if (buffer->parent != NULL) + gst_buffer_unparent (buffer); + /* make sure buffer contains no data */ + g_return_if_fail (buffer->data == NULL); + g_return_if_fail (buffer->size == 0); - buffer = pool->buffer_new (pool, offset, size, pool->user_data); - buffer->pool = pool; - buffer->free = pool->buffer_free; - buffer->copy = pool->buffer_copy; + gst_data_ref (GST_DATA (parent)); + buffer->data = parent->data + offset; + buffer->size = size; + /* make sure we're child from a root buffer */ + while (parent->parent) + { + parent = parent->parent; + } + buffer->parent = parent; + /* make sure nobody overwrites data in two buffers */ + GST_DATA_FLAG_SET(buffer, GST_DATA_READONLY); + if (GST_DATA_IS_WRITABLE (parent)) + GST_DATA_FLAG_SET(parent, GST_DATA_READONLY); +} +/** + * gst_buffer_unset_parent: + * @buffer: buffer to unset the parent for + * + * Unsets the buffers parent and clears the data. + * If the buffer has no parent, it simply returns. + */ +void +gst_buffer_unparent (GstBuffer *buffer) +{ + g_return_if_fail (buffer != NULL); + if (buffer->parent == NULL) + return; - GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p (size %x, offset %x)", - buffer, pool, size, offset); - - return buffer; + gst_data_unref (GST_DATA (buffer->parent)); + buffer->parent = NULL; + buffer->data = NULL; + buffer->size = 0; } - /** * gst_buffer_create_sub: * @parent: parent buffer @@ -167,48 +199,22 @@ gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size) * Returns: new buffer */ GstBuffer* -gst_buffer_create_sub (GstBuffer *parent, - guint32 offset, - guint32 size) +gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size) { GstBuffer *buffer; g_return_val_if_fail (parent != NULL, NULL); g_return_val_if_fail (GST_BUFFER_REFCOUNT(parent) > 0, NULL); g_return_val_if_fail (size > 0, NULL); - g_return_val_if_fail ((offset+size) <= parent->size, NULL); - - buffer = gst_buffer_new (); - gst_data_copy (GST_DATA (buffer), GST_DATA (parent)); - /* copy flags and type from parent, for lack of better */ - buffer->flags = parent->flags; - - /* set the data pointer, size, offset, and maxsize */ - buffer->data = parent->data + offset; - buffer->size = size; - buffer->maxsize = parent->size - offset; - /* deal with bogus/unknown offsets */ - GST_BUFFER_OFFSET (buffer) += GST_BUFFER_OFFSET (parent); + buffer = gst_buffer_new (parent->pool, 0); - /* again, for lack of better, copy parent's maxage */ - buffer->maxage = parent->maxage; - - /* if the parent buffer is a subbuffer itself, use its parent, a real buffer */ - if (parent->parent != NULL) - parent = parent->parent; - - /* set parentage and reference the parent */ - buffer->parent = parent; - gst_data_ref (GST_DATA (parent)); - - buffer->pool = NULL; + gst_buffer_set_parent (buffer, parent, offset, size); return buffer; } -/* FIXME FIXME: how does this overlap with the newly-added gst_buffer_span() ??? */ /** * gst_buffer_append: * @buffer: a buffer @@ -223,7 +229,6 @@ GstBuffer* gst_buffer_append (GstBuffer *buffer, GstBuffer *append) { - guint size; GstBuffer *newbuf; g_return_val_if_fail (buffer != NULL, NULL); @@ -234,30 +239,10 @@ gst_buffer_append (GstBuffer *buffer, GST_INFO (GST_CAT_BUFFER,"appending buffers %p and %p",buffer,append); - GST_BUFFER_LOCK (buffer); - /* the buffer is not used by anyone else */ - if (GST_BUFFER_REFCOUNT (buffer) == 1 && buffer->parent == NULL - && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE)) { - /* save the old size */ - size = buffer->size; - buffer->size += append->size; - buffer->data = g_realloc (buffer->data, buffer->size); - memcpy(buffer->data + size, append->data, append->size); - GST_BUFFER_UNLOCK (buffer); - } - /* the buffer is used, create a new one */ - else { - newbuf = gst_buffer_new (); - newbuf->size = buffer->size+append->size; - newbuf->data = g_malloc (newbuf->size); - memcpy (newbuf->data, buffer->data, buffer->size); - memcpy (newbuf->data+buffer->size, append->data, append->size); - GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buffer); - GST_BUFFER_UNLOCK (buffer); - gst_data_unref (GST_DATA (buffer)); - buffer = newbuf; - } - return buffer; + newbuf = gst_buffer_merge (buffer, append); + gst_data_unref (GST_DATA (buffer)); + + return newbuf; } /** * gst_buffer_copy: @@ -268,38 +253,12 @@ gst_buffer_append (GstBuffer *buffer, * Returns: new buffer */ GstBuffer * -gst_buffer_copy (GstBuffer *buffer) +gst_buffer_copy (const GstBuffer *buffer) { - GstBuffer *newbuf; - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL); - /* if a copy function exists, use it, else copy the bytes */ - if (buffer->copy != NULL) { - newbuf = (buffer->copy)(buffer); - } else { - /* allocate a new buffer */ - newbuf = gst_buffer_new(); - - /* copy the absolute size */ - newbuf->size = buffer->size; - /* allocate space for the copy */ - newbuf->data = (guchar *)g_malloc (buffer->size); - /* copy the data straight across */ - memcpy(newbuf->data,buffer->data,buffer->size); - /* the new maxsize is the same as the size, since we just malloc'd it */ - newbuf->maxsize = newbuf->size; - } - gst_data_copy (GST_DATA (newbuf), GST_DATA (buffer)); - newbuf->maxage = buffer->maxage; - - /* since we just created a new buffer, so we have no ties to old stuff */ - newbuf->parent = NULL; - newbuf->pool = NULL; - - return newbuf; + return buffer->pool->buffer_copy (buffer); } - /** * gst_buffer_is_span_fast: * @buf1: first source buffer @@ -319,8 +278,6 @@ gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2) (buf1->parent == buf2->parent) && ((buf1->data + buf1->size) == buf2->data)); } - - /** * gst_buffer_span: * @buf1: first source buffer to merge @@ -341,45 +298,29 @@ gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2) */ /* FIXME need to think about CoW and such... */ GstBuffer * -gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len) +gst_buffer_span (GstBuffer *buf1, guint offset, GstBuffer *buf2, guint len) { GstBuffer *newbuf; g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, NULL); g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, NULL); - /* make sure buf1 has a lower address than buf2 */ - if (buf1->data > buf2->data) { - GstBuffer *tmp = buf1; - /* g_print ("swapping buffers\n"); */ - buf1 = buf2; - buf2 = tmp; - } - /* if the two buffers have the same parent and are adjacent */ if (gst_buffer_is_span_fast(buf1,buf2)) { /* we simply create a subbuffer of the common parent */ - newbuf = gst_buffer_create_sub (buf1->parent, buf1->data - (buf1->parent->data) + offset, len); + newbuf = gst_buffer_create_sub (buf1->parent, buf1->data - buf1->parent->data + offset, len); } else { /* g_print ("slow path taken in buffer_span\n"); */ /* otherwise we simply have to brute-force copy the buffers */ - newbuf = gst_buffer_new (); + newbuf = gst_buffer_new (buf1->pool, len); /* copy relevant stuff from data struct of buffer1 */ gst_data_copy (GST_DATA (newbuf), GST_DATA (buf1)); - /* put in new size */ - newbuf->size = len; - /* allocate space for the copy */ - newbuf->data = (guchar *)g_malloc(len); /* copy the first buffer's data across */ - memcpy(newbuf->data, buf1->data + offset, buf1->size - offset); + memcpy (newbuf->data, buf1->data + offset, buf1->size - offset); /* copy the second buffer's data across */ - memcpy(newbuf->data + (buf1->size - offset), buf2->data, len - (buf1->size - offset)); - - if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage; - else newbuf->maxage = buf1->maxage; - + memcpy (newbuf->data + (buf1->size - offset), buf2->data, len - (buf1->size - offset)); } return newbuf; @@ -403,25 +344,16 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len) GstBuffer * gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2) { + guint i; GstBuffer *result; /* we're just a specific case of the more general gst_buffer_span() */ result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size); - GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (buf1); + /* but we can include offset info */ + for (i = 0; i < GST_OFFSET_TYPES; i++) + { + GST_DATA (result)->offset[i] = GST_DATA (buf1)->offset[i]; + } return result; } -/** - * gst_buffer_print_stats: - * - * Print statistics about live buffers. - */ -void -gst_buffer_print_stats (void) -{ - /*g_log (g_log_domain_gstreamer, G_LOG_LEVEL_INFO, - "%d live buffers", _gst_buffer_live); - */ -} - - diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index 88ea9e22da..fe01ed671e 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -36,7 +36,6 @@ */ #include <gst/gstdata.h> -#include <gst/gstevent.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,7 +53,7 @@ extern "C" { #define GST_BUFFER(buf) (((GstData*)(buf))->type == GST_BUFFER ? (GstBuffer *)(buf) : NULL) */ #define GST_BUFFER(buf) ((GstBuffer *)(buf)) -#define GST_IS_BUFFER(buf) (((GstData*)(buf))->type == GST_BUFFER) +#define GST_IS_BUFFER(buf) (((GstData*)(buf))->type == GST_DATA_BUFFER) #ifdef HAVE_ATOMIC_H # define GST_BUFFER_REFCOUNT(buf) (atomic_read(&(GST_DATA(buf)->refcount))) @@ -62,12 +61,6 @@ extern "C" { # define GST_BUFFER_REFCOUNT(buf) (GST_DATA(buf)->refcount) #endif -#define GST_BUFFER_FLAGS(buf) (GST_BUFFER(buf)->flags) -#define GST_BUFFER_FLAG_IS_SET(buf,flag) (GST_BUFFER_FLAGS(buf) & (1<<(flag))) -#define GST_BUFFER_FLAG_SET(buf,flag) G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (1<<(flag))); }G_STMT_END -#define GST_BUFFER_FLAG_UNSET(buf,flag) G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END - - #define GST_BUFFER_DATA(buf) (GST_BUFFER(buf)->data) #define GST_BUFFER_SIZE(buf) (GST_BUFFER(buf)->size) #define GST_BUFFER_OFFSET(buf) (GST_DATA(buf)->offset[GST_OFFSET_BYTES]) @@ -86,76 +79,53 @@ extern "C" { #define GST_BUFFER_UNLOCK(buf) (g_mutex_unlock(GST_BUFFER(buf)->lock)) -typedef enum { - GST_BUFFER_READONLY, - GST_BUFFER_ORIGINAL, - GST_BUFFER_DONTFREE, - -} GstBufferFlags; - +enum { + GST_BUFFER_ORIGINAL = GST_DATA_FLAG_LAST, + GST_BUFFER_FLAG_LAST, +}; typedef struct _GstBuffer GstBuffer; -typedef struct _GstBufferClass GstBufferClass; - - -typedef void (*GstBufferFreeFunc) (GstBuffer *buf); -typedef GstBuffer *(*GstBufferCopyFunc) (GstBuffer *srcbuf); - #include <gst/gstbufferpool.h> struct _GstBuffer { GstData data_type; - /* locking */ - GMutex *lock; - - /* flags */ - guint16 flags; - /* pointer to data and its size */ gpointer data; guint32 size; - guint32 maxsize; - gint64 maxage; - /* subbuffer support, who's my parent? */ GstBuffer *parent; /* this is a pointer to the buffer pool (if any) */ - GstBufferPool *pool; + GstBufferPool * pool; gpointer pool_private; - - /* utility function pointers */ - GstBufferFreeFunc free; /* free the data associated with the buffer */ - GstBufferCopyFunc copy; /* copy the data from one buffer to another */ }; /* initialization */ void _gst_buffer_initialize (void); +/* allocation */ +GstBuffer * gst_buffer_alloc (void); +void gst_buffer_free (GstBuffer *buffer); + /* inheritance */ -void gst_buffer_init (GstBuffer *buffer); +void gst_buffer_init (GstBuffer *buffer, GstBufferPool *pool); void gst_buffer_dispose (GstData *data); /* creating a new buffer from scratch */ -GstBuffer* gst_buffer_new (void); -GstBuffer* gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size); +GstBuffer* gst_buffer_new (GstBufferPool *pool, guint size); /* creating a subbuffer */ GstBuffer* gst_buffer_create_sub (GstBuffer *parent, guint32 offset, guint32 size); -/* refcounting */ -/* deprecated, use gst_data_(un)ref instead */ -#define gst_buffer_ref(buffer) gst_data_ref(buffer) -#define gst_buffer_unref(buffer) gst_data_unref(buffer) - -/* destroying the buffer */ -void gst_buffer_destroy (GstBuffer *buffer); - /* copy buffer */ -GstBuffer* gst_buffer_copy (GstBuffer *buffer); +GstBuffer* gst_buffer_copy (const GstBuffer *buffer); + +/* parentage */ +void gst_buffer_set_parent (GstBuffer *buffer, GstBuffer *parent, guint offset, guint size); +void gst_buffer_unparent (GstBuffer *buffer); /* merge, span, or append two buffers, intelligently */ GstBuffer* gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2); @@ -163,7 +133,6 @@ GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, GstBuffer* gst_buffer_append (GstBuffer *buffer, GstBuffer *append); gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2); -void gst_buffer_print_stats (void); #ifdef __cplusplus } diff --git a/gst/gstbufferpool.c b/gst/gstbufferpool.c index 52d5748a3e..72ccb0aa98 100644 --- a/gst/gstbufferpool.c +++ b/gst/gstbufferpool.c @@ -28,27 +28,34 @@ #include "gstlog.h" #include "gstinfo.h" -static GMutex *_default_pool_lock; -static GHashTable *_default_pools; +static GstBufferPool *_default_pool = NULL; -static GstBuffer* gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location, gint size, gpointer user_data); -static void gst_buffer_pool_default_buffer_free (GstBuffer *buffer); -static void gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data); - -typedef struct _GstBufferPoolDefault GstBufferPoolDefault; - -struct _GstBufferPoolDefault { - GMemChunk *mem_chunk; - guint size; -}; +static GstBuffer * gst_buffer_pool_default_buffer_new (GstBufferPool *pool, + guint size); +static GstBuffer * gst_buffer_pool_default_buffer_copy (const GstBuffer *buffer); +static void gst_buffer_pool_default_buffer_dispose (GstData *buffer); void _gst_buffer_pool_initialize (void) { - _default_pools = g_hash_table_new(NULL,NULL); - _default_pool_lock = g_mutex_new (); + if (_default_pool == NULL) + { + _default_pool = gst_buffer_pool_new (); + GST_INFO (GST_CAT_BUFFER, "Buffer pools are initialized now"); + } +} +/** + * gst_buffer_pool_default: + * + * Get the default buffer pool. + * + * Returns: the default buffer pool + */ +GstBufferPool * +gst_buffer_pool_default (void) +{ + return _default_pool; } - /** * gst_buffer_pool_new: * @@ -64,99 +71,18 @@ gst_buffer_pool_new (void) pool = g_new0 (GstBufferPool, 1); GST_DEBUG (GST_CAT_BUFFER,"allocating new buffer pool %p\n", pool); - /* all hooks and user data set to NULL or 0 by g_new0 */ + /* init data struct */ + gst_data_init (GST_DATA (pool)); + GST_DATA_TYPE (pool) = GST_DATA_BUFFERPOOL; - pool->lock = g_mutex_new (); -#ifdef HAVE_ATOMIC_H - atomic_set (&pool->refcount, 1); -#else - pool->refcount = 1; -#endif + /* set functions */ + pool->buffer_new = gst_buffer_pool_default_buffer_new; + pool->buffer_copy = gst_buffer_pool_default_buffer_copy; + pool->buffer_dispose = gst_buffer_pool_default_buffer_dispose; + pool->buffer_free = (GstDataFreeFunction) gst_buffer_free; return pool; } - -/** - * gst_buffer_pool_ref: - * @pool: the GstBufferPool to reference - * - * Increment the refcount of this buffer pool. - */ -void -gst_buffer_pool_ref (GstBufferPool *pool) -{ - g_return_if_fail (pool != NULL); - - GST_DEBUG(GST_CAT_BUFFER,"referencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool)); - -#ifdef HAVE_ATOMIC_H - atomic_inc (&(pool->refcount)); -#else - g_return_if_fail (pool->refcount > 0); - GST_BUFFER_POOL_LOCK (pool); - pool->refcount++; - GST_BUFFER_POOL_UNLOCK (pool); -#endif -} - -/** - * gst_buffer_pool_ref_by_count: - * @pool: the GstBufferPool to reference - * @count: a number - * - * Increment the refcount of this buffer pool by the given number. - */ -void -gst_buffer_pool_ref_by_count (GstBufferPool *pool, int count) -{ - g_return_if_fail (pool != NULL); - g_return_if_fail (count >= 0); - -#ifdef HAVE_ATOMIC_H - g_return_if_fail (atomic_read (&(pool->refcount)) > 0); - atomic_add (count, &(pool->refcount)); -#else - g_return_if_fail (pool->refcount > 0); - GST_BUFFER_POOL_LOCK (pool); - pool->refcount += count; - GST_BUFFER_POOL_UNLOCK (pool); -#endif -} - -/** - * gst_buffer_pool_unref: - * @pool: the GstBufferPool to unref - * - * Decrement the refcount of this buffer pool. If the refcount is - * zero and the pool is a default implementation, - * the buffer pool will be destroyed. - */ -void -gst_buffer_pool_unref (GstBufferPool *pool) -{ - gint zero; - - g_return_if_fail (pool != NULL); - - GST_DEBUG(GST_CAT_BUFFER, "unreferencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool)); - -#ifdef HAVE_ATOMIC_H - g_return_if_fail (atomic_read (&(pool->refcount)) > 0); - zero = atomic_dec_and_test (&(pool->refcount)); -#else - g_return_if_fail (pool->refcount > 0); - GST_BUFFER_POOL_LOCK (pool); - pool->refcount--; - zero = (pool->refcount == 0); - GST_BUFFER_POOL_UNLOCK (pool); -#endif - - /* if we ended up with the refcount at zero, destroy the buffer pool*/ - if (zero) { - gst_buffer_pool_destroy (pool); - } -} - /** * gst_buffer_pool_set_buffer_new_function: * @pool: the pool to set the buffer create function for @@ -170,62 +96,57 @@ gst_buffer_pool_set_buffer_new_function (GstBufferPool *pool, GstBufferPoolBufferNewFunction create) { g_return_if_fail (pool != NULL); + g_return_if_fail (create != NULL); pool->buffer_new = create; } +/** + * gst_buffer_pool_set_buffer_dispose_function: + * @pool: the pool to set the buffer dispose function for + * @free: the dispose function + * + * Sets the function that will be called when a buffer should be disposed. + */ +void +gst_buffer_pool_set_buffer_dispose_function (GstBufferPool *pool, + GstDataFreeFunction dispose) +{ + g_return_if_fail (pool != NULL); + g_return_if_fail (dispose != NULL); + pool->buffer_dispose = dispose; +} /** * gst_buffer_pool_set_buffer_free_function: * @pool: the pool to set the buffer free function for - * @destroy: the free function + * @free: the free function * - * Sets the function that will be called when a buffer is freed - * from this pool. + * Sets the function that will be called when a buffer should be freed. */ void gst_buffer_pool_set_buffer_free_function (GstBufferPool *pool, - GstBufferFreeFunc destroy) + GstDataFreeFunction free) { g_return_if_fail (pool != NULL); - - pool->buffer_free = destroy; -} + g_return_if_fail (free != NULL); + pool->buffer_free = free; +} /** * gst_buffer_pool_set_buffer_copy_function: * @pool: the pool to set the buffer copy function for * @copy: the copy function * * Sets the function that will be called when a buffer is copied. - * - * You may use the default GstBuffer implementation (gst_buffer_copy). */ void -gst_buffer_pool_set_buffer_copy_function (GstBufferPool *pool, - GstBufferCopyFunc copy) +gst_buffer_pool_set_buffer_copy_function (GstBufferPool *pool, GstBufferPoolBufferCopyFunction copy) { g_return_if_fail (pool != NULL); + g_return_if_fail (copy != NULL); pool->buffer_copy = copy; } - -/** - * gst_buffer_pool_set_destroy_hook: - * @pool: the pool to set the destroy hook for - * @destroy: the destroy function - * - * Sets the function that will be called before a bufferpool is destroyed. - * You can take care of you private_data here. - */ -void -gst_buffer_pool_set_destroy_hook (GstBufferPool *pool, - GstBufferPoolDestroyHook destroy) -{ - g_return_if_fail (pool != NULL); - - pool->destroy_hook = destroy; -} - /** * gst_buffer_pool_set_user_data: * @pool: the pool to set the user data for @@ -235,8 +156,7 @@ gst_buffer_pool_set_destroy_hook (GstBufferPool *pool, * You can put your private data here. */ void -gst_buffer_pool_set_user_data (GstBufferPool *pool, - gpointer user_data) +gst_buffer_pool_set_user_data (GstBufferPool *pool, gpointer user_data) { g_return_if_fail (pool != NULL); @@ -259,135 +179,43 @@ gst_buffer_pool_get_user_data (GstBufferPool *pool) return pool->user_data; } -/** - * gst_buffer_pool_destroy: - * @pool: the pool to destroy - * - * Frees the memory for this bufferpool, calls the destroy hook. - */ -void -gst_buffer_pool_destroy (GstBufferPool *pool) -{ - g_return_if_fail (pool != NULL); - - if (pool->destroy_hook) - pool->destroy_hook (pool, pool->user_data); - - g_free(pool); -} - -/* - * This is so we don't get messed up by GST_BUFFER_WHERE. - */ -static GstBuffer * -_pool_gst_buffer_copy (GstBuffer *buffer) -{ return gst_buffer_copy (buffer); } - -/** - * 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; - GMemChunk *data_chunk; - guint real_buffer_size; - GstBufferPoolDefault *def; - - /* 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 = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size, - real_buffer_size * pool_size, G_ALLOC_AND_FREE); - - pool = gst_buffer_pool_new(); - gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new); - gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free); - gst_buffer_pool_set_buffer_copy_function (pool, _pool_gst_buffer_copy); - gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook); - - def = g_new0 (GstBufferPoolDefault, 1); - def->size = buffer_size; - def->mem_chunk = data_chunk; - pool->user_data = 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 buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size); - - return pool; -} - static GstBuffer* -gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location /*unused*/, - gint size /*unused*/, gpointer user_data) +gst_buffer_pool_default_buffer_new (GstBufferPool *pool, guint size) { GstBuffer *buffer; - GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data; - GMemChunk *data_chunk = def->mem_chunk; - - gst_buffer_pool_ref(pool); - buffer = gst_buffer_new(); - GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool); - g_mutex_lock (pool->lock); - GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk); - g_mutex_unlock (pool->lock); + g_return_val_if_fail((buffer = gst_buffer_alloc()), NULL); - GST_BUFFER_SIZE(buffer) = def->size; - GST_BUFFER_MAXSIZE(buffer) = def->size; + GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p", buffer, pool); + + gst_buffer_init (buffer, pool); + + GST_BUFFER_DATA(buffer) = size > 0 ? g_malloc (size) : NULL; + GST_BUFFER_SIZE(buffer) = GST_BUFFER_DATA(buffer) ? size : 0; return buffer; } - -static void -gst_buffer_pool_default_buffer_free (GstBuffer *buffer) +GstBuffer * +gst_buffer_pool_default_buffer_copy (const GstBuffer *buffer) { - GstBufferPool *pool = buffer->pool; - GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data; - GMemChunk *data_chunk = def->mem_chunk; - gpointer data = GST_BUFFER_DATA(buffer); + GstBuffer *newbuf; - g_mutex_lock (pool->lock); - g_mem_chunk_free (data_chunk,data); - g_mutex_unlock (pool->lock); + /* allocate a new buffer with the right size */ + newbuf = gst_buffer_new (buffer->pool, buffer->size); + /* copy all relevant data stuff */ + gst_data_copy (GST_DATA (newbuf), GST_DATA (buffer)); + /* copy the data straight across */ + memcpy (newbuf->data, buffer->data, buffer->size); - buffer->pool = NULL; - gst_buffer_pool_unref(pool); + return newbuf; } - static void -gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data) +gst_buffer_pool_default_buffer_dispose(GstData *buffer) { - GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data; - GMemChunk *data_chunk = def->mem_chunk; - - GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool); + GstBuffer *buf = GST_BUFFER (buffer); - g_mutex_free (pool->lock); - g_mem_chunk_reset(data_chunk); - g_free(data_chunk); - g_free(def); + gst_buffer_dispose (buffer); + g_free (buf->data); + buf->data = NULL; + buf->size = 0; } diff --git a/gst/gstbufferpool.h b/gst/gstbufferpool.h index 4ac0283374..85e7479a1f 100644 --- a/gst/gstbufferpool.h +++ b/gst/gstbufferpool.h @@ -31,66 +31,47 @@ extern "C" { #endif /* __cplusplus */ -#define GST_BUFFER_POOL(pool) \ - ((GstBufferPool *)(pool)) -#define GST_BUFFER_POOL_LOCK(pool) (g_mutex_lock(GST_BUFFER_POOL(pool)->lock)) -#define GST_BUFFER_POOL_UNLOCK(pool) (g_mutex_unlock(GST_BUFFER_POOL(pool)->lock)) +#define GST_BUFFER_POOL(pool) ((GstBufferPool *)(pool)) typedef struct _GstBufferPool GstBufferPool; -typedef GstBuffer* (*GstBufferPoolBufferNewFunction) (GstBufferPool *pool, gint64 location, gint size, gpointer user_data); -typedef void (*GstBufferPoolDestroyHook) (GstBufferPool *pool, gpointer user_data); +typedef GstBuffer * (*GstBufferPoolBufferNewFunction) (GstBufferPool *pool, guint size); +typedef GstBuffer * (*GstBufferPoolBufferCopyFunction) (const GstBuffer *buffer); struct _GstBufferPool { - /* locking */ - GMutex *lock; - - /* refcounting */ -#ifdef HAVE_ATOMIC_H - atomic_t refcount; -#define GST_BUFFER_POOL_REFCOUNT(pool) (atomic_read(&(GST_BUFFER_POOL((pool))->refcount))) -#else - int refcount; -#define GST_BUFFER_POOL_REFCOUNT(pool) (GST_BUFFER_POOL(pool)->refcount) -#endif - - GstBufferPoolBufferNewFunction buffer_new; - GstBufferFreeFunc buffer_free; - GstBufferCopyFunc buffer_copy; - GstBufferPoolDestroyHook destroy_hook; - - gpointer user_data; + /* easiest way to get refcounting */ + GstData data; + + GstBufferPoolBufferNewFunction buffer_new; + GstBufferPoolBufferCopyFunction buffer_copy; + GstDataFreeFunction buffer_dispose; + GstDataFreeFunction buffer_free; + + gpointer user_data; }; -void _gst_buffer_pool_initialize (void); +void _gst_buffer_pool_initialize (void); /* creating a new buffer pool from scratch */ -GstBufferPool* gst_buffer_pool_new (void); +GstBufferPool * gst_buffer_pool_new (void); + +/* getting the default bufferpool */ +GstBufferPool * gst_buffer_pool_default (void); -/* refcounting */ -void gst_buffer_pool_ref (GstBufferPool *pool); -void gst_buffer_pool_ref_by_count (GstBufferPool *pool, int count); -void gst_buffer_pool_unref (GstBufferPool *pool); /* setting create and destroy functions */ void gst_buffer_pool_set_buffer_new_function (GstBufferPool *pool, GstBufferPoolBufferNewFunction create); -void gst_buffer_pool_set_buffer_free_function (GstBufferPool *pool, - GstBufferFreeFunc destroy); void gst_buffer_pool_set_buffer_copy_function (GstBufferPool *pool, - GstBufferCopyFunc copy); -void gst_buffer_pool_set_destroy_hook (GstBufferPool *pool, - GstBufferPoolDestroyHook destroy); + GstBufferPoolBufferCopyFunction copy); +void gst_buffer_pool_set_buffer_dispose_function (GstBufferPool *pool, + GstDataFreeFunction dispose); +void gst_buffer_pool_set_buffer_free_function (GstBufferPool *pool, + GstDataFreeFunction free); void gst_buffer_pool_set_user_data (GstBufferPool *pool, gpointer user_data); gpointer gst_buffer_pool_get_user_data (GstBufferPool *pool); -/* destroying the buffer pool */ -void gst_buffer_pool_destroy (GstBufferPool *pool); - -/* a default buffer pool implementation */ -GstBufferPool* gst_buffer_pool_get_default (guint buffer_size, guint pool_size); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gst/gstdata.c b/gst/gstdata.c index 51abe7114d..b36c3faa94 100644 --- a/gst/gstdata.c +++ b/gst/gstdata.c @@ -19,6 +19,7 @@ gst_data_init (GstData *data) data->refcount = 1; data->reflock = g_mutex_new(); #endif + data->flags = 0; for (i = 0; i < GST_OFFSET_TYPES; i++) { data->offset[i] = 0; @@ -29,8 +30,9 @@ gst_data_copy (GstData *to, const GstData *from) { guint i; - to->type = from->type; - to->dispose = from->dispose; + g_assert (to->type == from->type); + + to->flags = from->flags & (~GST_DATA_READONLY); for (i = 0; i < GST_OFFSET_TYPES; i++) { to->offset[i] = from->offset[i]; diff --git a/gst/gstdata.h b/gst/gstdata.h index dc87792d59..6c922c9384 100644 --- a/gst/gstdata.h +++ b/gst/gstdata.h @@ -43,7 +43,8 @@ typedef enum { GST_DATA_UNKNOWN, GST_DATA_NONE, /* uninitialized */ /* buffer */ - GST_BUFFER, + GST_DATA_BUFFER, + GST_DATA_BUFFERPOOL, /* events */ GST_EVENT_FIRST, /* instream events */ @@ -76,12 +77,24 @@ typedef enum { #define GST_DATA(data) ((GstData*)(data)) #define GST_DATA_TYPE(data) (((GstData*)(data))->type) -/* FIXME: delete this macro? */ -#define GST_DATA_TIMESTAMP(data) (((GstData*)(data))->offset[GST_TIMEOFFSET]) +#define GST_DATA_OFFSET_TIME(data) (((GstData*)(data))->offset[GST_OFFSET_TIME]) +#define GST_DATA_OFFSET_BYTES(data) (((GstData*)(data))->offset[GST_OFFSET_BYTES]) +#define GST_DATA_OFFSET_FRAMES(data) (((GstData*)(data))->offset[GST_OFFSET_FRAMES]) + +/* flags */ +#define GST_DATA_FLAGS(data) (GST_DATA(data)->flags) +#define GST_DATA_FLAG_IS_SET(data,flag) (GST_DATA_FLAGS(data) & (1<<(flag))) +#define GST_DATA_FLAG_SET(data,flag) G_STMT_START{ (GST_DATA_FLAGS(data) |= (1<<(flag))); }G_STMT_END +#define GST_DATA_FLAG_UNSET(data,flag) G_STMT_START{ (GST_DATA_FLAGS(data) &= ~(1<<(flag))); }G_STMT_END +enum { + GST_DATA_READONLY, + /* insert more */ + GST_DATA_FLAG_LAST +}; +#define GST_DATA_IS_WRITABLE(data) (!GST_DATA_FLAG_IS_SET((data), GST_DATA_READONLY)) typedef struct _GstData GstData; -typedef void (*GstDataCopyFunction) (GstData *from, GstData *to); typedef void (*GstDataFreeFunction) (GstData *data); struct _GstData @@ -99,8 +112,11 @@ struct _GstData GMutex * reflock; #endif + /* flags */ + guint flags; + /* offset in stream */ - /* FIXME: upstream events don't need that */ + /* FIXME: only instream data needs that */ guint64 offset[GST_OFFSET_TYPES]; }; diff --git a/gst/gstpad.c b/gst/gstpad.c index f2196d77e9..be2c0ce0c2 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1071,6 +1071,7 @@ gst_pad_try_set_caps (GstPad *pad, GstCaps *caps) GstRealPad *peer, *realpad; realpad = GST_PAD_REALIZE (pad); + g_return_val_if_fail (realpad != NULL, FALSE); peer = GST_RPAD_PEER (realpad); GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s", @@ -1562,6 +1563,22 @@ gst_pad_get_bufferpool (GstPad *pad) return NULL; } } +/** + * gst_pad_new_buffer: + * @pad: the pad to get the buffer from + * @size: the requested size of the buffer + * + * Creates a new buffer using the bufferpool of the given + * pad. + * See #gst_buffer_new. + * + * Returns: The new buffer or NULL on error. + */ +GstBuffer * +gst_pad_new_buffer (GstPad *pad, guint size) +{ + return gst_buffer_new (gst_pad_get_bufferpool (pad), size); +} static void gst_real_pad_dispose (GObject *object) diff --git a/gst/gstpad.h b/gst/gstpad.h index 0a76f10bd9..41bdef0f48 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -383,7 +383,8 @@ GstPadTemplate* gst_pad_get_padtemplate (GstPad *pad); GstPad* gst_pad_get_peer (GstPad *pad); -GstBufferPool* gst_pad_get_bufferpool (GstPad *pad); +GstBufferPool * gst_pad_get_bufferpool (GstPad *pad); +GstBuffer * gst_pad_new_buffer (GstPad *pad, guint size); gboolean gst_pad_can_connect (GstPad *srcpad, GstPad *sinkpad); gboolean gst_pad_can_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps); diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 7ce721a5a2..c60803a110 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -254,7 +254,7 @@ gst_queue_cleanup_buffers (gpointer data, const gpointer user_data) { GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, user_data, "cleaning buffer %p\n", data); - gst_buffer_unref (GST_DATA (data)); + gst_data_unref (GST_DATA (data)); } static void diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c index 6871e18a2b..c1b6a97575 100644 --- a/gst/gsttypefind.c +++ b/gst/gsttypefind.c @@ -211,5 +211,5 @@ gst_typefind_chain (GstPad *pad, GstData *buf) type_list = g_list_next (type_list); } end: - gst_buffer_unref (buf); + gst_data_unref (buf); } diff --git a/libs/gst/bytestream/bstest.c b/libs/gst/bytestream/bstest.c index 23cda3107d..d0dd2aafa1 100644 --- a/libs/gst/bytestream/bstest.c +++ b/libs/gst/bytestream/bstest.c @@ -205,11 +205,11 @@ gst_identity_loop (GstElement *element) /* THIS IS THE BYTE BASED ONE*/ do { for (i=0;i<identity->count;i++) { - buf = gst_buffer_new(); + buf = gst_buffer_new (NULL, 0); /* note that this is dangerous, as it does *NOT* refcount the data, it can go away!!! */ GST_BUFFER_DATA(buf) = gst_bytestream_peek_bytes(identity->bs,identity->byte_size); GST_BUFFER_SIZE(buf) = identity->byte_size; - GST_BUFFER_FLAG_SET(buf,GST_BUFFER_DONTFREE); + /* FIXME: data is destroyed upon unreffing the buffer */ gst_pad_push(identity->srcpad, GST_DATA(buf)); gst_bytestream_flush(identity->bs,identity->byte_size); } diff --git a/libs/gst/bytestream/bytestream.c b/libs/gst/bytestream/bytestream.c index 2cf3cc673b..98aeb92372 100644 --- a/libs/gst/bytestream/bytestream.c +++ b/libs/gst/bytestream/bytestream.c @@ -233,7 +233,7 @@ gst_bytestream_peek (GstByteStream * bs, guint32 len) else { bs_print ("peek: current buffer is not big enough for len %d\n", len); - retbuf = gst_buffer_new (); + retbuf = gst_buffer_new (NULL, 0); GST_BUFFER_SIZE (retbuf) = len; GST_BUFFER_DATA (retbuf) = gst_bytestream_assemble (bs, len); if (GST_BUFFER_OFFSET (headbuf) != -1) diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 6f07bb0bd7..41e8a05de6 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -370,9 +370,7 @@ gst_fakesrc_alloc_parent (GstFakeSrc *src) { GstBuffer *buf; - buf = gst_buffer_new (); - GST_BUFFER_DATA (buf) = g_malloc (src->parentsize); - GST_BUFFER_SIZE (buf) = src->parentsize; + buf = gst_buffer_new (NULL, src->parentsize); src->parent = buf; src->parentoffset = 0; @@ -546,26 +544,23 @@ gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf) } static GstBuffer* -gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size) +gst_fakesrc_alloc_buffer (GstPad *pad, guint size) { - GstBuffer *buf; - - buf = gst_buffer_new (); - GST_BUFFER_SIZE(buf) = size; + GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad)); + GstBuffer *buf = gst_pad_new_buffer (pad, size); if (size != 0) { switch (src->filltype) { case FAKESRC_FILLTYPE_NOTHING: - GST_BUFFER_DATA(buf) = g_malloc (size); break; case FAKESRC_FILLTYPE_NULL: + memset (buf->data, 0, buf->size); GST_BUFFER_DATA(buf) = g_malloc0 (size); break; case FAKESRC_FILLTYPE_RANDOM: case FAKESRC_FILLTYPE_PATTERN: case FAKESRC_FILLTYPE_PATTERN_CONT: default: - GST_BUFFER_DATA(buf) = g_malloc (size); gst_fakesrc_prepare_buffer (src, buf); break; } @@ -596,19 +591,20 @@ gst_fakesrc_get_size (GstFakeSrc *src) } static GstBuffer * -gst_fakesrc_create_buffer (GstFakeSrc *src) +gst_fakesrc_create_buffer (GstPad *pad) { GstBuffer *buf; guint size; + GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad)); gboolean dump = src->dump; size = gst_fakesrc_get_size (src); if (size == 0) - return gst_buffer_new(); + return gst_pad_new_buffer (pad, 0); switch (src->data) { case FAKESRC_DATA_ALLOCATE: - buf = gst_fakesrc_alloc_buffer (src, size); + buf = gst_fakesrc_alloc_buffer (pad, size); break; case FAKESRC_DATA_SUBBUFFER: /* see if we have a parent to subbuffer */ @@ -626,13 +622,13 @@ gst_fakesrc_create_buffer (GstFakeSrc *src) gst_data_unref (GST_DATA (src->parent)); src->parent = NULL; /* try again (this will allocate a new parent) */ - return gst_fakesrc_create_buffer (src); + return gst_fakesrc_create_buffer (pad); } gst_fakesrc_prepare_buffer (src, buf); break; default: g_warning ("fakesrc: dunno how to allocate buffers !"); - buf = gst_buffer_new(); + buf = gst_pad_new_buffer (pad, 0); break; } if (dump) { @@ -673,7 +669,7 @@ gst_fakesrc_get(GstPad *pad) return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } - buf = gst_fakesrc_create_buffer (src); + buf = gst_fakesrc_create_buffer (pad); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; if (!src->silent) { @@ -730,7 +726,7 @@ gst_fakesrc_loop(GstElement *element) return; } - buf = gst_fakesrc_create_buffer (src); + buf = gst_fakesrc_create_buffer (pad); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; if (!src->silent) { diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index 5ec4d10cdd..8e1745fdf4 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -190,12 +190,9 @@ gst_fdsrc_get(GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this*/ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, src->bytes_per_read); g_return_val_if_fail (buf, NULL); - - /* allocate the space for the buffer data */ - GST_BUFFER_DATA(buf) = g_malloc(src->bytes_per_read); - g_return_val_if_fail(GST_BUFFER_DATA(buf) != NULL, NULL); + g_return_val_if_fail (GST_BUFFER_DATA(buf) != NULL, NULL); /* read it in from the file */ readbytes = read(src->fd,GST_BUFFER_DATA(buf),src->bytes_per_read); diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 1301e70eb2..b2fbe81b32 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -98,20 +98,23 @@ enum { ARG_TOUCH, }; - -static void gst_filesrc_class_init (GstFileSrcClass *klass); -static void gst_filesrc_init (GstFileSrc *filesrc); -static void gst_filesrc_dispose (GObject *object); - -static void gst_filesrc_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void gst_filesrc_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - -static GstData * gst_filesrc_get (GstPad *pad); -static gpointer gst_filesrc_srcpad_event (GstPad *pad, GstData *event); - +/* standard GObject stuff */ +static void gst_filesrc_class_init (GstFileSrcClass *klass); +static void gst_filesrc_init (GstFileSrc *filesrc); +static void gst_filesrc_dispose (GObject *object); +/* properties */ +static void gst_filesrc_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_filesrc_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); +/* buffer handling */ +static GstData * gst_filesrc_get (GstPad *pad); +static gpointer gst_filesrc_srcpad_event (GstPad *pad, GstData *event); +/* state change */ static GstElementStateReturn gst_filesrc_change_state (GstElement *element); +/* bufferpool */ +static GstBuffer * gst_filesrc_buffer_new (GstBufferPool *pool, guint size); +static void gst_filesrc_buffer_dispose (GstData *buffer); static GstElementClass *parent_class = NULL; @@ -201,6 +204,11 @@ gst_filesrc_init (GstFileSrc *src) src->mapbuf = NULL; src->mapsize = 4 * 1024 * 1024; /* default is 4MB */ + src->pool = gst_buffer_pool_new (); + gst_buffer_pool_set_buffer_new_function (src->pool, gst_filesrc_buffer_new); + gst_buffer_pool_set_buffer_dispose_function (src->pool, gst_filesrc_buffer_dispose); + gst_buffer_pool_set_user_data (src->pool, src); + src->map_regions = g_tree_new(gst_filesrc_bufcmp); src->map_regions_lock = g_mutex_new(); @@ -316,9 +324,9 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS static void gst_filesrc_free_parent_mmap (GstBuffer *buf) { - GstFileSrc *src = GST_FILESRC(GST_BUFFER_POOL_PRIVATE(buf)); + GstFileSrc *src = GST_FILESRC(gst_buffer_pool_get_user_data (buf->pool)); - fs_print ("freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf)); + fs_print ("freeing mmap()d buffer at %d+%d\n", GST_BUFFER_OFFSET_BYTES(buf), GST_BUFFER_SIZE(buf)); /* remove the buffer from the list of available mmap'd regions */ g_mutex_lock(src->map_regions_lock); @@ -334,7 +342,7 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf) madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_DONTNEED); #endif /* now unmap the memory */ - munmap(GST_BUFFER_DATA(buf),GST_BUFFER_MAXSIZE(buf)); + munmap(GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); } static GstBuffer * @@ -348,7 +356,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) fs_print ("mapping region %08lx+%08lx from file into memory\n",offset,size); /* time to allocate a new mapbuf */ - buf = gst_buffer_new(); + buf = gst_buffer_new(src->pool, 0); /* mmap() the data into this new buffer */ GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset); if (GST_BUFFER_DATA(buf) == NULL) { @@ -362,16 +370,12 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL); #endif /* fill in the rest of the fields */ - GST_BUFFER_FLAGS(buf) = GST_BUFFER_READONLY | GST_BUFFER_ORIGINAL; + GST_DATA_FLAGS(buf) |= GST_DATA_READONLY; GST_BUFFER_SIZE(buf) = size; - GST_BUFFER_MAXSIZE(buf) = size; - GST_BUFFER_OFFSET(buf) = offset; - GST_BUFFER_TIMESTAMP(buf) = -1LL; - GST_BUFFER_POOL_PRIVATE(buf) = src; - GST_BUFFER_FREE_FUNC(buf) = gst_filesrc_free_parent_mmap; + GST_DATA_OFFSET_BYTES(buf) = offset; g_mutex_lock(src->map_regions_lock); - g_tree_insert(src->map_regions,buf,buf); + g_tree_insert(src->map_regions, buf, buf); g_mutex_unlock(src->map_regions_lock); return buf; @@ -715,3 +719,27 @@ gst_filesrc_srcpad_event (GstPad *pad, GstData *event) gst_data_unref (event); return ret; } +static GstBuffer * +gst_filesrc_buffer_new (GstBufferPool *pool, guint size) +{ + GstBuffer *buffer; + + if (size > 0) + g_warning("filesrc: ignoring size request when creating buffer"); + + g_return_val_if_fail((buffer = gst_buffer_alloc()), NULL); + gst_buffer_init (buffer, pool); + + return buffer; +} +static void +gst_filesrc_buffer_dispose (GstData *buffer) +{ + GstBuffer *buf = GST_BUFFER (buffer); + + gst_buffer_dispose (buffer); + if (buf->data) + gst_filesrc_free_parent_mmap (GST_BUFFER (buffer)); + buf->data = NULL; + buf->size = 0; +} diff --git a/plugins/elements/gstfilesrc.h b/plugins/elements/gstfilesrc.h index dd94c1e362..9bc67e30ec 100644 --- a/plugins/elements/gstfilesrc.h +++ b/plugins/elements/gstfilesrc.h @@ -74,6 +74,7 @@ struct _GstFileSrc { off_t block_size; /* bytes per read */ gboolean touch; /* whether to touch every page */ + GstBufferPool *pool; /* the pool creating the buffers */ GstBuffer *mapbuf; size_t mapsize; diff --git a/plugins/elements/gstmultidisksrc.c b/plugins/elements/gstmultidisksrc.c index 07554837e8..24cb27ff8b 100644 --- a/plugins/elements/gstmultidisksrc.c +++ b/plugins/elements/gstmultidisksrc.c @@ -218,14 +218,13 @@ gst_multidisksrc_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, 0); g_return_val_if_fail (buf != NULL, NULL); /* simply set the buffer to point to the correct region of the file */ GST_BUFFER_DATA (buf) = src->map; GST_BUFFER_OFFSET (buf) = 0; - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if (src->new_seek) { /* fixme, do something here */ diff --git a/plugins/elements/gstmultifilesrc.c b/plugins/elements/gstmultifilesrc.c index 07554837e8..24cb27ff8b 100644 --- a/plugins/elements/gstmultifilesrc.c +++ b/plugins/elements/gstmultifilesrc.c @@ -218,14 +218,13 @@ gst_multidisksrc_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - buf = gst_buffer_new (); + buf = gst_pad_new_buffer (pad, 0); g_return_val_if_fail (buf != NULL, NULL); /* simply set the buffer to point to the correct region of the file */ GST_BUFFER_DATA (buf) = src->map; GST_BUFFER_OFFSET (buf) = 0; - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if (src->new_seek) { /* fixme, do something here */ diff --git a/plugins/elements/gstpipefilter.c b/plugins/elements/gstpipefilter.c index cff2bfbf47..6902e67f98 100644 --- a/plugins/elements/gstpipefilter.c +++ b/plugins/elements/gstpipefilter.c @@ -64,7 +64,7 @@ static void gst_pipefilter_get_property (GObject *object, guint prop_id, GVal static GstData * gst_pipefilter_get (GstPad *pad); static void gst_pipefilter_chain (GstPad *pad, GstData *buf); -static gboolean gst_pipefilter_handle_event (GstPad *pad, GstData *event); +static gpointer gst_pipefilter_handle_event (GstPad *pad, GstData *event); static GstElementStateReturn gst_pipefilter_change_state (GstElement *element); @@ -133,7 +133,7 @@ gst_pipefilter_init (GstPipefilter *pipefilter) pipefilter->seq = 0; } -static gboolean +static gpointer gst_pipefilter_handle_event (GstPad *pad, GstData *event) { GstPipefilter *pipefilter; @@ -148,7 +148,7 @@ gst_pipefilter_handle_event (GstPad *pad, GstData *event) GST_FLAG_SET (pad, GST_PAD_EOS); - return TRUE; + return (gpointer) TRUE; } static GstData * @@ -162,11 +162,8 @@ gst_pipefilter_get (GstPad *pad) /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ - newbuf = gst_buffer_new(); + newbuf = gst_pad_new_buffer (pad, pipefilter->bytes_per_read); g_return_val_if_fail(newbuf, NULL); - - /* allocate the space for the buffer data */ - GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read); g_return_val_if_fail(GST_BUFFER_DATA(newbuf) != NULL, NULL); /* read it in from the file */ diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 7ce721a5a2..c60803a110 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -254,7 +254,7 @@ gst_queue_cleanup_buffers (gpointer data, const gpointer user_data) { GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, user_data, "cleaning buffer %p\n", data); - gst_buffer_unref (GST_DATA (data)); + gst_data_unref (GST_DATA (data)); } static void diff --git a/tools/gst-launch.c b/tools/gst-launch.c index c8ebdc854a..414d9ef3b7 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -191,7 +191,6 @@ main(int argc, char *argv[]) #endif if (run_pipeline) { - gst_buffer_print_stats(); fprintf(stderr,"RUNNING pipeline\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) { fprintf(stderr,"pipeline doesn't want to play\n"); @@ -202,7 +201,6 @@ main(int argc, char *argv[]) gst_main (); gst_element_set_state (pipeline, GST_STATE_NULL); - gst_buffer_print_stats(); } gst_object_unref (GST_OBJECT (pipeline)); |