diff --git a/ChangeLog b/ChangeLog index 1623e9d01f..b40014cb85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-05-16 Tim-Philipp Müller + + * gst/real/gstrealaudiodec.c: (gst_real_audio_dec_chain), + (gst_real_audio_dec_setcaps): + * gst/real/gstrealvideodec.c: (gst_real_video_dec_chain): + Don't crash when we get a buffer and our input caps haven't been set + yet; also, don't leak all the input buffers (realaudiodec only). + 2007-05-16 Stefan Kost patch by: Stanislav Brabec diff --git a/gst/real/gstrealaudiodec.c b/gst/real/gstrealaudiodec.c index ff169902ad..50d837561a 100644 --- a/gst/real/gstrealaudiodec.c +++ b/gst/real/gstrealaudiodec.c @@ -1,4 +1,4 @@ -/* GStreamer +/* RealAudio wrapper plugin * * Copyright (C) 2006 Lutz Mueller * Copyright (C) 2006 Edward Hervey @@ -137,30 +137,55 @@ static GstFlowReturn gst_real_audio_dec_chain (GstPad * pad, GstBuffer * in) { GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (GST_PAD_PARENT (pad)); - guint len; + GstFlowReturn flow; + GstClockTime timestamp; GstBuffer *out = NULL; guint16 res = 0; - GstFlowReturn ret = GST_FLOW_OK; - GstClockTime timestamp = GST_BUFFER_TIMESTAMP (in); + guint len; + + if (G_UNLIKELY (dec->funcs.RADecode == NULL || dec->module == NULL)) + goto not_negotiated; + + timestamp = GST_BUFFER_TIMESTAMP (in); + + flow = gst_pad_alloc_buffer (dec->src, GST_BUFFER_OFFSET_NONE, + dec->width * dec->leaf_size * dec->height * 16, + GST_PAD_CAPS (dec->src), &out); + + if (flow != GST_FLOW_OK) + goto done; - if ((ret = gst_pad_alloc_buffer (dec->src, GST_BUFFER_OFFSET_NONE, - dec->width * dec->leaf_size * dec->height * 16, - GST_PAD_CAPS (dec->src), &out)) != GST_FLOW_OK) - return ret; res = dec->funcs.RADecode (dec->context, GST_BUFFER_DATA (in), GST_BUFFER_SIZE (in), GST_BUFFER_DATA (out), &len, -1); - if (res) + + if (res != 0) goto could_not_decode; + GST_BUFFER_SIZE (out) = len; GST_BUFFER_TIMESTAMP (out) = timestamp; - return gst_pad_push (dec->src, out); + + flow = gst_pad_push (dec->src, out); + +done: + gst_buffer_unref (in); + return flow; /* Errors */ could_not_decode: - gst_buffer_unref (out); - GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Could not decode buffer (%i).", - res), (NULL)); - return GST_FLOW_ERROR; + { + gst_buffer_unref (out); + GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), + ("Could not decode buffer (%i).", res)); + flow = GST_FLOW_ERROR; + goto done; + } +not_negotiated: + { + GST_WARNING_OBJECT (dec, "decoder not open, probably no input caps set " + "yet, caps on input buffer: %" GST_PTR_FORMAT, GST_BUFFER_CAPS (in)); + flow = GST_FLOW_NOT_NEGOTIATED; + goto done; + } } static gboolean @@ -198,6 +223,7 @@ gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps) !gst_structure_get_int (s, "leaf_size", &leaf_size) || !gst_structure_get_int (s, "packet_size", &packet_size)) goto missing_keys; + if ((v = gst_structure_get_value (s, "codec_data"))) buf = g_value_peek_pointer (v); diff --git a/gst/real/gstrealvideodec.c b/gst/real/gstrealvideodec.c index 32b04ea783..5dceccd503 100644 --- a/gst/real/gstrealvideodec.c +++ b/gst/real/gstrealvideodec.c @@ -446,6 +446,9 @@ gst_real_video_dec_chain (GstPad * pad, GstBuffer * in) guint len = GST_BUFFER_SIZE (in); GstFlowReturn ret; + if (G_UNLIKELY (dec->hooks.transform == NULL || dec->hooks.module == NULL)) + goto not_negotiated; + /* Flags */ if (len < 1) goto not_enough_data; @@ -472,6 +475,13 @@ not_enough_data: gst_buffer_unref (in); return GST_FLOW_ERROR; } +not_negotiated: + { + GST_WARNING_OBJECT (dec, "decoder not open, probably no input caps set " + "yet, caps on input buffer: %" GST_PTR_FORMAT, GST_BUFFER_CAPS (in)); + gst_buffer_unref (in); + return GST_FLOW_NOT_NEGOTIATED; + } } static gboolean