Commit 04fa6793 authored by Wim Taymans's avatar Wim Taymans
Browse files

Leak fixes in oggdemux.

Original commit message from CVS:
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_internal_chain),
(gst_ogg_demux_submit_buffer), (gst_ogg_demux_get_data),
(gst_ogg_demux_chain_unlocked):
* gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_chain),
(gst_audio_convert_caps_remove_format_info),
(gst_audio_convert_getcaps), (gst_audio_convert_setcaps),
(gst_audio_convert_fixate), (gst_audio_convert_change_state):
* gst/ffmpegcolorspace/gstffmpegcolorspace.c:
(gst_ffmpegcsp_getcaps), (gst_ffmpegcsp_configure_context),
(gst_ffmpegcsp_setcaps), (gst_ffmpegcsp_init),
(gst_ffmpegcsp_bufferalloc), (gst_ffmpegcsp_chain),
(gst_ffmpegcsp_change_state), (gst_ffmpegcsp_set_property),
(gst_ffmpegcsp_get_property):
* sys/xvimage/xvimagesink.c: (gst_xvimage_buffer_destroy),
(gst_xvimage_buffer_finalize), (gst_xvimage_buffer_free),
(gst_xvimage_buffer_class_init), (gst_xvimage_buffer_get_type),
(gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new),
(gst_xvimagesink_xvimage_put), (gst_xvimagesink_imagepool_clear),
(gst_xvimagesink_setcaps), (gst_xvimagesink_change_state),
(gst_xvimagesink_show_frame), (gst_xvimagesink_buffer_free),
(gst_xvimagesink_buffer_alloc), (gst_xvimagesink_set_xwindow_id):
Leak fixes in oggdemux.
Some cleanups in audioconvert.
Make passthrough work along with buffer_alloc etc.
Make buffer_alloc and buffer recycling actually work in
xvimagesink.
parent 8f7b55d2
2005-05-17 Wim Taymans <wim@fluendo.com>
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_internal_chain),
(gst_ogg_demux_submit_buffer), (gst_ogg_demux_get_data),
(gst_ogg_demux_chain_unlocked):
* gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_chain),
(gst_audio_convert_caps_remove_format_info),
(gst_audio_convert_getcaps), (gst_audio_convert_setcaps),
(gst_audio_convert_fixate), (gst_audio_convert_change_state):
* gst/ffmpegcolorspace/gstffmpegcolorspace.c:
(gst_ffmpegcsp_getcaps), (gst_ffmpegcsp_configure_context),
(gst_ffmpegcsp_setcaps), (gst_ffmpegcsp_init),
(gst_ffmpegcsp_bufferalloc), (gst_ffmpegcsp_chain),
(gst_ffmpegcsp_change_state), (gst_ffmpegcsp_set_property),
(gst_ffmpegcsp_get_property):
* sys/xvimage/xvimagesink.c: (gst_xvimage_buffer_destroy),
(gst_xvimage_buffer_finalize), (gst_xvimage_buffer_free),
(gst_xvimage_buffer_class_init), (gst_xvimage_buffer_get_type),
(gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new),
(gst_xvimagesink_xvimage_put), (gst_xvimagesink_imagepool_clear),
(gst_xvimagesink_setcaps), (gst_xvimagesink_change_state),
(gst_xvimagesink_show_frame), (gst_xvimagesink_buffer_free),
(gst_xvimagesink_buffer_alloc), (gst_xvimagesink_set_xwindow_id):
Leak fixes in oggdemux.
Some cleanups in audioconvert.
Make passthrough work along with buffer_alloc etc.
Make buffer_alloc and buffer recycling actually work in
xvimagesink.
2005-05-17 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/subparse/gstsubparse.c: (parse_subrip), (parse_mpsub):
......
......@@ -512,6 +512,8 @@ gst_ogg_pad_internal_chain (GstPad * pad, GstBuffer * buffer)
if (oggpad->start_time == -1)
oggpad->start_time = timestamp;
gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
......@@ -981,6 +983,7 @@ gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer)
oggbuffer = ogg_sync_buffer (&ogg->sync, size);
memcpy (oggbuffer, data, size);
ogg_sync_wrote (&ogg->sync, size);
gst_buffer_unref (buffer);
return size;
}
......@@ -1019,7 +1022,6 @@ gst_ogg_demux_get_data (GstOggDemux * ogg)
return -1;
size = gst_ogg_demux_submit_buffer (ogg, buffer);
gst_buffer_unref (buffer);
return size;
}
......@@ -1862,7 +1864,6 @@ gst_ogg_demux_chain_unlocked (GstPad * pad, GstBuffer * buffer)
}
}
}
gst_buffer_unref (buffer);
return result;
}
......
......@@ -616,24 +616,32 @@ gst_audio_convert_fixate (GstPad * pad, GstCaps * caps)
static GstElementStateReturn
gst_audio_convert_change_state (GstElement * element)
{
GstElementStateReturn ret;
GstAudioConvert *this = GST_AUDIO_CONVERT (element);
gint transition;
switch (GST_STATE_TRANSITION (element)) {
transition = GST_STATE_TRANSITION (element);
switch (transition) {
default:
break;
}
ret = parent_class->change_state (element);
switch (transition) {
case GST_STATE_PAUSED_TO_READY:
GST_STREAM_LOCK (this->sink);
this->convert_internal = NULL;
gst_audio_convert_unset_matrix (this);
gst_caps_replace (&GST_RPAD_CAPS (this->sink), NULL);
gst_caps_replace (&GST_RPAD_CAPS (this->src), NULL);
GST_STREAM_UNLOCK (this->sink);
break;
default:
break;
}
if (parent_class->change_state) {
return parent_class->change_state (element);
} else {
return GST_STATE_SUCCESS;
}
return ret;
}
/* return a writable buffer of size which ideally is the same as before
......
......@@ -98,6 +98,8 @@ static void gst_ffmpegcsp_set_property (GObject * object,
static void gst_ffmpegcsp_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static GstBuffer *gst_ffmpegcsp_bufferalloc (GstPad * pad, guint64 offset,
guint size, GstCaps * caps);
static GstFlowReturn gst_ffmpegcsp_chain (GstPad * pad, GstBuffer * buffer);
static GstElementStateReturn gst_ffmpegcsp_change_state (GstElement * element);
......@@ -247,15 +249,17 @@ gst_ffmpegcsp_setcaps (GstPad * pad, GstCaps * caps)
par = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (!gst_ffmpegcsp_configure_context (pad, caps, width, height))
goto configure_error;
goto configure_error_source;
*prefered = caps;
gst_caps_replace (prefered, caps);
otherpeer = gst_pad_get_peer (otherpad);
if (otherpeer) {
/* check passthrough */
if (gst_pad_accept_caps (otherpeer, caps)) {
*other_prefered = gst_caps_ref (caps);
if (!gst_ffmpegcsp_configure_context (otherpad, caps, width, height))
goto configure_error_target;
gst_caps_replace (other_prefered, caps);
} else {
GstCaps *othercaps;
......@@ -277,7 +281,13 @@ gst_ffmpegcsp_setcaps (GstPad * pad, GstCaps * caps)
gst_value_get_fraction_numerator (par),
gst_value_get_fraction_denominator (par), NULL);
}
*other_prefered = targetcaps;
if (!gst_ffmpegcsp_configure_context (otherpad, targetcaps, width,
height)) {
gst_caps_unref (targetcaps);
goto configure_error_target;
}
gst_caps_replace (other_prefered, targetcaps);
gst_caps_unref (targetcaps);
}
}
gst_object_unref (GST_OBJECT (otherpeer));
......@@ -288,9 +298,15 @@ gst_ffmpegcsp_setcaps (GstPad * pad, GstCaps * caps)
return TRUE;
configure_error:
configure_error_source:
{
GST_DEBUG ("could not configure context for source");
return FALSE;
}
configure_error_target:
{
GST_DEBUG ("could not configure context");
gst_object_unref (GST_OBJECT (otherpeer));
GST_DEBUG ("could not configure context for target");
return FALSE;
}
}
......@@ -357,6 +373,7 @@ gst_ffmpegcsp_init (GstFFMpegCsp * space)
gst_pad_set_getcaps_function (space->sinkpad, gst_ffmpegcsp_getcaps);
gst_pad_set_setcaps_function (space->sinkpad, gst_ffmpegcsp_setcaps);
gst_pad_set_chain_function (space->sinkpad, gst_ffmpegcsp_chain);
gst_pad_set_bufferalloc_function (space->sinkpad, gst_ffmpegcsp_bufferalloc);
gst_element_add_pad (GST_ELEMENT (space), space->sinkpad);
space->srcpad = gst_pad_new_from_template (srctempl, "src");
......@@ -368,83 +385,126 @@ gst_ffmpegcsp_init (GstFFMpegCsp * space)
space->palette = NULL;
}
static GstBuffer *
gst_ffmpegcsp_bufferalloc (GstPad * pad, guint64 offset, guint size,
GstCaps * caps)
{
GstBuffer *buf;
GstFFMpegCsp *space;
space = GST_FFMPEGCSP (GST_PAD_PARENT (pad));
buf = gst_pad_alloc_buffer (space->srcpad, offset, size, caps);
return buf;
}
static GstFlowReturn
gst_ffmpegcsp_chain (GstPad * pad, GstBuffer * buffer)
{
GstBuffer *inbuf = GST_BUFFER (buffer);
GstFFMpegCsp *space;
GstFlowReturn res;
GstBuffer *outbuf = NULL;
//GstCaps *outcaps;
space = GST_FFMPEGCSP (GST_PAD_PARENT (pad));
if (!GST_PAD_IS_USABLE (space->srcpad)) {
gst_buffer_unref (inbuf);
return GST_FLOW_ERROR;
}
/* asume passthrough */
guint size =
avpicture_get_size (space->from_pixfmt, space->width, space->height);
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size,
space->src_prefered);
if (outbuf == NULL) {
return GST_FLOW_ERROR;
}
GST_STREAM_LOCK (pad);
if (space->from_pixfmt == PIX_FMT_NB || space->to_pixfmt == PIX_FMT_NB) {
GST_ELEMENT_ERROR (space, CORE, NOT_IMPLEMENTED, (NULL),
("attempting to convert colorspaces between unknown formats"));
gst_buffer_unref (inbuf);
return GST_FLOW_NOT_NEGOTIATED;
}
if (space->from_pixfmt == PIX_FMT_NB || space->to_pixfmt == PIX_FMT_NB)
goto unkown_format;
if (space->from_pixfmt == space->to_pixfmt) {
GST_DEBUG ("passthrough conversion %" GST_PTR_FORMAT,
GST_PAD_CAPS (space->srcpad));
outbuf = inbuf;
GST_DEBUG ("passthrough conversion");
/* use input as output buffer */
outbuf = buffer;
} else {
/* convert */
/* get size of our suggested output format */
guint size =
avpicture_get_size (space->to_pixfmt, space->width, space->height);
/* get buffer in prefered format, setcaps will be called when it is different */
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size,
space->src_prefered);
if (outbuf == NULL)
goto no_buffer;
/* fill from from with source data */
gst_ffmpegcsp_avpicture_fill (&space->from_frame,
GST_BUFFER_DATA (inbuf),
GST_BUFFER_DATA (buffer),
space->from_pixfmt, space->width, space->height);
/* fill optional palette */
if (space->palette)
space->from_frame.data[1] = (uint8_t *) space->palette;
/* fill target frame */
gst_ffmpegcsp_avpicture_fill (&space->to_frame,
GST_BUFFER_DATA (outbuf),
space->to_pixfmt, space->width, space->height);
/* and convert */
img_convert (&space->to_frame, space->to_pixfmt,
&space->from_frame, space->from_pixfmt, space->width, space->height);
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
gst_buffer_unref (inbuf);
/* copy timestamps */
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
/* we don't need source anymore */
gst_buffer_unref (buffer);
}
return gst_pad_push (space->srcpad, outbuf);
res = gst_pad_push (space->srcpad, outbuf);
GST_STREAM_UNLOCK (pad);
return res;
/* ERRORS */
no_buffer:
{
GST_STREAM_UNLOCK (pad);
gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
unkown_format:
{
GST_STREAM_UNLOCK (pad);
GST_ELEMENT_ERROR (space, CORE, NOT_IMPLEMENTED, (NULL),
("attempting to convert colorspaces between unknown formats"));
gst_buffer_unref (buffer);
return GST_FLOW_NOT_NEGOTIATED;
}
}
static GstElementStateReturn
gst_ffmpegcsp_change_state (GstElement * element)
{
GstFFMpegCsp *space;
GstElementStateReturn ret;
gint transition;
space = GST_FFMPEGCSP (element);
transition = GST_STATE_TRANSITION (element);
switch (transition) {
default:
break;
}
ret = parent_class->change_state (element);
switch (GST_STATE_TRANSITION (element)) {
switch (transition) {
case GST_STATE_PAUSED_TO_READY:
GST_STREAM_LOCK (space->sinkpad);
if (space->palette)
av_free (space->palette);
space->palette = NULL;
GST_STREAM_UNLOCK (space->sinkpad);
break;
default:
break;
}
if (parent_class->change_state)
return parent_class->change_state (element);
return GST_STATE_SUCCESS;
return ret;
}
static void
......@@ -453,12 +513,11 @@ gst_ffmpegcsp_set_property (GObject * object,
{
GstFFMpegCsp *space;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FFMPEGCSP (object));
space = GST_FFMPEGCSP (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
......@@ -469,8 +528,6 @@ gst_ffmpegcsp_get_property (GObject * object,
{
GstFFMpegCsp *space;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FFMPEGCSP (object));
space = GST_FFMPEGCSP (object);
switch (prop_id) {
......
......@@ -103,16 +103,13 @@ static gboolean error_caught = FALSE;
/* This function destroys a GstXvImage handling XShm availability */
static void
gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage)
gst_xvimage_buffer_destroy (GstXvImageBuffer * xvimage)
{
GstXvImageSink *xvimagesink;
g_return_if_fail (xvimage != NULL);
if (xvimage->xvimagesink == NULL)
return;
xvimagesink = xvimage->xvimagesink;
if (xvimagesink == NULL)
goto no_sink;
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
......@@ -147,8 +144,59 @@ gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage)
XSync (xvimagesink->xcontext->disp, FALSE);
g_mutex_unlock (xvimagesink->x_lock);
return;
no_sink:
{
GST_WARNING ("no sink found");
return;
}
}
static void
gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage)
{
GstXvImageSink *xvimagesink;
xvimagesink = xvimage->xvimagesink;
if (xvimagesink == NULL)
goto no_sink;
/* If our geometry changed we can't reuse that image. */
if ((xvimage->width != xvimagesink->video_width) ||
(xvimage->height != xvimagesink->video_height)) {
GST_DEBUG ("destroy image as its size changed %dx%d vs current %dx%d",
xvimage->width, xvimage->height,
xvimagesink->video_width, xvimagesink->video_height);
gst_xvimage_buffer_destroy (xvimage);
} else {
/* In that case we can reuse the image and add it to our image pool. */
GST_DEBUG ("recycling image in pool");
/* need to increment the refcount again to recycle */
gst_buffer_ref (GST_BUFFER (xvimage));
g_mutex_lock (xvimagesink->pool_lock);
xvimagesink->image_pool = g_slist_prepend (xvimagesink->image_pool,
xvimage);
g_mutex_unlock (xvimagesink->pool_lock);
}
return;
no_sink:
{
GST_WARNING ("no sink found");
return;
}
}
static void
gst_xvimage_buffer_free (GstXvImageBuffer * xvimage)
{
/* make sure it is not recycled */
xvimage->width = -1;
xvimage->height = -1;
gst_buffer_unref (GST_BUFFER (xvimage));
}
static void
gst_xvimage_buffer_init (GTypeInstance * instance, gpointer g_class)
......@@ -270,7 +318,7 @@ gst_xvimagesink_check_xshm_calls (GstXContext * xcontext)
beach:
XSetErrorHandler (handler);
gst_buffer_unref (GST_BUFFER (xvimage));
gst_xvimage_buffer_free (xvimage);
XSync (xcontext->disp, FALSE);
return result;
#endif /* HAVE_XSHM */
......@@ -363,7 +411,7 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink,
beach:
if (!succeeded) {
gst_buffer_unref (GST_BUFFER (xvimage));
gst_xvimage_buffer_free (xvimage);
xvimage = NULL;
}
......@@ -1164,7 +1212,7 @@ gst_xvimagesink_imagepool_clear (GstXvImageSink * xvimagesink)
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
xvimagesink->image_pool);
gst_buffer_unref (GST_BUFFER (xvimage));
gst_xvimage_buffer_free (xvimage);
}
g_mutex_unlock (xvimagesink->pool_lock);
......@@ -1363,7 +1411,7 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
GST_FOURCC_ARGS (xvimagesink->xcontext->im_format),
GST_FOURCC_ARGS (im_format));
GST_DEBUG_OBJECT (xvimagesink, "renewing xvimage");
gst_buffer_unref (GST_BUFFER (xvimagesink->xvimage));
gst_xvimage_buffer_free (xvimagesink->xvimage);
xvimagesink->xvimage = NULL;
}
......@@ -1415,7 +1463,7 @@ gst_xvimagesink_change_state (GstElement * element)
break;
case GST_STATE_READY_TO_NULL:
if (xvimagesink->xvimage) {
gst_buffer_unref (GST_BUFFER (xvimagesink->xvimage));
gst_xvimage_buffer_free (xvimagesink->xvimage);
xvimagesink->xvimage = NULL;
}
......@@ -1467,32 +1515,42 @@ gst_xvimagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
/* If this buffer has been allocated using our buffer management we simply
put the ximage which is in the PRIVATE pointer */
if (GST_IS_XVIMAGE_BUFFER (buf)) {
GST_DEBUG ("fast put of bufferpool buffer");
gst_xvimagesink_xvimage_put (xvimagesink, GST_XVIMAGE_BUFFER (buf));
} else {
GST_DEBUG ("slow copy into bufferpool buffer");
/* Else we have to copy the data into our private image, */
/* if we have one... */
if (!xvimagesink->xvimage) {
GST_DEBUG_OBJECT (xvimagesink, "creating our xvimage");
xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
xvimagesink->video_width, xvimagesink->video_height);
if (!xvimagesink->xvimage) {
/* No image available. That's very bad ! */
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (xvimagesink, CORE, NEGOTIATION, (NULL),
("Failed creating an XvImage in xvimagesink chain function."));
return GST_FLOW_ERROR;
}
if (!xvimagesink->xvimage)
goto no_image;
}
memcpy (xvimagesink->xvimage->xvimage->data,
GST_BUFFER_DATA (buf),
MIN (GST_BUFFER_SIZE (buf), xvimagesink->xvimage->size));
gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
}
gst_xvimagesink_handle_xevents (xvimagesink, GST_VIDEOSINK_PAD (xvimagesink));
return GST_FLOW_OK;
/* ERRORS */
no_image:
{
/* No image available. That's very bad ! */
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (xvimagesink, CORE, NEGOTIATION, (NULL),
("Failed creating an XvImage in xvimagesink chain function."));
return GST_FLOW_ERROR;
}
}
/* Buffer management */
......@@ -1501,25 +1559,6 @@ gst_xvimagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
static void
gst_xvimagesink_buffer_free (GstBuffer * buffer)
{
GstXvImageSink *xvimagesink;
GstXvImageBuffer *xvimage;
xvimage = GST_BUFFER_PRIVATE (buffer);
g_assert (GST_IS_XVIMAGESINK (xvimage->xvimagesink));
xvimagesink = xvimage->xvimagesink;
/* If our geometry changed we can't reuse that image. */
if ((xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
(xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)))
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
else {
/* In that case we can reuse the image and add it to our image pool. */
g_mutex_lock (xvimagesink->pool_lock);
xvimagesink->image_pool = g_slist_prepend (xvimagesink->image_pool,
xvimage);
g_mutex_unlock (xvimagesink->pool_lock);
}
}
#endif
......@@ -1553,14 +1592,15 @@ gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
xvimagesink->image_pool);
/* We check for geometry or image format changes */
if ((xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
(xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) ||
if ((xvimage->width != xvimagesink->video_width) ||
(xvimage->height != xvimagesink->video_height) ||
(xvimage->im_format != xvimagesink->xcontext->im_format)) {
/* This image is unusable. Destroying... */
gst_buffer_unref (GST_BUFFER (xvimage));
gst_xvimage_buffer_free (xvimage);
xvimage = NULL;
} else {
/* We found a suitable image */
GST_DEBUG_OBJECT (xvimagesink, "found usable image in pool");
break;
}
}
......@@ -1707,7 +1747,7 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
/* Clear the xvimage */
if (xvimagesink->xvimage) {
gst_buffer_unref (GST_BUFFER (xvimagesink->xvimage));
gst_xvimage_buffer_free (xvimagesink->xvimage);
xvimagesink->xvimage = NULL;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment