mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 20:35:40 +00:00
ext/ffmpeg/gstffmpegcolorspace.c: Implementing gst_pad_alloc_buffer to use optimized buffer allocation.
Original commit message from CVS: * ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_chain): Implementing gst_pad_alloc_buffer to use optimized buffer allocation. * gst-libs/gst/xoverlay/xoverlay.c: (gst_x_overlay_got_desired_size): Updating doc for the xid being 0. * gst/videoscale/gstvideoscale.c: (gst_videoscale_chain): Implementing gst_pad_alloc_buffer to use optimized buffer allocation. * gst/videotestsrc/gstvideotestsrc.c: (gst_videotestsrc_get): Implementing gst_pad_alloc_buffer to use optimized buffer allocation. * sys/ximage/ximagesink.c: (gst_ximagesink_chain), (gst_ximagesink_buffer_free), (gst_ximagesink_buffer_alloc), (gst_ximagesink_set_xwindow_id), (gst_ximagesink_init): Implementing the bufferalloc_function to replace bufferpools, fixing the XOverlay interface implementation to handle xid being 0 and fix some bugs triggered by Benjamin's testcase. * sys/xvimage/xvimagesink.c: (gst_xvimagesink_chain), (gst_xvimagesink_buffer_free), (gst_xvimagesink_buffer_alloc), (gst_xvimagesink_set_xwindow_id), (gst_xvimagesink_init): Implementing the bufferalloc_function to replace bufferpools, fixing the XOverlay interface implementation to handle xid being 0 and fix some bugs triggered by Benjamin's testcase.
This commit is contained in:
parent
6d950b5fd8
commit
7b89c1a8bf
7 changed files with 336 additions and 170 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,26 @@
|
|||
2004-01-09 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_chain):
|
||||
Implementing gst_pad_alloc_buffer to use optimized buffer allocation.
|
||||
* gst-libs/gst/xoverlay/xoverlay.c:
|
||||
(gst_x_overlay_got_desired_size): Updating doc for the xid being 0.
|
||||
* gst/videoscale/gstvideoscale.c: (gst_videoscale_chain):
|
||||
Implementing gst_pad_alloc_buffer to use optimized buffer allocation.
|
||||
* gst/videotestsrc/gstvideotestsrc.c: (gst_videotestsrc_get):
|
||||
Implementing gst_pad_alloc_buffer to use optimized buffer allocation.
|
||||
* sys/ximage/ximagesink.c: (gst_ximagesink_chain),
|
||||
(gst_ximagesink_buffer_free), (gst_ximagesink_buffer_alloc),
|
||||
(gst_ximagesink_set_xwindow_id), (gst_ximagesink_init): Implementing
|
||||
the bufferalloc_function to replace bufferpools, fixing the XOverlay
|
||||
interface implementation to handle xid being 0 and fix some bugs
|
||||
triggered by Benjamin's testcase.
|
||||
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_chain),
|
||||
(gst_xvimagesink_buffer_free), (gst_xvimagesink_buffer_alloc),
|
||||
(gst_xvimagesink_set_xwindow_id), (gst_xvimagesink_init): Implementing
|
||||
the bufferalloc_function to replace bufferpools, fixing the XOverlay
|
||||
interface implementation to handle xid being 0 and fix some bugs
|
||||
triggered by Benjamin's testcase.
|
||||
|
||||
2004-01-09 David Schleef <ds@schleef.org>
|
||||
|
||||
* ext/librfb/gstrfbsrc.c: Hacking. Added actual decoding and
|
||||
|
@ -39,7 +62,7 @@
|
|||
* gst/videodrop/gstvideodrop.c: (gst_videodrop_getcaps),
|
||||
(gst_videodrop_link), (gst_videodrop_init): Fix negotiation.
|
||||
|
||||
2004-01-08 Julien MOUTTE,,, <julien@moutte.net>
|
||||
2004-01-08 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* sys/ximage/ximagesink.c: (gst_ximagesink_handle_xevents): A
|
||||
configure event is not emiting the desired size signal. That fixes
|
||||
|
@ -87,7 +110,7 @@
|
|||
|
||||
* gst/modplug/gstmodplug.cc: fix element description
|
||||
|
||||
2004-01-07 Julien MOUTTE,,, <julien@moutte.net>
|
||||
2004-01-07 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* examples/gstplay/player.c: (got_time_tick), (got_stream_length),
|
||||
(got_video_size): Adding some new lines in g_print calls.
|
||||
|
|
|
@ -103,7 +103,8 @@ gst_x_overlay_base_init (gpointer g_class)
|
|||
*
|
||||
* This will call the video overlay's set_xwindow_id method. You should
|
||||
* use this method to tell to a XOverlay to display video output to a
|
||||
* specific XWindow.
|
||||
* specific XWindow. Passing 0 as the xwindow_id will tell the overlay to
|
||||
* stop using that window and create an internal one.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
|
||||
|
@ -182,4 +183,3 @@ gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
|
|||
g_signal_emit (G_OBJECT (overlay),
|
||||
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,8 @@ gst_x_overlay_base_init (gpointer g_class)
|
|||
*
|
||||
* This will call the video overlay's set_xwindow_id method. You should
|
||||
* use this method to tell to a XOverlay to display video output to a
|
||||
* specific XWindow.
|
||||
* specific XWindow. Passing 0 as the xwindow_id will tell the overlay to
|
||||
* stop using that window and create an internal one.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
|
||||
|
@ -182,4 +183,3 @@ gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
|
|||
g_signal_emit (G_OBJECT (overlay),
|
||||
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -370,9 +370,11 @@ gst_videoscale_chain (GstPad *pad, GstData *_data)
|
|||
g_return_if_fail (size == videoscale->from_buf_size);
|
||||
|
||||
outbuf = gst_buffer_new();
|
||||
/* FIXME: handle bufferpools */
|
||||
GST_BUFFER_SIZE(outbuf) = videoscale->to_buf_size;
|
||||
GST_BUFFER_DATA(outbuf) = g_malloc (videoscale->to_buf_size);
|
||||
outbuf = gst_pad_alloc_buffer (gst_pad_get_peer (pad),
|
||||
GST_BUFFER_OFFSET_NONE, videoscale->to_buf_size);
|
||||
|
||||
/*GST_BUFFER_SIZE(outbuf) = videoscale->to_buf_size;*/
|
||||
/*GST_BUFFER_DATA(outbuf) = g_malloc (videoscale->to_buf_size);*/
|
||||
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf);
|
||||
|
||||
g_return_if_fail(videoscale->format);
|
||||
|
|
|
@ -418,7 +418,7 @@ gst_videotestsrc_get (GstPad * pad)
|
|||
|
||||
GST_DEBUG ("size=%ld %dx%d", newsize, videotestsrc->width, videotestsrc->height);
|
||||
|
||||
buf = gst_buffer_new_and_alloc (newsize);
|
||||
buf = gst_pad_alloc_buffer (pad, GST_BUFFER_OFFSET_NONE, newsize);
|
||||
g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL);
|
||||
|
||||
videotestsrc->make_image (videotestsrc, (void *) GST_BUFFER_DATA (buf),
|
||||
|
|
|
@ -736,14 +736,14 @@ gst_ximagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_clock_id_free (id);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we have a pool and the image is from this pool, simply put it. */
|
||||
if ( (ximagesink->bufferpool) &&
|
||||
(GST_BUFFER_BUFFERPOOL (buf) == ximagesink->bufferpool) )
|
||||
gst_ximagesink_ximage_put (ximagesink, GST_BUFFER_POOL_PRIVATE (buf));
|
||||
/* If this buffer has been allocated using our buffer management we simply
|
||||
put the ximage which is in the PRIVATE pointer */
|
||||
if (GST_BUFFER_BUFFERPOOL (buf) == ximagesink)
|
||||
{
|
||||
gst_ximagesink_ximage_put (ximagesink, GST_BUFFER_POOL_PRIVATE (buf));
|
||||
}
|
||||
else /* Else we have to copy the data into our private image, */
|
||||
{ /* if we have one... */
|
||||
#endif
|
||||
if (ximagesink->ximage)
|
||||
{
|
||||
memcpy (ximagesink->ximage->ximage->data,
|
||||
|
@ -757,9 +757,8 @@ gst_ximagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_element_error (GST_ELEMENT (ximagesink), "no image to draw");
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set correct time for next buffer */
|
||||
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && ximagesink->framerate > 0) {
|
||||
ximagesink->time += GST_SECOND / ximagesink->framerate;
|
||||
|
@ -770,18 +769,45 @@ gst_ximagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_ximagesink_handle_xevents (ximagesink, pad);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GstBuffer*
|
||||
gst_ximagesink_buffer_new (GstBufferPool *pool,
|
||||
gint64 location, guint size, gpointer user_data)
|
||||
/* Buffer management */
|
||||
|
||||
static void
|
||||
gst_ximagesink_buffer_free (GstData *data)
|
||||
{
|
||||
GstXImageSink *ximagesink;
|
||||
GstXImage *ximage;
|
||||
GstBuffer *buffer;
|
||||
|
||||
ximagesink = GST_BUFFER_BUFFERPOOL (data);
|
||||
ximage = GST_BUFFER_POOL_PRIVATE (data);
|
||||
buffer = GST_BUFFER (data);
|
||||
|
||||
/* If our geometry changed we can't reuse that image. */
|
||||
if ( (ximage->width != GST_VIDEOSINK_WIDTH (ximagesink)) ||
|
||||
(ximage->height != GST_VIDEOSINK_HEIGHT (ximagesink)) )
|
||||
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
||||
else /* In that case we can reuse the image and add it to our image pool. */
|
||||
{
|
||||
g_mutex_lock (ximagesink->pool_lock);
|
||||
ximagesink->image_pool = g_slist_prepend (ximagesink->image_pool, ximage);
|
||||
g_mutex_unlock (ximagesink->pool_lock);
|
||||
}
|
||||
|
||||
GST_BUFFER_DATA (buffer) = NULL;
|
||||
|
||||
gst_buffer_default_free (buffer);
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_ximagesink_buffer_alloc (GstPad *pad, guint64 offset, guint size)
|
||||
{
|
||||
GstXImageSink *ximagesink;
|
||||
GstBuffer *buffer;
|
||||
GstXImage *ximage = NULL;
|
||||
gboolean not_found = TRUE;
|
||||
|
||||
ximagesink = GST_XIMAGESINK (user_data);
|
||||
|
||||
ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad));
|
||||
|
||||
g_mutex_lock (ximagesink->pool_lock);
|
||||
|
||||
/* Walking through the pool cleaning unsuable images and searching for a
|
||||
|
@ -803,22 +829,31 @@ gst_ximagesink_buffer_new (GstBufferPool *pool,
|
|||
ximage = NULL;
|
||||
}
|
||||
else /* We found a suitable image */
|
||||
break;
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (ximagesink->pool_lock);
|
||||
|
||||
if (!ximage) /* We found no suitable image in the pool. Creating... */
|
||||
ximage = gst_ximagesink_ximage_new (ximagesink,
|
||||
GST_VIDEOSINK_WIDTH (ximagesink),
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink));
|
||||
{
|
||||
ximage = gst_ximagesink_ximage_new (ximagesink,
|
||||
GST_VIDEOSINK_WIDTH (ximagesink),
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink));
|
||||
}
|
||||
|
||||
if (ximage)
|
||||
{
|
||||
buffer = gst_buffer_new ();
|
||||
|
||||
/* Storing some pointers in the buffer (bit hackish) */
|
||||
GST_BUFFER_BUFFERPOOL (buffer) = ximagesink;
|
||||
GST_BUFFER_POOL_PRIVATE (buffer) = ximage;
|
||||
|
||||
GST_BUFFER_DATA (buffer) = ximage->ximage->data;
|
||||
GST_DATA_FREE_FUNC (buffer) = gst_ximagesink_buffer_free;
|
||||
GST_BUFFER_SIZE (buffer) = ximage->size;
|
||||
return buffer;
|
||||
}
|
||||
|
@ -826,34 +861,6 @@ gst_ximagesink_buffer_new (GstBufferPool *pool,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ximagesink_buffer_free (GstBufferPool *pool,
|
||||
GstBuffer *buffer, gpointer user_data)
|
||||
{
|
||||
GstXImageSink *ximagesink;
|
||||
GstXImage *ximage;
|
||||
|
||||
ximagesink = GST_XIMAGESINK (user_data);
|
||||
|
||||
ximage = GST_BUFFER_POOL_PRIVATE (buffer);
|
||||
|
||||
/* If our geometry changed we can't reuse that image. */
|
||||
if ( (ximage->width != GST_VIDEOSINK_WIDTH (ximagesink)) ||
|
||||
(ximage->height != GST_VIDEOSINK_HEIGHT (ximagesink)) )
|
||||
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
||||
else /* In that case we can reuse the image and add it to our image pool. */
|
||||
{
|
||||
g_mutex_lock (ximagesink->pool_lock);
|
||||
ximagesink->image_pool = g_slist_prepend (ximagesink->image_pool, ximage);
|
||||
g_mutex_unlock (ximagesink->pool_lock);
|
||||
}
|
||||
|
||||
GST_BUFFER_DATA (buffer) = NULL;
|
||||
|
||||
gst_buffer_default_free (buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gst_ximagesink_imagepool_clear (GstXImageSink *ximagesink)
|
||||
{
|
||||
|
@ -936,36 +943,112 @@ gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
|
|||
g_return_if_fail (ximagesink != NULL);
|
||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||
|
||||
/* If we already use that window return */
|
||||
if (ximagesink->xwindow && (xwindow_id == ximagesink->xwindow->win))
|
||||
return;
|
||||
|
||||
/* If the element has not initialized the X11 context try to do so */
|
||||
if (!ximagesink->xcontext)
|
||||
ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
|
||||
|
||||
if ( (ximagesink->xwindow) && (ximagesink->ximage) )
|
||||
{ /* If we are replacing a window we destroy pictures and window as they
|
||||
are associated */
|
||||
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
||||
gst_ximagesink_imagepool_clear (ximagesink);
|
||||
gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
|
||||
if (!ximagesink->xcontext)
|
||||
{
|
||||
g_warning ("ximagesink was unable to obtain the X11 context.");
|
||||
return;
|
||||
}
|
||||
|
||||
xwindow = g_new0 (GstXWindow, 1);
|
||||
/* Clear image pool as the images are unusable anyway */
|
||||
gst_ximagesink_imagepool_clear (ximagesink);
|
||||
|
||||
xwindow->win = xwindow_id;
|
||||
/* Clear the ximage */
|
||||
if (ximagesink->ximage)
|
||||
{
|
||||
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
||||
ximagesink->ximage = NULL;
|
||||
}
|
||||
|
||||
/* We get window geometry, set the event we want to receive, and create a GC */
|
||||
g_mutex_lock (ximagesink->x_lock);
|
||||
XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
|
||||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
|
||||
xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
|
||||
xwindow->win, 0, NULL);
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
/* If a window is there already we destroy it */
|
||||
if (ximagesink->xwindow)
|
||||
{
|
||||
gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
|
||||
ximagesink->xwindow = NULL;
|
||||
}
|
||||
|
||||
ximagesink->xwindow = xwindow;
|
||||
/* If the xid is 0 we go back to an internal window */
|
||||
if (xwindow_id == 0)
|
||||
{
|
||||
/* If no width/height caps nego did not happen window will be created
|
||||
during caps nego then */
|
||||
if (GST_VIDEOSINK_WIDTH (ximagesink) &&
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink))
|
||||
{
|
||||
xwindow = gst_ximagesink_xwindow_new (ximagesink,
|
||||
GST_VIDEOSINK_WIDTH (ximagesink),
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xwindow = g_new0 (GstXWindow, 1);
|
||||
|
||||
xwindow->win = xwindow_id;
|
||||
|
||||
/* We get window geometry, set the event we want to receive,
|
||||
and create a GC */
|
||||
g_mutex_lock (ximagesink->x_lock);
|
||||
XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
|
||||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
|
||||
xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
|
||||
xwindow->win, 0, NULL);
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
|
||||
/* If that new window geometry differs from our one we try to
|
||||
renegotiate caps */
|
||||
if (xwindow->width != GST_VIDEOSINK_WIDTH (ximagesink) ||
|
||||
xwindow->height != GST_VIDEOSINK_HEIGHT (ximagesink))
|
||||
{
|
||||
GstPadLinkReturn r;
|
||||
r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
|
||||
gst_caps_new_simple ("video/x-raw-rgb",
|
||||
"bpp", G_TYPE_INT, ximagesink->xcontext->bpp,
|
||||
"depth", G_TYPE_INT, ximagesink->xcontext->depth,
|
||||
"endianness", G_TYPE_INT, ximagesink->xcontext->endianness,
|
||||
"red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
|
||||
"green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
|
||||
"blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
|
||||
"width", G_TYPE_INT, xwindow->width & ~3,
|
||||
"height", G_TYPE_INT, xwindow->height & ~3,
|
||||
"framerate", G_TYPE_DOUBLE, ximagesink->framerate,
|
||||
NULL));
|
||||
|
||||
/* If caps nego succeded updating our size */
|
||||
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
|
||||
{
|
||||
GST_VIDEOSINK_WIDTH (ximagesink) = xwindow->width & ~3;
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink) = xwindow->height & ~3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Recreating our ximage */
|
||||
if (!ximagesink->ximage &&
|
||||
GST_VIDEOSINK_WIDTH (ximagesink) &&
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink))
|
||||
{
|
||||
ximagesink->ximage = gst_ximagesink_ximage_new (
|
||||
ximagesink,
|
||||
GST_VIDEOSINK_WIDTH (ximagesink),
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink));
|
||||
}
|
||||
|
||||
if (xwindow)
|
||||
ximagesink->xwindow = xwindow;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1040,7 +1123,9 @@ gst_ximagesink_init (GstXImageSink *ximagesink)
|
|||
gst_ximagesink_getcaps);
|
||||
gst_pad_set_fixate_function (GST_VIDEOSINK_PAD (ximagesink),
|
||||
gst_ximagesink_fixate);
|
||||
|
||||
gst_pad_set_bufferalloc_function (GST_VIDEOSINK_PAD (ximagesink),
|
||||
gst_ximagesink_buffer_alloc);
|
||||
|
||||
ximagesink->xcontext = NULL;
|
||||
ximagesink->xwindow = NULL;
|
||||
ximagesink->ximage = NULL;
|
||||
|
|
|
@ -896,14 +896,12 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_clock_id_free (id);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we have a pool and the image is from this pool, simply put it. */
|
||||
if ( (xvimagesink->bufferpool) &&
|
||||
(GST_BUFFER_BUFFERPOOL (buf) == xvimagesink->bufferpool) )
|
||||
/* If this buffer has been allocated using our buffer management we simply
|
||||
put the ximage which is in the PRIVATE pointer */
|
||||
if (GST_BUFFER_BUFFERPOOL (buf) == xvimagesink)
|
||||
gst_xvimagesink_xvimage_put (xvimagesink, GST_BUFFER_POOL_PRIVATE (buf));
|
||||
else /* Else we have to copy the data into our private image, */
|
||||
{ /* if we have one... */
|
||||
#endif
|
||||
if (xvimagesink->xvimage)
|
||||
{
|
||||
memcpy (xvimagesink->xvimage->xvimage->data,
|
||||
|
@ -917,9 +915,8 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_element_error (GST_ELEMENT (xvimagesink), "no image to draw");
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set correct time for next buffer */
|
||||
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && xvimagesink->framerate > 0) {
|
||||
xvimagesink->time += GST_SECOND / xvimagesink->framerate;
|
||||
|
@ -930,72 +927,18 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
|
|||
gst_xvimagesink_handle_xevents (xvimagesink, pad);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GstBuffer*
|
||||
gst_xvimagesink_buffer_new (GstBufferPool *pool,
|
||||
gint64 location, guint size, gpointer user_data)
|
||||
{
|
||||
GstXvImageSink *xvimagesink;
|
||||
GstBuffer *buffer;
|
||||
GstXvImage *xvimage = NULL;
|
||||
gboolean not_found = TRUE;
|
||||
|
||||
xvimagesink = GST_XVIMAGESINK (user_data);
|
||||
|
||||
g_mutex_lock (xvimagesink->pool_lock);
|
||||
|
||||
/* Walking through the pool cleaning unsuable images and searching for a
|
||||
suitable one */
|
||||
while (not_found && xvimagesink->image_pool)
|
||||
{
|
||||
xvimage = xvimagesink->image_pool->data;
|
||||
|
||||
if (xvimage)
|
||||
{
|
||||
/* Removing from the pool */
|
||||
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
|
||||
xvimagesink->image_pool);
|
||||
|
||||
if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
|
||||
(xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) )
|
||||
{ /* This image is unusable. Destroying... */
|
||||
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
|
||||
xvimage = NULL;
|
||||
}
|
||||
else /* We found a suitable image */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (xvimagesink->pool_lock);
|
||||
|
||||
if (!xvimage) /* We found no suitable image in the pool. Creating... */
|
||||
xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
|
||||
GST_VIDEOSINK_WIDTH (xvimagesink),
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink));
|
||||
|
||||
if (xvimage)
|
||||
{
|
||||
buffer = gst_buffer_new ();
|
||||
GST_BUFFER_POOL_PRIVATE (buffer) = xvimage;
|
||||
GST_BUFFER_DATA (buffer) = xvimage->xvimage->data;
|
||||
GST_BUFFER_SIZE (buffer) = xvimage->size;
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
/* Buffer management */
|
||||
|
||||
static void
|
||||
gst_xvimagesink_buffer_free (GstBufferPool *pool,
|
||||
GstBuffer *buffer, gpointer user_data)
|
||||
gst_xvimagesink_buffer_free (GstData *data)
|
||||
{
|
||||
GstXvImageSink *xvimagesink;
|
||||
GstXvImage *xvimage;
|
||||
GstBuffer *buffer;
|
||||
|
||||
xvimagesink = GST_XVIMAGESINK (user_data);
|
||||
|
||||
xvimage = GST_BUFFER_POOL_PRIVATE (buffer);
|
||||
xvimagesink = GST_BUFFER_BUFFERPOOL (data);
|
||||
xvimage = GST_BUFFER_POOL_PRIVATE (data);
|
||||
buffer = GST_BUFFER (data);
|
||||
|
||||
/* If our geometry changed we can't reuse that image. */
|
||||
if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
|
||||
|
@ -1013,7 +956,69 @@ gst_xvimagesink_buffer_free (GstBufferPool *pool,
|
|||
|
||||
gst_buffer_default_free (buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
static GstBuffer *
|
||||
gst_xvimagesink_buffer_alloc (GstPad *pad, guint64 offset, guint size)
|
||||
{
|
||||
GstXvImageSink *xvimagesink;
|
||||
GstBuffer *buffer;
|
||||
GstXvImage *xvimage = NULL;
|
||||
gboolean not_found = TRUE;
|
||||
|
||||
xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad));
|
||||
|
||||
g_mutex_lock (xvimagesink->pool_lock);
|
||||
|
||||
/* Walking through the pool cleaning unsuable images and searching for a
|
||||
suitable one */
|
||||
while (not_found && xvimagesink->image_pool)
|
||||
{
|
||||
xvimage = xvimagesink->image_pool->data;
|
||||
|
||||
if (xvimage)
|
||||
{
|
||||
/* Removing from the pool */
|
||||
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
|
||||
xvimagesink->image_pool);
|
||||
|
||||
if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
|
||||
(xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) )
|
||||
{ /* This image is unusable. Destroying... */
|
||||
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
|
||||
xvimage = NULL;
|
||||
}
|
||||
else /* We found a suitable image */
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (xvimagesink->pool_lock);
|
||||
|
||||
if (!xvimage) /* We found no suitable image in the pool. Creating... */
|
||||
{
|
||||
xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
|
||||
GST_VIDEOSINK_WIDTH (xvimagesink),
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink));
|
||||
}
|
||||
|
||||
if (xvimage)
|
||||
{
|
||||
buffer = gst_buffer_new ();
|
||||
|
||||
/* Storing some pointers in the buffer (bit hackish) */
|
||||
GST_BUFFER_BUFFERPOOL (buffer) = xvimagesink;
|
||||
GST_BUFFER_POOL_PRIVATE (buffer) = xvimage;
|
||||
|
||||
GST_BUFFER_DATA (buffer) = xvimage->xvimage->data;
|
||||
GST_DATA_FREE_FUNC (buffer) = gst_xvimagesink_buffer_free;
|
||||
GST_BUFFER_SIZE (buffer) = xvimage->size;
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink)
|
||||
|
@ -1091,36 +1096,85 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
|
|||
g_return_if_fail (xvimagesink != NULL);
|
||||
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
||||
|
||||
/* If we already use that window return */
|
||||
if (xvimagesink->xwindow && (xwindow_id == xvimagesink->xwindow->win))
|
||||
return;
|
||||
|
||||
/* If the element has not initialized the X11 context try to do so */
|
||||
if (!xvimagesink->xcontext)
|
||||
xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
|
||||
|
||||
if ( (xvimagesink->xwindow) && (xvimagesink->xvimage) )
|
||||
{ /* If we are replacing a window we destroy pictures and window as they
|
||||
are associated */
|
||||
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
|
||||
gst_xvimagesink_imagepool_clear (xvimagesink);
|
||||
gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
|
||||
if (!xvimagesink->xcontext)
|
||||
{
|
||||
g_warning ("xvimagesink was unable to obtain the X11 context.");
|
||||
return;
|
||||
}
|
||||
|
||||
xwindow = g_new0 (GstXWindow, 1);
|
||||
/* Clear image pool as the images are unusable anyway */
|
||||
gst_xvimagesink_imagepool_clear (xvimagesink);
|
||||
|
||||
xwindow->win = xwindow_id;
|
||||
/* Clear the xvimage */
|
||||
if (xvimagesink->xvimage)
|
||||
{
|
||||
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
|
||||
xvimagesink->xvimage = NULL;
|
||||
}
|
||||
|
||||
/* We get window geometry, set the event we want to receive, and create a GC */
|
||||
g_mutex_lock (xvimagesink->x_lock);
|
||||
XGetWindowAttributes (xvimagesink->xcontext->disp, xwindow->win, &attr);
|
||||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
|
||||
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
||||
xwindow->win, 0, NULL);
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
/* If a window is there already we destroy it */
|
||||
if (xvimagesink->xwindow)
|
||||
{
|
||||
gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
|
||||
xvimagesink->xwindow = NULL;
|
||||
}
|
||||
|
||||
xvimagesink->xwindow = xwindow;
|
||||
/* If the xid is 0 we go back to an internal window */
|
||||
if (xwindow_id == 0)
|
||||
{
|
||||
/* If no width/height caps nego did not happen window will be created
|
||||
during caps nego then */
|
||||
if (GST_VIDEOSINK_WIDTH (xvimagesink) &&
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink))
|
||||
{
|
||||
xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
|
||||
GST_VIDEOSINK_WIDTH (xvimagesink),
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xwindow = g_new0 (GstXWindow, 1);
|
||||
|
||||
xwindow->win = xwindow_id;
|
||||
|
||||
/* We get window geometry, set the event we want to receive,
|
||||
and create a GC */
|
||||
g_mutex_lock (xvimagesink->x_lock);
|
||||
XGetWindowAttributes (xvimagesink->xcontext->disp, xwindow->win, &attr);
|
||||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
|
||||
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
||||
xwindow->win, 0, NULL);
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
}
|
||||
|
||||
/* Recreating our xvimage */
|
||||
if (!xvimagesink->xvimage &&
|
||||
GST_VIDEOSINK_WIDTH (xvimagesink) &&
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink))
|
||||
{
|
||||
xvimagesink->xvimage = gst_xvimagesink_xvimage_new (
|
||||
xvimagesink,
|
||||
GST_VIDEOSINK_WIDTH (xvimagesink),
|
||||
GST_VIDEOSINK_HEIGHT (xvimagesink));
|
||||
}
|
||||
|
||||
if (xwindow)
|
||||
xvimagesink->xwindow = xwindow;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1195,7 +1249,9 @@ gst_xvimagesink_init (GstXvImageSink *xvimagesink)
|
|||
gst_xvimagesink_getcaps);
|
||||
gst_pad_set_fixate_function (GST_VIDEOSINK_PAD (xvimagesink),
|
||||
gst_xvimagesink_fixate);
|
||||
|
||||
gst_pad_set_bufferalloc_function (GST_VIDEOSINK_PAD (xvimagesink),
|
||||
gst_xvimagesink_buffer_alloc);
|
||||
|
||||
xvimagesink->xcontext = NULL;
|
||||
xvimagesink->xwindow = NULL;
|
||||
xvimagesink->xvimage = NULL;
|
||||
|
|
Loading…
Reference in a new issue