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:
Julien Moutte 2004-01-09 18:05:57 +00:00
parent 6d950b5fd8
commit 7b89c1a8bf
7 changed files with 336 additions and 170 deletions

View file

@ -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.

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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),

View file

@ -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;

View file

@ -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;