From 540c7d46c5627d7c8f229756c4885dac90f77311 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 6 Jan 2008 01:19:48 +0000 Subject: sys/glsink/: Reenable video/x-raw-rgb and x-raw-yuv for glimagesink. Enable vblank synchronization. Remove unused c... Original commit message from CVS: * sys/glsink/glextensions.c: * sys/glsink/glextensions.h: * sys/glsink/glimagesink.c: * sys/glsink/glimagesink.h: * sys/glsink/gstgldisplay.c: * sys/glsink/gstgldisplay.h: * sys/glsink/gstopengl.c: Reenable video/x-raw-rgb and x-raw-yuv for glimagesink. Enable vblank synchronization. Remove unused code. --- sys/glsink/glextensions.c | 1 + sys/glsink/glextensions.h | 2 +- sys/glsink/glimagesink.c | 203 +++++++++++++--------------------------------- sys/glsink/glimagesink.h | 3 + sys/glsink/gstgldisplay.c | 190 +++++++++++-------------------------------- sys/glsink/gstgldisplay.h | 3 +- sys/glsink/gstopengl.c | 2 +- 7 files changed, 113 insertions(+), 291 deletions(-) (limited to 'sys/glsink') diff --git a/sys/glsink/glextensions.c b/sys/glsink/glextensions.c index ccf55726..c5bde8a1 100644 --- a/sys/glsink/glextensions.c +++ b/sys/glsink/glextensions.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "glextensions.h" diff --git a/sys/glsink/glextensions.h b/sys/glsink/glextensions.h index e161b8c4..8ac880fd 100644 --- a/sys/glsink/glextensions.h +++ b/sys/glsink/glextensions.h @@ -2,7 +2,7 @@ #define __GST_GLEXTENSIONS_H__ #include -#include +//#include int gl_have_extension (const char *name); diff --git a/sys/glsink/glimagesink.c b/sys/glsink/glimagesink.c index 365e4c4e..0ce65a27 100644 --- a/sys/glsink/glimagesink.c +++ b/sys/glsink/glimagesink.c @@ -83,15 +83,15 @@ GST_ELEMENT_DETAILS ("OpenGL video sink", #define YUV_CAPS #endif static GstStaticPadTemplate gst_glimage_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) + GST_STATIC_CAPS (GST_GL_VIDEO_CAPS ";" + GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" + GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" + GST_VIDEO_CAPS_YUV ("{ AYUV, UYVY, YUY2 }")) ); -//GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" -//GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR YUV_CAPS) - enum { ARG_0, @@ -287,24 +287,13 @@ gst_glimage_sink_start (GstBaseSink * bsink) { GstGLImageSink *glimage_sink; - //gboolean ret; - GST_DEBUG ("start"); glimage_sink = GST_GLIMAGE_SINK (bsink); -#if 0 - glimage_sink->display = gst_gl_display_new (); - ret = gst_gl_display_connect (glimage_sink->display, - glimage_sink->display_name); - if (!ret) { - GST_ERROR ("failed to open display"); - return FALSE; - } -#endif - if (glimage_sink->display && glimage_sink->window_id) { gst_gl_display_set_window (glimage_sink->display, glimage_sink->window_id); + gst_gl_display_set_visible (glimage_sink->display, TRUE); } GST_DEBUG ("start done"); @@ -322,6 +311,7 @@ gst_glimage_sink_stop (GstBaseSink * bsink) glimage_sink = GST_GLIMAGE_SINK (bsink); if (glimage_sink->display) { + gst_gl_display_set_visible (glimage_sink->display, FALSE); g_object_unref (glimage_sink->display); glimage_sink->display = NULL; } @@ -390,29 +380,34 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) int par_n, par_d; GstVideoFormat format; GstStructure *structure; + gboolean is_gl; GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); glimage_sink = GST_GLIMAGE_SINK (bsink); structure = gst_caps_get_structure (caps, 0); - if (0) { - ok = gst_video_format_parse_caps (caps, &format, &width, &height); - ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d); - ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d); - } else { + if (gst_structure_has_name (structure, "video/x-raw-gl")) { + is_gl = TRUE; + format = GST_VIDEO_FORMAT_UNKNOWN; ok = gst_structure_get_int (structure, "width", &width); ok &= gst_structure_get_int (structure, "height", &height); - ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d); - ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d); + } else { + is_gl = FALSE; + ok = gst_video_format_parse_caps (caps, &format, &width, &height); } + ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d); + ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d); if (!ok) return FALSE; GST_VIDEO_SINK_WIDTH (glimage_sink) = width; GST_VIDEO_SINK_HEIGHT (glimage_sink) = height; - //glimage_sink->format = format; + glimage_sink->is_gl = is_gl; + glimage_sink->format = format; + glimage_sink->width = width; + glimage_sink->height = height; glimage_sink->fps_n = fps_n; glimage_sink->fps_d = fps_d; glimage_sink->par_n = par_n; @@ -425,73 +420,53 @@ static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstGLImageSink *glimage_sink; - GstGLBuffer *gl_buffer = GST_GL_BUFFER (buf); + GstGLBuffer *gl_buffer; GstGLDisplay *display; - GST_DEBUG ("render"); - glimage_sink = GST_GLIMAGE_SINK (bsink); - if (glimage_sink->display == NULL) { - glimage_sink->display = g_object_ref (gl_buffer->display); -#if 1 - if (glimage_sink->window_id) { - gst_gl_display_set_window (glimage_sink->display, - glimage_sink->window_id); - } -#endif - } else { - g_assert (gl_buffer->display == glimage_sink->display); - } - - display = gl_buffer->display; - - /* FIXME polling causes a round-trip delay. This should be changed - * to catch structure events */ - gst_gl_display_update_attributes (display); - - gst_gl_display_lock (display); - glViewport (0, 0, display->win_width, display->win_height); - - glClearColor (0.3, 0.3, 0.3, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); + if (glimage_sink->is_gl) { + gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, gl_buffer->texture); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + if (glimage_sink->display == NULL) { + glimage_sink->display = g_object_ref (gl_buffer->display); + if (glimage_sink->window_id) { + gst_gl_display_set_window (glimage_sink->display, + glimage_sink->window_id); + } + } else { + g_assert (gl_buffer->display == glimage_sink->display); + } + display = gl_buffer->display; - glColor4f (1, 0, 1, 1); + } else { + if (glimage_sink->display == NULL) { + gboolean ret; + + glimage_sink->display = gst_gl_display_new (); + ret = gst_gl_display_connect (glimage_sink->display, NULL); + if (!ret) { + g_object_unref (glimage_sink->display); + return GST_FLOW_ERROR; + } + if (glimage_sink->window_id) { + gst_gl_display_set_window (glimage_sink->display, + glimage_sink->window_id); + } + gst_gl_display_set_visible (glimage_sink->display, TRUE); + } + display = glimage_sink->display; - glBegin (GL_QUADS); - glNormal3f (0, 0, -1); - glTexCoord2f (gl_buffer->width, 0); - glVertex3f (1.0, 1.0, 0); - glTexCoord2f (0, 0); - glVertex3f (-1.0, 1.0, 0); - glTexCoord2f (0, gl_buffer->height); - glVertex3f (-1.0, -1.0, 0); - glTexCoord2f (gl_buffer->width, gl_buffer->height); - glVertex3f (1.0, -1.0, 0); - glEnd (); + gl_buffer = gst_gl_buffer_new_from_video_format (display, + glimage_sink->format, glimage_sink->width, glimage_sink->height); + gst_gl_buffer_upload (gl_buffer, glimage_sink->format, + GST_BUFFER_DATA (buf)); + } - glXSwapBuffers (display->display, display->window); + gst_gl_display_draw_texture (display, gl_buffer->texture, + gl_buffer->width, gl_buffer->height); - gst_gl_display_unlock (display); + gst_buffer_unref (GST_BUFFER (gl_buffer)); return GST_FLOW_OK; } @@ -557,65 +532,3 @@ gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass) { klass->supported = gst_glimage_sink_interface_supported; } - - -/* - * helper functions - */ - -#if 0 -static void -gst_caps_set_all (GstCaps * caps, char *field, ...) -{ - GstStructure *structure; - va_list var_args; - int i; - - for (i = 0; i < gst_caps_get_size (caps); i++) { - structure = gst_caps_get_structure (caps, i); - - va_start (var_args, field); - gst_structure_set_valist (structure, field, var_args); - va_end (var_args); - } -} -#endif - -#if 0 -static void -gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink) -{ - GstCaps *caps; - int max_size; - - if (glimage_sink->display == NULL) { - caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD - (glimage_sink))); - gst_caps_replace (&glimage_sink->caps, caps); - return; - } - - caps = - gst_caps_from_string (GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" - GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR); -#ifdef GL_YCBCR_MESA - if (glimage_sink->display->have_ycbcr_texture) { - GstCaps *ycaps = - gst_caps_from_string (GST_VIDEO_CAPS_YUV ("{ AYUV, UYVY, YUY2 }")); - gst_caps_append (ycaps, caps); - caps = ycaps; - } -#endif - - max_size = glimage_sink->display->max_texture_size; - if (max_size == 0) { - max_size = 1024; - } - - gst_caps_set_all (caps, - "width", GST_TYPE_INT_RANGE, 16, max_size, - "height", GST_TYPE_INT_RANGE, 16, max_size, NULL); - - gst_caps_replace (&glimage_sink->caps, caps); -} -#endif diff --git a/sys/glsink/glimagesink.h b/sys/glsink/glimagesink.h index 3a5effe9..74ec3308 100644 --- a/sys/glsink/glimagesink.h +++ b/sys/glsink/glimagesink.h @@ -54,6 +54,9 @@ struct _GstGLImageSink /* caps */ GstCaps *caps; GstVideoFormat format; + int width; + int height; + gboolean is_gl; int fps_n, fps_d; int par_n, par_d; diff --git a/sys/glsink/gstgldisplay.c b/sys/glsink/gstgldisplay.c index f0995c1b..d90e5e72 100644 --- a/sys/glsink/gstgldisplay.c +++ b/sys/glsink/gstgldisplay.c @@ -85,7 +85,7 @@ gst_gl_display_new (void) return g_object_new (GST_TYPE_GL_DISPLAY, NULL); } -#define HANDLE_X_ERRORS +//#define HANDLE_X_ERRORS #ifdef HANDLE_X_ERRORS static int x_error_handler (Display * display, XErrorEvent * event) @@ -167,28 +167,11 @@ gst_gl_display_check_features (GstGLDisplay * display) GST_DEBUG ("No GLX extension"); return FALSE; } -#if 0 - { - int i; - int n; - - visinfo = XGetVisualInfo (display->display, 0, NULL, &n); - for (i = 0; i < n; i++) { - GST_ERROR ("%d: %d %ld", i, visinfo[i].depth, visinfo[i].visualid); - if (visinfo[i].depth == 32) - break; - } - - visinfo += i; - } -#endif - if (1) { - visinfo = glXChooseVisual (display->display, scrnum, attrib); - if (visinfo == NULL) { - GST_DEBUG ("No usable visual"); - return FALSE; - } + visinfo = glXChooseVisual (display->display, scrnum, attrib); + if (visinfo == NULL) { + GST_DEBUG ("No usable visual"); + return FALSE; } display->visinfo = visinfo; @@ -204,7 +187,7 @@ gst_gl_display_check_features (GstGLDisplay * display) mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect; - GST_ERROR ("creating window with visual %ld", visinfo->visualid); + GST_DEBUG ("creating window with visual %ld", visinfo->visualid); window = XCreateWindow (display->display, root, 0, 0, 100, 100, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); @@ -331,7 +314,9 @@ gst_gl_display_init_tmp_window (GstGLDisplay * display) parent_window, 0, 0, width, height, 0, display->visinfo->depth, InputOutput, display->visinfo->visual, mask, &attr); - XMapWindow (display->display, display->window); + if (display->visible) { + XMapWindow (display->display, display->window); + } XSync (display->display, FALSE); } @@ -341,35 +326,32 @@ gst_gl_display_destroy_tmp_window (GstGLDisplay * display) XDestroyWindow (display->display, display->window); } +void +gst_gl_display_set_visible (GstGLDisplay * display, gboolean visible) +{ + if (display->visible == visible) + return; + display->visible = visible; + if (display->visible) { + XMapWindow (display->display, display->window); + } else { + XUnmapWindow (display->display, display->window); + } + XSync (display->display, FALSE); +} + void gst_gl_display_set_window (GstGLDisplay * display, Window window) { g_mutex_lock (display->lock); -#if 0 - if (window != display->assigned_window) { - if (display->assigned_window == None) { - gst_gl_display_destroy_tmp_window (display); - } - display->assigned_window = window; - if (display->assigned_window == None) { - gst_gl_display_init_tmp_window (display); - } else { - display->window = window; - } - } -#else if (window != display->parent_window) { gst_gl_display_destroy_tmp_window (display); display->parent_window = window; gst_gl_display_init_tmp_window (display); - - //XReparentWindow (display->display, display->window, - // display->assigned_window, 0, 0); } -#endif g_mutex_unlock (display->lock); } @@ -478,6 +460,7 @@ gst_gl_display_upload_texture_rectangle (GstGLDisplay * display, } +#if 0 static void draw_rect_texture (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height) @@ -689,7 +672,9 @@ draw_pow2_texture (GstGLDisplay * display, GstVideoFormat type, glEnd (); glDeleteTextures (1, &texture); } +#endif +#if 0 void gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height) @@ -710,7 +695,7 @@ gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, ret = glXGetSyncValuesOML (display->display, display->window, &ust, &mst, &sbc); - GST_DEBUG ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); + GST_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); } #endif @@ -763,17 +748,15 @@ gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, gst_gl_display_unlock (display); } +#endif void -gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, +gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, int width, int height) { - GLuint texture; - GLuint fbo; - g_return_if_fail (width > 0); g_return_if_fail (height > 0); - g_return_if_fail (rbo != None); + g_return_if_fail (texture != None); gst_gl_display_lock (display); @@ -781,103 +764,24 @@ gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, g_assert (display->context != NULL); gst_gl_display_update_attributes (display); - - glViewport (0, 0, display->win_width, display->win_height); - - glClearColor (0.3, 0.3, 0.3, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); - - glGenFramebuffersEXT (1, &fbo); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); - - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo); - - glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); - glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); - - g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == - GL_FRAMEBUFFER_COMPLETE_EXT); - -#if 1 +#if 0 + /* Doesn't work */ { - void *buffer; + int64_t ust = 1234; + int64_t mst = 1234; + int64_t sbc = 1234; + gboolean ret; - buffer = malloc (320 * 240 * 4); - memset (buffer, random (), 320 * 240 * 4); - free (buffer); + ret = glXGetSyncValuesOML (display->display, display->window, + &ust, &mst, &sbc); + GST_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); } #endif - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glGenTextures (1, &texture); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, - GL_RGB, GL_UNSIGNED_BYTE, NULL); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_RECTANGLE_ARB, texture, 0); - - glDrawBuffer (0); - glReadBuffer (0); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); - glColor4f (1, 0, 1, 1); - gst_gl_display_check_error (display, __LINE__); -//glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - glTexCoord2f (width, 0); - glVertex3f (0.9, 0.9, 0); - glTexCoord2f (0, 0); - glVertex3f (-0.9, 0.9, 0); - glTexCoord2f (0, height); - glVertex3f (-0.9, -0.9, 0); - glTexCoord2f (width, height); - glVertex3f (0.9, -0.9, 0); - glEnd (); - gst_gl_display_check_error (display, __LINE__); - glDeleteTextures (1, &texture); - - glDeleteFramebuffersEXT (1, &fbo); - gst_gl_display_check_error (display, __LINE__); - - glXSwapBuffers (display->display, display->window); - - gst_gl_display_unlock (display); -} - -void -gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, - int width, int height) -{ - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); - g_return_if_fail (texture != None); - - gst_gl_display_lock (display); - - g_assert (display->window != None); - g_assert (display->context != NULL); - - gst_gl_display_update_attributes (display); +#if 1 + /* Doesn't work */ + glXSwapIntervalSGI (1); +#endif glViewport (0, 0, display->win_width, display->win_height); @@ -910,13 +814,13 @@ gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, glNormal3f (0, 0, -1); glTexCoord2f (width, 0); - glVertex3f (0.9, 0.9, 0); + glVertex3f (1.0, 1.0, 0); glTexCoord2f (0, 0); - glVertex3f (-0.9, 0.9, 0); + glVertex3f (-1.0, 1.0, 0); glTexCoord2f (0, height); - glVertex3f (-0.9, -0.9, 0); + glVertex3f (-1.0, -1.0, 0); glTexCoord2f (width, height); - glVertex3f (0.9, -0.9, 0); + glVertex3f (1.0, -1.0, 0); glEnd (); gst_gl_display_check_error (display, __LINE__); diff --git a/sys/glsink/gstgldisplay.h b/sys/glsink/gstgldisplay.h index 907f2c8f..5886884d 100644 --- a/sys/glsink/gstgldisplay.h +++ b/sys/glsink/gstgldisplay.h @@ -46,7 +46,7 @@ struct _GstGLDisplay { gboolean have_color_matrix; Window window; - //Window assigned_window; + gboolean visible; Window parent_window; int win_width; @@ -80,6 +80,7 @@ void gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, void gst_gl_display_check_error (GstGLDisplay *display, int line); GLuint gst_gl_display_upload_texture_rectangle (GstGLDisplay *display, GstVideoFormat type, void *data, int width, int height); +void gst_gl_display_set_visible (GstGLDisplay *display, gboolean visible); #endif diff --git a/sys/glsink/gstopengl.c b/sys/glsink/gstopengl.c index 7acbe1fd..6c73f4f4 100644 --- a/sys/glsink/gstopengl.c +++ b/sys/glsink/gstopengl.c @@ -46,7 +46,7 @@ plugin_init (GstPlugin * plugin) "glimagesink element"); if (!gst_element_register (plugin, "glimagesink", - GST_RANK_MARGINAL, GST_TYPE_GLIMAGE_SINK)) { + GST_RANK_SECONDARY, GST_TYPE_GLIMAGE_SINK)) { return FALSE; } if (!gst_element_register (plugin, "glupload", -- cgit v1.2.1