GstVideoSink subclassing. 90% done.

Original commit message from CVS:
GstVideoSink subclassing. 90% done.
This commit is contained in:
Julien Moutte 2003-11-19 20:43:49 +00:00
parent 280c25766a
commit bbac18352f
4 changed files with 119 additions and 138 deletions

View file

@ -48,7 +48,7 @@ GST_PAD_TEMPLATE_FACTORY (gst_ximagesink_sink_template_factory,
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)) "height", GST_PROPS_INT_RANGE (0, G_MAXINT))
) )
static GstElementClass *parent_class = NULL; static GstVideoSinkClass *parent_class = NULL;
/* ============================================================= */ /* ============================================================= */
/* */ /* */
@ -297,7 +297,6 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
KeyReleaseMask | ButtonPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask, &e)) ButtonReleaseMask, &e))
{ {
GstEvent *event = NULL;
KeySym keysym; KeySym keysym;
/* We lock only for the X function call */ /* We lock only for the X function call */
@ -319,7 +318,7 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
ximagesink->xwindow->width = e.xconfigure.width; ximagesink->xwindow->width = e.xconfigure.width;
ximagesink->xwindow->height = e.xconfigure.height; ximagesink->xwindow->height = e.xconfigure.height;
r = gst_pad_try_set_caps (ximagesink->sinkpad, r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
GST_CAPS_NEW ("ximagesink_ximage_caps", "video/x-raw-rgb", GST_CAPS_NEW ("ximagesink_ximage_caps", "video/x-raw-rgb",
"bpp", GST_PROPS_INT (ximagesink->xcontext->bpp), "bpp", GST_PROPS_INT (ximagesink->xcontext->bpp),
"depth", GST_PROPS_INT (ximagesink->xcontext->depth), "depth", GST_PROPS_INT (ximagesink->xcontext->depth),
@ -333,12 +332,12 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) ) if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
{ {
ximagesink->width = e.xconfigure.width; GST_VIDEOSINK_WIDTH (ximagesink) = e.xconfigure.width;
ximagesink->height = e.xconfigure.height; GST_VIDEOSINK_HEIGHT (ximagesink) = e.xconfigure.height;
if ( (ximagesink->ximage) && if ( (ximagesink->ximage) &&
( (ximagesink->width != ximagesink->ximage->width) || ( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
(ximagesink->height != ximagesink->ximage->height) ) ) (GST_VIDEOSINK_HEIGHT (ximagesink) != ximagesink->ximage->height) ) )
{ {
/* We renew our ximage only if size changed */ /* We renew our ximage only if size changed */
gst_ximagesink_ximage_destroy (ximagesink, gst_ximagesink_ximage_destroy (ximagesink,
@ -346,13 +345,13 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
ximagesink->ximage = gst_ximagesink_ximage_new ( ximagesink->ximage = gst_ximagesink_ximage_new (
ximagesink, ximagesink,
ximagesink->width, GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
} }
gst_x_overlay_got_video_size ( gst_video_sink_got_video_size (GST_VIDEOSINK (ximagesink),
GST_X_OVERLAY (ximagesink), GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->width, ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
} }
} }
break; break;
@ -390,9 +389,6 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
default: default:
GST_DEBUG ("ximagesink unhandled X event (%d)", e.type); GST_DEBUG ("ximagesink unhandled X event (%d)", e.type);
} }
if (event)
gst_pad_send_event (gst_pad_get_peer (pad), event);
g_mutex_lock (ximagesink->x_lock); g_mutex_lock (ximagesink->x_lock);
} }
@ -551,9 +547,9 @@ gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps)
GST_DEBUG ("sinkconnect %s with %s", gst_caps_to_string(caps), GST_DEBUG ("sinkconnect %s with %s", gst_caps_to_string(caps),
gst_caps_to_string(ximagesink->xcontext->caps)); gst_caps_to_string(ximagesink->xcontext->caps));
if (!gst_caps_get_int (caps, "width", &ximagesink->width)) if (!gst_caps_get_int (caps, "width", &(GST_VIDEOSINK_WIDTH (ximagesink))))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
if (!gst_caps_get_int (caps, "height", &ximagesink->height)) if (!gst_caps_get_int (caps, "height", &(GST_VIDEOSINK_HEIGHT (ximagesink))))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
if (!gst_caps_get_float (caps, "framerate", &ximagesink->framerate)) if (!gst_caps_get_float (caps, "framerate", &ximagesink->framerate))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
@ -571,26 +567,27 @@ gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps)
/* Creating our window and our image */ /* Creating our window and our image */
if (!ximagesink->xwindow) if (!ximagesink->xwindow)
ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink, ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink,
ximagesink->width, GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
if ( (ximagesink->ximage) && if ( (ximagesink->ximage) &&
( (ximagesink->width != ximagesink->ximage->width) || ( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
(ximagesink->height != ximagesink->ximage->height) ) ) (GST_VIDEOSINK_HEIGHT (ximagesink) != ximagesink->ximage->height) ) )
{ /* We renew our ximage only if size changed */ { /* We renew our ximage only if size changed */
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage); gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink, ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
ximagesink->width, GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
} }
else if (!ximagesink->ximage) /* If no ximage, creating one */ else if (!ximagesink->ximage) /* If no ximage, creating one */
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink, ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
ximagesink->width, GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
gst_x_overlay_got_video_size (GST_X_OVERLAY (ximagesink), gst_video_sink_got_video_size (GST_VIDEOSINK (ximagesink),
ximagesink->width, ximagesink->height); GST_VIDEOSINK_WIDTH (ximagesink),
GST_VIDEOSINK_HEIGHT (ximagesink));
return GST_PAD_LINK_OK; return GST_PAD_LINK_OK;
} }
@ -662,8 +659,9 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time); GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time);
if (ximagesink->clock) { if (GST_VIDEOSINK_CLOCK (ximagesink)) {
GstClockID id = gst_clock_new_single_shot_id (ximagesink->clock, time); GstClockID id;
id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (ximagesink), time);
gst_element_clock_wait (GST_ELEMENT (ximagesink), id, NULL); gst_element_clock_wait (GST_ELEMENT (ximagesink), id, NULL);
gst_clock_id_free (id); gst_clock_id_free (id);
} }
@ -694,16 +692,6 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
gst_ximagesink_handle_xevents (ximagesink, pad); gst_ximagesink_handle_xevents (ximagesink, pad);
} }
static void
gst_ximagesink_set_clock (GstElement *element, GstClock *clock)
{
GstXImageSink *ximagesink;
ximagesink = GST_XIMAGESINK (element);
ximagesink->clock = clock;
}
static GstBuffer* static GstBuffer*
gst_ximagesink_buffer_new (GstBufferPool *pool, gst_ximagesink_buffer_new (GstBufferPool *pool,
gint64 location, guint size, gpointer user_data) gint64 location, guint size, gpointer user_data)
@ -729,8 +717,8 @@ gst_ximagesink_buffer_new (GstBufferPool *pool,
ximagesink->image_pool = g_slist_delete_link (ximagesink->image_pool, ximagesink->image_pool = g_slist_delete_link (ximagesink->image_pool,
ximagesink->image_pool); ximagesink->image_pool);
if ( (ximage->width != ximagesink->width) || if ( (ximage->width != GST_VIDEOSINK_WIDTH (ximagesink)) ||
(ximage->height != ximagesink->height) ) (ximage->height != GST_VIDEOSINK_HEIGHT (ximagesink)) )
{ /* This image is unusable. Destroying... */ { /* This image is unusable. Destroying... */
gst_ximagesink_ximage_destroy (ximagesink, ximage); gst_ximagesink_ximage_destroy (ximagesink, ximage);
ximage = NULL; ximage = NULL;
@ -744,8 +732,8 @@ gst_ximagesink_buffer_new (GstBufferPool *pool,
if (!ximage) /* We found no suitable image in the pool. Creating... */ if (!ximage) /* We found no suitable image in the pool. Creating... */
ximage = gst_ximagesink_ximage_new (ximagesink, ximage = gst_ximagesink_ximage_new (ximagesink,
ximagesink->width, GST_VIDEOSINK_WIDTH (ximagesink),
ximagesink->height); GST_VIDEOSINK_HEIGHT (ximagesink));
if (ximage) if (ximage)
{ {
@ -771,8 +759,8 @@ gst_ximagesink_buffer_free (GstBufferPool *pool,
ximage = GST_BUFFER_POOL_PRIVATE (buffer); ximage = GST_BUFFER_POOL_PRIVATE (buffer);
/* If our geometry changed we can't reuse that image. */ /* If our geometry changed we can't reuse that image. */
if ( (ximage->width != ximagesink->width) || if ( (ximage->width != GST_VIDEOSINK_WIDTH (ximagesink)) ||
(ximage->height != ximagesink->height) ) (ximage->height != GST_VIDEOSINK_HEIGHT (ximagesink)) )
gst_ximagesink_ximage_destroy (ximagesink, ximage); gst_ximagesink_ximage_destroy (ximagesink, ximage);
else /* In that case we can reuse the image and add it to our image pool. */ else /* In that case we can reuse the image and add it to our image pool. */
{ {
@ -842,7 +830,8 @@ gst_ximagesink_interface_init (GstInterfaceClass *klass)
} }
static void static void
gst_ximagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure) gst_ximagesink_navigation_send_event (GstNavigation *navigation,
GstStructure *structure)
{ {
GstXImageSink *ximagesink = GST_XIMAGESINK (navigation); GstXImageSink *ximagesink = GST_XIMAGESINK (navigation);
GstEvent *event; GstEvent *event;
@ -858,8 +847,8 @@ gst_ximagesink_navigation_send_event (GstNavigation *navigation, GstStructure *s
to match the applied scaling. So here we just add the offset if the image to match the applied scaling. So here we just add the offset if the image
is centered in the window. */ is centered in the window. */
x_offset = ximagesink->xwindow->width - ximagesink->width; x_offset = ximagesink->xwindow->width - GST_VIDEOSINK_WIDTH (ximagesink);
y_offset = ximagesink->xwindow->height - ximagesink->height; y_offset = ximagesink->xwindow->height - GST_VIDEOSINK_HEIGHT (ximagesink);
if (gst_structure_get_double (structure, "pointer_x", &x)) if (gst_structure_get_double (structure, "pointer_x", &x))
{ {
@ -872,7 +861,7 @@ gst_ximagesink_navigation_send_event (GstNavigation *navigation, GstStructure *s
gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL); gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
} }
gst_pad_send_event (gst_pad_get_peer (ximagesink->sinkpad), event); gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (ximagesink)), event);
} }
static void static void
@ -916,7 +905,7 @@ gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
xwindow->internal = FALSE; xwindow->internal = FALSE;
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask | XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
StructureNotifyMask | PointerMotionMask | KeyPressMask | StructureNotifyMask | PointerMotionMask | KeyPressMask |
KeyReleaseMask /*| ButtonPressMask | ButtonReleaseMask*/); KeyReleaseMask);
xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
xwindow->win, 0, NULL); xwindow->win, 0, NULL);
@ -974,23 +963,26 @@ gst_ximagesink_dispose (GObject *object)
static void static void
gst_ximagesink_init (GstXImageSink *ximagesink) gst_ximagesink_init (GstXImageSink *ximagesink)
{ {
ximagesink->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET ( GST_VIDEOSINK_PAD (ximagesink) = gst_pad_new_from_template (
gst_ximagesink_sink_template_factory), GST_PAD_TEMPLATE_GET (
"sink"); gst_ximagesink_sink_template_factory),
gst_element_add_pad (GST_ELEMENT (ximagesink), ximagesink->sinkpad); "sink");
gst_element_add_pad (GST_ELEMENT (ximagesink),
GST_VIDEOSINK_PAD (ximagesink));
gst_pad_set_chain_function (ximagesink->sinkpad, gst_ximagesink_chain); gst_pad_set_chain_function (GST_VIDEOSINK_PAD (ximagesink),
gst_pad_set_link_function (ximagesink->sinkpad, gst_ximagesink_sinkconnect); gst_ximagesink_chain);
gst_pad_set_getcaps_function (ximagesink->sinkpad, gst_ximagesink_getcaps); gst_pad_set_link_function (GST_VIDEOSINK_PAD (ximagesink),
gst_pad_set_bufferpool_function (ximagesink->sinkpad, gst_ximagesink_sinkconnect);
gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (ximagesink),
gst_ximagesink_getcaps);
gst_pad_set_bufferpool_function (GST_VIDEOSINK_PAD (ximagesink),
gst_ximagesink_get_bufferpool); gst_ximagesink_get_bufferpool);
ximagesink->xcontext = NULL; ximagesink->xcontext = NULL;
ximagesink->xwindow = NULL; ximagesink->xwindow = NULL;
ximagesink->ximage = NULL; ximagesink->ximage = NULL;
ximagesink->clock = NULL;
ximagesink->width = ximagesink->height = 0;
ximagesink->framerate = 0; ximagesink->framerate = 0;
@ -1025,12 +1017,11 @@ gst_ximagesink_class_init (GstXImageSinkClass *klass)
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass; gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK);
gobject_class->dispose = gst_ximagesink_dispose; gobject_class->dispose = gst_ximagesink_dispose;
gstelement_class->change_state = gst_ximagesink_change_state; gstelement_class->change_state = gst_ximagesink_change_state;
gstelement_class->set_clock = gst_ximagesink_set_clock;
} }
/* ============================================================= */ /* ============================================================= */
@ -1079,7 +1070,7 @@ gst_ximagesink_get_type (void)
NULL, NULL,
}; };
ximagesink_type = g_type_register_static (GST_TYPE_ELEMENT, ximagesink_type = g_type_register_static (GST_TYPE_VIDEOSINK,
"GstXImageSink", "GstXImageSink",
&ximagesink_info, 0); &ximagesink_info, 0);
@ -1097,6 +1088,10 @@ gst_ximagesink_get_type (void)
static gboolean static gboolean
plugin_init (GstPlugin *plugin) plugin_init (GstPlugin *plugin)
{ {
/* Loading the library containing GstVideoSink, our parent object */
if (!gst_library_load ("gstvideo"))
return FALSE;
if (!gst_element_register (plugin, "ximagesink", if (!gst_element_register (plugin, "ximagesink",
GST_RANK_SECONDARY, GST_TYPE_XIMAGESINK)) GST_RANK_SECONDARY, GST_TYPE_XIMAGESINK))
return FALSE; return FALSE;

View file

@ -20,7 +20,7 @@
#ifndef __GST_XIMAGESINK_H__ #ifndef __GST_XIMAGESINK_H__
#define __GST_XIMAGESINK_H__ #define __GST_XIMAGESINK_H__
#include <gst/gst.h> #include <gst/video/gstvideosink.h>
/* FIXME : We should have a configure test for shm support */ /* FIXME : We should have a configure test for shm support */
#define HAVE_XSHM #define HAVE_XSHM
@ -104,17 +104,12 @@ struct _GstXImage {
struct _GstXImageSink { struct _GstXImageSink {
/* Our element stuff */ /* Our element stuff */
GstElement element; GstVideoSink videosink;
GstPad *sinkpad;
GstClock *clock;
GstXContext *xcontext; GstXContext *xcontext;
GstXWindow *xwindow; GstXWindow *xwindow;
GstXImage *ximage; GstXImage *ximage;
gint width, height;
gfloat framerate; gfloat framerate;
GMutex *x_lock; GMutex *x_lock;
@ -127,7 +122,7 @@ struct _GstXImageSink {
}; };
struct _GstXImageSinkClass { struct _GstXImageSinkClass {
GstElementClass parent_class; GstVideoSinkClass parent_class;
}; };
GType gst_ximagesink_get_type(void); GType gst_ximagesink_get_type(void);

View file

@ -52,7 +52,7 @@ GST_PAD_TEMPLATE_FACTORY (gst_xvimagesink_sink_template_factory,
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)) "height", GST_PROPS_INT_RANGE(0, G_MAXINT))
) )
static GstElementClass *parent_class = NULL; static GstVideoSinkClass *parent_class = NULL;
/* ============================================================= */ /* ============================================================= */
/* */ /* */
@ -308,7 +308,6 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
KeyReleaseMask | ButtonPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask, &e)) ButtonReleaseMask, &e))
{ {
GstEvent *event = NULL;
KeySym keysym; KeySym keysym;
/* We lock only for the X function call */ /* We lock only for the X function call */
@ -356,9 +355,6 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type); GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type);
} }
if (event)
gst_pad_send_event (gst_pad_get_peer (pad), event);
g_mutex_lock (xvimagesink->x_lock); g_mutex_lock (xvimagesink->x_lock);
} }
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
@ -620,9 +616,9 @@ gst_xvimagesink_sinkconnect (GstPad *pad, GstCaps *caps)
GST_DEBUG ("sinkconnect %s with %s", gst_caps_to_string(caps), GST_DEBUG ("sinkconnect %s with %s", gst_caps_to_string(caps),
gst_caps_to_string(xvimagesink->xcontext->caps)); gst_caps_to_string(xvimagesink->xcontext->caps));
if (!gst_caps_get_int (caps, "width", &xvimagesink->width)) if (!gst_caps_get_int (caps, "width", &(GST_VIDEOSINK_WIDTH (xvimagesink))))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
if (!gst_caps_get_int (caps, "height", &xvimagesink->height)) if (!gst_caps_get_int (caps, "height", &(GST_VIDEOSINK_HEIGHT (xvimagesink))))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
if (!gst_caps_get_float (caps, "framerate", &xvimagesink->framerate)) if (!gst_caps_get_float (caps, "framerate", &xvimagesink->framerate))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
@ -643,26 +639,27 @@ gst_xvimagesink_sinkconnect (GstPad *pad, GstCaps *caps)
/* Creating our window and our image */ /* Creating our window and our image */
if (!xvimagesink->xwindow) if (!xvimagesink->xwindow)
xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink, xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
xvimagesink->width, GST_VIDEOSINK_WIDTH (xvimagesink),
xvimagesink->height); GST_VIDEOSINK_HEIGHT (xvimagesink));
if ( (xvimagesink->xvimage) && if ( (xvimagesink->xvimage) &&
( (xvimagesink->width != xvimagesink->xvimage->width) || ( (GST_VIDEOSINK_WIDTH (xvimagesink) != xvimagesink->xvimage->width) ||
(xvimagesink->height != xvimagesink->xvimage->height) ) ) (GST_VIDEOSINK_HEIGHT (xvimagesink) != xvimagesink->xvimage->height) ) )
{ /* We renew our xvimage only if size changed */ { /* We renew our xvimage only if size changed */
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage); gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink, xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
xvimagesink->width, GST_VIDEOSINK_WIDTH (xvimagesink),
xvimagesink->height); GST_VIDEOSINK_HEIGHT (xvimagesink));
} }
else if (!xvimagesink->xvimage) /* If no xvimage, creating one */ else if (!xvimagesink->xvimage) /* If no xvimage, creating one */
xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink, xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
xvimagesink->width, GST_VIDEOSINK_WIDTH (xvimagesink),
xvimagesink->height); GST_VIDEOSINK_HEIGHT (xvimagesink));
gst_x_overlay_got_video_size (GST_X_OVERLAY (xvimagesink), gst_video_sink_got_video_size (GST_VIDEOSINK (xvimagesink),
xvimagesink->width, xvimagesink->height); GST_VIDEOSINK_WIDTH (xvimagesink),
GST_VIDEOSINK_HEIGHT (xvimagesink));
return GST_PAD_LINK_OK; return GST_PAD_LINK_OK;
} }
@ -694,8 +691,8 @@ gst_xvimagesink_change_state (GstElement *element)
break; break;
} }
if (parent_class->change_state) if (GST_ELEMENT_CLASS (parent_class)->change_state)
return parent_class->change_state (element); return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS; return GST_STATE_SUCCESS;
} }
@ -734,8 +731,9 @@ gst_xvimagesink_chain (GstPad *pad, GstData *_data)
GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time); GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time);
if (xvimagesink->clock) { if (GST_VIDEOSINK_CLOCK (xvimagesink)) {
GstClockID id = gst_clock_new_single_shot_id (xvimagesink->clock, time); GstClockID id;
id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink), time);
gst_element_clock_wait (GST_ELEMENT (xvimagesink), id, NULL); gst_element_clock_wait (GST_ELEMENT (xvimagesink), id, NULL);
gst_clock_id_free (id); gst_clock_id_free (id);
} }
@ -766,16 +764,6 @@ gst_xvimagesink_chain (GstPad *pad, GstData *_data)
gst_xvimagesink_handle_xevents (xvimagesink, pad); gst_xvimagesink_handle_xevents (xvimagesink, pad);
} }
static void
gst_xvimagesink_set_clock (GstElement *element, GstClock *clock)
{
GstXvImageSink *xvimagesink;
xvimagesink = GST_XVIMAGESINK (element);
xvimagesink->clock = clock;
}
static GstBuffer* static GstBuffer*
gst_xvimagesink_buffer_new (GstBufferPool *pool, gst_xvimagesink_buffer_new (GstBufferPool *pool,
gint64 location, guint size, gpointer user_data) gint64 location, guint size, gpointer user_data)
@ -801,8 +789,8 @@ gst_xvimagesink_buffer_new (GstBufferPool *pool,
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool, xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
xvimagesink->image_pool); xvimagesink->image_pool);
if ( (xvimage->width != xvimagesink->width) || if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
(xvimage->height != xvimagesink->height) ) (xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) )
{ /* This image is unusable. Destroying... */ { /* This image is unusable. Destroying... */
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage); gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
xvimage = NULL; xvimage = NULL;
@ -816,8 +804,8 @@ gst_xvimagesink_buffer_new (GstBufferPool *pool,
if (!xvimage) /* We found no suitable image in the pool. Creating... */ if (!xvimage) /* We found no suitable image in the pool. Creating... */
xvimage = gst_xvimagesink_xvimage_new (xvimagesink, xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
xvimagesink->width, GST_VIDEOSINK_WIDTH (xvimagesink),
xvimagesink->height); GST_VIDEOSINK_HEIGHT (xvimagesink));
if (xvimage) if (xvimage)
{ {
@ -843,13 +831,14 @@ gst_xvimagesink_buffer_free (GstBufferPool *pool,
xvimage = GST_BUFFER_POOL_PRIVATE (buffer); xvimage = GST_BUFFER_POOL_PRIVATE (buffer);
/* If our geometry changed we can't reuse that image. */ /* If our geometry changed we can't reuse that image. */
if ( (xvimage->width != xvimagesink->width) || if ( (xvimage->width != GST_VIDEOSINK_WIDTH (xvimagesink)) ||
(xvimage->height != xvimagesink->height) ) (xvimage->height != GST_VIDEOSINK_HEIGHT (xvimagesink)) )
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage); gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
else /* In that case we can reuse the image and add it to our image pool. */ else /* In that case we can reuse the image and add it to our image pool. */
{ {
g_mutex_lock (xvimagesink->pool_lock); g_mutex_lock (xvimagesink->pool_lock);
xvimagesink->image_pool = g_slist_prepend (xvimagesink->image_pool, xvimage); xvimagesink->image_pool = g_slist_prepend (xvimagesink->image_pool,
xvimage);
g_mutex_unlock (xvimagesink->pool_lock); g_mutex_unlock (xvimagesink->pool_lock);
} }
@ -867,7 +856,7 @@ gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink)
{ {
GstXvImage *xvimage = xvimagesink->image_pool->data; GstXvImage *xvimage = xvimagesink->image_pool->data;
xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool, xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
xvimagesink->image_pool); xvimagesink->image_pool);
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage); gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
} }
@ -914,7 +903,8 @@ gst_xvimagesink_interface_init (GstInterfaceClass *klass)
} }
static void static void
gst_xvimagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure) gst_xvimagesink_navigation_send_event (GstNavigation *navigation,
GstStructure *structure)
{ {
GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation); GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation);
GstEvent *event; GstEvent *event;
@ -926,18 +916,18 @@ gst_xvimagesink_navigation_send_event (GstNavigation *navigation, GstStructure *
/* Converting pointer coordinates to the non scaled geometry */ /* Converting pointer coordinates to the non scaled geometry */
if (gst_structure_get_double (structure, "pointer_x", &x)) if (gst_structure_get_double (structure, "pointer_x", &x))
{ {
x *= xvimagesink->width; x *= GST_VIDEOSINK_WIDTH (xvimagesink);
x /= xvimagesink->xwindow->width; x /= xvimagesink->xwindow->width;
gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL); gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
} }
if (gst_structure_get_double (structure, "pointer_y", &y)) if (gst_structure_get_double (structure, "pointer_y", &y))
{ {
y *= xvimagesink->height; y *= GST_VIDEOSINK_HEIGHT (xvimagesink);
y /= xvimagesink->xwindow->height; y /= xvimagesink->xwindow->height;
gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL); gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
} }
gst_pad_send_event (gst_pad_get_peer (xvimagesink->sinkpad), event); gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)), event);
} }
static void static void
@ -981,7 +971,7 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
xwindow->internal = FALSE; xwindow->internal = FALSE;
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask | XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
StructureNotifyMask | PointerMotionMask | KeyPressMask | StructureNotifyMask | PointerMotionMask | KeyPressMask |
KeyReleaseMask /*| ButtonPressMask | ButtonReleaseMask*/); KeyReleaseMask);
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp, xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
xwindow->win, 0, NULL); xwindow->win, 0, NULL);
@ -1039,23 +1029,26 @@ gst_xvimagesink_dispose (GObject *object)
static void static void
gst_xvimagesink_init (GstXvImageSink *xvimagesink) gst_xvimagesink_init (GstXvImageSink *xvimagesink)
{ {
xvimagesink->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET ( GST_VIDEOSINK_PAD (xvimagesink) = gst_pad_new_from_template (
gst_xvimagesink_sink_template_factory), GST_PAD_TEMPLATE_GET (
"sink"); gst_xvimagesink_sink_template_factory),
gst_element_add_pad (GST_ELEMENT (xvimagesink), xvimagesink->sinkpad); "sink");
gst_element_add_pad (GST_ELEMENT (xvimagesink),
GST_VIDEOSINK_PAD (xvimagesink));
gst_pad_set_chain_function (xvimagesink->sinkpad, gst_xvimagesink_chain); gst_pad_set_chain_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_pad_set_link_function (xvimagesink->sinkpad, gst_xvimagesink_sinkconnect); gst_xvimagesink_chain);
gst_pad_set_getcaps_function (xvimagesink->sinkpad, gst_xvimagesink_getcaps); gst_pad_set_link_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_pad_set_bufferpool_function (xvimagesink->sinkpad, gst_xvimagesink_sinkconnect);
gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_xvimagesink_getcaps);
gst_pad_set_bufferpool_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_xvimagesink_get_bufferpool); gst_xvimagesink_get_bufferpool);
xvimagesink->xcontext = NULL; xvimagesink->xcontext = NULL;
xvimagesink->xwindow = NULL; xvimagesink->xwindow = NULL;
xvimagesink->xvimage = NULL; xvimagesink->xvimage = NULL;
xvimagesink->clock = NULL;
xvimagesink->width = xvimagesink->height = 0;
xvimagesink->framerate = 0; xvimagesink->framerate = 0;
@ -1090,12 +1083,11 @@ gst_xvimagesink_class_init (GstXvImageSinkClass *klass)
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass; gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK);
gobject_class->dispose = gst_xvimagesink_dispose; gobject_class->dispose = gst_xvimagesink_dispose;
gstelement_class->change_state = gst_xvimagesink_change_state; gstelement_class->change_state = gst_xvimagesink_change_state;
gstelement_class->set_clock = gst_xvimagesink_set_clock;
} }
/* ============================================================= */ /* ============================================================= */
@ -1144,7 +1136,7 @@ gst_xvimagesink_get_type (void)
NULL, NULL,
}; };
xvimagesink_type = g_type_register_static (GST_TYPE_ELEMENT, xvimagesink_type = g_type_register_static (GST_TYPE_VIDEOSINK,
"GstXvImageSink", "GstXvImageSink",
&xvimagesink_info, 0); &xvimagesink_info, 0);
@ -1162,6 +1154,10 @@ gst_xvimagesink_get_type (void)
static gboolean static gboolean
plugin_init (GstPlugin *plugin) plugin_init (GstPlugin *plugin)
{ {
/* Loading the library containing GstVideoSink, our parent object */
if (!gst_library_load ("gstvideo"))
return FALSE;
if (!gst_element_register (plugin, "xvimagesink", if (!gst_element_register (plugin, "xvimagesink",
GST_RANK_PRIMARY, GST_TYPE_XVIMAGESINK)) GST_RANK_PRIMARY, GST_TYPE_XVIMAGESINK))
return FALSE; return FALSE;

View file

@ -20,7 +20,7 @@
#ifndef __GST_XVIMAGESINK_H__ #ifndef __GST_XVIMAGESINK_H__
#define __GST_XVIMAGESINK_H__ #define __GST_XVIMAGESINK_H__
#include <gst/gst.h> #include <gst/video/gstvideosink.h>
/* FIXME : We should have a configure test for shm support */ /* FIXME : We should have a configure test for shm support */
#define HAVE_XSHM #define HAVE_XSHM
@ -112,17 +112,12 @@ struct _GstXvImage {
struct _GstXvImageSink { struct _GstXvImageSink {
/* Our element stuff */ /* Our element stuff */
GstElement element; GstVideoSink videosink;
GstPad *sinkpad;
GstClock *clock;
GstXContext *xcontext; GstXContext *xcontext;
GstXWindow *xwindow; GstXWindow *xwindow;
GstXvImage *xvimage; GstXvImage *xvimage;
gint width, height;
gfloat framerate; gfloat framerate;
GMutex *x_lock; GMutex *x_lock;
@ -135,7 +130,7 @@ struct _GstXvImageSink {
}; };
struct _GstXvImageSinkClass { struct _GstXvImageSinkClass {
GstElementClass parent_class; GstVideoSinkClass parent_class;
}; };
GType gst_xvimagesink_get_type(void); GType gst_xvimagesink_get_type(void);