basetransform: cache transformed caps where appropriate

Speeds up negotiation a fair bit on a contrived pipeline
with a dozen colorspace conversions.

Hopefully clears out the cache every time it ought to.

https://bugzilla.gnome.org/show_bug.cgi?id=662291
This commit is contained in:
Vincent Penquerc'h 2011-10-20 14:02:44 +01:00 committed by Sebastian Dröge
parent 905d1fea18
commit 168e5c0abb

View file

@ -282,6 +282,9 @@ struct _GstBaseTransformPrivate
GstClockTime last_stop_out;
GList *delayed_events;
GstCaps *cached_peer_caps[2];
GstCaps *cached_transformed_caps[2];
};
static GstElementClass *parent_class = NULL;
@ -369,6 +372,24 @@ gst_base_transform_drop_delayed_events (GstBaseTransform * trans)
GST_OBJECT_UNLOCK (trans);
}
static void
gst_base_transform_clear_transformed_caps_cache (GstBaseTransform * trans)
{
struct _GstBaseTransformPrivate *priv = trans->priv;
int n;
for (n = 0; n < 2; ++n) {
if (priv->cached_peer_caps[n]) {
gst_caps_unref (priv->cached_peer_caps[n]);
priv->cached_peer_caps[n] = NULL;
}
if (priv->cached_transformed_caps[n]) {
gst_caps_unref (priv->cached_transformed_caps[n]);
priv->cached_transformed_caps[n] = NULL;
}
}
}
static void
gst_base_transform_finalize (GObject * object)
{
@ -380,6 +401,8 @@ gst_base_transform_finalize (GObject * object)
gst_caps_replace (&trans->priv->sink_suggest, NULL);
g_mutex_free (trans->transform_lock);
gst_base_transform_clear_transformed_caps_cache (trans);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -674,13 +697,36 @@ gst_base_transform_getcaps (GstPad * pad)
GstPad *otherpad;
const GstCaps *templ;
GstCaps *peercaps, *caps, *temp;
gboolean samecaps;
int cache_index;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
cache_index = (pad == trans->srcpad) ? 0 : 1;
/* we can do what the peer can */
peercaps = gst_pad_peer_get_caps_reffed (otherpad);
GST_OBJECT_LOCK (trans);
samecaps = (peercaps && trans->priv->cached_peer_caps[cache_index]
&& gst_caps_is_equal (peercaps,
trans->priv->cached_peer_caps[cache_index]));
if (!samecaps) {
if (trans->priv->cached_peer_caps[cache_index]) {
gst_caps_unref (trans->priv->cached_peer_caps[cache_index]);
trans->priv->cached_peer_caps[cache_index] = NULL;
}
if (trans->priv->cached_transformed_caps[cache_index]) {
gst_caps_unref (trans->priv->cached_transformed_caps[cache_index]);
trans->priv->cached_transformed_caps[cache_index] = NULL;
}
} else {
caps = gst_caps_ref (trans->priv->cached_transformed_caps[cache_index]);
GST_OBJECT_UNLOCK (trans);
return caps;
}
GST_OBJECT_UNLOCK (trans);
if (peercaps) {
GST_DEBUG_OBJECT (pad, "peer caps %" GST_PTR_FORMAT, peercaps);
@ -726,6 +772,15 @@ gst_base_transform_getcaps (GstPad * pad)
done:
GST_DEBUG_OBJECT (trans, "returning %" GST_PTR_FORMAT, caps);
GST_OBJECT_LOCK (trans);
if (peercaps) {
trans->priv->cached_peer_caps[cache_index] = gst_caps_ref (peercaps);
}
if (caps) {
trans->priv->cached_transformed_caps[cache_index] = gst_caps_ref (caps);
}
GST_OBJECT_UNLOCK (trans);
if (peercaps)
gst_caps_unref (peercaps);
@ -2616,6 +2671,10 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
GST_OBJECT_LOCK (trans);
gst_base_transform_clear_transformed_caps_cache (trans);
GST_OBJECT_UNLOCK (trans);
if (active) {
if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start)
result &= bclass->start (trans);
@ -2987,6 +3046,7 @@ gst_base_transform_reconfigure (GstBaseTransform * trans)
GST_OBJECT_LOCK (trans);
GST_DEBUG_OBJECT (trans, "marking reconfigure");
trans->priv->reconfigure = TRUE;
gst_base_transform_clear_transformed_caps_cache (trans);
gst_caps_replace (&trans->priv->sink_alloc, NULL);
GST_OBJECT_UNLOCK (trans);
}