Revert "context: use context on buffers instead of caps"

This reverts commit 9ef1346b1f.

Way to much for one commit and I'm not sure we want to get rid of the pad caps
just like that. It's nice to have the buffer and its type in onw nice bundle
without having to drag the complete context with it.
This commit is contained in:
Wim Taymans 2011-05-05 10:37:19 +02:00
parent 419f48d0d1
commit c4751ec8c1
28 changed files with 495 additions and 268 deletions

View file

@ -670,7 +670,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
_gst_query_initialize ();
_gst_caps_initialize ();
_gst_meta_init ();
gst_context_get_type ();
g_type_class_ref (gst_object_get_type ());
g_type_class_ref (gst_pad_get_type ());

View file

@ -306,6 +306,10 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
}
}
if (flags & GST_BUFFER_COPY_CAPS) {
gst_caps_replace (&GST_BUFFER_CAPS (dest), GST_BUFFER_CAPS (src));
}
if (flags & GST_BUFFER_COPY_MEMORY) {
GstMemory *mem;
gsize skip, left, len, i, bsize;
@ -398,7 +402,7 @@ _gst_buffer_free (GstBuffer * buffer)
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
gst_context_replace (&GST_BUFFER_CONTEXT (buffer), NULL);
gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
/* free metadata */
for (walk = GST_BUFFER_META (buffer); walk; walk = next) {
@ -440,7 +444,7 @@ gst_buffer_init (GstBufferImpl * buffer, gsize size)
(GstMiniObjectFreeFunction) _gst_buffer_free;
GST_BUFFER (buffer)->pool = NULL;
GST_BUFFER_CONTEXT (buffer) = NULL;
GST_BUFFER_CAPS (buffer) = NULL;
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
@ -1053,65 +1057,71 @@ gst_buffer_memcmp (GstBuffer * buffer, gsize offset, gconstpointer mem,
}
/**
* gst_buffer_get_context:
* gst_buffer_get_caps:
* @buffer: a #GstBuffer.
*
* Gets the context of the buffer. This can be NULL if there
* is no context attached to this buffer.
* Gets the media type of the buffer. This can be NULL if there
* is no media type attached to this buffer.
*
* Returns: (transfer full): a reference to the #GstContext. unref after usage.
* Returns NULL if there was no context on this buffer.
* Returns: (transfer full): a reference to the #GstCaps. unref after usage.
* Returns NULL if there were no caps on this buffer.
*/
/* this is not made atomic because if the buffer were reffed from multiple
* threads, it would have a refcount > 2 and thus be immutable.
*/
GstContext *
gst_buffer_get_context (GstBuffer * buffer)
GstCaps *
gst_buffer_get_caps (GstBuffer * buffer)
{
GstContext *ret;
GstCaps *ret;
g_return_val_if_fail (buffer != NULL, NULL);
ret = GST_BUFFER_CONTEXT (buffer);
ret = GST_BUFFER_CAPS (buffer);
if (ret)
gst_context_ref (ret);
gst_caps_ref (ret);
return ret;
}
/**
* gst_buffer_set_context:
* gst_buffer_set_caps:
* @buffer: a #GstBuffer.
* @context: (transfer none): a #GstContext.
* @caps: (transfer none): a #GstCaps.
*
* Sets the media type on the buffer. The refcount of the context will
* be increased and any previous context on the buffer will be
* Sets the media type on the buffer. The refcount of the caps will
* be increased and any previous caps on the buffer will be
* unreffed.
*/
/* this is not made atomic because if the buffer were reffed from multiple
* threads, it would have a refcount > 2 and thus be immutable.
*/
void
gst_buffer_set_context (GstBuffer * buffer, GstContext * context)
gst_buffer_set_caps (GstBuffer * buffer, GstCaps * caps)
{
g_return_if_fail (buffer != NULL);
g_return_if_fail (gst_buffer_is_writable (buffer));
g_return_if_fail (caps == NULL || GST_CAPS_IS_SIMPLE (caps));
gst_context_replace (&GST_BUFFER_CONTEXT (buffer), context);
#if GST_VERSION_NANO == 1
/* we enable this extra debugging in git versions only for now */
g_warn_if_fail (gst_buffer_is_writable (buffer));
/* FIXME: would be nice to also check if caps are fixed here, but expensive */
#endif
gst_caps_replace (&GST_BUFFER_CAPS (buffer), caps);
}
/**
* gst_buffer_copy_region:
* @parent: a #GstBuffer.
* @offset: the offset into parent #GstBuffer at which the new sub-buffer
* @offset: the offset into parent #GstBuffer at which the new sub-buffer
* begins.
* @size: the size of the new #GstBuffer sub-buffer, in bytes.
*
* Creates a sub-buffer from @parent at @offset and @size.
* This sub-buffer uses the actual memory space of the parent buffer.
* This function will copy the offset and timestamp fields when the
* offset is 0. If not, they will be set to #GST_CLOCK_TIME_NONE and
* offset is 0. If not, they will be set to #GST_CLOCK_TIME_NONE and
* #GST_BUFFER_OFFSET_NONE.
* If @offset equals 0 and @size equals the total size of @buffer, the
* duration and offset end fields are also copied. If not they will be set
@ -1499,22 +1509,3 @@ gst_buffer_iterate_meta (GstBuffer * buffer, gpointer * state)
else
return NULL;
}
GstCaps *
gst_buffer_caps (GstBuffer * buffer)
{
GstContext *context;
GstEvent *event;
GstCaps *caps = NULL;
if (!(context = GST_BUFFER_CONTEXT (buffer)))
return NULL;
if (!(event = gst_context_get (context, GST_EVENT_CAPS)))
return NULL;
gst_event_parse_caps (event, &caps);
gst_event_unref (event);
return caps;
}

View file

@ -24,18 +24,18 @@
#ifndef __GST_BUFFER_H__
#define __GST_BUFFER_H__
typedef struct _GstBuffer GstBuffer;
typedef struct _GstBufferPool GstBufferPool;
#include <gst/gstminiobject.h>
#include <gst/gstclock.h>
#include <gst/gstcontext.h>
#include <gst/gstcaps.h>
#include <gst/gstmemory.h>
G_BEGIN_DECLS
extern GType _gst_buffer_type;
typedef struct _GstBuffer GstBuffer;
typedef struct _GstBufferPool GstBufferPool;
/**
* GST_BUFFER_TRACE_NAME:
*
@ -112,12 +112,12 @@ extern GType _gst_buffer_type;
*/
#define GST_BUFFER_DURATION(buf) (GST_BUFFER_CAST(buf)->duration)
/**
* GST_BUFFER_CONTEXT:
* GST_BUFFER_CAPS:
* @buf: a #GstBuffer.
*
* The context for this buffer.
* The caps for this buffer.
*/
#define GST_BUFFER_CONTEXT(buf) (GST_BUFFER_CAST(buf)->context)
#define GST_BUFFER_CAPS(buf) (GST_BUFFER_CAST(buf)->caps)
/**
* GST_BUFFER_OFFSET:
* @buf: a #GstBuffer.
@ -260,7 +260,7 @@ struct _GstBuffer {
/*< public >*/ /* with COW */
GstBufferPool *pool;
/* the media type of this buffer */
GstContext *context;
GstCaps *caps;
/* timestamp */
GstClockTime timestamp;
@ -386,6 +386,7 @@ gst_buffer_copy (const GstBuffer * buf)
* @GST_BUFFER_COPY_FLAGS: flag indicating that buffer flags should be copied
* @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration,
* offset and offset_end should be copied
* @GST_BUFFER_COPY_CAPS: flag indicating that buffer caps should be copied
* @GST_BUFFER_COPY_MEMORY: flag indicating that buffer memory should be copied
* and appended to already existing memory
* @GST_BUFFER_COPY_MERGE: flag indicating that buffer memory should be
@ -398,6 +399,7 @@ typedef enum {
GST_BUFFER_COPY_NONE = 0,
GST_BUFFER_COPY_FLAGS = (1 << 0),
GST_BUFFER_COPY_TIMESTAMPS = (1 << 1),
GST_BUFFER_COPY_CAPS = (1 << 2),
GST_BUFFER_COPY_MEMORY = (1 << 3),
GST_BUFFER_COPY_MERGE = (1 << 4)
} GstBufferCopyFlags;
@ -408,7 +410,7 @@ typedef enum {
* Combination of all possible metadata fields that can be copied with
* gst_buffer_copy_into().
*/
#define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS)
#define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS)
/**
* GST_BUFFER_COPY_ALL:
@ -467,8 +469,8 @@ G_STMT_START { \
GST_MINI_OBJECT_CAST (nbuf)); \
} G_STMT_END
GstContext* gst_buffer_get_context (GstBuffer *buffer);
void gst_buffer_set_context (GstBuffer *buffer, GstContext *context);
GstCaps* gst_buffer_get_caps (GstBuffer *buffer);
void gst_buffer_set_caps (GstBuffer *buffer, GstCaps *caps);
/* creating a region */
GstBuffer* gst_buffer_copy_region (GstBuffer *parent, GstBufferCopyFlags flags,
@ -516,9 +518,6 @@ GstMeta * gst_buffer_iterate_meta (GstBuffer *buffer, gpointer *st
*/
#define gst_value_get_buffer(v) GST_BUFFER_CAST (g_value_get_boxed(v))
/* shortcuts */
GstCaps * gst_buffer_caps (GstBuffer *buffer);
G_END_DECLS
#endif /* __GST_BUFFER_H__ */

View file

@ -60,11 +60,11 @@ gst_context_get_type (void)
static void
_gst_context_free (GstContext * context)
{
GST_LOG ("freeing context %p", context);
g_return_if_fail (context != NULL);
g_return_if_fail (GST_IS_CONTEXT (context));
GST_LOG ("freeing context %p", context);
gst_context_clear (context);
g_slice_free1 (GST_MINI_OBJECT_SIZE (context), context);
@ -181,22 +181,3 @@ gst_context_clear (GstContext * context)
for (i = 0; i < GST_EVENT_MAX_STICKY; i++)
gst_event_replace (&context->events[i], NULL);
}
/**
* gst_context_foreach:
* @context: a #GstContext
* @func: a #GFunc
* @user_data: user data
*
* Call @func with the non NULL event and @user_data.
*/
void
gst_context_foreach (GstContext * context, GFunc func, gpointer user_data)
{
guint i;
GstEvent *event;
for (i = 0; i < GST_EVENT_MAX_STICKY; i++)
if ((event = context->events[i]))
func (event, user_data);
}

View file

@ -23,8 +23,6 @@
#ifndef __GST_CONTEXT_H__
#define __GST_CONTEXT_H__
typedef struct _GstContext GstContext;
#include <gst/gstminiobject.h>
#include <gst/gstevent.h>
@ -32,6 +30,7 @@ G_BEGIN_DECLS
#define GST_CONTEXT_TRACE_NAME "GstContext"
typedef struct _GstContext GstContext;
#define GST_TYPE_CONTEXT (gst_context_get_type())
#define GST_IS_CONTEXT(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_CONTEXT))
@ -135,15 +134,11 @@ gst_context_copy (const GstContext * context)
GstContext * gst_context_new (void);
/* updating and setting events */
void gst_context_update (GstContext *context, GstEvent *event);
GstEvent * gst_context_get (GstContext *context, GstEventType type);
void gst_context_clear (GstContext *context);
/* foreach */
void gst_context_foreach (GstContext *context, GFunc func, gpointer user_data);
G_END_DECLS
#endif /* __GST_CONTEXT_H__ */

View file

@ -25,13 +25,10 @@
#ifndef __GST_EVENT_H__
#define __GST_EVENT_H__
typedef struct _GstEvent GstEvent;
#include <gst/gstminiobject.h>
#include <gst/gstformat.h>
#include <gst/gstobject.h>
#include <gst/gstclock.h>
#include <gst/gstcaps.h>
#include <gst/gststructure.h>
#include <gst/gsttaglist.h>
@ -170,6 +167,8 @@ typedef enum {
*/
#define GST_EVENT_TRACE_NAME "GstEvent"
typedef struct _GstEvent GstEvent;
#define GST_TYPE_EVENT (gst_event_get_type())
#define GST_IS_EVENT(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_EVENT))
#define GST_EVENT(obj) ((GstEvent *)(obj))

View file

@ -623,8 +623,6 @@ gst_ghost_pad_do_unlink (GstPad * pad)
static void
on_int_notify (GstPad * internal, GParamSpec * unused, GstGhostPad * pad)
{
/* FIXME, add new signal for notifying when the context caps change */
#if 0
GstCaps *caps;
gboolean changed;
@ -648,14 +646,11 @@ on_int_notify (GstPad * internal, GParamSpec * unused, GstGhostPad * pad)
if (caps)
gst_caps_unref (caps);
#endif
}
static void
on_src_target_notify (GstPad * target, GParamSpec * unused, gpointer user_data)
{
/* FIXME, add new signal for notifying when the context caps change */
#if 0
GstProxyPad *proxypad;
GstGhostPad *gpad;
GstCaps *caps;
@ -707,7 +702,6 @@ on_src_target_notify (GstPad * target, GParamSpec * unused, gpointer user_data)
done:
if (caps)
gst_caps_unref (caps);
#endif
}
static gboolean

View file

@ -100,6 +100,7 @@ typedef struct _GstPadPushCache GstPadPushCache;
struct _GstPadPushCache
{
GstPad *peer; /* reffed peer pad */
GstCaps *caps; /* caps for this link */
};
static GstPadPushCache _pad_cache_invalid = { NULL, };
@ -370,6 +371,8 @@ gst_pad_init (GstPad * pad)
g_static_rec_mutex_init (pad->stream_rec_lock);
pad->block_cond = g_cond_new ();
pad->context = gst_context_new ();
}
static void
@ -403,10 +406,7 @@ gst_pad_dispose (GObject * object)
pad->block_data = NULL;
}
if (GST_PAD_CONTEXT (pad))
gst_context_replace (&GST_PAD_CONTEXT (pad), NULL);
gst_context_clear (pad->context);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@ -434,6 +434,8 @@ gst_pad_finalize (GObject * object)
pad->block_cond = NULL;
}
gst_context_unref (pad->context);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -618,8 +620,7 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
/* ensures that streaming stops */
GST_PAD_STREAM_LOCK (pad);
GST_DEBUG_OBJECT (pad, "stopped streaming");
if (pad->context)
gst_context_clear (pad->context);
gst_context_clear (pad->context);
GST_PAD_STREAM_UNLOCK (pad);
break;
}
@ -2604,42 +2605,52 @@ could_not_set:
}
}
typedef struct
static gboolean
gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
{
GstPadEventFunction eventfunc;
GstPad *pad;
GstFlowReturn ret;
} ContextData;
gboolean res;
static void
context_func (GstEvent * event, ContextData * data)
{
data->eventfunc (data->pad, gst_event_ref (event));
/* FIXME, update return value when we can */
/* See if pad accepts the caps */
if (!gst_caps_can_intersect (caps, gst_pad_get_pad_template_caps (pad)))
goto not_accepted;
/* set caps on pad if call succeeds */
res = gst_pad_set_caps (pad, caps);
/* no need to unref the caps here, set_caps takes a ref and
* our ref goes away when we leave this function. */
return res;
not_accepted:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
"caps %" GST_PTR_FORMAT " not accepted", caps);
return FALSE;
}
}
static GstFlowReturn
gst_pad_configure_sink (GstPad * pad, GstContext * context)
/* returns TRUE if the src pad could be configured to accept the given caps */
static gboolean
gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
{
ContextData data;
gboolean res;
if (G_UNLIKELY ((data.eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
goto no_function;
if (dosetcaps) {
/* See if pad accepts the caps */
if (!gst_pad_accept_caps (pad, caps))
goto not_accepted;
data.ret = GST_FLOW_OK;
data.pad = pad;
gst_context_foreach (context, (GFunc) context_func, &data);
res = gst_pad_set_caps (pad, caps);
} else {
res = TRUE;
}
return res;
/* set context on pad if all succeeds */
gst_context_replace (&GST_PAD_CONTEXT (pad), context);
return data.ret;
no_function:
not_accepted:
{
g_warning ("pad %s:%s has no event handler, file a bug.",
GST_DEBUG_PAD_NAME (pad));
return GST_FLOW_ERROR;
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
"caps %" GST_PTR_FORMAT " not accepted", caps);
return FALSE;
}
}
@ -3397,22 +3408,22 @@ gst_pad_data_unref (gboolean is_buffer, void *data)
}
}
static GstContext *
gst_pad_data_get_context (gboolean is_buffer, void *data)
static GstCaps *
gst_pad_data_get_caps (gboolean is_buffer, void *data)
{
GstContext *context;
GstCaps *caps;
if (G_LIKELY (is_buffer)) {
context = GST_BUFFER_CONTEXT (data);
caps = GST_BUFFER_CAPS (data);
} else {
GstBuffer *buf;
if ((buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0)))
context = GST_BUFFER_CONTEXT (buf);
caps = GST_BUFFER_CAPS (buf);
else
context = NULL;
caps = NULL;
}
return context;
return caps;
}
/* this is the chain function that does not perform the additional argument
@ -3420,9 +3431,10 @@ gst_pad_data_get_context (gboolean is_buffer, void *data)
*/
static inline GstFlowReturn
gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
GstContext * context, GstPadPushCache * cache)
GstPadPushCache * cache)
{
gboolean context_changed;
GstCaps *caps;
gboolean caps_changed;
GstFlowReturn ret;
gboolean emit_signal;
@ -3432,8 +3444,44 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
context_changed = context && context != GST_PAD_CONTEXT (pad);
caps = gst_pad_data_get_caps (is_buffer, data);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
#if 0
if (G_UNLIKELY (GST_PAD_IS_STICKY_PENDING (pad))) {
GstPadEventFunction eventfunc;
if (G_LIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)))) {
GstEvent *events[GST_EVENT_MAX_STICKY];
GstEvent *event;
guint i;
/* need to make a copy because when we release the object lock, things
* could just change */
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
if ((event = pad->sticky[i]))
events[i] = gst_event_ref (event);
else
events[i] = NULL;
}
/* clear the flag */
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_STICKY_PENDING);
GST_OBJECT_UNLOCK (pad);
/* and push */
GST_DEBUG_OBJECT (pad, "pushing sticky events");
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
if ((event = events[i]))
eventfunc (pad, event);
}
/* and restart, we released the lock things might have changed */
goto again;
}
}
#endif
GST_OBJECT_UNLOCK (pad);
/* see if the signal should be emited, we emit before caps nego as
@ -3451,9 +3499,9 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
}
/* we got a new datatype on the pad, see if it can handle it */
if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "context changed to %p", context);
if (G_UNLIKELY (gst_pad_configure_sink (pad, context) != GST_FLOW_OK))
if (G_UNLIKELY (caps_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
goto not_negotiated;
}
@ -3474,6 +3522,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
if (cache) {
cache->peer = gst_object_ref (pad);
cache->caps = caps ? gst_caps_ref (caps) : NULL;
}
ret = chainfunc (pad, GST_BUFFER_CAST (data));
@ -3517,10 +3566,9 @@ chain_groups:
for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i);
context = GST_BUFFER_CONTEXT (buffer);
ret =
gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_ref (buffer),
context, NULL);
NULL);
if (ret != GST_FLOW_OK)
break;
}
@ -3601,8 +3649,7 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
return gst_pad_chain_data_unchecked (pad, TRUE, buffer,
GST_BUFFER_CONTEXT (buffer), NULL);
return gst_pad_chain_data_unchecked (pad, TRUE, buffer, NULL);
}
/**
@ -3641,17 +3688,17 @@ gst_pad_chain_list (GstPad * pad, GstBufferList * list)
g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
return gst_pad_chain_data_unchecked (pad, FALSE, list,
gst_pad_data_get_context (FALSE, list), NULL);
return gst_pad_chain_data_unchecked (pad, FALSE, list, NULL);
}
static GstFlowReturn
gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
GstContext * context, GstPadPushCache * cache)
GstPadPushCache * cache)
{
GstPad *peer;
GstFlowReturn ret;
gboolean context_changed;
GstCaps *caps;
gboolean caps_changed;
GST_OBJECT_LOCK (pad);
@ -3683,25 +3730,25 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
goto not_linked;
/* Before pushing the buffer to the peer pad, ensure that context
* is set on the buffer */
context_changed = context != GST_PAD_CONTEXT (pad);
/* Before pushing the buffer to the peer pad, ensure that caps
* are set on this pad */
caps = gst_pad_data_get_caps (is_buffer, data);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
/* take ref to peer pad before releasing the lock */
gst_object_ref (peer);
GST_OBJECT_UNLOCK (pad);
/* we got a new datatype from the pad, it had better handle it */
if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "setting context %p on buffer", context);
data = gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (data));
if (is_buffer)
gst_buffer_set_context (GST_BUFFER_CAST (data), context);
if (G_UNLIKELY (caps_changed)) {
GST_DEBUG_OBJECT (pad,
"caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
GST_PAD_CAPS (pad), caps, caps);
if (G_UNLIKELY (!gst_pad_set_caps (pad, caps)))
goto not_negotiated;
}
ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, context, cache);
ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, cache);
gst_object_unref (peer);
@ -3720,8 +3767,7 @@ push_groups:
for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i);
ret = gst_pad_push_data (pad, TRUE, gst_buffer_ref (buffer),
GST_BUFFER_CONTEXT (buffer), NULL);
ret = gst_pad_push_data (pad, TRUE, gst_buffer_ref (buffer), NULL);
if (ret != GST_FLOW_OK)
break;
}
@ -3752,6 +3798,14 @@ not_linked:
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_NOT_LINKED;
}
not_negotiated:
{
gst_pad_data_unref (is_buffer, data);
gst_object_unref (peer);
GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
"element pushed data then refused to accept the caps");
return GST_FLOW_NOT_NEGOTIATED;
}
}
static inline GstPadPushCache *
@ -3777,6 +3831,8 @@ static inline void
pad_free_cache (GstPadPushCache * cache)
{
gst_object_unref (cache->peer);
if (cache->caps)
gst_caps_unref (cache->caps);
g_slice_free (GstPadPushCache, cache);
}
@ -3856,6 +3912,7 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
GstFlowReturn ret;
gpointer *cache_ptr;
GstPad *peer;
GstCaps *caps;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
@ -3868,6 +3925,13 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
if (G_UNLIKELY (cache == NULL))
goto slow_path;
/* check caps */
caps = GST_BUFFER_CAPS (buffer);
if (G_UNLIKELY (caps && caps != cache->caps)) {
pad_free_cache (cache);
goto slow_path;
}
peer = cache->peer;
GST_PAD_STREAM_LOCK (peer);
@ -3898,9 +3962,7 @@ slow_path:
GST_LOG_OBJECT (pad, "Taking slow path");
ret =
gst_pad_push_data (pad, TRUE, buffer, GST_BUFFER_CONTEXT (buffer),
&scache);
ret = gst_pad_push_data (pad, TRUE, buffer, &scache);
if (scache.peer) {
GstPadPushCache *ncache;
@ -3962,10 +4024,12 @@ invalid:
GstFlowReturn
gst_pad_push_list (GstPad * pad, GstBufferList * list)
{
GstBuffer *buf;
GstPadPushCache *cache;
GstFlowReturn ret;
gpointer *cache_ptr;
GstPad *peer;
GstCaps *caps;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
@ -3978,6 +4042,17 @@ gst_pad_push_list (GstPad * pad, GstBufferList * list)
if (G_UNLIKELY (cache == NULL))
goto slow_path;
/* check caps */
if ((buf = gst_buffer_list_get (list, 0)))
caps = GST_BUFFER_CAPS (buf);
else
caps = NULL;
if (G_UNLIKELY (caps && caps != cache->caps)) {
pad_free_cache (cache);
goto slow_path;
}
peer = cache->peer;
GST_PAD_STREAM_LOCK (peer);
@ -3999,8 +4074,7 @@ slow_path:
GST_LOG_OBJECT (pad, "Taking slow path");
ret = gst_pad_push_data (pad, FALSE, list,
gst_pad_data_get_context (FALSE, list), &scache);
ret = gst_pad_push_data (pad, FALSE, list, &scache);
if (scache.peer) {
GstPadPushCache *ncache;
@ -4100,8 +4174,8 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
GstFlowReturn ret;
GstPadGetRangeFunction getrangefunc;
gboolean emit_signal;
GstContext *context;
gboolean context_changed;
GstCaps *caps;
gboolean caps_changed;
GST_PAD_STREAM_LOCK (pad);
@ -4134,17 +4208,17 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
goto get_range_failed;
GST_OBJECT_LOCK (pad);
/* Before pushing the buffer to the peer pad, ensure that context
* is set on this buffer */
context = GST_PAD_CONTEXT (pad);
context_changed = context != GST_BUFFER_CONTEXT (*buffer);
/* Before pushing the buffer to the peer pad, ensure that caps
* are set on this pad */
caps = GST_BUFFER_CAPS (*buffer);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
GST_OBJECT_UNLOCK (pad);
if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "set context on buffer %p", *buffer);
*buffer = gst_buffer_make_writable (*buffer);
gst_buffer_set_context (*buffer, context);
if (G_UNLIKELY (caps_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
/* this should usually work because the element produced the buffer */
if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
goto not_negotiated;
}
return ret;
@ -4182,6 +4256,14 @@ get_range_failed:
pad, "getrange failed, flow: %s", gst_flow_get_name (ret));
return ret;
}
not_negotiated:
{
gst_buffer_unref (*buffer);
*buffer = NULL;
GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
"getrange returned buffer of unaccaptable caps");
return GST_FLOW_NOT_NEGOTIATED;
}
}
/**
@ -4254,8 +4336,8 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
GstPad *peer;
GstFlowReturn ret;
gboolean emit_signal;
GstContext *context;
gboolean context_changed;
GstCaps *caps;
gboolean caps_changed;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
@ -4292,14 +4374,14 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
GST_OBJECT_LOCK (pad);
/* Before pushing the buffer to the peer pad, ensure that caps
* are set on this pad */
context = GST_BUFFER_CONTEXT (*buffer);
context_changed = context && context != GST_PAD_CONTEXT (pad);
caps = GST_BUFFER_CAPS (*buffer);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
GST_OBJECT_UNLOCK (pad);
/* we got a new datatype on the pad, see if it can handle it */
if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "context changed to %p", context);
if (G_UNLIKELY (gst_pad_configure_sink (pad, context) != GST_FLOW_OK))
if (G_UNLIKELY (caps_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
goto not_negotiated;
}
return ret;
@ -4415,13 +4497,7 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
/* store the event on the pad, but only on srcpads */
if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
if (pad->context)
pad->context = gst_context_make_writable (pad->context);
else
pad->context = gst_context_new ();
g_assert (GST_IS_CONTEXT (GST_PAD_CONTEXT (pad)));
pad->context = gst_context_make_writable (pad->context);
gst_context_update (pad->context, event);
}

