mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-26 09:50:39 +00:00
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.
This commit is contained in:
parent
8f7b55d277
commit
04fa67937d
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
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");
|
||||
GST_DEBUG ("could not configure context for source");
|
||||
return FALSE;
|
||||
}
|
||||
configure_error_target:
|
||||
{
|
||||
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 GstFlowReturn
|
||||
gst_ffmpegcsp_chain (GstPad * pad, GstBuffer * buffer)
|
||||
static GstBuffer *
|
||||
gst_ffmpegcsp_bufferalloc (GstPad * pad, guint64 offset, guint size,
|
||||
GstCaps * caps)
|
||||
{
|
||||
GstBuffer *inbuf = GST_BUFFER (buffer);
|
||||
GstBuffer *buf;
|
||||
GstFFMpegCsp *space;
|
||||
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;
|
||||
}
|
||||
buf = gst_pad_alloc_buffer (space->srcpad, offset, size, caps);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* asume passthrough */
|
||||
guint size =
|
||||
avpicture_get_size (space->from_pixfmt, space->width, space->height);
|
||||
static GstFlowReturn
|
||||
gst_ffmpegcsp_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstFFMpegCsp *space;
|
||||
GstFlowReturn res;
|
||||
GstBuffer *outbuf = NULL;
|
||||
|
||||
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size,
|
||||
space->src_prefered);
|
||||
if (outbuf == NULL) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
space = GST_FFMPEGCSP (GST_PAD_PARENT (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;
|
||||
}
|
||||
GST_STREAM_LOCK (pad);
|
||||
|
||||
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 (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
if (space->palette)
|
||||
av_free (space->palette);
|
||||
space->palette = NULL;
|
||||
switch (transition) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (parent_class->change_state)
|
||||
return parent_class->change_state (element);
|
||||
ret = parent_class->change_state (element);
|
||||
|
||||
return GST_STATE_SUCCESS;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue