context: use context on buffers instead of caps

Put the srcpad context on buffers instead of caps. This allows us to associate
all the relevant info contained in events with a buffer.
This commit is contained in:
Wim Taymans 2011-05-04 18:59:47 +02:00
parent 9136abf623
commit 9ef1346b1f
28 changed files with 266 additions and 493 deletions

View file

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

View file

@ -306,10 +306,6 @@ 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) { if (flags & GST_BUFFER_COPY_MEMORY) {
GstMemory *mem; GstMemory *mem;
gsize skip, left, len, i, bsize; gsize skip, left, len, i, bsize;
@ -402,7 +398,7 @@ _gst_buffer_free (GstBuffer * buffer)
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer); GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL); gst_context_replace (&GST_BUFFER_CONTEXT (buffer), NULL);
/* free metadata */ /* free metadata */
for (walk = GST_BUFFER_META (buffer); walk; walk = next) { for (walk = GST_BUFFER_META (buffer); walk; walk = next) {
@ -444,7 +440,7 @@ gst_buffer_init (GstBufferImpl * buffer, gsize size)
(GstMiniObjectFreeFunction) _gst_buffer_free; (GstMiniObjectFreeFunction) _gst_buffer_free;
GST_BUFFER (buffer)->pool = NULL; GST_BUFFER (buffer)->pool = NULL;
GST_BUFFER_CAPS (buffer) = NULL; GST_BUFFER_CONTEXT (buffer) = NULL;
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE; GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
@ -1057,58 +1053,52 @@ gst_buffer_memcmp (GstBuffer * buffer, gsize offset, gconstpointer mem,
} }
/** /**
* gst_buffer_get_caps: * gst_buffer_get_context:
* @buffer: a #GstBuffer. * @buffer: a #GstBuffer.
* *
* Gets the media type of the buffer. This can be NULL if there * Gets the context of the buffer. This can be NULL if there
* is no media type attached to this buffer. * is no context attached to this buffer.
* *
* Returns: (transfer full): a reference to the #GstCaps. unref after usage. * Returns: (transfer full): a reference to the #GstContext. unref after usage.
* Returns NULL if there were no caps on this buffer. * Returns NULL if there was no context on this buffer.
*/ */
/* this is not made atomic because if the buffer were reffed from multiple /* this is not made atomic because if the buffer were reffed from multiple
* threads, it would have a refcount > 2 and thus be immutable. * threads, it would have a refcount > 2 and thus be immutable.
*/ */
GstCaps * GstContext *
gst_buffer_get_caps (GstBuffer * buffer) gst_buffer_get_context (GstBuffer * buffer)
{ {
GstCaps *ret; GstContext *ret;
g_return_val_if_fail (buffer != NULL, NULL); g_return_val_if_fail (buffer != NULL, NULL);
ret = GST_BUFFER_CAPS (buffer); ret = GST_BUFFER_CONTEXT (buffer);
if (ret) if (ret)
gst_caps_ref (ret); gst_context_ref (ret);
return ret; return ret;
} }
/** /**
* gst_buffer_set_caps: * gst_buffer_set_context:
* @buffer: a #GstBuffer. * @buffer: a #GstBuffer.
* @caps: (transfer none): a #GstCaps. * @context: (transfer none): a #GstContext.
* *
* Sets the media type on the buffer. The refcount of the caps will * Sets the media type on the buffer. The refcount of the context will
* be increased and any previous caps on the buffer will be * be increased and any previous context on the buffer will be
* unreffed. * unreffed.
*/ */
/* this is not made atomic because if the buffer were reffed from multiple /* this is not made atomic because if the buffer were reffed from multiple
* threads, it would have a refcount > 2 and thus be immutable. * threads, it would have a refcount > 2 and thus be immutable.
*/ */
void void
gst_buffer_set_caps (GstBuffer * buffer, GstCaps * caps) gst_buffer_set_context (GstBuffer * buffer, GstContext * context)
{ {
g_return_if_fail (buffer != NULL); g_return_if_fail (buffer != NULL);
g_return_if_fail (caps == NULL || GST_CAPS_IS_SIMPLE (caps)); g_return_if_fail (gst_buffer_is_writable (buffer));
#if GST_VERSION_NANO == 1 gst_context_replace (&GST_BUFFER_CONTEXT (buffer), context);
/* 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);
} }
/** /**
@ -1509,3 +1499,22 @@ gst_buffer_iterate_meta (GstBuffer * buffer, gpointer * state)
else else
return NULL; 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__ #ifndef __GST_BUFFER_H__
#define __GST_BUFFER_H__ #define __GST_BUFFER_H__
typedef struct _GstBuffer GstBuffer;
typedef struct _GstBufferPool GstBufferPool;
#include <gst/gstminiobject.h> #include <gst/gstminiobject.h>
#include <gst/gstclock.h> #include <gst/gstclock.h>
#include <gst/gstcaps.h> #include <gst/gstcontext.h>
#include <gst/gstmemory.h> #include <gst/gstmemory.h>
G_BEGIN_DECLS G_BEGIN_DECLS
extern GType _gst_buffer_type; extern GType _gst_buffer_type;
typedef struct _GstBuffer GstBuffer;
typedef struct _GstBufferPool GstBufferPool;
/** /**
* GST_BUFFER_TRACE_NAME: * GST_BUFFER_TRACE_NAME:
* *
@ -112,12 +112,12 @@ typedef struct _GstBufferPool GstBufferPool;
*/ */
#define GST_BUFFER_DURATION(buf) (GST_BUFFER_CAST(buf)->duration) #define GST_BUFFER_DURATION(buf) (GST_BUFFER_CAST(buf)->duration)
/** /**
* GST_BUFFER_CAPS: * GST_BUFFER_CONTEXT:
* @buf: a #GstBuffer. * @buf: a #GstBuffer.
* *
* The caps for this buffer. * The context for this buffer.
*/ */
#define GST_BUFFER_CAPS(buf) (GST_BUFFER_CAST(buf)->caps) #define GST_BUFFER_CONTEXT(buf) (GST_BUFFER_CAST(buf)->context)
/** /**
* GST_BUFFER_OFFSET: * GST_BUFFER_OFFSET:
* @buf: a #GstBuffer. * @buf: a #GstBuffer.
@ -260,7 +260,7 @@ struct _GstBuffer {
/*< public >*/ /* with COW */ /*< public >*/ /* with COW */
GstBufferPool *pool; GstBufferPool *pool;
/* the media type of this buffer */ /* the media type of this buffer */
GstCaps *caps; GstContext *context;
/* timestamp */ /* timestamp */
GstClockTime timestamp; GstClockTime timestamp;
@ -386,7 +386,6 @@ gst_buffer_copy (const GstBuffer * buf)
* @GST_BUFFER_COPY_FLAGS: flag indicating that buffer flags should be copied * @GST_BUFFER_COPY_FLAGS: flag indicating that buffer flags should be copied
* @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration, * @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration,
* offset and offset_end should be copied * 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 * @GST_BUFFER_COPY_MEMORY: flag indicating that buffer memory should be copied
* and appended to already existing memory * and appended to already existing memory
* @GST_BUFFER_COPY_MERGE: flag indicating that buffer memory should be * @GST_BUFFER_COPY_MERGE: flag indicating that buffer memory should be
@ -399,7 +398,6 @@ typedef enum {
GST_BUFFER_COPY_NONE = 0, GST_BUFFER_COPY_NONE = 0,
GST_BUFFER_COPY_FLAGS = (1 << 0), GST_BUFFER_COPY_FLAGS = (1 << 0),
GST_BUFFER_COPY_TIMESTAMPS = (1 << 1), GST_BUFFER_COPY_TIMESTAMPS = (1 << 1),
GST_BUFFER_COPY_CAPS = (1 << 2),
GST_BUFFER_COPY_MEMORY = (1 << 3), GST_BUFFER_COPY_MEMORY = (1 << 3),
GST_BUFFER_COPY_MERGE = (1 << 4) GST_BUFFER_COPY_MERGE = (1 << 4)
} GstBufferCopyFlags; } GstBufferCopyFlags;
@ -410,7 +408,7 @@ typedef enum {
* Combination of all possible metadata fields that can be copied with * Combination of all possible metadata fields that can be copied with
* gst_buffer_copy_into(). * gst_buffer_copy_into().
*/ */
#define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS) #define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS)
/** /**
* GST_BUFFER_COPY_ALL: * GST_BUFFER_COPY_ALL:
@ -469,8 +467,8 @@ G_STMT_START { \
GST_MINI_OBJECT_CAST (nbuf)); \ GST_MINI_OBJECT_CAST (nbuf)); \
} G_STMT_END } G_STMT_END
GstCaps* gst_buffer_get_caps (GstBuffer *buffer); GstContext* gst_buffer_get_context (GstBuffer *buffer);
void gst_buffer_set_caps (GstBuffer *buffer, GstCaps *caps); void gst_buffer_set_context (GstBuffer *buffer, GstContext *context);
/* creating a region */ /* creating a region */
GstBuffer* gst_buffer_copy_region (GstBuffer *parent, GstBufferCopyFlags flags, GstBuffer* gst_buffer_copy_region (GstBuffer *parent, GstBufferCopyFlags flags,
@ -518,6 +516,9 @@ GstMeta * gst_buffer_iterate_meta (GstBuffer *buffer, gpointer *st
*/ */
#define gst_value_get_buffer(v) GST_BUFFER_CAST (g_value_get_boxed(v)) #define gst_value_get_buffer(v) GST_BUFFER_CAST (g_value_get_boxed(v))
/* shortcuts */
GstCaps * gst_buffer_caps (GstBuffer *buffer);
G_END_DECLS G_END_DECLS
#endif /* __GST_BUFFER_H__ */ #endif /* __GST_BUFFER_H__ */

View file

@ -60,11 +60,11 @@ gst_context_get_type (void)
static void static void
_gst_context_free (GstContext * context) _gst_context_free (GstContext * context)
{ {
GST_LOG ("freeing context %p", context);
g_return_if_fail (context != NULL); g_return_if_fail (context != NULL);
g_return_if_fail (GST_IS_CONTEXT (context)); g_return_if_fail (GST_IS_CONTEXT (context));
GST_LOG ("freeing context %p", context);
gst_context_clear (context); gst_context_clear (context);
g_slice_free1 (GST_MINI_OBJECT_SIZE (context), context); g_slice_free1 (GST_MINI_OBJECT_SIZE (context), context);
@ -181,3 +181,22 @@ gst_context_clear (GstContext * context)
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) for (i = 0; i < GST_EVENT_MAX_STICKY; i++)
gst_event_replace (&context->events[i], NULL); 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,6 +23,8 @@
#ifndef __GST_CONTEXT_H__ #ifndef __GST_CONTEXT_H__
#define __GST_CONTEXT_H__ #define __GST_CONTEXT_H__
typedef struct _GstContext GstContext;
#include <gst/gstminiobject.h> #include <gst/gstminiobject.h>
#include <gst/gstevent.h> #include <gst/gstevent.h>
@ -30,7 +32,6 @@ G_BEGIN_DECLS
#define GST_CONTEXT_TRACE_NAME "GstContext" #define GST_CONTEXT_TRACE_NAME "GstContext"
typedef struct _GstContext GstContext;
#define GST_TYPE_CONTEXT (gst_context_get_type()) #define GST_TYPE_CONTEXT (gst_context_get_type())
#define GST_IS_CONTEXT(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_CONTEXT)) #define GST_IS_CONTEXT(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_CONTEXT))
@ -134,11 +135,15 @@ gst_context_copy (const GstContext * context)
GstContext * gst_context_new (void); GstContext * gst_context_new (void);
/* updating and setting events */
void gst_context_update (GstContext *context, GstEvent *event); void gst_context_update (GstContext *context, GstEvent *event);
GstEvent * gst_context_get (GstContext *context, GstEventType type); GstEvent * gst_context_get (GstContext *context, GstEventType type);
void gst_context_clear (GstContext *context); void gst_context_clear (GstContext *context);
/* foreach */
void gst_context_foreach (GstContext *context, GFunc func, gpointer user_data);
G_END_DECLS G_END_DECLS
#endif /* __GST_CONTEXT_H__ */ #endif /* __GST_CONTEXT_H__ */

View file

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

View file

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

View file

@ -100,7 +100,6 @@ typedef struct _GstPadPushCache GstPadPushCache;
struct _GstPadPushCache struct _GstPadPushCache
{ {
GstPad *peer; /* reffed peer pad */ GstPad *peer; /* reffed peer pad */
GstCaps *caps; /* caps for this link */
}; };
static GstPadPushCache _pad_cache_invalid = { NULL, }; static GstPadPushCache _pad_cache_invalid = { NULL, };
@ -371,8 +370,6 @@ gst_pad_init (GstPad * pad)
g_static_rec_mutex_init (pad->stream_rec_lock); g_static_rec_mutex_init (pad->stream_rec_lock);
pad->block_cond = g_cond_new (); pad->block_cond = g_cond_new ();
pad->context = gst_context_new ();
} }
static void static void
@ -406,7 +403,10 @@ gst_pad_dispose (GObject * object)
pad->block_data = NULL; pad->block_data = NULL;
} }
gst_context_clear (pad->context);
if (GST_PAD_CONTEXT (pad))
gst_context_replace (&GST_PAD_CONTEXT (pad), NULL);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -434,8 +434,6 @@ gst_pad_finalize (GObject * object)
pad->block_cond = NULL; pad->block_cond = NULL;
} }
gst_context_unref (pad->context);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -620,6 +618,7 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
/* ensures that streaming stops */ /* ensures that streaming stops */
GST_PAD_STREAM_LOCK (pad); GST_PAD_STREAM_LOCK (pad);
GST_DEBUG_OBJECT (pad, "stopped streaming"); GST_DEBUG_OBJECT (pad, "stopped streaming");
if (pad->context)
gst_context_clear (pad->context); gst_context_clear (pad->context);
GST_PAD_STREAM_UNLOCK (pad); GST_PAD_STREAM_UNLOCK (pad);
break; break;
@ -2605,52 +2604,42 @@ could_not_set:
} }
} }
static gboolean typedef struct
gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
{ {
gboolean res; GstPadEventFunction eventfunc;
GstPad *pad;
GstFlowReturn ret;
} ContextData;
/* See if pad accepts the caps */ static void
if (!gst_caps_can_intersect (caps, gst_pad_get_pad_template_caps (pad))) context_func (GstEvent * event, ContextData * data)
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, data->eventfunc (data->pad, gst_event_ref (event));
"caps %" GST_PTR_FORMAT " not accepted", caps); /* FIXME, update return value when we can */
return FALSE;
}
} }
/* returns TRUE if the src pad could be configured to accept the given caps */ static GstFlowReturn
static gboolean gst_pad_configure_sink (GstPad * pad, GstContext * context)
gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
{ {
gboolean res; ContextData data;
if (dosetcaps) { if (G_UNLIKELY ((data.eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
/* See if pad accepts the caps */ goto no_function;
if (!gst_pad_accept_caps (pad, caps))
goto not_accepted;
res = gst_pad_set_caps (pad, caps); data.ret = GST_FLOW_OK;
} else { data.pad = pad;
res = TRUE; gst_context_foreach (context, (GFunc) context_func, &data);
}
return res;
not_accepted: /* set context on pad if all succeeds */
gst_context_replace (&GST_PAD_CONTEXT (pad), context);
return data.ret;
no_function:
{ {
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, g_warning ("pad %s:%s has no event handler, file a bug.",
"caps %" GST_PTR_FORMAT " not accepted", caps); GST_DEBUG_PAD_NAME (pad));
return FALSE; return GST_FLOW_ERROR;
} }
} }
@ -3407,22 +3396,22 @@ gst_pad_data_unref (gboolean is_buffer, void *data)
} }
} }
static GstCaps * static GstContext *
gst_pad_data_get_caps (gboolean is_buffer, void *data) gst_pad_data_get_context (gboolean is_buffer, void *data)
{ {
GstCaps *caps; GstContext *context;
if (G_LIKELY (is_buffer)) { if (G_LIKELY (is_buffer)) {
caps = GST_BUFFER_CAPS (data); context = GST_BUFFER_CONTEXT (data);
} else { } else {
GstBuffer *buf; GstBuffer *buf;
if ((buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0))) if ((buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0)))
caps = GST_BUFFER_CAPS (buf); context = GST_BUFFER_CONTEXT (buf);
else else
caps = NULL; context = NULL;
} }
return caps; return context;
} }
/* this is the chain function that does not perform the additional argument /* this is the chain function that does not perform the additional argument
@ -3430,10 +3419,9 @@ gst_pad_data_get_caps (gboolean is_buffer, void *data)
*/ */
static inline GstFlowReturn static inline GstFlowReturn
gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data, gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
GstPadPushCache * cache) GstContext * context, GstPadPushCache * cache)
{ {
GstCaps *caps; gboolean context_changed;
gboolean caps_changed;
GstFlowReturn ret; GstFlowReturn ret;
gboolean emit_signal; gboolean emit_signal;
@ -3443,44 +3431,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing; goto flushing;
caps = gst_pad_data_get_caps (is_buffer, data); context_changed = context && context != GST_PAD_CONTEXT (pad);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0; 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); GST_OBJECT_UNLOCK (pad);
/* see if the signal should be emited, we emit before caps nego as /* see if the signal should be emited, we emit before caps nego as
@ -3498,9 +3450,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 */ /* we got a new datatype on the pad, see if it can handle it */
if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps); GST_DEBUG_OBJECT (pad, "context changed to %p", context);
if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps))) if (G_UNLIKELY (gst_pad_configure_sink (pad, context) != GST_FLOW_OK))
goto not_negotiated; goto not_negotiated;
} }
@ -3521,7 +3473,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
if (cache) { if (cache) {
cache->peer = gst_object_ref (pad); cache->peer = gst_object_ref (pad);
cache->caps = caps ? gst_caps_ref (caps) : NULL;
} }
ret = chainfunc (pad, GST_BUFFER_CAST (data)); ret = chainfunc (pad, GST_BUFFER_CAST (data));
@ -3565,9 +3516,10 @@ chain_groups:
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i); buffer = gst_buffer_list_get (list, i);
context = GST_BUFFER_CONTEXT (buffer);
ret = ret =
gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_ref (buffer), gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_ref (buffer),
NULL); context, NULL);
if (ret != GST_FLOW_OK) if (ret != GST_FLOW_OK)
break; break;
} }
@ -3648,7 +3600,8 @@ 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_PAD_IS_SINK (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
return gst_pad_chain_data_unchecked (pad, TRUE, buffer, NULL); return gst_pad_chain_data_unchecked (pad, TRUE, buffer,
GST_BUFFER_CONTEXT (buffer), NULL);
} }
/** /**
@ -3687,17 +3640,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_PAD_IS_SINK (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 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, NULL); return gst_pad_chain_data_unchecked (pad, FALSE, list,
gst_pad_data_get_context (FALSE, list), NULL);
} }
static GstFlowReturn static GstFlowReturn
gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data, gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
GstPadPushCache * cache) GstContext * context, GstPadPushCache * cache)
{ {
GstPad *peer; GstPad *peer;
GstFlowReturn ret; GstFlowReturn ret;
GstCaps *caps; gboolean context_changed;
gboolean caps_changed;
GST_OBJECT_LOCK (pad); GST_OBJECT_LOCK (pad);
@ -3729,25 +3682,25 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL)) if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
goto not_linked; goto not_linked;
/* Before pushing the buffer to the peer pad, ensure that caps /* Before pushing the buffer to the peer pad, ensure that context
* are set on this pad */ * is set on the buffer */
caps = gst_pad_data_get_caps (is_buffer, data); context_changed = context != GST_PAD_CONTEXT (pad);
caps_changed = caps && caps != GST_PAD_CAPS (pad);
/* take ref to peer pad before releasing the lock */ /* take ref to peer pad before releasing the lock */
gst_object_ref (peer); gst_object_ref (peer);
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
/* we got a new datatype from the pad, it had better handle it */ /* we got a new datatype from the pad, it had better handle it */
if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, GST_DEBUG_OBJECT (pad, "setting context %p on buffer", context);
"caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
GST_PAD_CAPS (pad), caps, caps); data = gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (data));
if (G_UNLIKELY (!gst_pad_set_caps (pad, caps)))
goto not_negotiated; if (is_buffer)
gst_buffer_set_context (GST_BUFFER_CAST (data), context);
} }
ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, cache); ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, context, cache);
gst_object_unref (peer); gst_object_unref (peer);
@ -3766,7 +3719,8 @@ push_groups:
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i); buffer = gst_buffer_list_get (list, i);
ret = gst_pad_push_data (pad, TRUE, gst_buffer_ref (buffer), NULL); ret = gst_pad_push_data (pad, TRUE, gst_buffer_ref (buffer),
GST_BUFFER_CONTEXT (buffer), NULL);
if (ret != GST_FLOW_OK) if (ret != GST_FLOW_OK)
break; break;
} }
@ -3797,14 +3751,6 @@ not_linked:
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
return GST_FLOW_NOT_LINKED; 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 * static inline GstPadPushCache *
@ -3830,8 +3776,6 @@ static inline void
pad_free_cache (GstPadPushCache * cache) pad_free_cache (GstPadPushCache * cache)
{ {
gst_object_unref (cache->peer); gst_object_unref (cache->peer);
if (cache->caps)
gst_caps_unref (cache->caps);
g_slice_free (GstPadPushCache, cache); g_slice_free (GstPadPushCache, cache);
} }
@ -3911,7 +3855,6 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
GstFlowReturn ret; GstFlowReturn ret;
gpointer *cache_ptr; gpointer *cache_ptr;
GstPad *peer; GstPad *peer;
GstCaps *caps;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); 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); g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
@ -3924,13 +3867,6 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
if (G_UNLIKELY (cache == NULL)) if (G_UNLIKELY (cache == NULL))
goto slow_path; 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; peer = cache->peer;
GST_PAD_STREAM_LOCK (peer); GST_PAD_STREAM_LOCK (peer);
@ -3961,7 +3897,9 @@ slow_path:
GST_LOG_OBJECT (pad, "Taking slow path"); GST_LOG_OBJECT (pad, "Taking slow path");
ret = gst_pad_push_data (pad, TRUE, buffer, &scache); ret =
gst_pad_push_data (pad, TRUE, buffer, GST_BUFFER_CONTEXT (buffer),
&scache);
if (scache.peer) { if (scache.peer) {
GstPadPushCache *ncache; GstPadPushCache *ncache;
@ -4023,12 +3961,10 @@ invalid:
GstFlowReturn GstFlowReturn
gst_pad_push_list (GstPad * pad, GstBufferList * list) gst_pad_push_list (GstPad * pad, GstBufferList * list)
{ {
GstBuffer *buf;
GstPadPushCache *cache; GstPadPushCache *cache;
GstFlowReturn ret; GstFlowReturn ret;
gpointer *cache_ptr; gpointer *cache_ptr;
GstPad *peer; GstPad *peer;
GstCaps *caps;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); 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); g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
@ -4041,17 +3977,6 @@ gst_pad_push_list (GstPad * pad, GstBufferList * list)
if (G_UNLIKELY (cache == NULL)) if (G_UNLIKELY (cache == NULL))
goto slow_path; 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; peer = cache->peer;
GST_PAD_STREAM_LOCK (peer); GST_PAD_STREAM_LOCK (peer);
@ -4073,7 +3998,8 @@ slow_path:
GST_LOG_OBJECT (pad, "Taking slow path"); GST_LOG_OBJECT (pad, "Taking slow path");
ret = gst_pad_push_data (pad, FALSE, list, &scache); ret = gst_pad_push_data (pad, FALSE, list,
gst_pad_data_get_context (FALSE, list), &scache);
if (scache.peer) { if (scache.peer) {
GstPadPushCache *ncache; GstPadPushCache *ncache;
@ -4173,8 +4099,8 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
GstFlowReturn ret; GstFlowReturn ret;
GstPadGetRangeFunction getrangefunc; GstPadGetRangeFunction getrangefunc;
gboolean emit_signal; gboolean emit_signal;
GstCaps *caps; GstContext *context;
gboolean caps_changed; gboolean context_changed;
GST_PAD_STREAM_LOCK (pad); GST_PAD_STREAM_LOCK (pad);
@ -4207,17 +4133,17 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
goto get_range_failed; goto get_range_failed;
GST_OBJECT_LOCK (pad); GST_OBJECT_LOCK (pad);
/* Before pushing the buffer to the peer pad, ensure that caps /* Before pushing the buffer to the peer pad, ensure that context
* are set on this pad */ * is set on this buffer */
caps = GST_BUFFER_CAPS (*buffer); context = GST_PAD_CONTEXT (pad);
caps_changed = caps && caps != GST_PAD_CAPS (pad); context_changed = context != GST_BUFFER_CONTEXT (*buffer);
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps); GST_DEBUG_OBJECT (pad, "set context on buffer %p", *buffer);
/* this should usually work because the element produced the buffer */
if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE))) *buffer = gst_buffer_make_writable (*buffer);
goto not_negotiated; gst_buffer_set_context (*buffer, context);
} }
return ret; return ret;
@ -4255,14 +4181,6 @@ get_range_failed:
pad, "getrange failed, flow: %s", gst_flow_get_name (ret)); pad, "getrange failed, flow: %s", gst_flow_get_name (ret));
return 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;
}
} }
/** /**
@ -4335,8 +4253,8 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
GstPad *peer; GstPad *peer;
GstFlowReturn ret; GstFlowReturn ret;
gboolean emit_signal; gboolean emit_signal;
GstCaps *caps; GstContext *context;
gboolean caps_changed; gboolean context_changed;
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); 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); g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
@ -4373,14 +4291,14 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
GST_OBJECT_LOCK (pad); GST_OBJECT_LOCK (pad);
/* Before pushing the buffer to the peer pad, ensure that caps /* Before pushing the buffer to the peer pad, ensure that caps
* are set on this pad */ * are set on this pad */
caps = GST_BUFFER_CAPS (*buffer); context = GST_BUFFER_CONTEXT (*buffer);
caps_changed = caps && caps != GST_PAD_CAPS (pad); context_changed = context && context != GST_PAD_CONTEXT (pad);
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
/* we got a new datatype on the pad, see if it can handle it */ /* we got a new datatype on the pad, see if it can handle it */
if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (context_changed)) {
GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps); GST_DEBUG_OBJECT (pad, "context changed to %p", context);
if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps))) if (G_UNLIKELY (gst_pad_configure_sink (pad, context) != GST_FLOW_OK))
goto not_negotiated; goto not_negotiated;
} }
return ret; return ret;
@ -4496,7 +4414,13 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
/* store the event on the pad, but only on srcpads */ /* store the event on the pad, but only on srcpads */
if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) { if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
if (pad->context)
pad->context = gst_context_make_writable (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)));
gst_context_update (pad->context, event); gst_context_update (pad->context, event);
} }

View file

@ -684,6 +684,7 @@ struct _GstPadClass {
* The caps for this pad. * The caps for this pad.
*/ */
#define GST_PAD_CAPS(pad) (GST_PAD_CAST(pad)->caps) #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_GETCAPSFUNC(pad) (GST_PAD_CAST(pad)->getcapsfunc)
#define GST_PAD_SETCAPSFUNC(pad) (GST_PAD_CAST(pad)->setcapsfunc) #define GST_PAD_SETCAPSFUNC(pad) (GST_PAD_CAST(pad)->setcapsfunc)
#define GST_PAD_ACCEPTCAPSFUNC(pad) (GST_PAD_CAST(pad)->acceptcapsfunc) #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))) { while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
queued_frame->buffer = gst_buffer_make_writable (queued_frame->buffer); queued_frame->buffer = gst_buffer_make_writable (queued_frame->buffer);
gst_buffer_set_caps (queued_frame->buffer, gst_buffer_set_context (queued_frame->buffer,
GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse))); GST_PAD_CONTEXT (GST_BASE_PARSE_SRC_PAD (parse)));
gst_base_parse_push_frame (parse, queued_frame); gst_base_parse_push_frame (parse, queued_frame);
gst_base_parse_frame_free (queued_frame); gst_base_parse_frame_free (queued_frame);
} }
@ -1858,7 +1858,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* decorate */ /* decorate */
buffer = gst_buffer_make_writable (buffer); buffer = gst_buffer_make_writable (buffer);
gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad)); gst_buffer_set_context (buffer, GST_PAD_CONTEXT (parse->srcpad));
parse->priv->seen_keyframe |= parse->priv->is_video && parse->priv->seen_keyframe |= parse->priv->is_video &&
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);