View file

@ -684,7 +684,6 @@ struct _GstPadClass {
* The caps for this pad.
*/
#define GST_PAD_CAPS(pad) (GST_PAD_CAST(pad)->caps)
#define GST_PAD_CONTEXT(pad) (GST_PAD_CAST(pad)->context)
#define GST_PAD_GETCAPSFUNC(pad) (GST_PAD_CAST(pad)->getcapsfunc)
#define GST_PAD_SETCAPSFUNC(pad) (GST_PAD_CAST(pad)->setcapsfunc)
#define GST_PAD_ACCEPTCAPSFUNC(pad) (GST_PAD_CAST(pad)->acceptcapsfunc)

View file

@ -1668,8 +1668,8 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
queued_frame->buffer = gst_buffer_make_writable (queued_frame->buffer);
gst_buffer_set_context (queued_frame->buffer,
GST_PAD_CONTEXT (GST_BASE_PARSE_SRC_PAD (parse)));
gst_buffer_set_caps (queued_frame->buffer,
GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)));
gst_base_parse_push_frame (parse, queued_frame);
gst_base_parse_frame_free (queued_frame);
}
@ -1858,7 +1858,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* decorate */
buffer = gst_buffer_make_writable (buffer);
gst_buffer_set_context (buffer, GST_PAD_CONTEXT (parse->srcpad));
gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
parse->priv->seen_keyframe |= parse->priv->is_video &&
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);

