#include "../../../gst/gst_private.h"
#include "../../../gst/gst-i18n-lib.h"
+#include "../../../gst/glib-compat-private.h"
#include "gstbasetransform.h"
#include <gst/gstmarshal.h>
/* previous buffer had a discont */
gboolean discont;
- GstActivateMode pad_mode;
+ GstPadMode pad_mode;
gboolean gap_aware;
GstClockTime position_out;
GstBufferPool *pool;
- const GstAllocator *allocator;
+ GstAllocator *allocator;
guint prefix;
guint alignment;
};
const GValue * value, GParamSpec * pspec);
static void gst_base_transform_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static gboolean gst_base_transform_src_activate_pull (GstPad * pad,
- gboolean active);
-static gboolean gst_base_transform_sink_activate_push (GstPad * pad,
- gboolean active);
+static gboolean gst_base_transform_src_activate_mode (GstPad * pad,
+ GstObject * parent, GstPadMode mode, gboolean active);
+static gboolean gst_base_transform_sink_activate_mode (GstPad * pad,
+ GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_base_transform_activate (GstBaseTransform * trans,
gboolean active);
static gboolean gst_base_transform_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, gsize * size);
-static gboolean gst_base_transform_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_base_transform_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans,
GstEvent * event);
-static gboolean gst_base_transform_sink_event (GstPad * pad, GstEvent * event);
+static gboolean gst_base_transform_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
static gboolean gst_base_transform_sink_eventfunc (GstBaseTransform * trans,
GstEvent * event);
-static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
- guint length, GstBuffer ** buffer);
-static GstFlowReturn gst_base_transform_chain (GstPad * pad,
+static GstFlowReturn gst_base_transform_getrange (GstPad * pad,
+ GstObject * parent, guint64 offset, guint length, GstBuffer ** buffer);
+static GstFlowReturn gst_base_transform_chain (GstPad * pad, GstObject * parent,
GstBuffer * buffer);
-static GstCaps *gst_base_transform_getcaps (GstPad * pad, GstCaps * filter);
-static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_base_transform_default_transform_caps (GstBaseTransform *
+ trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter);
+static void gst_base_transform_default_fixate (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
+static GstCaps *gst_base_transform_query_caps (GstBaseTransform * trans,
+ GstPad * pad, GstCaps * filter);
static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps);
static gboolean gst_base_transform_setcaps (GstBaseTransform * trans,
GstPad * pad, GstCaps * caps);
-static gboolean gst_base_transform_query (GstPad * pad, GstQuery * query);
+static gboolean gst_base_transform_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
static gboolean gst_base_transform_default_query (GstBaseTransform * trans,
GstPadDirection direction, GstQuery * query);
-static const GstQueryType *gst_base_transform_query_type (GstPad * pad);
+static gboolean gst_base_transform_default_transform_size (GstBaseTransform *
+ trans, GstPadDirection direction, GstCaps * caps, gsize size,
+ GstCaps * othercaps, gsize * othersize);
static GstFlowReturn default_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer ** outbuf);
trans = GST_BASE_TRANSFORM (object);
- g_mutex_free (trans->transform_lock);
+ g_mutex_clear (&trans->transform_lock);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
gobject_class->finalize = gst_base_transform_finalize;
klass->passthrough_on_same_caps = FALSE;
- klass->sink_event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc);
- klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc);
+
+ klass->transform_caps =
+ GST_DEBUG_FUNCPTR (gst_base_transform_default_transform_caps);
+ klass->fixate_caps = GST_DEBUG_FUNCPTR (gst_base_transform_default_fixate);
klass->accept_caps =
GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps_default);
+ klass->query = GST_DEBUG_FUNCPTR (gst_base_transform_default_query);
+ klass->transform_size =
+ GST_DEBUG_FUNCPTR (gst_base_transform_default_transform_size);
+
+ klass->sink_event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc);
+ klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc);
klass->prepare_output_buffer =
GST_DEBUG_FUNCPTR (default_prepare_output_buffer);
klass->copy_metadata = GST_DEBUG_FUNCPTR (default_copy_metadata);
- klass->query = GST_DEBUG_FUNCPTR (gst_base_transform_default_query);
}
static void
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
g_return_if_fail (pad_template != NULL);
trans->sinkpad = gst_pad_new_from_template (pad_template, "sink");
- gst_pad_set_getcaps_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
- gst_pad_set_acceptcaps_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
gst_pad_set_event_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_sink_event));
gst_pad_set_chain_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_chain));
- gst_pad_set_activatepush_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_sink_activate_push));
+ gst_pad_set_activatemode_function (trans->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_base_transform_sink_activate_mode));
gst_pad_set_query_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_query));
- gst_pad_set_query_type_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_query_type));
gst_element_add_pad (GST_ELEMENT (trans), trans->sinkpad);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
g_return_if_fail (pad_template != NULL);
trans->srcpad = gst_pad_new_from_template (pad_template, "src");
- gst_pad_set_getcaps_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
- gst_pad_set_acceptcaps_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
gst_pad_set_event_function (trans->srcpad,
GST_DEBUG_FUNCPTR (gst_base_transform_src_event));
gst_pad_set_getrange_function (trans->srcpad,
GST_DEBUG_FUNCPTR (gst_base_transform_getrange));
- gst_pad_set_activatepull_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_src_activate_pull));
+ gst_pad_set_activatemode_function (trans->srcpad,
+ GST_DEBUG_FUNCPTR (gst_base_transform_src_activate_mode));
gst_pad_set_query_function (trans->srcpad,
GST_DEBUG_FUNCPTR (gst_base_transform_query));
- gst_pad_set_query_type_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_query_type));
gst_element_add_pad (GST_ELEMENT (trans), trans->srcpad);
- trans->transform_lock = g_mutex_new ();
+ g_mutex_init (&trans->transform_lock);
trans->priv->qos_enabled = DEFAULT_PROP_QOS;
trans->cache_caps1 = NULL;
trans->cache_caps2 = NULL;
- trans->priv->pad_mode = GST_ACTIVATE_NONE;
+ trans->priv->pad_mode = GST_PAD_MODE_NONE;
trans->priv->gap_aware = FALSE;
trans->passthrough = FALSE;
trans->priv->dropped = 0;
}
+static GstCaps *
+gst_base_transform_default_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps, GstCaps * filter)
+{
+ GstCaps *ret;
+
+ GST_DEBUG_OBJECT (trans, "identity from: %" GST_PTR_FORMAT, caps);
+ /* no transform function, use the identity transform */
+ if (filter) {
+ ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ } else {
+ ret = gst_caps_ref (caps);
+ }
+ return ret;
+}
+
/* given @caps on the src or sink pad (given by @direction)
* calculate the possible caps on the other pad.
*
gst_base_transform_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
- GstCaps *ret;
+ GstCaps *ret = NULL;
GstBaseTransformClass *klass;
if (caps == NULL)
/* if there is a custom transform function, use this */
if (klass->transform_caps) {
-
GST_DEBUG_OBJECT (trans, "transform caps (direction = %d)", direction);
GST_LOG_OBJECT (trans, "from: %" GST_PTR_FORMAT, caps);
intersection =
gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (intersection);
+ gst_caps_unref (ret);
ret = intersection;
}
}
#endif
- } else {
- GST_DEBUG_OBJECT (trans, "identity from: %" GST_PTR_FORMAT, caps);
- /* no transform function, use the identity transform */
- if (filter) {
- ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
- } else {
- ret = gst_caps_ref (caps);
- }
}
- GST_DEBUG_OBJECT (trans, "to: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (ret),
- ret);
+ GST_DEBUG_OBJECT (trans, "to: %" GST_PTR_FORMAT, ret);
return ret;
}
-/* transform a buffer of @size with @caps on the pad with @direction to
- * the size of a buffer with @othercaps and store the result in @othersize
- *
- * We have two ways of doing this:
- * 1) use a custom transform size function, this is for complicated custom
- * cases with no fixed unit_size.
- * 2) use the unit_size functions where there is a relationship between the
- * caps and the size of a buffer.
- */
static gboolean
-gst_base_transform_transform_size (GstBaseTransform * trans,
- GstPadDirection direction, GstCaps * caps,
- gsize size, GstCaps * othercaps, gsize * othersize)
+gst_base_transform_default_transform_size (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps, gsize size,
+ GstCaps * othercaps, gsize * othersize)
{
gsize inunitsize, outunitsize, units;
GstBaseTransformClass *klass;
- gboolean ret;
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
- GST_DEBUG_OBJECT (trans,
- "asked to transform size %" G_GSIZE_FORMAT " for caps %"
- GST_PTR_FORMAT " to size for caps %" GST_PTR_FORMAT " in direction %s",
- size, caps, othercaps, direction == GST_PAD_SRC ? "SRC" : "SINK");
-
- if (klass->transform_size) {
- /* if there is a custom transform function, use this */
- ret = klass->transform_size (trans, direction, caps, size, othercaps,
- othersize);
- } else if (klass->get_unit_size == NULL) {
+ if (klass->get_unit_size == NULL) {
/* if there is no transform_size and no unit_size, it means the
* element does not modify the size of a buffer */
*othersize = size;
- ret = TRUE;
} else {
/* there is no transform_size function, we have to use the unit_size
* functions. This method assumes there is a fixed unit_size associated with
*othersize = units * outunitsize;
GST_DEBUG_OBJECT (trans, "transformed size to %" G_GSIZE_FORMAT,
*othersize);
-
- ret = TRUE;
}
- return ret;
+ return TRUE;
/* ERRORS */
no_in_size:
}
}
+/* transform a buffer of @size with @caps on the pad with @direction to
+ * the size of a buffer with @othercaps and store the result in @othersize
+ *
+ * We have two ways of doing this:
+ * 1) use a custom transform size function, this is for complicated custom
+ * cases with no fixed unit_size.
+ * 2) use the unit_size functions where there is a relationship between the
+ * caps and the size of a buffer.
+ */
+static gboolean
+gst_base_transform_transform_size (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps,
+ gsize size, GstCaps * othercaps, gsize * othersize)
+{
+ GstBaseTransformClass *klass;
+ gboolean ret = FALSE;
+
+ klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
+
+ GST_DEBUG_OBJECT (trans,
+ "asked to transform size %" G_GSIZE_FORMAT " for caps %"
+ GST_PTR_FORMAT " to size for caps %" GST_PTR_FORMAT " in direction %s",
+ size, caps, othercaps, direction == GST_PAD_SRC ? "SRC" : "SINK");
+
+ if (klass->transform_size) {
+ /* if there is a custom transform function, use this */
+ ret = klass->transform_size (trans, direction, caps, size, othercaps,
+ othersize);
+ }
+ return ret;
+}
+
/* get the caps that can be handled by @pad. We perform:
*
* - take the caps of peer of otherpad,
* If there is no peer, we simply return the caps of the padtemplate of pad.
*/
static GstCaps *
-gst_base_transform_getcaps (GstPad * pad, GstCaps * filter)
+gst_base_transform_query_caps (GstBaseTransform * trans, GstPad * pad,
+ GstCaps * filter)
{
- GstBaseTransform *trans;
GstPad *otherpad;
GstCaps *peercaps, *caps, *temp, *peerfilter = NULL;
GstCaps *templ;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
/* we can do what the peer can */
peerfilter = temp;
}
- peercaps = gst_pad_peer_get_caps (otherpad, peerfilter);
+ peercaps = gst_pad_peer_query_caps (otherpad, peerfilter);
if (peerfilter)
gst_caps_unref (peerfilter);
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
gst_caps_unref (templ);
} else {
- temp = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
+ temp = gst_pad_get_pad_template_caps (otherpad);
}
/* then see what we can transform this to */
if (peercaps)
gst_caps_unref (peercaps);
- gst_object_unref (trans);
-
return caps;
}
static gboolean
gst_base_transform_set_allocation (GstBaseTransform * trans,
- GstBufferPool * pool, const GstAllocator * allocator, guint prefix,
+ GstBufferPool * pool, GstAllocator * allocator, guint prefix,
guint alignment)
{
+ GstAllocator *oldalloc;
GstBufferPool *oldpool;
GstBaseTransformPrivate *priv = trans->priv;
GST_OBJECT_LOCK (trans);
oldpool = priv->pool;
priv->pool = pool;
+ oldalloc = priv->allocator;
priv->allocator = allocator;
priv->prefix = prefix;
priv->alignment = alignment;
gst_buffer_pool_set_active (oldpool, FALSE);
gst_object_unref (oldpool);
}
+ if (oldalloc) {
+ gst_allocator_unref (oldalloc);
+ }
return TRUE;
/* ERRORS */
GstBufferPool *pool = NULL, *oldpool;
guint size, min, max, prefix, alignment;
GstBaseTransformClass *klass;
- const GstAllocator *allocator = NULL;
+ GstAllocator *allocator = NULL;
/* there are these possibilities:
*
return ret;
}
+static void
+gst_base_transform_default_fixate (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
+{
+ GST_DEBUG_OBJECT (trans, "using default caps fixate function");
+ gst_caps_fixate (othercaps);
+}
+
/* given a fixed @caps on @pad, create the best possible caps for the
* other pad.
* @caps must be fixed when calling this function.
GST_DEBUG_OBJECT (trans,
"Checking peer caps with filter %" GST_PTR_FORMAT, othercaps);
- peercaps = gst_pad_get_caps (otherpeer, othercaps);
+ peercaps = gst_pad_query_caps (otherpeer, othercaps);
GST_DEBUG_OBJECT (trans, "Resulted in %" GST_PTR_FORMAT, peercaps);
+ if (!gst_caps_is_empty (peercaps)) {
+ templ_caps = gst_pad_get_pad_template_caps (otherpad);
- templ_caps = gst_pad_get_pad_template_caps (otherpad);
+ GST_DEBUG_OBJECT (trans,
+ "Intersecting with template caps %" GST_PTR_FORMAT, templ_caps);
- GST_DEBUG_OBJECT (trans,
- "Intersecting with template caps %" GST_PTR_FORMAT, templ_caps);
+ intersection =
+ gst_caps_intersect_full (peercaps, templ_caps,
+ GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT,
+ intersection);
+ gst_caps_unref (peercaps);
+ gst_caps_unref (templ_caps);
+ peercaps = intersection;
- intersection =
- gst_caps_intersect_full (peercaps, templ_caps,
- GST_CAPS_INTERSECT_FIRST);
- GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
- gst_caps_unref (peercaps);
- gst_caps_unref (templ_caps);
- peercaps = intersection;
+ GST_DEBUG_OBJECT (trans,
+ "Intersecting with transformed caps %" GST_PTR_FORMAT, othercaps);
+ intersection =
+ gst_caps_intersect_full (peercaps, othercaps,
+ GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT,
+ intersection);
+ gst_caps_unref (peercaps);
+ gst_caps_unref (othercaps);
+ othercaps = intersection;
+ } else {
+ othercaps = peercaps;
+ }
- GST_DEBUG_OBJECT (trans,
- "Intersecting with transformed caps %" GST_PTR_FORMAT, othercaps);
- intersection =
- gst_caps_intersect_full (peercaps, othercaps,
- GST_CAPS_INTERSECT_FIRST);
- GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
- gst_caps_unref (peercaps);
- gst_caps_unref (othercaps);
- othercaps = intersection;
is_fixed = gst_caps_is_fixed (othercaps);
} else {
GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
if (gst_caps_is_empty (othercaps))
goto no_transform_possible;
- /* second attempt at fixation, call the fixate vmethod and
- * ultimately call the pad fixate function. */
- if (!is_fixed) {
- GST_DEBUG_OBJECT (trans,
- "trying to fixate %" GST_PTR_FORMAT " on pad %s:%s",
- othercaps, GST_DEBUG_PAD_NAME (otherpad));
-
- /* since we have no other way to fixate left, we might as well just take
- * the first of the caps list and fixate that */
-
- /* FIXME: when fixating using the vmethod, it might make sense to fixate
- * each of the caps; but Wim doesn't see a use case for that yet */
- gst_caps_truncate (othercaps);
-
- if (klass->fixate_caps) {
- GST_DEBUG_OBJECT (trans, "trying to fixate %" GST_PTR_FORMAT
- " using caps %" GST_PTR_FORMAT
- " on pad %s:%s using fixate_caps vmethod", othercaps, caps,
- GST_DEBUG_PAD_NAME (otherpad));
- klass->fixate_caps (trans, GST_PAD_DIRECTION (pad), caps, othercaps);
- is_fixed = gst_caps_is_fixed (othercaps);
- }
- /* if still not fixed, no other option but to let the default pad fixate
- * function do its job */
- if (!is_fixed) {
- GST_DEBUG_OBJECT (trans, "trying to fixate %" GST_PTR_FORMAT
- " on pad %s:%s using gst_pad_fixate_caps", othercaps,
- GST_DEBUG_PAD_NAME (otherpad));
- gst_pad_fixate_caps (otherpad, othercaps);
- is_fixed = gst_caps_is_fixed (othercaps);
- }
+ GST_DEBUG ("have %sfixed caps %" GST_PTR_FORMAT, (is_fixed ? "" : "non-"),
+ othercaps);
+
+ /* second attempt at fixation, call the fixate vmethod */
+ /* caps could be fixed but the subclass may want to add fields */
+ if (klass->fixate_caps) {
+ othercaps = gst_caps_make_writable (othercaps);
+
+ GST_DEBUG_OBJECT (trans, "calling fixate_caps for %" GST_PTR_FORMAT
+ " using caps %" GST_PTR_FORMAT " on pad %s:%s", othercaps, caps,
+ GST_DEBUG_PAD_NAME (otherpad));
+ /* note that we pass the complete array of structures to the fixate
+ * function, it needs to truncate itself */
+ klass->fixate_caps (trans, GST_PAD_DIRECTION (pad), caps, othercaps);
+ is_fixed = gst_caps_is_fixed (othercaps);
GST_DEBUG_OBJECT (trans, "after fixating %" GST_PTR_FORMAT, othercaps);
- } else {
- GST_DEBUG ("caps are fixed");
- /* else caps are fixed but the subclass may want to add fields */
- if (klass->fixate_caps) {
- othercaps = gst_caps_make_writable (othercaps);
-
- GST_DEBUG_OBJECT (trans, "doing fixate %" GST_PTR_FORMAT
- " using caps %" GST_PTR_FORMAT
- " on pad %s:%s using fixate_caps vmethod", othercaps, caps,
- GST_DEBUG_PAD_NAME (otherpad));
-
- klass->fixate_caps (trans, GST_PAD_DIRECTION (pad), caps, othercaps);
- is_fixed = gst_caps_is_fixed (othercaps);
- }
}
/* caps should be fixed now, if not we have to fail. */
goto could_not_fixate;
/* and peer should accept */
- if (!gst_pad_accept_caps (otherpeer, othercaps))
+ if (otherpeer && !gst_pad_query_accept_caps (otherpeer, othercaps))
goto peer_no_accept;
GST_DEBUG_OBJECT (trans, "Input caps were %" GST_PTR_FORMAT
/* get all the formats we can handle on this pad */
if (direction == GST_PAD_SRC)
- allowed = gst_pad_get_caps (trans->srcpad, NULL);
+ allowed = gst_pad_query_caps (trans->srcpad, NULL);
else
- allowed = gst_pad_get_caps (trans->sinkpad, NULL);
+ allowed = gst_pad_query_caps (trans->sinkpad, NULL);
if (!allowed) {
- GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed");
+ GST_DEBUG_OBJECT (trans, "gst_pad_query_caps() failed");
goto no_transform_possible;
}
}
}
-static gboolean
-gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps)
-{
- gboolean ret = TRUE;
- GstBaseTransform *trans;
- GstBaseTransformClass *bclass;
-
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
- bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
-
- if (bclass->accept_caps)
- ret = bclass->accept_caps (trans, GST_PAD_DIRECTION (pad), caps);
-
- gst_object_unref (trans);
-
- return ret;
-}
-
/* called when new caps arrive on the sink or source pad,
* We try to find the best caps for the other side using our _find_transform()
* function. If there are caps, we configure the transform for this new
goto failed_configure;
GST_OBJECT_LOCK (trans->sinkpad);
- GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+ GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_FLAG_NEED_RECONFIGURE);
trans->priv->reconfigure = FALSE;
GST_OBJECT_UNLOCK (trans->sinkpad);
/* we know this will work, we implement the setcaps */
gst_pad_push_event (otherpad, gst_event_new_caps (othercaps));
- if (pad == trans->srcpad && trans->priv->pad_mode == GST_ACTIVATE_PULL) {
+ if (pad == trans->srcpad && trans->priv->pad_mode == GST_PAD_MODE_PULL) {
/* FIXME hm? */
ret &= gst_pad_push_event (otherpeer, gst_event_new_caps (othercaps));
if (!ret) {
GstPadDirection direction, GstQuery * query)
{
gboolean ret = FALSE;
- GstPad *otherpad;
+ GstPad *pad, *otherpad;
+ GstBaseTransformClass *klass;
+
+ if (direction == GST_PAD_SRC) {
+ pad = trans->srcpad;
+ otherpad = trans->sinkpad;
+ } else {
+ pad = trans->sinkpad;
+ otherpad = trans->srcpad;
+ }
- otherpad = (direction == GST_PAD_SRC) ? trans->sinkpad : trans->srcpad;
+ klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_ALLOCATION:
goto done;
GST_BASE_TRANSFORM_LOCK (trans);
- passthrough = trans->passthrough || trans->always_in_place;
+ passthrough = trans->passthrough;
GST_BASE_TRANSFORM_UNLOCK (trans);
- if (passthrough) {
+ GST_DEBUG_OBJECT (trans, "propose allocation values");
+ /* pass the query to the propose_allocation vmethod if any */
+ if (G_LIKELY (klass->propose_allocation)) {
+ ret = klass->propose_allocation (trans, query);
+ } else if (passthrough) {
GST_DEBUG_OBJECT (trans, "doing passthrough query");
ret = gst_pad_peer_query (otherpad, query);
} else {
- GstBaseTransformClass *klass;
-
- GST_DEBUG_OBJECT (trans, "propose allocation values");
-
- klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
- /* pass the query to the propose_allocation vmethod if any */
- if (G_LIKELY (klass->propose_allocation))
- ret = klass->propose_allocation (trans, query);
- else
- ret = FALSE;
+ ret = FALSE;
}
GST_DEBUG_OBJECT (trans, "ALLOCATION ret %d, %" GST_PTR_FORMAT, ret,
query);
}
break;
}
+ case GST_QUERY_ACCEPT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_query_parse_accept_caps (query, &caps);
+ if (klass->accept_caps) {
+ ret = klass->accept_caps (trans, direction, caps);
+ gst_query_set_accept_caps_result (query, ret);
+ /* return TRUE, we answered the query */
+ ret = TRUE;
+ }
+ break;
+ }
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *filter, *caps;
+
+ gst_query_parse_caps (query, &filter);
+ caps = gst_base_transform_query_caps (trans, pad, filter);
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ ret = TRUE;
+ break;
+ }
default:
ret = gst_pad_peer_query (otherpad, query);
break;
}
static gboolean
-gst_base_transform_query (GstPad * pad, GstQuery * query)
+gst_base_transform_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
- gboolean ret;
-
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
- if (G_UNLIKELY (trans == NULL))
- return FALSE;
+ gboolean ret = FALSE;
+ trans = GST_BASE_TRANSFORM (parent);
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->query)
ret = bclass->query (trans, GST_PAD_DIRECTION (pad), query);
- else
- ret = gst_pad_query_default (pad, query);
-
- gst_object_unref (trans);
return ret;
}
-static const GstQueryType *
-gst_base_transform_query_type (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_NONE
- };
-
- return types;
-}
-
/* this function either returns the input buffer without incrementing the
* refcount or it allocates a new (writable) buffer */
static GstFlowReturn
}
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
- if (bclass->get_unit_size) {
- res = bclass->get_unit_size (trans, caps, size);
- GST_DEBUG_OBJECT (trans,
- "caps %" GST_PTR_FORMAT ") has unit size %" G_GSIZE_FORMAT ", res %s",
- caps, *size, res ? "TRUE" : "FALSE");
-
- if (res) {
- /* and cache the values */
- if (trans->cache_caps1 == NULL) {
- gst_caps_replace (&trans->cache_caps1, caps);
- trans->cache_caps1_size = *size;
- GST_DEBUG_OBJECT (trans,
- "caching %" G_GSIZE_FORMAT " in first cache", *size);
- } else if (trans->cache_caps2 == NULL) {
- gst_caps_replace (&trans->cache_caps2, caps);
- trans->cache_caps2_size = *size;
- GST_DEBUG_OBJECT (trans,
- "caching %" G_GSIZE_FORMAT " in second cache", *size);
- } else {
- GST_DEBUG_OBJECT (trans, "no free spot to cache unit_size");
- }
+ res = bclass->get_unit_size (trans, caps, size);
+ GST_DEBUG_OBJECT (trans,
+ "caps %" GST_PTR_FORMAT ") has unit size %" G_GSIZE_FORMAT ", res %s",
+ caps, *size, res ? "TRUE" : "FALSE");
+
+ if (res) {
+ /* and cache the values */
+ if (trans->cache_caps1 == NULL) {
+ gst_caps_replace (&trans->cache_caps1, caps);
+ trans->cache_caps1_size = *size;
+ GST_DEBUG_OBJECT (trans,
+ "caching %" G_GSIZE_FORMAT " in first cache", *size);
+ } else if (trans->cache_caps2 == NULL) {
+ gst_caps_replace (&trans->cache_caps2, caps);
+ trans->cache_caps2_size = *size;
+ GST_DEBUG_OBJECT (trans,
+ "caching %" G_GSIZE_FORMAT " in second cache", *size);
+ } else {
+ GST_DEBUG_OBJECT (trans, "no free spot to cache unit_size");
}
- } else {
- GST_DEBUG_OBJECT (trans, "Sub-class does not implement get_unit_size");
}
return res;
}
static gboolean
-gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
+gst_base_transform_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = TRUE;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
- if (G_UNLIKELY (trans == NULL)) {
- gst_event_unref (event);
- return FALSE;
- }
+ trans = GST_BASE_TRANSFORM (parent);
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->sink_event)
else
gst_event_unref (event);
- gst_object_unref (trans);
-
return ret;
}
}
static gboolean
-gst_base_transform_src_event (GstPad * pad, GstEvent * event)
+gst_base_transform_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = TRUE;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
- if (G_UNLIKELY (trans == NULL)) {
- gst_event_unref (event);
- return FALSE;
- }
-
+ trans = GST_BASE_TRANSFORM (parent);
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->src_event)
else
gst_event_unref (event);
- gst_object_unref (trans);
-
return ret;
}
GST_OBJECT_LOCK (trans->sinkpad);
reconfigure = GST_PAD_NEEDS_RECONFIGURE (trans->srcpad)
|| trans->priv->reconfigure;
- GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+ GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_FLAG_NEED_RECONFIGURE);
trans->priv->reconfigure = FALSE;
GST_OBJECT_UNLOCK (trans->sinkpad);
GST_DEBUG_OBJECT (trans, "doing inplace transform");
if (inbuf != *outbuf) {
- guint8 *indata, *outdata;
- gsize insize, outsize;
+ GstMapInfo ininfo, outinfo;
/* Different buffer. The data can still be the same when we are dealing
* with subbuffers of the same buffer. Note that because of the FIXME in
* prepare_output_buffer() we have decreased the refcounts of inbuf and
* outbuf to keep them writable */
- indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
- outdata = gst_buffer_map (*outbuf, &outsize, NULL, GST_MAP_WRITE);
+ g_assert (gst_buffer_map (inbuf, &ininfo, GST_MAP_READ));
+ g_assert (gst_buffer_map (*outbuf, &outinfo, GST_MAP_WRITE));
- if (indata != outdata)
- memcpy (outdata, indata, insize);
+ if (ininfo.data != outinfo.data)
+ memcpy (outinfo.data, ininfo.data, ininfo.size);
- gst_buffer_unmap (inbuf, indata, insize);
- gst_buffer_unmap (*outbuf, outdata, outsize);
+ gst_buffer_unmap (inbuf, &ininfo);
+ gst_buffer_unmap (*outbuf, &outinfo);
}
ret = bclass->transform_ip (trans, *outbuf);
} else {
* end based on the transform_size result.
*/
static GstFlowReturn
-gst_base_transform_getrange (GstPad * pad, guint64 offset,
+gst_base_transform_getrange (GstPad * pad, GstObject * parent, guint64 offset,
guint length, GstBuffer ** buffer)
{
GstBaseTransform *trans;
GstFlowReturn ret;
GstBuffer *inbuf;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
+ trans = GST_BASE_TRANSFORM (parent);
ret = gst_pad_pull_range (trans->sinkpad, offset, length, &inbuf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
GST_BASE_TRANSFORM_UNLOCK (trans);
done:
- gst_object_unref (trans);
-
return ret;
/* ERRORS */
}
static GstFlowReturn
-gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
+gst_base_transform_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstBaseTransform *trans;
GstBaseTransformClass *klass;
GstClockTime timestamp, duration;
GstBuffer *outbuf = NULL;
- trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
+ trans = GST_BASE_TRANSFORM (parent);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
/* apply DISCONT flag if the buffer is not yet marked as such */
if (trans->priv->discont) {
+ GST_DEBUG_OBJECT (trans, "we have a pending DISCONT");
if (!GST_BUFFER_IS_DISCONT (outbuf)) {
+ GST_DEBUG_OBJECT (trans, "marking DISCONT on output buffer");
outbuf = gst_buffer_make_writable (outbuf);
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
}
ret = gst_pad_push (trans->srcpad, outbuf);
} else {
+ GST_DEBUG_OBJECT (trans, "we got return %s", gst_flow_get_name (ret));
gst_buffer_unref (outbuf);
}
}
/* convert internal flow to OK and mark discont for the next buffer. */
if (ret == GST_BASE_TRANSFORM_FLOW_DROPPED) {
+ GST_DEBUG_OBJECT (trans, "dropped a buffer, marking DISCONT");
trans->priv->discont = TRUE;
ret = GST_FLOW_OK;
}
if (active) {
GstCaps *incaps, *outcaps;
- if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start)
+ if (trans->priv->pad_mode == GST_PAD_MODE_NONE && bclass->start)
result &= bclass->start (trans);
incaps = gst_pad_get_current_caps (trans->sinkpad);
gst_caps_replace (&trans->cache_caps1, NULL);
gst_caps_replace (&trans->cache_caps2, NULL);
- if (trans->priv->pad_mode != GST_ACTIVATE_NONE && bclass->stop)
+ if (trans->priv->pad_mode != GST_PAD_MODE_NONE && bclass->stop)
result &= bclass->stop (trans);
gst_base_transform_set_allocation (trans, NULL, NULL, 0, 0);
}
static gboolean
-gst_base_transform_sink_activate_push (GstPad * pad, gboolean active)
+gst_base_transform_sink_activate_mode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
- gboolean result = TRUE;
+ gboolean result = FALSE;
GstBaseTransform *trans;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
- result = gst_base_transform_activate (trans, active);
+ trans = GST_BASE_TRANSFORM (parent);
- if (result)
- trans->priv->pad_mode = active ? GST_ACTIVATE_PUSH : GST_ACTIVATE_NONE;
+ switch (mode) {
+ case GST_PAD_MODE_PUSH:
+ {
+ result = gst_base_transform_activate (trans, active);
- gst_object_unref (trans);
+ if (result)
+ trans->priv->pad_mode = active ? GST_PAD_MODE_PUSH : GST_PAD_MODE_NONE;
+ break;
+ }
+ default:
+ result = TRUE;
+ break;
+ }
return result;
}
static gboolean
-gst_base_transform_src_activate_pull (GstPad * pad, gboolean active)
+gst_base_transform_src_activate_mode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
gboolean result = FALSE;
GstBaseTransform *trans;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
- result = gst_pad_activate_pull (trans->sinkpad, active);
+ trans = GST_BASE_TRANSFORM (parent);
- if (result)
- result &= gst_base_transform_activate (trans, active);
+ switch (mode) {
+ case GST_PAD_MODE_PULL:
+ {
+ result =
+ gst_pad_activate_mode (trans->sinkpad, GST_PAD_MODE_PULL, active);
- if (result)
- trans->priv->pad_mode = active ? GST_ACTIVATE_PULL : GST_ACTIVATE_NONE;
+ if (result)
+ result &= gst_base_transform_activate (trans, active);
- gst_object_unref (trans);
+ if (result)
+ trans->priv->pad_mode = active ? mode : GST_PAD_MODE_NONE;
+ break;
+ }
+ default:
+ result = TRUE;
+ break;
+ }
return result;
}