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
This commit is contained in:
Andy Wingo 2002-07-24 18:31:12 +00:00
parent c2ba148309
commit 74eba3a615
8 changed files with 311 additions and 95 deletions

View 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) \

View 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 ();

View 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;
};

View 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);
}

View 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

165
gst/gstbufferpool-default.c Normal file
View file

@ -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);
}

View 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 ();

View 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;
};