+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
* 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
* 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.
*
* 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)
g_signal_emit (G_OBJECT (overlay),
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
}
-
*
* 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)
g_signal_emit (G_OBJECT (overlay),
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
}
-
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);
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),
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,
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;
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
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;
}
}
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)
{
g_mutex_lock(ximagesink->pool_lock);
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 */
+ if (!ximagesink->xcontext)
+ {
+ g_warning ("ximagesink was unable to obtain the X11 context.");
+ return;
+ }
+
+ /* Clear image pool as the images are unusable anyway */
+ gst_ximagesink_imagepool_clear (ximagesink);
+
+ /* Clear the ximage */
+ if (ximagesink->ximage)
+ {
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
- gst_ximagesink_imagepool_clear (ximagesink);
+ ximagesink->ximage = NULL;
+ }
+
+ /* If a window is there already we destroy it */
+ if (ximagesink->xwindow)
+ {
gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
+ ximagesink->xwindow = NULL;
}
- xwindow = g_new0 (GstXWindow, 1);
-
- xwindow->win = xwindow_id;
+ /* 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);
+ /* 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;
+ }
+ }
+ }
- xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
- xwindow->win, 0, NULL);
- g_mutex_unlock (ximagesink->x_lock);
+ /* 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));
+ }
- ximagesink->xwindow = xwindow;
+ if (xwindow)
+ ximagesink->xwindow = xwindow;
}
static void
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;
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,
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;
gst_xvimagesink_handle_xevents (xvimagesink, pad);
}
-#if 0
-static GstBuffer*
-gst_xvimagesink_buffer_new (GstBufferPool *pool,
- gint64 location, guint size, gpointer user_data)
+/* Buffer management */
+
+static void
+gst_xvimagesink_buffer_free (GstData *data)
+{
+ GstXvImageSink *xvimagesink;
+ GstXvImage *xvimage;
+ GstBuffer *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)) ||
+ (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);
+ }
+
+ GST_BUFFER_DATA (buffer) = NULL;
+
+ gst_buffer_default_free (buffer);
+}
+
+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 (user_data);
-
+ 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
{
/* Removing from the pool */
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
- xvimagesink->image_pool);
+ xvimagesink->image_pool);
if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
(xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) )
xvimage = NULL;
}
else /* We found a suitable image */
- break;
+ {
+ 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));
+ {
+ 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;
}
}
static void
-gst_xvimagesink_buffer_free (GstBufferPool *pool,
- GstBuffer *buffer, gpointer user_data)
-{
- GstXvImageSink *xvimagesink;
- GstXvImage *xvimage;
-
- xvimagesink = GST_XVIMAGESINK (user_data);
-
- xvimage = GST_BUFFER_POOL_PRIVATE (buffer);
-
- /* 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);
- }
-
- GST_BUFFER_DATA (buffer) = NULL;
-
- gst_buffer_default_free (buffer);
-}
-#endif
-
-static void
gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink)
{
g_mutex_lock(xvimagesink->pool_lock);
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 */
+ if (!xvimagesink->xcontext)
+ {
+ g_warning ("xvimagesink was unable to obtain the X11 context.");
+ return;
+ }
+
+ /* Clear image pool as the images are unusable anyway */
+ gst_xvimagesink_imagepool_clear (xvimagesink);
+
+ /* Clear the xvimage */
+ if (xvimagesink->xvimage)
+ {
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
- gst_xvimagesink_imagepool_clear (xvimagesink);
+ xvimagesink->xvimage = NULL;
+ }
+
+ /* If a window is there already we destroy it */
+ if (xvimagesink->xwindow)
+ {
gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
+ xvimagesink->xwindow = NULL;
}
- xwindow = g_new0 (GstXWindow, 1);
-
- xwindow->win = xwindow_id;
+ /* 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);
+ /* 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);
+ }
- 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));
+ }
- xvimagesink->xwindow = xwindow;
+ if (xwindow)
+ xvimagesink->xwindow = xwindow;
}
static void
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;