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>
|
||||
|
||||
* gst/rtpmanager/gstrtpbin.c: (find_session_by_id),
|
||||
|
|
|
@ -69,6 +69,7 @@ struct _GstGLImageSink
|
|||
|
||||
Display *display;
|
||||
GLXContext context;
|
||||
gboolean internal;
|
||||
|
||||
int max_texture_size;
|
||||
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_set_property (GObject * object, guint prop_id,
|
||||
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 GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
||||
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 gboolean gst_glimage_sink_init_display (GstGLImageSink * glimage_sink);
|
||||
|
@ -130,8 +148,27 @@ enum
|
|||
ARG_DISPLAY
|
||||
};
|
||||
|
||||
GST_BOILERPLATE (GstGLImageSink, gst_glimage_sink, GstVideoSink,
|
||||
GST_TYPE_VIDEO_SINK);
|
||||
GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink,
|
||||
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
|
||||
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->preroll = 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
|
||||
gst_glimage_sink_init (GstGLImageSink * glimage_sink,
|
||||
GstGLImageSinkClass * glimage_sink_class)
|
||||
{
|
||||
int screen;
|
||||
|
||||
glimage_sink->display = XOpenDisplay (NULL);
|
||||
if (glimage_sink->display) {
|
||||
screen = DefaultScreen (glimage_sink->display);
|
||||
|
||||
XSynchronize (glimage_sink->display, True);
|
||||
}
|
||||
/* XSetErrorHandler (error_handler); */
|
||||
glimage_sink->width = 400;
|
||||
glimage_sink->height = 400;
|
||||
glimage_sink->width = -1;
|
||||
glimage_sink->height = -1;
|
||||
|
||||
glimage_sink->display_name = NULL;
|
||||
gst_glimage_sink_update_caps (glimage_sink);
|
||||
glimage_sink->display_name = g_strdup ("");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -205,10 +237,7 @@ gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case ARG_DISPLAY:
|
||||
/* FIXME this should close/reopen display */
|
||||
if (glimage_sink->display_name) {
|
||||
g_free (glimage_sink->display_name);
|
||||
}
|
||||
glimage_sink->display_name = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
|
@ -230,10 +259,6 @@ gst_glimage_sink_finalize (GObject * object)
|
|||
gst_caps_unref (glimage_sink->caps);
|
||||
}
|
||||
g_free (glimage_sink->display_name);
|
||||
|
||||
if (glimage_sink->display) {
|
||||
XCloseDisplay (glimage_sink->display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -272,11 +297,6 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
|
||||
switch (transition) {
|
||||
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;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
break;
|
||||
|
@ -314,10 +334,65 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
* 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
|
||||
gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||
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) {
|
||||
gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!glimage_sink->window) {
|
||||
gst_glimage_sink_create_window (glimage_sink);
|
||||
|
@ -433,6 +506,87 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
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
|
||||
|
@ -460,14 +614,10 @@ gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink)
|
|||
GstCaps *caps;
|
||||
int max_size;
|
||||
|
||||
if (glimage_sink->caps) {
|
||||
gst_caps_unref (glimage_sink->caps);
|
||||
}
|
||||
|
||||
if (glimage_sink->display == NULL) {
|
||||
glimage_sink->caps =
|
||||
gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
|
||||
caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
|
||||
(glimage_sink)));
|
||||
gst_caps_replace (&glimage_sink->caps, caps);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -490,7 +640,7 @@ gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink)
|
|||
"width", GST_TYPE_INT_RANGE, 16, max_size,
|
||||
"height", GST_TYPE_INT_RANGE, 16, max_size, NULL);
|
||||
|
||||
glimage_sink->caps = caps;
|
||||
gst_caps_replace (&glimage_sink->caps, caps);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -546,6 +696,9 @@ gst_glimage_sink_create_window (GstGLImageSink * glimage_sink)
|
|||
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,
|
||||
glimage_sink->context);
|
||||
|
||||
|
@ -574,7 +727,7 @@ gst_glimage_sink_init_display (GstGLImageSink * glimage_sink)
|
|||
const char *extstring;
|
||||
Window window;
|
||||
|
||||
GST_LOG_OBJECT (glimage_sink, "initializing display");
|
||||
GST_DEBUG_OBJECT (glimage_sink, "initializing display");
|
||||
|
||||
glimage_sink->display = XOpenDisplay (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);
|
||||
if (!ret) {
|
||||
GST_LOG_OBJECT (glimage_sink, "No GLX extension");
|
||||
GST_DEBUG_OBJECT (glimage_sink, "No GLX extension");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
visinfo = glXChooseVisual (glimage_sink->display, scrnum, attrib);
|
||||
if (visinfo == NULL) {
|
||||
GST_LOG_OBJECT (glimage_sink, "No usable visual");
|
||||
GST_DEBUG_OBJECT (glimage_sink, "No usable visual");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -803,7 +956,7 @@ static gboolean
|
|||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_element_register (plugin, "glimagesink",
|
||||
GST_RANK_NONE, GST_TYPE_GLIMAGE_SINK))
|
||||
GST_RANK_MARGINAL, GST_TYPE_GLIMAGE_SINK))
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
|
||||
|
|
Loading…
Reference in a new issue