basetransform: add accept_caps vmethod

Allow subclasses to override the acceptcaps function because in some cases a
custom implementation can be much much faster than the default one.

See #621190
This commit is contained in:
Wim Taymans 2010-06-14 12:36:54 +02:00
parent 140c4ed20c
commit 76f7a001fc
2 changed files with 40 additions and 10 deletions

View file

@ -321,6 +321,8 @@ static GstFlowReturn gst_base_transform_chain (GstPad * pad,
GstBuffer * buffer); GstBuffer * buffer);
static GstCaps *gst_base_transform_getcaps (GstPad * pad); static GstCaps *gst_base_transform_getcaps (GstPad * pad);
static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps); static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps);
static gboolean gst_base_transform_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_base_transform_setcaps (GstPad * pad, GstCaps * caps);
static GstFlowReturn gst_base_transform_buffer_alloc (GstPad * pad, static GstFlowReturn gst_base_transform_buffer_alloc (GstPad * pad,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
@ -368,6 +370,8 @@ gst_base_transform_class_init (GstBaseTransformClass * klass)
klass->passthrough_on_same_caps = FALSE; klass->passthrough_on_same_caps = FALSE;
klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc); klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc);
klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc); klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc);
klass->accept_caps =
GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps_default);
} }
static void static void
@ -984,17 +988,15 @@ error_cleanup:
} }
static gboolean static gboolean
gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps) gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps)
{ {
GstBaseTransform *trans;
#if 0 #if 0
GstPad *otherpad; GstPad *otherpad;
GstCaps *othercaps = NULL; GstCaps *othercaps = NULL;
#endif #endif
gboolean ret = TRUE; gboolean ret = TRUE;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
#if 0 #if 0
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad; otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
@ -1005,16 +1007,20 @@ gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps)
{ {
GstCaps *allowed; GstCaps *allowed;
GST_DEBUG_OBJECT (pad, "non fixed accept caps %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (trans, "non fixed accept caps %" GST_PTR_FORMAT, caps);
/* get all the formats we can handle on this pad */ /* get all the formats we can handle on this pad */
allowed = gst_pad_get_caps_reffed (pad); if (direction == GST_PAD_SRC)
allowed = gst_pad_get_caps_reffed (trans->srcpad);
else
allowed = gst_pad_get_caps_reffed (trans->sinkpad);
if (!allowed) { if (!allowed) {
GST_DEBUG_OBJECT (pad, "gst_pad_get_caps() failed"); GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed");
goto no_transform_possible; goto no_transform_possible;
} }
GST_DEBUG_OBJECT (pad, "allowed caps %" GST_PTR_FORMAT, allowed); GST_DEBUG_OBJECT (trans, "allowed caps %" GST_PTR_FORMAT, allowed);
/* intersect with the requested format */ /* intersect with the requested format */
ret = gst_caps_can_intersect (allowed, caps); ret = gst_caps_can_intersect (allowed, caps);
@ -1043,7 +1049,6 @@ done:
if (othercaps) if (othercaps)
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
#endif #endif
gst_object_unref (trans);
return ret; return ret;
@ -1058,6 +1063,24 @@ 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, /* 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() * 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 * function. If there are caps, we configure the transform for this new

View file

@ -186,6 +186,10 @@ struct _GstBaseTransform {
* This method is called right before the base class will * This method is called right before the base class will
* start processing. Dynamic properties or other delayed * start processing. Dynamic properties or other delayed
* configuration could be performed in this method. * configuration could be performed in this method.
* @accept_caps: Optional. Since 0.10.30
* Subclasses can override this method to check if @caps can be
* handled by the element. The default implementation might not be
* the most optimal way to check this in all cases.
* *
* Subclasses can override any of the available virtual methods or not, as * Subclasses can override any of the available virtual methods or not, as
* needed. At minimum either @transform or @transform_ip need to be overridden. * needed. At minimum either @transform or @transform_ip need to be overridden.
@ -237,8 +241,11 @@ struct _GstBaseTransformClass {
void (*before_transform) (GstBaseTransform *trans, GstBuffer *buffer); void (*before_transform) (GstBaseTransform *trans, GstBuffer *buffer);
gboolean (*accept_caps) (GstBaseTransform *trans, GstPadDirection direction,
GstCaps *caps);
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE - 2]; gpointer _gst_reserved[GST_PADDING_LARGE - 3];
}; };
GType gst_base_transform_get_type (void); GType gst_base_transform_get_type (void);