diff -up gstreamer-0.10.21/libs/gst/base/gstbasetransform.c.BAD gstreamer-0.10.21/libs/gst/base/gstbasetransform.c --- gstreamer-0.10.21/libs/gst/base/gstbasetransform.c.BAD 2008-11-11 16:45:10.000000000 -0500 +++ gstreamer-0.10.21/libs/gst/base/gstbasetransform.c 2008-11-11 16:45:16.000000000 -0500 @@ -251,7 +251,7 @@ struct _GstBaseTransformPrivate /* upstream caps and size suggestions */ GstCaps *sink_suggest; guint size_suggest; - gint suggest_pending; + gboolean suggest_pending; gboolean reconfigure; }; @@ -896,6 +896,18 @@ gst_base_transform_find_transform (GstBa gst_pad_fixate_caps (otherpad, othercaps); } GST_DEBUG_OBJECT (trans, "after fixating %" GST_PTR_FORMAT, othercaps); + } else { + /* 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); + } } /* caps should be fixed now, if not we have to fail. */ @@ -1074,6 +1086,8 @@ gst_base_transform_prepare_output_buffer priv = trans->priv; + *out_buf = NULL; + /* figure out how to allocate a buffer based on the current configuration */ if (trans->passthrough) { GST_DEBUG_OBJECT (trans, "doing passthrough alloc"); @@ -1224,7 +1238,7 @@ gst_base_transform_prepare_output_buffer gst_caps_unref (priv->sink_suggest); priv->sink_suggest = gst_caps_ref (othercaps); priv->size_suggest = size_suggest; - g_atomic_int_set (&trans->priv->suggest_pending, 1); + trans->priv->suggest_pending = TRUE; GST_OBJECT_UNLOCK (trans->sinkpad); } gst_caps_unref (othercaps); @@ -1366,7 +1380,7 @@ gst_base_transform_buffer_alloc (GstPad GstBaseTransform *trans; GstBaseTransformPrivate *priv; GstFlowReturn res; - gboolean proxy, suggest; + gboolean proxy, suggest, same_caps; GstCaps *sink_suggest; guint size_suggest; @@ -1384,8 +1398,12 @@ gst_base_transform_buffer_alloc (GstPad /* we remember our previous alloc request to quickly see if we can proxy or * not. We skip this check if we have a pending suggestion. */ - if (g_atomic_int_get (&priv->suggest_pending) == 0 && caps && - gst_caps_is_equal (priv->sink_alloc, caps)) { + GST_OBJECT_LOCK (pad); + same_caps = !priv->suggest_pending && caps && + gst_caps_is_equal (priv->sink_alloc, caps); + GST_OBJECT_UNLOCK (pad); + + if (same_caps) { /* we have seen this before, see below if we need to proxy */ GST_DEBUG_OBJECT (trans, "have old caps"); sink_suggest = caps; @@ -1414,7 +1432,7 @@ gst_base_transform_buffer_alloc (GstPad size_suggest = size; suggest = FALSE; } - g_atomic_int_set (&priv->suggest_pending, 0); + priv->suggest_pending = FALSE; GST_OBJECT_UNLOCK (pad); /* check if we actually handle this format on the sinkpad */ @@ -1462,7 +1480,10 @@ gst_base_transform_buffer_alloc (GstPad } } /* remember the new caps */ + GST_OBJECT_LOCK (pad); gst_caps_replace (&priv->sink_alloc, sink_suggest); + GST_OBJECT_UNLOCK (pad); + proxy = priv->proxy_alloc; GST_DEBUG_OBJECT (trans, "doing default alloc, proxy %d", proxy); @@ -1487,11 +1508,13 @@ gst_base_transform_buffer_alloc (GstPad if (!gst_caps_is_equal (newcaps, caps)) { GST_DEBUG_OBJECT (trans, "caps are new"); /* we have new caps, see if we can proxy downstream */ - if (gst_pad_peer_accept_caps (trans->sinkpad, newcaps)) { + if (gst_pad_peer_accept_caps (pad, newcaps)) { /* peer accepts the caps, return a buffer in this format */ GST_DEBUG_OBJECT (trans, "peer accepted new caps"); /* remember the format */ + GST_OBJECT_LOCK (pad); gst_caps_replace (&priv->sink_alloc, newcaps); + GST_OBJECT_UNLOCK (pad); } else { GST_DEBUG_OBJECT (trans, "peer did not accept new caps"); /* peer does not accept the caps, free the buffer we received and @@ -1694,6 +1717,7 @@ gst_base_transform_handle_buffer (GstBas GST_OBJECT_UNLOCK (trans); if (G_UNLIKELY (reconfigure)) { + GST_DEBUG_OBJECT (trans, "we had a pending reconfigure"); /* if we need to reconfigure we pretend a buffer with new caps arrived. This * will reconfigure the transform with the new output format. We can only * do this if the buffer actually has caps. */ @@ -1853,15 +1877,25 @@ gst_base_transform_getrange (GstPad * pa trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); ret = gst_pad_pull_range (trans->sinkpad, offset, length, &inbuf); - if (ret == GST_FLOW_OK) { - GST_BASE_TRANSFORM_LOCK (trans); - ret = gst_base_transform_handle_buffer (trans, inbuf, buffer); - GST_BASE_TRANSFORM_UNLOCK (trans); - } + if (G_UNLIKELY (ret != GST_FLOW_OK)) + goto pull_error; + + GST_BASE_TRANSFORM_LOCK (trans); + ret = gst_base_transform_handle_buffer (trans, inbuf, buffer); + GST_BASE_TRANSFORM_UNLOCK (trans); +done: gst_object_unref (trans); return ret; + + /* ERRORS */ +pull_error: + { + GST_DEBUG_OBJECT (trans, "failed to pull a buffer: %s", + gst_flow_get_name (ret)); + goto done; + } } static GstFlowReturn @@ -2305,7 +2339,7 @@ gst_base_transform_suggest (GstBaseTrans caps = gst_caps_copy (caps); trans->priv->sink_suggest = caps; trans->priv->size_suggest = size; - g_atomic_int_set (&trans->priv->suggest_pending, 1); + trans->priv->suggest_pending = TRUE; GST_DEBUG_OBJECT (trans, "new suggest %" GST_PTR_FORMAT, caps); GST_OBJECT_UNLOCK (trans->sinkpad); } @@ -2326,6 +2360,7 @@ gst_base_transform_reconfigure (GstBaseT g_return_if_fail (GST_IS_BASE_TRANSFORM (trans)); GST_OBJECT_LOCK (trans); + GST_DEBUG_OBJECT (trans, "marking reconfigure"); trans->priv->reconfigure = TRUE; GST_OBJECT_UNLOCK (trans); }