View file

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

View file

@ -751,6 +751,7 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
return ret; return ret;
} }
#if 0
/* check if caps @in on @pad can be transformed to @out on the other pad. /* 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 * We don't have a vmethod to test this yet so we have to do a somewhat less
* efficient check for this. * efficient check for this.
@ -798,6 +799,7 @@ no_subset:
return FALSE; return FALSE;
} }
} }
#endif
/* given a fixed @caps on @pad, create the best possible caps for the /* given a fixed @caps on @pad, create the best possible caps for the
* other pad. * other pad.
@ -1273,6 +1275,7 @@ gst_base_transform_query_type (GstPad * pad)
return types; return types;
} }
#if 0
static void static void
compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize, compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize,
GstCaps * caps) GstCaps * caps)
@ -1317,6 +1320,7 @@ compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize,
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
} }
} }
#endif
/* Allocate a buffer using gst_pad_alloc_buffer /* Allocate a buffer using gst_pad_alloc_buffer
* *
@ -1333,9 +1337,9 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
GstBaseTransformClass *bclass; GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv; GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gsize insize, outsize, newsize, expsize; gsize insize, outsize;
gboolean discard, setcaps, copymeta; gboolean discard, setcaps, copymeta;
GstCaps *incaps, *oldcaps, *newcaps, *outcaps; GstCaps *oldcaps, *outcaps;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
@ -1418,7 +1422,6 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
oldcaps); oldcaps);
*out_buf = gst_buffer_new_and_alloc (outsize); *out_buf = gst_buffer_new_and_alloc (outsize);
gst_buffer_set_caps (*out_buf, oldcaps);
#if 0 #if 0
ret = gst_pad_alloc_buffer (trans->srcpad, ret = gst_pad_alloc_buffer (trans->srcpad,
GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf); GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
@ -1432,108 +1435,6 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
if (*out_buf == NULL) if (*out_buf == NULL)
goto no_buffer; 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 */ /* these are the final output caps */
outcaps = GST_PAD_CAPS (trans->srcpad); outcaps = GST_PAD_CAPS (trans->srcpad);
@ -1586,21 +1487,12 @@ 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, /* we need to modify the metadata when the element is not gap aware,
* passthrough is not used and the gap flag is set */ * passthrough is not used and the gap flag is set */
copymeta |= !trans->priv->gap_aware && !trans->passthrough copymeta |= !trans->priv->gap_aware && !trans->passthrough
&& (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP); && (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP);
if (setcaps || copymeta) { if (copymeta) {
GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta); GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta);
if (!gst_buffer_is_writable (*out_buf)) { if (!gst_buffer_is_writable (*out_buf)) {
GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf); GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf);
@ -1610,8 +1502,6 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
*out_buf = gst_buffer_make_writable (*out_buf); *out_buf = gst_buffer_make_writable (*out_buf);
} }
/* when we get here, the metadata should be writable */ /* when we get here, the metadata should be writable */
if (setcaps)
gst_buffer_set_caps (*out_buf, outcaps);
if (copymeta) if (copymeta)
gst_buffer_copy_into (*out_buf, in_buf, gst_buffer_copy_into (*out_buf, in_buf,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
@ -1639,11 +1529,6 @@ unknown_size:
GST_ERROR_OBJECT (trans, "unknown output size"); GST_ERROR_OBJECT (trans, "unknown output size");
return GST_FLOW_ERROR; 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. /* Given @caps calcultate the size of one unit.
@ -1864,14 +1749,14 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
{ {
GstBaseTransformClass *bclass; GstBaseTransformClass *bclass;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gboolean want_in_place, reconfigure; gboolean want_in_place;
GstClockTime running_time; GstClockTime running_time;
GstClockTime timestamp; GstClockTime timestamp;
GstCaps *incaps;
gsize insize; gsize insize;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
#if 0
if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) { if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) {
GST_OBJECT_LOCK (trans); GST_OBJECT_LOCK (trans);
reconfigure = trans->priv->reconfigure; reconfigure = trans->priv->reconfigure;
@ -1887,6 +1772,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
goto not_negotiated; goto not_negotiated;
} }
} }
#endif
insize = gst_buffer_get_size (inbuf); 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) if (ret != GST_FLOW_OK)
goto error; goto error;
caps = GST_BUFFER_CAPS (buffer); caps = gst_buffer_caps (buffer);
if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) { if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) {
GST_DEBUG ("buffer has caps %" GST_PTR_FORMAT ", suggest max probability", 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, gst_check_element_push_buffer_list (const gchar * element_name,
GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return) GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return)
{ {
GstCaps *sink_caps; //GstCaps *sink_caps;
GstCaps *src_caps = NULL; //GstCaps *src_caps = NULL;
GstElement *element; GstElement *element;
GstPad *pad_peer; GstPad *pad_peer;
GstPad *sink_pad = NULL; GstPad *sink_pad = NULL;
@ -427,9 +427,9 @@ gst_check_element_push_buffer_list (const gchar * element_name,
buffer = GST_BUFFER (buffer_in->data); buffer = GST_BUFFER (buffer_in->data);
fail_unless (GST_IS_BUFFER (buffer), "There should be a buffer in buffer_in"); 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); 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"); pad_peer = gst_element_get_static_pad (element, "sink");
fail_if (pad_peer == NULL); fail_if (pad_peer == NULL);
fail_unless (gst_pad_link (src_pad, pad_peer) == GST_PAD_LINK_OK, 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"); GST_DEBUG ("src pad activated");
/* don't create the sink_pad if there is no buffer_out list */ /* don't create the sink_pad if there is no buffer_out list */
if (buffer_out != NULL) { if (buffer_out != NULL) {
gchar *temp; //gchar *temp;
GST_DEBUG ("buffer out detected, creating the sink pad"); GST_DEBUG ("buffer out detected, creating the sink pad");
/* get the sink caps */ /* get the sink caps */
sink_caps = GST_BUFFER_CAPS (GST_BUFFER (buffer_out->data)); //sink_caps = gst_buffer_caps (GST_BUFFER (buffer_out->data));
fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps"); //fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps");
temp = gst_caps_to_string (sink_caps); //temp = gst_caps_to_string (sink_caps);
GST_DEBUG ("sink caps requested by buffer out: '%s'", temp); //GST_DEBUG ("sink caps requested by buffer out: '%s'", temp);
g_free (temp); //g_free (temp);
fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps"); //fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps");
/* get the sink pad */ /* get the sink pad */
sink_pad = gst_pad_new (NULL, GST_PAD_SINK); sink_pad = gst_pad_new (NULL, GST_PAD_SINK);
fail_unless (GST_IS_PAD (sink_pad)); 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 */ /* get the peer pad */
pad_peer = gst_element_get_static_pad (element, "src"); pad_peer = gst_element_get_static_pad (element, "src");
fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK, fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK,
@ -497,10 +497,8 @@ gst_check_element_push_buffer_list (const gchar * element_name,
newdata = gst_buffer_map (new, &newsize, NULL, GST_MAP_READ); newdata = gst_buffer_map (new, &newsize, NULL, GST_MAP_READ);
origdata = gst_buffer_map (orig, &origsize, NULL, GST_MAP_READ); origdata = gst_buffer_map (orig, &origsize, NULL, GST_MAP_READ);
GST_LOG ("orig buffer: size %u, caps %" GST_PTR_FORMAT, GST_LOG ("orig buffer: size %u", origsize);
origsize, GST_BUFFER_CAPS (orig)); GST_LOG ("new buffer: size %u", newsize);
GST_LOG ("new buffer: size %u, caps %" GST_PTR_FORMAT,
newsize, GST_BUFFER_CAPS (new));
GST_MEMDUMP ("orig buffer", origdata, origsize); GST_MEMDUMP ("orig buffer", origdata, origsize);
GST_MEMDUMP ("new buffer", newdata, newsize); GST_MEMDUMP ("new buffer", newdata, newsize);
@ -511,7 +509,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 (origsize == newsize, "size of the buffers are not the same");
fail_unless (memcmp (origdata, newdata, newsize) == 0, fail_unless (memcmp (origdata, newdata, newsize) == 0,
"data is not the same"); "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 (orig, origdata, origsize);
gst_buffer_unmap (new, newdata, newsize); gst_buffer_unmap (new, newdata, newsize);

View file

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

View file

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

View file

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

View file

@ -949,12 +949,10 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
if (GST_IS_BUFFER (object)) { if (GST_IS_BUFFER (object)) {
GstBuffer *buffer; GstBuffer *buffer;
GstClockTime timestamp, duration; GstClockTime timestamp, duration;
GstCaps *caps;
buffer = GST_BUFFER_CAST (object); buffer = GST_BUFFER_CAST (object);
timestamp = GST_BUFFER_TIMESTAMP (buffer); timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer); duration = GST_BUFFER_DURATION (buffer);
caps = GST_BUFFER_CAPS (buffer);
apply_buffer (mq, sq, timestamp, duration, &sq->src_segment); apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
@ -965,12 +963,6 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
"SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT, "SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
sq->id, buffer, GST_TIME_ARGS (timestamp)); 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); result = gst_pad_push (sq->srcpad, buffer);
} else if (GST_IS_EVENT (object)) { } else if (GST_IS_EVENT (object)) {
GstEvent *event; GstEvent *event;

View file

@ -1094,7 +1094,6 @@ gst_queue_push_one (GstQueue * queue)
next: next:
if (is_buffer) { if (is_buffer) {
GstBuffer *buffer; GstBuffer *buffer;
GstCaps *caps;
buffer = GST_BUFFER_CAST (data); buffer = GST_BUFFER_CAST (data);
@ -1110,16 +1109,7 @@ next:
queue->head_needs_discont = FALSE; queue->head_needs_discont = FALSE;
} }
caps = GST_BUFFER_CAPS (buffer);
GST_QUEUE_MUTEX_UNLOCK (queue); 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) { if (queue->push_newsegment) {
gst_queue_push_newsegment (queue); gst_queue_push_newsegment (queue);

View file

@ -2204,15 +2204,8 @@ next:
if (is_buffer) { if (is_buffer) {
GstBuffer *buffer; GstBuffer *buffer;
GstCaps *caps;
buffer = GST_BUFFER_CAST (data); 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); result = gst_pad_push (queue->srcpad, buffer);

View file

@ -481,9 +481,6 @@ stop_typefinding (GstTypeFindElement * typefind)
goto no_data; goto no_data;
buffer = gst_adapter_take_buffer (typefind->adapter, avail); 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_OBJECT_UNLOCK (typefind);
if (!push_cached_buffers) { if (!push_cached_buffers) {
@ -629,8 +626,6 @@ gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps)
goto no_data; goto no_data;
buffer = gst_adapter_take_buffer (typefind->adapter, avail); 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_OBJECT_UNLOCK (typefind);
GST_DEBUG_OBJECT (typefind, "Pushing buffer: %d", avail); GST_DEBUG_OBJECT (typefind, "Pushing buffer: %d", avail);
@ -744,9 +739,6 @@ gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
/* we should already have called GST_ELEMENT_ERROR */ /* we should already have called GST_ELEMENT_ERROR */
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
case MODE_NORMAL: 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); return gst_pad_push (typefind->src, buffer);
case MODE_TYPEFIND: case MODE_TYPEFIND:
{ {
@ -880,12 +872,6 @@ gst_type_find_element_getrange (GstPad * srcpad,
ret = gst_pad_pull_range (typefind->sink, offset, length, buffer); 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; return ret;
} }

View file

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

View file

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

View file

@ -32,50 +32,6 @@
#include <gst/check/gstcheck.h> #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) GST_START_TEST (test_subbuffer)
{ {
GstBuffer *buffer, *sub; GstBuffer *buffer, *sub;
@ -492,7 +448,6 @@ gst_buffer_suite (void)
TCase *tc_chain = tcase_create ("general"); TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain); 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);
tcase_add_test (tc_chain, test_subbuffer_make_writable); tcase_add_test (tc_chain, test_subbuffer_make_writable);
tcase_add_test (tc_chain, test_make_writable); tcase_add_test (tc_chain, test_make_writable);

View file

@ -66,7 +66,6 @@ GST_START_TEST (test_buffer)
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (1000); 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_caps_unref (c1);
gst_buffer_unref (buffer); /* Should now drop both references */ gst_buffer_unref (buffer); /* Should now drop both references */

View file

@ -579,7 +579,6 @@ GST_START_TEST (test_push_negotiation)
/* Should fail if src pad caps are incompatible with sink pad caps */ /* Should fail if src pad caps are incompatible with sink pad caps */
gst_pad_set_caps (src, caps); gst_pad_set_caps (src, caps);
gst_buffer_set_caps (buffer, caps);
gst_buffer_ref (buffer); gst_buffer_ref (buffer);
fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_NEGOTIATED); fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_NEGOTIATED);
ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1); 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 (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); fail_unless (gst_buffer_get_size (buffer) == 20);
/* caps should not have been set */ /* caps should not have been set */
fail_unless (GST_BUFFER_CAPS (buffer) == NULL); //fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
@ -107,7 +107,7 @@ GST_START_TEST (basetransform_chain_pt1)
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 10); fail_unless (gst_buffer_get_size (buffer) == 10);
/* caps should not have been set */ /* caps should not have been set */
fail_unless (GST_BUFFER_CAPS (buffer) == NULL); //fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
@ -173,7 +173,7 @@ GST_START_TEST (basetransform_chain_pt2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 20"); GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
buffer = gst_buffer_new_and_alloc (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; buffer_alloc_pt1_called = FALSE;
set_caps_pt2_called = FALSE; set_caps_pt2_called = FALSE;
@ -186,7 +186,7 @@ GST_START_TEST (basetransform_chain_pt2)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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); gst_buffer_unref (buffer);
@ -211,7 +211,7 @@ GST_START_TEST (basetransform_chain_pt2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 10"); GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
buffer = gst_buffer_new_and_alloc (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; buffer_alloc_pt1_called = FALSE;
set_caps_pt2_called = FALSE; set_caps_pt2_called = FALSE;
@ -224,7 +224,7 @@ GST_START_TEST (basetransform_chain_pt2)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 10); 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); gst_buffer_unref (buffer);
@ -438,7 +438,7 @@ GST_START_TEST (basetransform_chain_ip2)
GST_DEBUG_OBJECT (trans, "buffer with caps, size 20"); GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
buffer = gst_buffer_new_and_alloc (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_called = FALSE;
transform_ip_1_writable = FALSE; transform_ip_1_writable = FALSE;
@ -455,7 +455,7 @@ GST_START_TEST (basetransform_chain_ip2)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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); gst_buffer_unref (buffer);
#if 0 #if 0
@ -472,7 +472,7 @@ GST_START_TEST (basetransform_chain_ip2)
GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20"); GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20");
buffer = gst_buffer_new_and_alloc (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 */ /* take additional ref to make it non-writable */
gst_buffer_ref (buffer); gst_buffer_ref (buffer);
@ -492,7 +492,7 @@ GST_START_TEST (basetransform_chain_ip2)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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 */ /* output buffer has refcount 1 */
//fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 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 */ /* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20); 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); 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); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 40); 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); gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20); 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 */ /* take additional ref to make it non-writable */
gst_buffer_ref (buffer); gst_buffer_ref (buffer);
@ -730,7 +730,7 @@ GST_START_TEST (basetransform_chain_ct1)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 40); 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 */ /* output buffer has refcount 1 */
fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 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 */ /* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20); 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); 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); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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); gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20); 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 */ /* take additional ref to make it non-writable */
gst_buffer_ref (buffer); gst_buffer_ref (buffer);
@ -1023,7 +1023,7 @@ GST_START_TEST (basetransform_chain_ct2)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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 */ /* output buffer has refcount 1 */
//fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 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 */ /* try to push a buffer with caps */
buffer = gst_buffer_new_and_alloc (20); 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); 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); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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); gst_buffer_unref (buffer);
buffer = gst_buffer_new_and_alloc (20); 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 */ /* take additional ref to make it non-writable */
gst_buffer_ref (buffer); gst_buffer_ref (buffer);
@ -1181,7 +1181,7 @@ GST_START_TEST (basetransform_chain_ct3)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
fail_unless (gst_buffer_get_size (buffer) == 20); 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 */ /* output buffer has refcount 1 */
fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1); fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@ -1224,7 +1224,7 @@ GST_START_TEST (basetransform_chain_ct3)
GST_DEBUG_OBJECT (trans, GST_DEBUG_OBJECT (trans,
"buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps); "buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps);
buffer = gst_buffer_new_and_alloc (10); buffer = gst_buffer_new_and_alloc (10);
gst_buffer_set_caps (buffer, incaps); //gst_buffer_set_caps (buffer, incaps);
/* don't suggest anything else */ /* don't suggest anything else */
buffer_alloc_ct2_case = 1; buffer_alloc_ct2_case = 1;
@ -1241,8 +1241,8 @@ GST_START_TEST (basetransform_chain_ct3)
buffer = gst_test_trans_pop (trans); buffer = gst_test_trans_pop (trans);
fail_unless (buffer != NULL); fail_unless (buffer != NULL);
/* FIXME changing src caps should produce converted buffer */ /* FIXME changing src caps should produce converted buffer */
GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT, //GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT,
GST_BUFFER_CAPS (buffer)); // GST_BUFFER_CAPS (buffer));
//fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps)); //fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
//fail_unless (gst_buffer_get_size (buffer) == 20); //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); GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
buffer = gst_buffer_new_and_alloc (10); buffer = gst_buffer_new_and_alloc (10);
gst_buffer_set_caps (buffer, incaps); //gst_buffer_set_caps (buffer, incaps);
/* don't suggest anything else */ /* don't suggest anything else */
buffer_alloc_ct2_suggest = FALSE; buffer_alloc_ct2_suggest = FALSE;

View file

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