mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
sys/glsink/glimagesink.c: Fix handling of video/x-raw-yuv. Add overlay handling.
Original commit message from CVS: * sys/glsink/glimagesink.c: Fix handling of video/x-raw-yuv. Add overlay handling.
This commit is contained in:
parent
e66c32e9d7
commit
f9fc86a140
2 changed files with 197 additions and 39 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2007-04-03 David Schleef <ds@schleef.org>
|
||||||
|
|
||||||
|
* sys/glsink/glimagesink.c:
|
||||||
|
Fix handling of video/x-raw-yuv. Add overlay handling.
|
||||||
|
|
||||||
2007-04-03 Wim Taymans <wim@fluendo.com>
|
2007-04-03 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/rtpmanager/gstrtpbin.c: (find_session_by_id),
|
* gst/rtpmanager/gstrtpbin.c: (find_session_by_id),
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct _GstGLImageSink
|
||||||
|
|
||||||
Display *display;
|
Display *display;
|
||||||
GLXContext context;
|
GLXContext context;
|
||||||
|
gboolean internal;
|
||||||
|
|
||||||
int max_texture_size;
|
int max_texture_size;
|
||||||
gboolean have_yuv;
|
gboolean have_yuv;
|
||||||
|
@ -84,6 +85,8 @@ struct _GstGLImageSinkClass
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void gst_glimage_sink_init_interfaces (GType type);
|
||||||
|
|
||||||
static void gst_glimage_sink_finalize (GObject * object);
|
static void gst_glimage_sink_finalize (GObject * object);
|
||||||
static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * param_spec);
|
const GValue * value, GParamSpec * param_spec);
|
||||||
|
@ -99,6 +102,21 @@ static GstCaps *gst_glimage_sink_get_caps (GstBaseSink * bsink);
|
||||||
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
|
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
|
||||||
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
|
static gboolean gst_glimage_sink_start (GstBaseSink * bsink);
|
||||||
|
static gboolean gst_glimage_sink_stop (GstBaseSink * bsink);
|
||||||
|
static gboolean gst_glimage_sink_unlock (GstBaseSink * bsink);
|
||||||
|
|
||||||
|
static void gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface);
|
||||||
|
static void gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay,
|
||||||
|
XID window_id);
|
||||||
|
static void gst_glimage_sink_expose (GstXOverlay * overlay);
|
||||||
|
static void gst_glimage_sink_set_event_handling (GstXOverlay * overlay,
|
||||||
|
gboolean handle_events);
|
||||||
|
|
||||||
|
static gboolean gst_glimage_sink_interface_supported (GstImplementsInterface *
|
||||||
|
iface, GType type);
|
||||||
|
static void gst_glimage_sink_implements_init (GstImplementsInterfaceClass *
|
||||||
|
klass);
|
||||||
|
|
||||||
static void gst_glimage_sink_create_window (GstGLImageSink * glimage_sink);
|
static void gst_glimage_sink_create_window (GstGLImageSink * glimage_sink);
|
||||||
static gboolean gst_glimage_sink_init_display (GstGLImageSink * glimage_sink);
|
static gboolean gst_glimage_sink_init_display (GstGLImageSink * glimage_sink);
|
||||||
|
@ -130,8 +148,27 @@ enum
|
||||||
ARG_DISPLAY
|
ARG_DISPLAY
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_BOILERPLATE (GstGLImageSink, gst_glimage_sink, GstVideoSink,
|
GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink,
|
||||||
GST_TYPE_VIDEO_SINK);
|
GST_TYPE_VIDEO_SINK, gst_glimage_sink_init_interfaces);
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_init_interfaces (GType type)
|
||||||
|
{
|
||||||
|
static const GInterfaceInfo overlay_info = {
|
||||||
|
(GInterfaceInitFunc) gst_glimage_sink_xoverlay_init,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static const GInterfaceInfo implements_info = {
|
||||||
|
(GInterfaceInitFunc) gst_glimage_sink_implements_init,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
|
||||||
|
&implements_info);
|
||||||
|
g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &overlay_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_glimage_sink_base_init (gpointer g_class)
|
gst_glimage_sink_base_init (gpointer g_class)
|
||||||
|
@ -171,26 +208,21 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
|
||||||
gstbasesink_class->get_times = gst_glimage_sink_get_times;
|
gstbasesink_class->get_times = gst_glimage_sink_get_times;
|
||||||
gstbasesink_class->preroll = gst_glimage_sink_render;
|
gstbasesink_class->preroll = gst_glimage_sink_render;
|
||||||
gstbasesink_class->render = gst_glimage_sink_render;
|
gstbasesink_class->render = gst_glimage_sink_render;
|
||||||
|
gstbasesink_class->start = gst_glimage_sink_start;
|
||||||
|
gstbasesink_class->stop = gst_glimage_sink_stop;
|
||||||
|
gstbasesink_class->unlock = gst_glimage_sink_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_glimage_sink_init (GstGLImageSink * glimage_sink,
|
gst_glimage_sink_init (GstGLImageSink * glimage_sink,
|
||||||
GstGLImageSinkClass * glimage_sink_class)
|
GstGLImageSinkClass * glimage_sink_class)
|
||||||
{
|
{
|
||||||
int screen;
|
|
||||||
|
|
||||||
glimage_sink->display = XOpenDisplay (NULL);
|
glimage_sink->width = -1;
|
||||||
if (glimage_sink->display) {
|
glimage_sink->height = -1;
|
||||||
screen = DefaultScreen (glimage_sink->display);
|
|
||||||
|
|
||||||
XSynchronize (glimage_sink->display, True);
|
|
||||||
}
|
|
||||||
/* XSetErrorHandler (error_handler); */
|
|
||||||
glimage_sink->width = 400;
|
|
||||||
glimage_sink->height = 400;
|
|
||||||
|
|
||||||
|
glimage_sink->display_name = NULL;
|
||||||
gst_glimage_sink_update_caps (glimage_sink);
|
gst_glimage_sink_update_caps (glimage_sink);
|
||||||
glimage_sink->display_name = g_strdup ("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -205,10 +237,7 @@ gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_DISPLAY:
|
case ARG_DISPLAY:
|
||||||
/* FIXME this should close/reopen display */
|
g_free (glimage_sink->display_name);
|
||||||
if (glimage_sink->display_name) {
|
|
||||||
g_free (glimage_sink->display_name);
|
|
||||||
}
|
|
||||||
glimage_sink->display_name = g_strdup (g_value_get_string (value));
|
glimage_sink->display_name = g_strdup (g_value_get_string (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -230,10 +259,6 @@ gst_glimage_sink_finalize (GObject * object)
|
||||||
gst_caps_unref (glimage_sink->caps);
|
gst_caps_unref (glimage_sink->caps);
|
||||||
}
|
}
|
||||||
g_free (glimage_sink->display_name);
|
g_free (glimage_sink->display_name);
|
||||||
|
|
||||||
if (glimage_sink->display) {
|
|
||||||
XCloseDisplay (glimage_sink->display);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -272,11 +297,6 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
if (!gst_glimage_sink_init_display (glimage_sink)) {
|
|
||||||
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, WRITE, (NULL),
|
|
||||||
("Could not initialize OpenGL"));
|
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
|
@ -314,10 +334,65 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
* GstBaseSink methods
|
* GstBaseSink methods
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_glimage_sink_start (GstBaseSink * bsink)
|
||||||
|
{
|
||||||
|
GstGLImageSink *glimage_sink;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
|
ret = gst_glimage_sink_init_display (glimage_sink);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_glimage_sink_stop (GstBaseSink * bsink)
|
||||||
|
{
|
||||||
|
GstGLImageSink *glimage_sink;
|
||||||
|
|
||||||
|
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
|
if (glimage_sink->display) {
|
||||||
|
XCloseDisplay (glimage_sink->display);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_glimage_sink_unlock (GstBaseSink * bsink)
|
||||||
|
{
|
||||||
|
//GstGLImageSink *glimage_sink;
|
||||||
|
|
||||||
|
//glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||||
GstClockTime * start, GstClockTime * end)
|
GstClockTime * start, GstClockTime * end)
|
||||||
{
|
{
|
||||||
|
GstGLImageSink *glimagesink;
|
||||||
|
|
||||||
|
glimagesink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
|
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||||
|
*start = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
|
||||||
|
*end = *start + GST_BUFFER_DURATION (buf);
|
||||||
|
} else {
|
||||||
|
if (glimagesink->fps_n > 0) {
|
||||||
|
*end = *start +
|
||||||
|
gst_util_uint64_scale_int (GST_SECOND, glimagesink->fps_d,
|
||||||
|
glimagesink->fps_n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,11 +483,9 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!glimage_sink->window) {
|
if (!glimage_sink->window) {
|
||||||
gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink));
|
gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!glimage_sink->window) {
|
if (!glimage_sink->window) {
|
||||||
gst_glimage_sink_create_window (glimage_sink);
|
gst_glimage_sink_create_window (glimage_sink);
|
||||||
|
@ -433,6 +506,87 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XOverlay
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface)
|
||||||
|
{
|
||||||
|
iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id;
|
||||||
|
iface->expose = gst_glimage_sink_expose;
|
||||||
|
iface->handle_events = gst_glimage_sink_set_event_handling;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay, XID window_id)
|
||||||
|
{
|
||||||
|
GstGLImageSink *glimage_sink;
|
||||||
|
|
||||||
|
g_return_if_fail (GST_IS_GLIMAGE_SINK (overlay));
|
||||||
|
|
||||||
|
glimage_sink = GST_GLIMAGE_SINK (overlay);
|
||||||
|
if (glimage_sink->window == window_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME check if display inited */
|
||||||
|
|
||||||
|
if (window_id == 0) {
|
||||||
|
/* go back to independent window */
|
||||||
|
/* FIXME */
|
||||||
|
glimage_sink->internal = TRUE;
|
||||||
|
} else {
|
||||||
|
XWindowAttributes attr;
|
||||||
|
|
||||||
|
glimage_sink->window = window_id;
|
||||||
|
|
||||||
|
XGetWindowAttributes (glimage_sink->display, window_id, &attr);
|
||||||
|
glimage_sink->width = attr.width;
|
||||||
|
glimage_sink->height = attr.height;
|
||||||
|
glimage_sink->internal = FALSE;
|
||||||
|
#if 0
|
||||||
|
/* FIXME */
|
||||||
|
if (glimage_sink->handle_events) {
|
||||||
|
XSelectInput (glimage_sink->display, window_id,
|
||||||
|
ExposureMask | StructureNotifyMask | PointerMotionMask | KeyPressMask
|
||||||
|
| KeyReleaseMask);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_expose (GstXOverlay * overlay)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
GST_DEBUG ("expose");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_set_event_handling (GstXOverlay * overlay,
|
||||||
|
gboolean handle_events)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
GST_DEBUG ("handle_events %d", handle_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GstImplementsInterface
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
gst_glimage_sink_interface_supported (GstImplementsInterface * iface,
|
||||||
|
GType type)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass)
|
||||||
|
{
|
||||||
|
klass->supported = gst_glimage_sink_interface_supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* helper functions
|
* helper functions
|
||||||
|
@ -460,14 +614,10 @@ gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink)
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
int max_size;
|
int max_size;
|
||||||
|
|
||||||
if (glimage_sink->caps) {
|
|
||||||
gst_caps_unref (glimage_sink->caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glimage_sink->display == NULL) {
|
if (glimage_sink->display == NULL) {
|
||||||
glimage_sink->caps =
|
caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
|
||||||
gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
|
|
||||||
(glimage_sink)));
|
(glimage_sink)));
|
||||||
|
gst_caps_replace (&glimage_sink->caps, caps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +640,7 @@ gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink)
|
||||||
"width", GST_TYPE_INT_RANGE, 16, max_size,
|
"width", GST_TYPE_INT_RANGE, 16, max_size,
|
||||||
"height", GST_TYPE_INT_RANGE, 16, max_size, NULL);
|
"height", GST_TYPE_INT_RANGE, 16, max_size, NULL);
|
||||||
|
|
||||||
glimage_sink->caps = caps;
|
gst_caps_replace (&glimage_sink->caps, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -546,6 +696,9 @@ gst_glimage_sink_create_window (GstGLImageSink * glimage_sink)
|
||||||
XMapWindow (glimage_sink->display, glimage_sink->window);
|
XMapWindow (glimage_sink->display, glimage_sink->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (glimage_sink),
|
||||||
|
glimage_sink->window);
|
||||||
|
|
||||||
glXMakeCurrent (glimage_sink->display, glimage_sink->window,
|
glXMakeCurrent (glimage_sink->display, glimage_sink->window,
|
||||||
glimage_sink->context);
|
glimage_sink->context);
|
||||||
|
|
||||||
|
@ -574,7 +727,7 @@ gst_glimage_sink_init_display (GstGLImageSink * glimage_sink)
|
||||||
const char *extstring;
|
const char *extstring;
|
||||||
Window window;
|
Window window;
|
||||||
|
|
||||||
GST_LOG_OBJECT (glimage_sink, "initializing display");
|
GST_DEBUG_OBJECT (glimage_sink, "initializing display");
|
||||||
|
|
||||||
glimage_sink->display = XOpenDisplay (NULL);
|
glimage_sink->display = XOpenDisplay (NULL);
|
||||||
if (glimage_sink->display == NULL) {
|
if (glimage_sink->display == NULL) {
|
||||||
|
@ -588,13 +741,13 @@ gst_glimage_sink_init_display (GstGLImageSink * glimage_sink)
|
||||||
|
|
||||||
ret = glXQueryExtension (glimage_sink->display, &error_base, &event_base);
|
ret = glXQueryExtension (glimage_sink->display, &error_base, &event_base);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GST_LOG_OBJECT (glimage_sink, "No GLX extension");
|
GST_DEBUG_OBJECT (glimage_sink, "No GLX extension");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
visinfo = glXChooseVisual (glimage_sink->display, scrnum, attrib);
|
visinfo = glXChooseVisual (glimage_sink->display, scrnum, attrib);
|
||||||
if (visinfo == NULL) {
|
if (visinfo == NULL) {
|
||||||
GST_LOG_OBJECT (glimage_sink, "No usable visual");
|
GST_DEBUG_OBJECT (glimage_sink, "No usable visual");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,7 +956,7 @@ static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
if (!gst_element_register (plugin, "glimagesink",
|
if (!gst_element_register (plugin, "glimagesink",
|
||||||
GST_RANK_NONE, GST_TYPE_GLIMAGE_SINK))
|
GST_RANK_MARGINAL, GST_TYPE_GLIMAGE_SINK))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
|
GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
|
||||||
|
|
Loading…
Reference in a new issue