gst/: Change GstBuffer private structure element names. (all files)

Original commit message from CVS:
* gst/elements/gstfilesrc.c: (gst_filesrc_free_parent_mmap),
(gst_filesrc_map_region):
* gst/gstbuffer.c: (_gst_buffer_initialize),
(_gst_buffer_sub_free), (gst_buffer_default_copy),
(gst_buffer_new), (gst_buffer_create_sub),
(gst_buffer_is_span_fast), (gst_buffer_span):
* gst/gstbuffer.h:
Change GstBuffer private structure element names. (all files)
* gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps),
(gst_queue_link):
* gst/gstqueue.h:
Implement getcaps/pad_link functions that handle the case where
there are data in the queue.
This commit is contained in:
David Schleef 2004-01-11 22:11:35 +00:00
parent a06605e4e3
commit 09012ae0da
9 changed files with 139 additions and 44 deletions

View file

@ -1,3 +1,19 @@
2004-01-11 David Schleef <ds@schleef.org>
* gst/elements/gstfilesrc.c: (gst_filesrc_free_parent_mmap),
(gst_filesrc_map_region):
* gst/gstbuffer.c: (_gst_buffer_initialize),
(_gst_buffer_sub_free), (gst_buffer_default_copy),
(gst_buffer_new), (gst_buffer_create_sub),
(gst_buffer_is_span_fast), (gst_buffer_span):
* gst/gstbuffer.h:
Change GstBuffer private structure element names. (all files)
* gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps),
(gst_queue_link):
* gst/gstqueue.h:
Implement getcaps/pad_link functions that handle the case where
there are data in the queue.
2004-01-11 Benjamin Otte <in7y118@public.uni-hamburg.de> 2004-01-11 Benjamin Otte <in7y118@public.uni-hamburg.de>
* gst/elements/gstbufferstore.c: * gst/elements/gstbufferstore.c:

View file