View file

@ -2160,10 +2160,10 @@ again:
GST_BUFFER_TIMESTAMP (*buf) = 0;
}
/* set pad context on the buffer if the buffer had no caps */
if (GST_BUFFER_CONTEXT (*buf) == NULL) {
/* set pad caps on the buffer if the buffer had no caps */
if (GST_BUFFER_CAPS (*buf) == NULL) {
*buf = gst_buffer_make_writable (*buf);
gst_buffer_set_context (*buf, GST_PAD_CONTEXT (src->srcpad));
gst_buffer_set_caps (*buf, GST_PAD_CAPS (src->srcpad));
}
/* now sync before pushing the buffer */

View file

@ -751,7 +751,6 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
return ret;
}
#if 0
/* check if caps @in on @pad can be transformed to @out on the other pad.
* We don't have a vmethod to test this yet so we have to do a somewhat less
* efficient check for this.
@ -799,7 +798,6 @@ no_subset:
return FALSE;
}
}
#endif
/* given a fixed @caps on @pad, create the best possible caps for the
* other pad.
@ -1275,7 +1273,6 @@ gst_base_transform_query_type (GstPad * pad)
return types;
}
#if 0
static void
compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize,
GstCaps * caps)
@ -1320,7 +1317,6 @@ compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize,
gst_caps_unref (othercaps);
}
}
#endif
/* Allocate a buffer using gst_pad_alloc_buffer
*
@ -1337,9 +1333,9 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
gsize insize, outsize;
gboolean discard, copymeta;
GstCaps *oldcaps, *outcaps;
gsize insize, outsize, newsize, expsize;
gboolean discard, setcaps, copymeta;
GstCaps *incaps, *oldcaps, *newcaps, *outcaps;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
@ -1422,6 +1418,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
oldcaps);
*out_buf = gst_buffer_new_and_alloc (outsize);
gst_buffer_set_caps (*out_buf, oldcaps);
#if 0
ret = gst_pad_alloc_buffer (trans->srcpad,
GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
@ -1435,6 +1432,108 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
if (*out_buf == NULL)
goto no_buffer;
/* check if we got different caps on this new output buffer */
newcaps = GST_BUFFER_CAPS (*out_buf);
newsize = gst_buffer_get_size (*out_buf);
if (newcaps && !gst_caps_is_equal (newcaps, oldcaps)) {
GstCaps *othercaps;
gboolean can_convert;
GST_DEBUG_OBJECT (trans, "received new caps %" GST_PTR_FORMAT, newcaps);
incaps = GST_PAD_CAPS (trans->sinkpad);
/* check if we can convert the current incaps to the new target caps */
can_convert =
gst_base_transform_can_transform (trans, trans->sinkpad, incaps,
newcaps);
if (!can_convert) {
GST_DEBUG_OBJECT (trans, "cannot perform transform on current buffer");
gst_base_transform_transform_size (trans,
GST_PAD_SINK, incaps, insize, newcaps, &expsize);
compute_upstream_suggestion (trans, expsize, newcaps);
/* we got a suggested caps but we can't transform to it. See if there is
* another downstream format that we can transform to */
othercaps =
gst_base_transform_find_transform (trans, trans->sinkpad, incaps);
if (othercaps && !gst_caps_is_empty (othercaps)) {
GST_DEBUG_OBJECT (trans, "we found target caps %" GST_PTR_FORMAT,
othercaps);
*out_buf = gst_buffer_make_writable (*out_buf);
gst_buffer_set_caps (*out_buf, othercaps);
gst_caps_unref (othercaps);
newcaps = GST_BUFFER_CAPS (*out_buf);
can_convert = TRUE;
} else if (othercaps)
gst_caps_unref (othercaps);
}
/* it's possible that the buffer we got is of the wrong size, get the
* expected size here, we will check the size if we are going to use the
* buffer later on. */
gst_base_transform_transform_size (trans,
GST_PAD_SINK, incaps, insize, newcaps, &expsize);
if (can_convert) {
GST_DEBUG_OBJECT (trans, "reconfigure transform for current buffer");
/* subclass might want to add fields to the caps */
if (bclass->fixate_caps != NULL) {
newcaps = gst_caps_copy (newcaps);
GST_DEBUG_OBJECT (trans, "doing fixate %" GST_PTR_FORMAT
" using caps %" GST_PTR_FORMAT
" on pad %s:%s using fixate_caps vmethod", newcaps, incaps,
GST_DEBUG_PAD_NAME (trans->srcpad));
bclass->fixate_caps (trans, GST_PAD_SINK, incaps, newcaps);
*out_buf = gst_buffer_make_writable (*out_buf);
gst_buffer_set_caps (*out_buf, newcaps);
gst_caps_unref (newcaps);
newcaps = GST_BUFFER_CAPS (*out_buf);
}
/* caps not empty, try to renegotiate to the new format */
if (!gst_base_transform_configure_caps (trans, incaps, newcaps)) {
/* not sure we need to fail hard here, we can simply continue our
* conversion with what we negotiated before */
goto failed_configure;
}
/* new format configure, and use the new output buffer */
gst_pad_set_caps (trans->srcpad, newcaps);
discard = FALSE;
/* clear previous cached sink-pad caps, so buffer_alloc knows that
* it needs to revisit the decision about whether to proxy or not: */
gst_caps_replace (&priv->sink_alloc, NULL);
/* if we got a buffer of the wrong size, discard it now and make sure we
* allocate a propertly sized buffer later. */
if (newsize != expsize) {
if (in_buf != *out_buf)
gst_buffer_unref (*out_buf);
*out_buf = NULL;
}
outsize = expsize;
} else {
compute_upstream_suggestion (trans, expsize, newcaps);
if (in_buf != *out_buf)
gst_buffer_unref (*out_buf);
*out_buf = NULL;
}
} else if (outsize != newsize) {
GST_WARNING_OBJECT (trans, "Caps did not change but allocated size does "
"not match expected size (%d != %d)", newsize, outsize);
if (in_buf != *out_buf)
gst_buffer_unref (*out_buf);
*out_buf = NULL;
}
/* these are the final output caps */
outcaps = GST_PAD_CAPS (trans->srcpad);
@ -1487,13 +1586,22 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
}
}
/* check if we need to make things writable. We need this when we need to
* update the caps or the metadata on the output buffer. */
newcaps = GST_BUFFER_CAPS (*out_buf);
/* we check the pointers as a quick check and then go to the more involved
* check. This is needed when we receive different pointers on the sinkpad
* that mean the same caps. What we then want to do is prefer those caps over
* the ones on the srcpad and set the srcpad caps to the buffer caps */
setcaps = !newcaps || ((newcaps != outcaps)
&& (!gst_caps_is_equal (newcaps, outcaps)));
/* we need to modify the metadata when the element is not gap aware,
* passthrough is not used and the gap flag is set */
copymeta |= !trans->priv->gap_aware && !trans->passthrough
&& (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP);
if (copymeta) {
GST_DEBUG_OBJECT (trans, "copymeta %d", copymeta);
if (setcaps || copymeta) {
GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta);
if (!gst_buffer_is_writable (*out_buf)) {
GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf);
if (in_buf == *out_buf)
@ -1502,6 +1610,8 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
*out_buf = gst_buffer_make_writable (*out_buf);
}
/* when we get here, the metadata should be writable */
if (setcaps)
gst_buffer_set_caps (*out_buf, outcaps);
if (copymeta)
gst_buffer_copy_into (*out_buf, in_buf,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
@ -1529,6 +1639,11 @@ unknown_size:
GST_ERROR_OBJECT (trans, "unknown output size");
return GST_FLOW_ERROR;
}
failed_configure:
{
GST_WARNING_OBJECT (trans, "failed to configure caps");
return GST_FLOW_NOT_NEGOTIATED;
}
}
/* Given @caps calcultate the size of one unit.
@ -1749,14 +1864,14 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
{
GstBaseTransformClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
gboolean want_in_place;
gboolean want_in_place, reconfigure;
GstClockTime running_time;
GstClockTime timestamp;
GstCaps *incaps;
gsize insize;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
#if 0
if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) {
GST_OBJECT_LOCK (trans);
reconfigure = trans->priv->reconfigure;
@ -1772,7 +1887,6 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
goto not_negotiated;
}
}
#endif
insize = gst_buffer_get_size (inbuf);

View file

@ -136,7 +136,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
if (ret != GST_FLOW_OK)
goto error;
caps = gst_buffer_caps (buffer);
caps = GST_BUFFER_CAPS (buffer);
if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) {
GST_DEBUG ("buffer has caps %" GST_PTR_FORMAT ", suggest max probability",

View file

@ -409,8 +409,8 @@ void
gst_check_element_push_buffer_list (const gchar * element_name,
GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return)
{
//GstCaps *sink_caps;
//GstCaps *src_caps = NULL;
GstCaps *sink_caps;
GstCaps *src_caps = NULL;
GstElement *element;
GstPad *pad_peer;
GstPad *sink_pad = NULL;
@ -427,9 +427,9 @@ gst_check_element_push_buffer_list (const gchar * element_name,
buffer = GST_BUFFER (buffer_in->data);
fail_unless (GST_IS_BUFFER (buffer), "There should be a buffer in buffer_in");
//src_caps = gst_buffer_caps (buffer);
src_caps = GST_BUFFER_CAPS (buffer);
src_pad = gst_pad_new (NULL, GST_PAD_SRC);
//gst_pad_set_caps (src_pad, src_caps);
gst_pad_set_caps (src_pad, src_caps);
pad_peer = gst_element_get_static_pad (element, "sink");
fail_if (pad_peer == NULL);
fail_unless (gst_pad_link (src_pad, pad_peer) == GST_PAD_LINK_OK,
@ -440,21 +440,21 @@ gst_check_element_push_buffer_list (const gchar * element_name,
GST_DEBUG ("src pad activated");
/* don't create the sink_pad if there is no buffer_out list */
if (buffer_out != NULL) {
//gchar *temp;
gchar *temp;
GST_DEBUG ("buffer out detected, creating the sink pad");
/* get the sink caps */
//sink_caps = gst_buffer_caps (GST_BUFFER (buffer_out->data));
//fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps");
//temp = gst_caps_to_string (sink_caps);
sink_caps = GST_BUFFER_CAPS (GST_BUFFER (buffer_out->data));
fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps");
temp = gst_caps_to_string (sink_caps);
//GST_DEBUG ("sink caps requested by buffer out: '%s'", temp);
//g_free (temp);
//fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps");
GST_DEBUG ("sink caps requested by buffer out: '%s'", temp);
g_free (temp);
fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps");
/* get the sink pad */
sink_pad = gst_pad_new (NULL, GST_PAD_SINK);
fail_unless (GST_IS_PAD (sink_pad));
//gst_pad_set_caps (sink_pad, sink_caps);
gst_pad_set_caps (sink_pad, sink_caps);
/* get the peer pad */
pad_peer = gst_element_get_static_pad (element, "src");
fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK,
@ -497,8 +497,10 @@ gst_check_element_push_buffer_list (const gchar * element_name,
newdata = gst_buffer_map (new, &newsize, NULL, GST_MAP_READ);
origdata = gst_buffer_map (orig, &origsize, NULL, GST_MAP_READ);
GST_LOG ("orig buffer: size %u", origsize);
GST_LOG ("new buffer: size %u", newsize);
GST_LOG ("orig buffer: size %u, caps %" GST_PTR_FORMAT,
origsize, GST_BUFFER_CAPS (orig));
GST_LOG ("new buffer: size %u, caps %" GST_PTR_FORMAT,
newsize, GST_BUFFER_CAPS (new));
GST_MEMDUMP ("orig buffer", origdata, origsize);
GST_MEMDUMP ("new buffer", newdata, newsize);
@ -509,7 +511,7 @@ gst_check_element_push_buffer_list (const gchar * element_name,
fail_unless (origsize == newsize, "size of the buffers are not the same");
fail_unless (memcmp (origdata, newdata, newsize) == 0,
"data is not the same");
//gst_check_caps_equal (GST_BUFFER_CAPS (orig), GST_BUFFER_CAPS (new));
gst_check_caps_equal (GST_BUFFER_CAPS (orig), GST_BUFFER_CAPS (new));
gst_buffer_unmap (orig, origdata, origsize);
gst_buffer_unmap (new, newdata, newsize);

View file

@ -321,10 +321,6 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
{
GstFlowReturn ret = GST_FLOW_OK;
*buf = input;
gst_buffer_ref (input);
#if 0
if (GST_BUFFER_CAPS (input) != NULL) {
/* Output buffer already has caps */
GST_LOG_OBJECT (trans, "Input buffer already has caps (implicitely fixed)");
@ -393,7 +389,6 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
g_free (caps_str);
}
}
#endif
return ret;
}

View file

@ -237,7 +237,7 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
GstFunnelPad *fpad = GST_FUNNEL_PAD_CAST (pad);
GstEvent *event = NULL;
GstClockTime newts;
//GstCaps *padcaps;
GstCaps *padcaps;
GST_DEBUG_OBJECT (funnel, "received buffer %p", buffer);
@ -271,23 +271,23 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
if (!gst_pad_push_event (funnel->srcpad, event))
GST_WARNING_OBJECT (funnel, "Could not push out newsegment event");
}
#if 0
GST_OBJECT_LOCK (pad);
padcontext = GST_PAD_CONTEXT (funnel->srcpad);
padcaps = GST_PAD_CAPS (funnel->srcpad);
GST_OBJECT_UNLOCK (pad);
if (GST_BUFFER_CONTEXT (buffer) && GST_BUFFER_CONTEXT (buffer) != padcontext) {
if (!gst_pad_set_context (funnel->srcpad, GST_BUFFER_CONTEXT (buffer))) {
if (GST_BUFFER_CAPS (buffer) && GST_BUFFER_CAPS (buffer) != padcaps) {
if (!gst_pad_set_caps (funnel->srcpad, GST_BUFFER_CAPS (buffer))) {
res = GST_FLOW_NOT_NEGOTIATED;
goto out;
}
}
#endif
res = gst_pad_push (funnel->srcpad, buffer);
GST_LOG_OBJECT (funnel, "handled buffer %s", gst_flow_get_name (res));
out:
gst_object_unref (funnel);
return res;

View file

@ -541,6 +541,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
GstClockTime start_time;
GstSegment *seg;
GstEvent *close_event = NULL, *start_event = NULL;
GstCaps *caps;
sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
selpad = GST_SELECTOR_PAD_CAST (pad);
@ -629,12 +630,10 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
/* forward */
GST_LOG_OBJECT (pad, "Forwarding buffer %p", buf);
#if 0
if ((caps = GST_BUFFER_CAPS (buf))) {
if (GST_PAD_CAPS (sel->srcpad) != caps)
gst_pad_set_caps (sel->srcpad, caps);
}
#endif
res = gst_pad_push (sel->srcpad, buf);
selpad->pushed = TRUE;

View file

@ -949,10 +949,12 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
if (GST_IS_BUFFER (object)) {
GstBuffer *buffer;
GstClockTime timestamp, duration;
GstCaps *caps;
buffer = GST_BUFFER_CAST (object);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
caps = GST_BUFFER_CAPS (buffer);
apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
@ -963,6 +965,12 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
"SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
sq->id, buffer, GST_TIME_ARGS (timestamp));
/* Set caps on pad before pushing, this avoids core calling the acceptcaps
* function on the srcpad, which will call acceptcaps upstream, which might
* not accept these caps (anymore). */
if (caps && caps != GST_PAD_CAPS (sq->srcpad))
gst_pad_set_caps (sq->srcpad, caps);
result = gst_pad_push (sq->srcpad, buffer);
} else if (GST_IS_EVENT (object)) {
GstEvent *event;

View file

@ -1094,6 +1094,7 @@ gst_queue_push_one (GstQueue * queue)
next:
if (is_buffer) {
GstBuffer *buffer;
GstCaps *caps;
buffer = GST_BUFFER_CAST (data);
@ -1109,7 +1110,16 @@ next:
queue->head_needs_discont = FALSE;
}
caps = GST_BUFFER_CAPS (buffer);
GST_QUEUE_MUTEX_UNLOCK (queue);
/* set the right caps on the pad now. We do this before pushing the buffer
* because the pad_push call will check (using acceptcaps) if the buffer can
* be set on the pad, which might fail because this will be propagated
* upstream. Also note that if the buffer has NULL caps, it means that the
* caps did not change, so we don't have to change caps on the pad. */
if (caps && caps != GST_PAD_CAPS (queue->srcpad))
gst_pad_set_caps (queue->srcpad, caps);
if (queue->push_newsegment) {
gst_queue_push_newsegment (queue);

View file

@ -2204,8 +2204,15 @@ next:
if (is_buffer) {
GstBuffer *buffer;
GstCaps *caps;
buffer = GST_BUFFER_CAST (data);
caps = GST_BUFFER_CAPS (buffer);
/* set caps before pushing the buffer so that core does not try to do
* something fancy to check if this is possible. */
if (caps && caps != GST_PAD_CAPS (queue->srcpad))
gst_pad_set_caps (queue->srcpad, caps);
result = gst_pad_push (queue->srcpad, buffer);

View file

@ -481,6 +481,9 @@ stop_typefinding (GstTypeFindElement * typefind)
goto no_data;
buffer = gst_adapter_take_buffer (typefind->adapter, avail);
buffer = gst_buffer_make_writable (buffer);
gst_buffer_set_caps (buffer, typefind->caps);
GST_OBJECT_UNLOCK (typefind);
if (!push_cached_buffers) {
@ -626,6 +629,8 @@ gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps)
goto no_data;
buffer = gst_adapter_take_buffer (typefind->adapter, avail);
buffer = gst_buffer_make_writable (buffer);
gst_buffer_set_caps (buffer, typefind->caps);
GST_OBJECT_UNLOCK (typefind);
GST_DEBUG_OBJECT (typefind, "Pushing buffer: %d", avail);
@ -739,6 +744,9 @@ gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
/* we should already have called GST_ELEMENT_ERROR */
return GST_FLOW_ERROR;
case MODE_NORMAL:
/* don't take object lock as typefind->caps should not change anymore */
buffer = gst_buffer_make_writable (buffer);
gst_buffer_set_caps (buffer, typefind->caps);
return gst_pad_push (typefind->src, buffer);
case MODE_TYPEFIND:
{
@ -872,6 +880,12 @@ gst_type_find_element_getrange (GstPad * srcpad,
ret = gst_pad_pull_range (typefind->sink, offset, length, buffer);
if (ret == GST_FLOW_OK && buffer && *buffer) {
/* don't take object lock as typefind->caps should not change anymore */
/* we assume that pulled buffers are meta-data writable */
gst_buffer_set_caps (*buffer, typefind->caps);
}
return ret;
}

View file

@ -211,6 +211,7 @@ push_switched_buffers (GList * input_pads,
/* setup dummy buffer */
caps = gst_caps_from_string ("application/x-unknown");
buf = gst_buffer_new_and_alloc (1);
gst_buffer_set_caps (buf, caps);
gst_caps_unref (caps);
while (l != NULL) {

View file

@ -490,7 +490,7 @@ GST_START_TEST (test_flow_aggregation)
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
buffer = gst_buffer_new ();
//gst_buffer_set_caps (buffer, caps);
gst_buffer_set_caps (buffer, caps);
/* First check if everything works in normal state */
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);

View file

@ -32,6 +32,50 @@
#include <gst/check/gstcheck.h>
GST_START_TEST (test_caps)
{
GstBuffer *buffer;
GstCaps *caps, *caps2;
buffer = gst_buffer_new_and_alloc (4);
caps = gst_caps_from_string ("audio/x-raw-int");
ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
gst_buffer_set_caps (buffer, caps);
ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
fail_unless (GST_BUFFER_CAPS (buffer) == caps);
ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
fail_unless (gst_buffer_get_caps (buffer) == caps);
gst_caps_unref (caps);
ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
caps2 = gst_caps_from_string ("audio/x-raw-float");
ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
gst_buffer_set_caps (buffer, caps2);
ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
ASSERT_CAPS_REFCOUNT (caps2, "caps2", 2);
gst_buffer_set_caps (buffer, NULL);
ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
/* clean up, with caps2 still set as caps */
gst_buffer_set_caps (buffer, caps2);
ASSERT_CAPS_REFCOUNT (caps2, "caps2", 2);
gst_buffer_unref (buffer);
ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
gst_caps_unref (caps);
gst_caps_unref (caps2);
}
GST_END_TEST;
GST_START_TEST (test_subbuffer)
{
GstBuffer *buffer, *sub;
@ -448,6 +492,7 @@ gst_buffer_suite (void)
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_caps);
tcase_add_test (tc_chain, test_subbuffer);
tcase_add_test (tc_chain, test_subbuffer_make_writable);
tcase_add_test (tc_chain, test_make_writable);

View file

@ -66,6 +66,7 @@ GST_START_TEST (test_buffer)
gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (1000);
gst_buffer_set_caps (buffer, c1); /* doesn't give away our c1 ref */
gst_caps_unref (c1);
gst_buffer_unref (buffer); /* Should now drop both references */

View file

@ -579,6 +579,7 @@ GST_START_TEST (test_push_negotiation)
/* Should fail if src pad caps are incompatible with sink pad caps */
gst_pad_set_caps (src, caps);
gst_buffer_set_caps (buffer, caps);
gst_buffer_ref (buffer);
fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_NEGOTIATED);
ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);

View file

@ -88,7 +88,7 @@ GST_START_TEST (basetransform_chain_pt1)
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
/* caps should not have been set */
//fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
gst_buffer_unref (buffer);
@ -107,7 +107,7 @@ GST_START_TEST (basetransform_chain_pt1)
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 10);
/* caps should not have been set */
//fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
gst_buffer_unref (buffer);
@ -173,7 +173,7 @@ GST_START_TEST (basetransform_chain_pt2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, caps);
gst_buffer_set_caps (buffer, caps);
buffer_alloc_pt1_called = FALSE;
set_caps_pt2_called = FALSE;
@ -186,7 +186,7 @@ GST_START_TEST (basetransform_chain_pt2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
gst_buffer_unref (buffer);
@ -211,7 +211,7 @@ GST_START_TEST (basetransform_chain_pt2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
buffer = gst_buffer_new_and_alloc (10);
//gst_buffer_set_caps (buffer, caps);
gst_buffer_set_caps (buffer, caps);
buffer_alloc_pt1_called = FALSE;
set_caps_pt2_called = FALSE;
@ -224,7 +224,7 @@ GST_START_TEST (basetransform_chain_pt2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 10);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
gst_buffer_unref (buffer);
@ -438,7 +438,7 @@ GST_START_TEST (basetransform_chain_ip2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, caps);
gst_buffer_set_caps (buffer, caps);
transform_ip_1_called = FALSE;
transform_ip_1_writable = FALSE;
@ -455,7 +455,7 @@ GST_START_TEST (basetransform_chain_ip2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
gst_buffer_unref (buffer);
#if 0
@ -472,7 +472,7 @@ GST_START_TEST (basetransform_chain_ip2)
GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20");
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, caps);
gst_buffer_set_caps (buffer, caps);
/* take additional ref to make it non-writable */
gst_buffer_ref (buffer);
@ -492,7 +492,7 @@ GST_START_TEST (basetransform_chain_ip2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
/* output buffer has refcount 1 */
//fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@ -686,7 +686,7 @@ GST_START_TEST (basetransform_chain_ct1)
/* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
@ -704,11 +704,11 @@ GST_START_TEST (basetransform_chain_ct1)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 40);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
/* take additional ref to make it non-writable */
gst_buffer_ref (buffer);
@ -730,7 +730,7 @@ GST_START_TEST (basetransform_chain_ct1)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 40);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
/* output buffer has refcount 1 */
fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@ -977,7 +977,7 @@ GST_START_TEST (basetransform_chain_ct2)
/* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
@ -997,11 +997,11 @@ GST_START_TEST (basetransform_chain_ct2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
/* take additional ref to make it non-writable */
gst_buffer_ref (buffer);
@ -1023,7 +1023,7 @@ GST_START_TEST (basetransform_chain_ct2)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
/* output buffer has refcount 1 */
//fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@ -1139,7 +1139,7 @@ GST_START_TEST (basetransform_chain_ct3)
/* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
@ -1157,11 +1157,11 @@ GST_START_TEST (basetransform_chain_ct3)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
/* take additional ref to make it non-writable */
gst_buffer_ref (buffer);
@ -1181,7 +1181,7 @@ GST_START_TEST (basetransform_chain_ct3)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20);
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
/* output buffer has refcount 1 */
fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@ -1224,7 +1224,7 @@ GST_START_TEST (basetransform_chain_ct3)
GST_DEBUG_OBJECT (trans,
"buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps);
buffer = gst_buffer_new_and_alloc (10);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
/* don't suggest anything else */
buffer_alloc_ct2_case = 1;
@ -1241,8 +1241,8 @@ GST_START_TEST (basetransform_chain_ct3)
buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL);
/* FIXME changing src caps should produce converted buffer */
//GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT,
// GST_BUFFER_CAPS (buffer));
GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT,
GST_BUFFER_CAPS (buffer));
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
//fail_unless (gst_buffer_get_size (buffer) == 20);
@ -1272,7 +1272,7 @@ GST_START_TEST (basetransform_chain_ct3)
GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
buffer = gst_buffer_new_and_alloc (10);
//gst_buffer_set_caps (buffer, incaps);
gst_buffer_set_caps (buffer, incaps);
/* don't suggest anything else */
buffer_alloc_ct2_suggest = FALSE;

View file

@ -367,15 +367,12 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
if (img) {
gchar *caps_str;
GstCaps *caps;
caps = gst_buffer_caps (img);
caps_str = caps ? gst_caps_to_string (caps) : g_strdup ("unknown");
caps_str = GST_BUFFER_CAPS (img) ?
gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown");
str = g_strdup_printf ("buffer of %" G_GSIZE_FORMAT " bytes, type: %s",
gst_buffer_get_size (img), caps_str);
g_free (caps_str);
if (caps)
gst_caps_unref (caps);
} else {
str = g_strdup ("NULL buffer");
}