diff --git a/gst-libs/gst/gl/glextensions.c b/gst-libs/gst/gl/glextensions.c index ccf557261f..c5bde8a13c 100644 --- a/gst-libs/gst/gl/glextensions.c +++ b/gst-libs/gst/gl/glextensions.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "glextensions.h" diff --git a/gst-libs/gst/gl/glextensions.h b/gst-libs/gst/gl/glextensions.h index e161b8c444..8ac880fd67 100644 --- a/gst-libs/gst/gl/glextensions.h +++ b/gst-libs/gst/gl/glextensions.h @@ -2,7 +2,7 @@ #define __GST_GLEXTENSIONS_H__ #include -#include +//#include int gl_have_extension (const char *name); diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index f0995c1bca..d90e5e72b9 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/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,107 +748,8 @@ gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, gst_gl_display_unlock (display); } - -void -gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, - 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); - - gst_gl_display_lock (display); - - g_assert (display->window != None); - 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 - { - void *buffer; - - buffer = malloc (320 * 240 * 4); - memset (buffer, random (), 320 * 240 * 4); - free (buffer); - } #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) @@ -878,6 +764,24 @@ gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, g_assert (display->context != NULL); gst_gl_display_update_attributes (display); +#if 0 + /* Doesn't work */ + { + int64_t ust = 1234; + int64_t mst = 1234; + int64_t sbc = 1234; + gboolean ret; + + ret = glXGetSyncValuesOML (display->display, display->window, + &ust, &mst, &sbc); + GST_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); + } +#endif + +#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/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 907f2c8f26..5886884d6b 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/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/gst/gl/glimagesink.c b/gst/gl/glimagesink.c index 365e4c4e49..0ce65a27cc 100644 --- a/gst/gl/glimagesink.c +++ b/gst/gl/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); + if (glimage_sink->is_gl) { + gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); + + 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); } -#endif + display = gl_buffer->display; + } else { - g_assert (gl_buffer->display == glimage_sink->display); + 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; + + 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)); } - display = gl_buffer->display; + gst_gl_display_draw_texture (display, gl_buffer->texture, + gl_buffer->width, gl_buffer->height); - /* 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); - - 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); - - glColor4f (1, 0, 1, 1); - - 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 (); - - glXSwapBuffers (display->display, display->window); - - 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/gst/gl/glimagesink.h b/gst/gl/glimagesink.h index 3a5effe917..74ec33080a 100644 --- a/gst/gl/glimagesink.h +++ b/gst/gl/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/gst/gl/gstopengl.c b/gst/gl/gstopengl.c index 7acbe1fdc7..6c73f4f4c9 100644 --- a/gst/gl/gstopengl.c +++ b/gst/gl/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",