@ -345,7 +345,7 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
static void static void
gst_filesrc_free_parent_mmap (GstBuffer *buf) gst_filesrc_free_parent_mmap (GstBuffer *buf)
{ {
GstFileSrc *src = GST_FILESRC (GST_BUFFER_POOL_PRIVATE (buf)); GstFileSrc *src = GST_FILESRC (GST_BUFFER_PRIVATE (buf));
GST_LOG_OBJECT (src, "freeing mmap()d buffer at %"G_GUINT64_FORMAT"+%u", GST_LOG_OBJECT (src, "freeing mmap()d buffer at %"G_GUINT64_FORMAT"+%u",
GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf)); GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
@ -418,7 +418,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
GST_BUFFER_MAXSIZE (buf) = size; GST_BUFFER_MAXSIZE (buf) = size;
GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET (buf) = offset;
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_POOL_PRIVATE (buf) = src; GST_BUFFER_PRIVATE (buf) = src;
g_object_ref (src); g_object_ref (src);
GST_BUFFER_FREE_FUNC (buf) = (GstDataFreeFunction) gst_filesrc_free_parent_mmap; GST_BUFFER_FREE_FUNC (buf) = (GstDataFreeFunction) gst_filesrc_free_parent_mmap;

View file

@ -29,7 +29,6 @@
#include "gstinfo.h" #include "gstinfo.h"
GType _gst_buffer_type; GType _gst_buffer_type;
GType _gst_buffer_pool_type;
#ifndef GST_DISABLE_TRACE #ifndef GST_DISABLE_TRACE
/* #define GST_WITH_ALLOC_TRACE */ /* #define GST_WITH_ALLOC_TRACE */
@ -47,10 +46,6 @@ _gst_buffer_initialize (void)
(GBoxedCopyFunc) gst_data_ref, (GBoxedCopyFunc) gst_data_ref,
(GBoxedFreeFunc) gst_data_unref); (GBoxedFreeFunc) gst_data_unref);
_gst_buffer_pool_type = g_boxed_type_register_static ("GstBufferPool",
(GBoxedCopyFunc) gst_data_ref,
(GBoxedFreeFunc) gst_data_unref);
#ifndef GST_DISABLE_TRACE #ifndef GST_DISABLE_TRACE
_gst_buffer_trace = gst_alloc_trace_register (GST_BUFFER_TRACE_NAME); _gst_buffer_trace = gst_alloc_trace_register (GST_BUFFER_TRACE_NAME);
#endif #endif
@ -70,7 +65,7 @@ gst_buffer_get_type (void)
static void static void
_gst_buffer_sub_free (GstBuffer *buffer) _gst_buffer_sub_free (GstBuffer *buffer)
{ {
gst_data_unref (GST_DATA (buffer->pool_private)); gst_data_unref (GST_DATA (buffer->buffer_private));
GST_BUFFER_DATA (buffer) = NULL; GST_BUFFER_DATA (buffer) = NULL;
GST_BUFFER_SIZE (buffer) = 0; GST_BUFFER_SIZE (buffer) = 0;
@ -89,7 +84,6 @@ _gst_buffer_sub_free (GstBuffer *buffer)
* *
* Frees the memory associated with the buffer including the buffer data, * Frees the memory associated with the buffer including the buffer data,
* unless the GST_BUFFER_DONTFREE flags was set or the buffer data is NULL. * unless the GST_BUFFER_DONTFREE flags was set or the buffer data is NULL.
* This function is used by buffer pools.
*/ */
void void
gst_buffer_default_free (GstBuffer *buffer) gst_buffer_default_free (GstBuffer *buffer)
@ -136,7 +130,6 @@ gst_buffer_stamp (GstBuffer *dest, const GstBuffer *src)
* @buffer: a #GstBuffer to make a copy of. * @buffer: a #GstBuffer to make a copy of.
* *
* Make a full newly allocated copy of the given buffer, data and all. * Make a full newly allocated copy of the given buffer, data and all.
* This function is used by buffer pools.
* *
* Returns: the new #GstBuffer. * Returns: the new #GstBuffer.
*/ */
@ -166,8 +159,8 @@ gst_buffer_default_copy (GstBuffer *buffer)
GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_SIZE (buffer); GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_SIZE (buffer);
gst_buffer_stamp (copy, buffer); gst_buffer_stamp (copy, buffer);
GST_BUFFER_BUFFERPOOL (copy) = NULL; GST_BUFFER_FREE_DATA_FUNC (copy) = NULL;
GST_BUFFER_POOL_PRIVATE (copy) = NULL; GST_BUFFER_PRIVATE (copy) = NULL;
return copy; return copy;
} }
@ -204,8 +197,8 @@ gst_buffer_new (void)
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_BUFFERPOOL (newbuf) = NULL; GST_BUFFER_FREE_DATA_FUNC (newbuf) = NULL;
GST_BUFFER_POOL_PRIVATE (newbuf) = NULL; GST_BUFFER_PRIVATE (newbuf) = NULL;
return newbuf; return newbuf;
} }
@ -261,7 +254,7 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
buffer_data = parent->data + offset; buffer_data = parent->data + offset;
/* make sure we're child not child from a child buffer */ /* make sure we're child not child from a child buffer */
while (GST_BUFFER_FLAG_IS_SET (parent, GST_BUFFER_SUBBUFFER)) { while (GST_BUFFER_FLAG_IS_SET (parent, GST_BUFFER_SUBBUFFER)) {
parent = GST_BUFFER (parent->pool_private); parent = GST_BUFFER (parent->buffer_private);
} }
/* ref the real parent */ /* ref the real parent */
gst_data_ref (GST_DATA (parent)); gst_data_ref (GST_DATA (parent));
@ -287,8 +280,8 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
GST_BUFFER_DATA (buffer) = buffer_data; GST_BUFFER_DATA (buffer) = buffer_data;
GST_BUFFER_SIZE (buffer) = size; GST_BUFFER_SIZE (buffer) = size;
GST_BUFFER_MAXSIZE (buffer) = size; GST_BUFFER_MAXSIZE (buffer) = size;
GST_BUFFER_BUFFERPOOL (buffer) = NULL; GST_BUFFER_FREE_DATA_FUNC (buffer) = NULL;
GST_BUFFER_POOL_PRIVATE (buffer) = parent; GST_BUFFER_PRIVATE (buffer) = parent;
/* we can copy the timestamp and offset if the new buffer starts at /* we can copy the timestamp and offset if the new buffer starts at
* offset 0 */ * offset 0 */
if (offset == 0) { if (offset == 0) {
@ -356,7 +349,7 @@ gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
/* it's only fast if we have subbuffers of the same parent */ /* it's only fast if we have subbuffers of the same parent */
return ((GST_BUFFER_FLAG_IS_SET (buf1, GST_BUFFER_SUBBUFFER)) && return ((GST_BUFFER_FLAG_IS_SET (buf1, GST_BUFFER_SUBBUFFER)) &&
(GST_BUFFER_FLAG_IS_SET (buf2, GST_BUFFER_SUBBUFFER)) && (GST_BUFFER_FLAG_IS_SET (buf2, GST_BUFFER_SUBBUFFER)) &&
(buf1->pool_private == buf2->pool_private) && (buf1->buffer_private == buf2->buffer_private) &&
((buf1->data + buf1->size) == buf2->data)); ((buf1->data + buf1->size) == buf2->data));
} }
@ -393,7 +386,7 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
/* if the two buffers have the same parent and are adjacent */ /* if the two buffers have the same parent and are adjacent */
if (gst_buffer_is_span_fast (buf1, buf2)) { if (gst_buffer_is_span_fast (buf1, buf2)) {
GstBuffer *parent = GST_BUFFER (buf1->pool_private); GstBuffer *parent = GST_BUFFER (buf1->buffer_private);
/* we simply create a subbuffer of the common parent */ /* we simply create a subbuffer of the common parent */
newbuf = gst_buffer_create_sub (parent, newbuf = gst_buffer_create_sub (parent,
buf1->data - parent->data + offset, len); buf1->data - parent->data + offset, len);
@ -434,9 +427,3 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
return newbuf; return newbuf;
} }
GType
gst_buffer_pool_get_type (void)
{
return _gst_buffer_pool_type;
}

View file

@ -31,6 +31,8 @@ G_BEGIN_DECLS
typedef struct _GstBuffer GstBuffer; typedef struct _GstBuffer GstBuffer;
typedef void (*GstBufferFreeDataFunc) (GstBuffer *buffer);
#define GST_BUFFER_TRACE_NAME "GstBuffer" #define GST_BUFFER_TRACE_NAME "GstBuffer"
extern GType _gst_buffer_type; extern GType _gst_buffer_type;
@ -39,7 +41,6 @@ extern GType _gst_buffer_type;
#define GST_BUFFER(buf) ((GstBuffer *)(buf)) #define GST_BUFFER(buf) ((GstBuffer *)(buf))
#define GST_IS_BUFFER(buf) (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER) #define GST_IS_BUFFER(buf) (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER)
#define GST_IS_BUFFER_POOL(buf) (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER_POOL)
#define GST_BUFFER_REFCOUNT(buf) GST_DATA_REFCOUNT(buf) #define GST_BUFFER_REFCOUNT(buf) GST_DATA_REFCOUNT(buf)
#define GST_BUFFER_REFCOUNT_VALUE(buf) GST_DATA_REFCOUNT_VALUE(buf) #define GST_BUFFER_REFCOUNT_VALUE(buf) GST_DATA_REFCOUNT_VALUE(buf)
@ -59,8 +60,8 @@ extern GType _gst_buffer_type;
#define GST_BUFFER_FORMAT(buf) (GST_BUFFER(buf)->format) #define GST_BUFFER_FORMAT(buf) (GST_BUFFER(buf)->format)
#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset) #define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset)
#define GST_BUFFER_OFFSET_END(buf) (GST_BUFFER(buf)->offset_end) #define GST_BUFFER_OFFSET_END(buf) (GST_BUFFER(buf)->offset_end)
#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool) #define GST_BUFFER_FREE_DATA_FUNC(buf) (GST_BUFFER(buf)->free_data)
#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private) #define GST_BUFFER_PRIVATE(buf) (GST_BUFFER(buf)->buffer_private)
#define GST_BUFFER_OFFSET_NONE ((guint64)-1) #define GST_BUFFER_OFFSET_NONE ((guint64)-1)
#define GST_BUFFER_MAXSIZE_NONE ((guint)0) #define GST_BUFFER_MAXSIZE_NONE ((guint)0)
@ -76,9 +77,8 @@ typedef enum {
GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST, GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST,
GST_BUFFER_ORIGINAL, GST_BUFFER_ORIGINAL,
GST_BUFFER_DONTFREE, GST_BUFFER_DONTFREE,
GST_BUFFER_DISCONTINUOUS,
GST_BUFFER_KEY_UNIT, GST_BUFFER_KEY_UNIT,
GST_BUFFER_PREROLL, GST_BUFFER_DONTKEEP,
GST_BUFFER_FLAG_LAST = GST_DATA_FLAG_LAST + 8 GST_BUFFER_FLAG_LAST = GST_DATA_FLAG_LAST + 8
} GstBufferFlag; } GstBufferFlag;
@ -105,9 +105,9 @@ struct _GstBuffer {
guint64 offset_end; guint64 offset_end;
/* this is a pointer to the buffer pool (if any) */ /* this is a pointer to the buffer pool (if any) */
gpointer pool; GstBufferFreeDataFunc free_data;
/* pointer to pool private data of parent buffer in case of a subbuffer */ /* pointer to pool private data of parent buffer in case of a subbuffer */
gpointer pool_private; gpointer buffer_private;
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };

View file

@ -90,6 +90,10 @@ static GstData *gst_queue_get (GstPad *pad);
static gboolean gst_queue_handle_src_event (GstPad *pad, static gboolean gst_queue_handle_src_event (GstPad *pad,
GstEvent *event); GstEvent *event);
static GstCaps *gst_queue_getcaps (GstPad *pad);
static GstPadLinkReturn
gst_queue_link (GstPad *pad,
const GstCaps *caps);
static void gst_queue_locked_flush (GstQueue *queue); static void gst_queue_locked_flush (GstQueue *queue);
static GstElementStateReturn static GstElementStateReturn
@ -247,15 +251,15 @@ gst_queue_init (GstQueue *queue)
queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_chain)); gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_chain));
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
gst_pad_set_link_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_link_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_link));
gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps));
gst_pad_set_active (queue->sinkpad, TRUE); gst_pad_set_active (queue->sinkpad, TRUE);
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get)); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link));
gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps));
gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event));
gst_pad_set_active (queue->srcpad, TRUE); gst_pad_set_active (queue->srcpad, TRUE);
@ -311,6 +315,46 @@ gst_queue_dispose (GObject *object)
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static GstCaps *
gst_queue_getcaps (GstPad *pad)
{
GstQueue *queue;
queue = GST_QUEUE (gst_pad_get_parent (pad));
if (queue->queue->length > 0) {
return gst_caps_copy (queue->negotiated_caps);
}
return gst_pad_proxy_getcaps (pad);
}
static GstPadLinkReturn
gst_queue_link (GstPad *pad, const GstCaps *caps)
{
GstQueue *queue;
GstPadLinkReturn link_ret;
queue = GST_QUEUE (gst_pad_get_parent (pad));
if (queue->queue->length > 0) {
if (gst_caps_is_equal_fixed (caps, queue->negotiated_caps)) {
return GST_PAD_LINK_OK;
}
return GST_PAD_LINK_REFUSED;
}
link_ret = gst_pad_proxy_pad_link (pad, caps);
if (GST_PAD_LINK_SUCCESSFUL (link_ret)) {
/* we store an extra copy of the negotiated caps, just in case
* the pads become unnegotiated while we have buffers */
gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps));
}
return link_ret;
}
static void static void
gst_queue_locked_flush (GstQueue *queue) gst_queue_locked_flush (GstQueue *queue)
{ {

View file

@ -88,7 +88,9 @@ struct _GstQueue {
GTimeVal *timeval; /* the timeout for the queue locking */ GTimeVal *timeval; /* the timeout for the queue locking */
GQueue *events; /* upstream events get decoupled here */ GQueue *events; /* upstream events get decoupled here */
gpointer _gst_reserved[GST_PADDING]; GstCaps *negotiated_caps;
gpointer _gst_reserved[GST_PADDING - 1];
}; };
struct _GstQueueClass { struct _GstQueueClass {

View file

@ -345,7 +345,7 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
static void static void
gst_filesrc_free_parent_mmap (GstBuffer *buf) gst_filesrc_free_parent_mmap (GstBuffer *buf)
{ {
GstFileSrc *src = GST_FILESRC (GST_BUFFER_POOL_PRIVATE (buf)); GstFileSrc *src = GST_FILESRC (GST_BUFFER_PRIVATE (buf));
GST_LOG_OBJECT (src, "freeing mmap()d buffer at %"G_GUINT64_FORMAT"+%u", GST_LOG_OBJECT (src, "freeing mmap()d buffer at %"G_GUINT64_FORMAT"+%u",
GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf)); GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
@ -418,7 +418,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
GST_BUFFER_MAXSIZE (buf) = size; GST_BUFFER_MAXSIZE (buf) = size;
GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET (buf) = offset;
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_POOL_PRIVATE (buf) = src; GST_BUFFER_PRIVATE (buf) = src;
g_object_ref (src); g_object_ref (src);
GST_BUFFER_FREE_FUNC (buf) = (GstDataFreeFunction) gst_filesrc_free_parent_mmap; GST_BUFFER_FREE_FUNC (buf) = (GstDataFreeFunction) gst_filesrc_free_parent_mmap;

View file

@ -90,6 +90,10 @@ static GstData *gst_queue_get (GstPad *pad);
static gboolean gst_queue_handle_src_event (GstPad *pad, static gboolean gst_queue_handle_src_event (GstPad *pad,
GstEvent *event); GstEvent *event);
static GstCaps *gst_queue_getcaps (GstPad *pad);
static GstPadLinkReturn
gst_queue_link (GstPad *pad,
const GstCaps *caps);
static void gst_queue_locked_flush (GstQueue *queue); static void gst_queue_locked_flush (GstQueue *queue);
static GstElementStateReturn static GstElementStateReturn
@ -247,15 +251,15 @@ gst_queue_init (GstQueue *queue)
queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_chain)); gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_chain));
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
gst_pad_set_link_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_link_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_link));
gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps));
gst_pad_set_active (queue->sinkpad, TRUE); gst_pad_set_active (queue->sinkpad, TRUE);
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get)); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link));
gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps));
gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event));
gst_pad_set_active (queue->srcpad, TRUE); gst_pad_set_active (queue->srcpad, TRUE);
@ -311,6 +315,46 @@ gst_queue_dispose (GObject *object)
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static GstCaps *
gst_queue_getcaps (GstPad *pad)
{
GstQueue *queue;
queue = GST_QUEUE (gst_pad_get_parent (pad));
if (queue->queue->length > 0) {
return gst_caps_copy (queue->negotiated_caps);
}
return gst_pad_proxy_getcaps (pad);
}
static GstPadLinkReturn
gst_queue_link (GstPad *pad, const GstCaps *caps)
{
GstQueue *queue;
GstPadLinkReturn link_ret;
queue = GST_QUEUE (gst_pad_get_parent (pad));
if (queue->queue->length > 0) {
if (gst_caps_is_equal_fixed (caps, queue->negotiated_caps)) {
return GST_PAD_LINK_OK;
}
return GST_PAD_LINK_REFUSED;
}
link_ret = gst_pad_proxy_pad_link (pad, caps);
if (GST_PAD_LINK_SUCCESSFUL (link_ret)) {
/* we store an extra copy of the negotiated caps, just in case
* the pads become unnegotiated while we have buffers */
gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps));
}
return link_ret;
}
static void static void
gst_queue_locked_flush (GstQueue *queue) gst_queue_locked_flush (GstQueue *queue)
{ {

View file

@ -88,7 +88,9 @@ struct _GstQueue {
GTimeVal *timeval; /* the timeout for the queue locking */ GTimeVal *timeval; /* the timeout for the queue locking */
GQueue *events; /* upstream events get decoupled here */ GQueue *events; /* upstream events get decoupled here */
gpointer _gst_reserved[GST_PADDING]; GstCaps *negotiated_caps;
gpointer _gst_reserved[GST_PADDING - 1];
}; };
struct _GstQueueClass { struct _GstQueueClass {