diff --git a/ChangeLog b/ChangeLog index eb0eae243f..6a5b980647 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-05-21 Tim-Philipp Müller + + * gst/gstpad.c: (gst_pad_alloc_buffer_full): + Move size sanity check to the right place: downstream may return + a buffer with a smaller size if the buffer caps are different than + the requested ones, as may happen when doing reverse negotiation. + 2008-05-21 Wim Taymans * plugins/elements/gstfilesink.c: (gst_file_sink_set_location), diff --git a/gst/gstpad.c b/gst/gstpad.c index 4d5cd3e5c0..01ad4c66eb 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -2679,10 +2679,6 @@ gst_pad_buffer_alloc_unchecked (GstPad * pad, guint64 offset, gint size, if (G_UNLIKELY (*buf == NULL)) goto fallback; - /* sanity check */ - if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size)) - goto wrong_size; - /* If the buffer alloc function didn't set up the caps like it should, * do it for it */ if (G_UNLIKELY (caps && (GST_BUFFER_CAPS (*buf) == NULL))) { @@ -2705,14 +2701,6 @@ error: "alloc function returned error (%d) %s", ret, gst_flow_get_name (ret)); return ret; } -wrong_size: - { - GST_CAT_ERROR_OBJECT (GST_CAT_PADS, pad, "buffer returned by alloc " - "function is too small: %u < %d", GST_BUFFER_SIZE (*buf), size); - gst_buffer_unref (*buf); - *buf = NULL; - goto fallback; - } fallback: { /* fallback case, allocate a buffer of our own, add pad caps. */ @@ -2781,7 +2769,12 @@ gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size, GST_PAD_CAPS (pad), caps, caps); if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, setcaps))) goto not_negotiated; + } else { + /* sanity check (only if caps haven't changed) */ + if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size)) + goto wrong_size_fallback; } + return ret; flushed: @@ -2812,6 +2805,24 @@ not_negotiated: "alloc function returned unacceptable buffer"); return GST_FLOW_NOT_NEGOTIATED; } +wrong_size_fallback: + { + GST_CAT_ERROR_OBJECT (GST_CAT_PADS, pad, "buffer returned by alloc " + "function is too small (%u < %d), doing fallback buffer alloc", + GST_BUFFER_SIZE (*buf), size); + + gst_buffer_unref (*buf); + + if ((*buf = gst_buffer_try_new_and_alloc (size))) { + GST_BUFFER_OFFSET (*buf) = offset; + gst_buffer_set_caps (*buf, caps); + return GST_FLOW_OK; + } else { + GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, + "out of memory allocating %d bytes", size); + return GST_FLOW_ERROR; + } + } } /**