mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
GstVideoSink subclassing. 90% done.
Original commit message from CVS: GstVideoSink subclassing. 90% done.
This commit is contained in:
parent
280c25766a
commit
bbac18352f
4 changed files with 119 additions and 138 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue