[049/906] * configure.ac: * sys/glsink/glextensions.c: * sys/glsink/glextensions...
authorDavid Schleef <ds@schleef.org>
Sat, 29 Dec 2007 00:37:40 +0000 (00:37 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:16 +0000 (19:31 +0000)
gst-libs/gst/gl/glextensions.c
gst-libs/gst/gl/glextensions.h
gst-libs/gst/gl/gstglbuffer.c
gst-libs/gst/gl/gstglbuffer.h
gst-libs/gst/gl/gstgldisplay.c
gst-libs/gst/gl/gstgldisplay.h

index 6926a97..ccf5572 100644 (file)
@@ -49,6 +49,7 @@ DEFINE_FUNC_RET (glCreateShaderObjectARB, GLhandleARB,
     (GLenum shaderType), (shaderType));
 #if 0
 typedef GLhandleARB type_glCreateShaderObjectARB (GLenum shaderType);
+
 GLhandleARB
 glCreateShaderObjectARB (GLenum shaderType)
 {
@@ -181,3 +182,8 @@ DEFINE_FUNC (glGetFramebufferAttachmentParameterivEXT, (GLenum target,
 DEFINE_FUNC (glGenerateMipmapEXT, (GLenum target), (target));
 
 DEFINE_FUNC (glWindowPos2iARB, (GLint x, GLint y), (x, y));
+
+DEFINE_FUNC (glGenProgramsARB, (GLsizei a, GLuint * b), (a, b));
+DEFINE_FUNC (glBindProgramARB, (GLenum a, GLuint b), (a, b));
+DEFINE_FUNC (glProgramStringARB,
+    (GLenum a, GLenum b, GLsizei c, const GLvoid * d), (a, b, c, d));
index 7ef0186..e161b8c 100644 (file)
@@ -56,5 +56,9 @@ void glGenerateMipmapEXT (GLenum target);
 
 void glWindowPos2iARB (GLint x, GLint y);
 
+void glGenProgramsARB (GLsizei, GLuint *);
+void glBindProgramARB (GLenum, GLuint);
+void glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *);
+
 #endif
 
index 7a217a3..c1d5bb7 100644 (file)
@@ -77,11 +77,24 @@ gst_gl_buffer_get_type (void)
 
 
 GstGLBuffer *
-gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
-    int width, int height)
+gst_gl_buffer_new (GstGLDisplay * display, int width, int height)
+{
+  g_return_val_if_fail (display != NULL, NULL);
+  g_return_val_if_fail (width > 0, NULL);
+  g_return_val_if_fail (height > 0, NULL);
+
+  return gst_gl_buffer_new_with_format (display, GST_GL_BUFFER_FORMAT_RGBA,
+      width, height);
+}
+
+GstGLBuffer *
+gst_gl_buffer_new_with_format (GstGLDisplay * display,
+    GstGLBufferFormat format, int width, int height)
 {
   GstGLBuffer *buffer;
 
+  g_return_val_if_fail (format != GST_GL_BUFFER_FORMAT_UNKNOWN, NULL);
+  g_return_val_if_fail (display != NULL, NULL);
   g_return_val_if_fail (width > 0, NULL);
   g_return_val_if_fail (height > 0, NULL);
 
@@ -90,9 +103,9 @@ gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
   buffer->display = g_object_ref (display);
   buffer->width = width;
   buffer->height = height;
-  /* this is not strictly true, but it's used for compatibility with
-   * queue and BaseTransform */
-  GST_BUFFER_SIZE (buffer) = width * height * 4;
+  buffer->format = format;
+  GST_BUFFER_SIZE (buffer) = gst_gl_buffer_format_get_size (format, width,
+      height);
 
   gst_gl_display_lock (buffer->display);
   glGenTextures (1, &buffer->texture);
@@ -100,11 +113,69 @@ gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
   switch (format) {
     case GST_GL_BUFFER_FORMAT_RGBA:
       glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_FLOAT, NULL);
+          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       break;
     case GST_GL_BUFFER_FORMAT_RGB:
       glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+          buffer->width, buffer->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+      break;
+    case GST_GL_BUFFER_FORMAT_YUYV:
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA,
+          buffer->width, buffer->height,
+          0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
+      break;
+    case GST_GL_BUFFER_FORMAT_PLANAR444:
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          buffer->width, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_u);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          buffer->width, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_v);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          buffer->width, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+      break;
+    case GST_GL_BUFFER_FORMAT_PLANAR422:
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          buffer->width, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_u);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          GST_ROUND_UP_2 (buffer->width) / 2, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_v);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          GST_ROUND_UP_2 (buffer->width) / 2, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+      break;
+    case GST_GL_BUFFER_FORMAT_PLANAR420:
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          buffer->width, buffer->height,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_u);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          GST_ROUND_UP_2 (buffer->width) / 2,
+          GST_ROUND_UP_2 (buffer->height) / 2,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+
+      glGenTextures (1, &buffer->texture_v);
+      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
+      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
+          GST_ROUND_UP_2 (buffer->width) / 2,
+          GST_ROUND_UP_2 (buffer->height) / 2,
+          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
       break;
     default:
       g_warning ("GL buffer format not handled");
@@ -116,138 +187,135 @@ gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
 }
 
 GstGLBuffer *
-gst_gl_buffer_new_from_data (GstGLDisplay * display, GstVideoFormat format,
-    int width, int height, void *data)
+gst_gl_buffer_new_from_video_format (GstGLDisplay * display,
+    GstVideoFormat video_format, int width, int height)
 {
   GstGLBuffer *buffer;
-  int comp;
 
   g_return_val_if_fail (width > 0, NULL);
   g_return_val_if_fail (height > 0, NULL);
-  g_return_val_if_fail (data != NULL, NULL);
+
+  buffer = gst_gl_buffer_new_with_format (display,
+      gst_gl_buffer_format_from_video_format (video_format), width, height);
+
+  switch (video_format) {
+    case GST_VIDEO_FORMAT_RGBx:
+    case GST_VIDEO_FORMAT_BGRx:
+    case GST_VIDEO_FORMAT_xRGB:
+    case GST_VIDEO_FORMAT_xBGR:
+      buffer->is_yuv = FALSE;
+      break;
+    case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_UYVY:
+      /* counterintuitive: when you use a GL_YCBCR_MESA texture, the
+       * colorspace is automatically converted, so it's referred to
+       * as RGB */
+      buffer->is_yuv = FALSE;
+      break;
+    case GST_VIDEO_FORMAT_AYUV:
+    case GST_VIDEO_FORMAT_I420:
+    case GST_VIDEO_FORMAT_YV12:
+      buffer->is_yuv = TRUE;
+      break;
+    default:
+      g_assert_not_reached ();
+  }
+
+  return buffer;
+}
+
+void
+gst_gl_buffer_upload (GstGLBuffer * buffer, GstVideoFormat video_format,
+    void *data)
+{
+  int width = buffer->width;
+  int height = buffer->height;
 
   GST_DEBUG ("uploading %p %dx%d", data, width, height);
 
-  buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
-  buffer->display = g_object_ref (display);
-  buffer->width = width;
-  buffer->height = height;
-  /* this is not strictly true, but it's used for compatibility with
-   * queue and BaseTransform */
-  GST_BUFFER_SIZE (buffer) = width * height * 4;
+  g_return_if_fail (buffer->format ==
+      gst_gl_buffer_format_from_video_format (video_format));
 
   gst_gl_display_lock (buffer->display);
-  glGenTextures (1, &buffer->texture);
   glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
 
-  switch (format) {
+  switch (video_format) {
     case GST_VIDEO_FORMAT_RGBx:
-      buffer->format = GST_GL_BUFFER_FORMAT_RGB;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_RGBA, GL_UNSIGNED_BYTE, data);
       break;
     case GST_VIDEO_FORMAT_BGRx:
-      buffer->format = GST_GL_BUFFER_FORMAT_RGB;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_BGRA, GL_UNSIGNED_BYTE, data);
       break;
+    case GST_VIDEO_FORMAT_AYUV:
     case GST_VIDEO_FORMAT_xRGB:
-      buffer->format = GST_GL_BUFFER_FORMAT_RGB;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
       break;
     case GST_VIDEO_FORMAT_xBGR:
-      buffer->format = GST_GL_BUFFER_FORMAT_RGB;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
       break;
     case GST_VIDEO_FORMAT_YUY2:
-      buffer->format = GST_GL_BUFFER_FORMAT_YUYV;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
-          0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
       break;
     case GST_VIDEO_FORMAT_UYVY:
-      buffer->format = GST_GL_BUFFER_FORMAT_YUYV;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
-          0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
       break;
-    case GST_VIDEO_FORMAT_AYUV:
-      buffer->format = GST_GL_BUFFER_FORMAT_RGB;
-      buffer->is_yuv = TRUE;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-          buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-      glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
-          GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
-      break;
     case GST_VIDEO_FORMAT_I420:
     case GST_VIDEO_FORMAT_YV12:
-      buffer->format = GST_GL_BUFFER_FORMAT_PLANAR420;
-      buffer->is_yuv = TRUE;
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
-          buffer->width, buffer->height,
-          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
           GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
 
-      glGenTextures (1, &buffer->texture_u);
       glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
-          GST_ROUND_UP_2 (buffer->width) / 2,
-          GST_ROUND_UP_2 (buffer->height) / 2,
-          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
-      comp = (format == GST_VIDEO_FORMAT_I420) ? 1 : 2;
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
           GST_ROUND_UP_2 (buffer->width) / 2,
           GST_ROUND_UP_2 (buffer->height) / 2,
           GL_LUMINANCE, GL_UNSIGNED_BYTE,
           (guint8 *) data +
-          gst_video_format_get_component_offset (format, comp, width, height));
+          gst_video_format_get_component_offset (video_format, 1, width,
+              height));
 
-      glGenTextures (1, &buffer->texture_v);
       glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
-          GST_ROUND_UP_2 (buffer->width) / 2,
-          GST_ROUND_UP_2 (buffer->height) / 2,
-          0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
-      comp = (format == GST_VIDEO_FORMAT_I420) ? 2 : 1;
       glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
           GST_ROUND_UP_2 (buffer->width) / 2,
           GST_ROUND_UP_2 (buffer->height) / 2,
           GL_LUMINANCE, GL_UNSIGNED_BYTE,
           (guint8 *) data +
-          gst_video_format_get_component_offset (format, comp, width, height));
+          gst_video_format_get_component_offset (video_format, 2, width,
+              height));
       break;
     default:
       g_assert_not_reached ();
   }
 
   gst_gl_display_unlock (buffer->display);
-
-  return buffer;
 }
 
 
 void
-gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat format, void *data)
+gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat video_format,
+    void *data)
 {
   GLuint fbo;
 
+  g_return_if_fail (buffer->format ==
+      gst_gl_buffer_format_from_video_format (video_format));
+
   GST_DEBUG ("downloading");
 
   gst_gl_display_lock (buffer->display);
 
+  /* we need a reset function */
+  glMatrixMode (GL_COLOR);
+  glLoadIdentity ();
+  glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
+  glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
+  glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
+
   glGenFramebuffersEXT (1, &fbo);
   glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
 
@@ -260,14 +328,7 @@ gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat format, void *data)
   g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
       GL_FRAMEBUFFER_COMPLETE_EXT);
 
-  /* we need a reset function */
-  glMatrixMode (GL_COLOR);
-  glLoadIdentity ();
-  glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
-  glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
-  glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
-
-  switch (format) {
+  switch (video_format) {
     case GST_VIDEO_FORMAT_RGBx:
       glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
           GL_UNSIGNED_BYTE, data);
@@ -280,10 +341,42 @@ gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat format, void *data)
       glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
           GL_UNSIGNED_INT_8_8_8_8, data);
       break;
+    case GST_VIDEO_FORMAT_AYUV:
     case GST_VIDEO_FORMAT_xRGB:
       glReadPixels (0, 0, buffer->width, buffer->height, GL_BGRA,
           GL_UNSIGNED_INT_8_8_8_8, data);
       break;
+    case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_UYVY:
+      g_warning ("video format not supported for download from GL texture");
+      break;
+    case GST_VIDEO_FORMAT_I420:
+    case GST_VIDEO_FORMAT_YV12:
+      glReadPixels (0, 0, buffer->width, buffer->height,
+          GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+
+      glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
+          GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB,
+          buffer->texture_u, 0);
+      glReadPixels (0, 0,
+          GST_ROUND_UP_2 (buffer->width) / 2,
+          GST_ROUND_UP_2 (buffer->height) / 2,
+          GL_LUMINANCE, GL_UNSIGNED_BYTE,
+          (guint8 *) data +
+          gst_video_format_get_component_offset (video_format, 1, buffer->width,
+              buffer->height));
+
+      glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
+          GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB,
+          buffer->texture_v, 0);
+      glReadPixels (0, 0,
+          GST_ROUND_UP_2 (buffer->width) / 2,
+          GST_ROUND_UP_2 (buffer->height) / 2,
+          GL_LUMINANCE, GL_UNSIGNED_BYTE,
+          (guint8 *) data +
+          gst_video_format_get_component_offset (video_format, 2, buffer->width,
+              buffer->height));
+      break;
     default:
       g_assert_not_reached ();
   }
@@ -292,3 +385,67 @@ gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat format, void *data)
 
   gst_gl_display_unlock (buffer->display);
 }
+
+
+
+/* buffer format */
+
+GstGLBufferFormat
+gst_gl_buffer_format_from_video_format (GstVideoFormat format)
+{
+  switch (format) {
+    case GST_VIDEO_FORMAT_RGBx:
+    case GST_VIDEO_FORMAT_BGRx:
+    case GST_VIDEO_FORMAT_xRGB:
+    case GST_VIDEO_FORMAT_xBGR:
+    case GST_VIDEO_FORMAT_RGBA:
+    case GST_VIDEO_FORMAT_BGRA:
+    case GST_VIDEO_FORMAT_ARGB:
+    case GST_VIDEO_FORMAT_ABGR:
+    case GST_VIDEO_FORMAT_AYUV:
+      return GST_GL_BUFFER_FORMAT_RGBA;
+    case GST_VIDEO_FORMAT_RGB:
+    case GST_VIDEO_FORMAT_BGR:
+      return GST_GL_BUFFER_FORMAT_RGB;
+    case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_UYVY:
+      return GST_GL_BUFFER_FORMAT_YUYV;
+    case GST_VIDEO_FORMAT_I420:
+    case GST_VIDEO_FORMAT_YV12:
+      return GST_GL_BUFFER_FORMAT_PLANAR420;
+    case GST_VIDEO_FORMAT_UNKNOWN:
+      return GST_GL_BUFFER_FORMAT_UNKNOWN;
+  }
+
+  g_return_val_if_reached (GST_GL_BUFFER_FORMAT_UNKNOWN);
+}
+
+int
+gst_gl_buffer_format_get_size (GstGLBufferFormat format, int width, int height)
+{
+  /* this is not strictly true, but it's used for compatibility with
+   * queue and BaseTransform */
+  return width * height * 4;
+}
+
+gboolean
+gst_gl_buffer_format_parse_caps (GstCaps * caps, GstGLBufferFormat * format,
+    int *width, int *height)
+{
+  GstStructure *structure;
+  int format_as_int;
+  gboolean ret;
+
+  structure = gst_caps_get_structure (caps, 0);
+
+  if (!gst_structure_has_name (structure, "video/x-raw-gl")) {
+    return FALSE;
+  }
+
+  ret = gst_structure_get_int (structure, "format", &format_as_int);
+  *format = format_as_int;
+  ret &= gst_structure_get_int (structure, "width", width);
+  ret &= gst_structure_get_int (structure, "height", height);
+
+  return ret;
+}
index e5a3944..cf2e014 100644 (file)
@@ -14,6 +14,7 @@ typedef struct _GstGLBuffer GstGLBuffer;
 #define GST_GL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GL_BUFFER, GstGLBuffer))
 
 typedef enum {
+  GST_GL_BUFFER_FORMAT_UNKNOWN,
   GST_GL_BUFFER_FORMAT_RGBA,
   GST_GL_BUFFER_FORMAT_RGB,
   GST_GL_BUFFER_FORMAT_YUYV,
@@ -41,21 +42,32 @@ struct _GstGLBuffer {
 GType gst_gl_buffer_get_type (void);
 
 GstGLBuffer * gst_gl_buffer_new (GstGLDisplay *display,
+    int width, int height);
+GstGLBuffer * gst_gl_buffer_new_with_format (GstGLDisplay *display,
     GstGLBufferFormat format, int width, int height);
-GstGLBuffer * gst_gl_buffer_new_from_data (GstGLDisplay *display,
-    GstVideoFormat format, int width, int height, void *data);
+GstGLBuffer * gst_gl_buffer_new_from_video_format (GstGLDisplay *display,
+    GstVideoFormat format, int width, int height);
+void gst_gl_buffer_upload (GstGLBuffer *buffer,
+    GstVideoFormat format, void *data);
 void gst_gl_buffer_download (GstGLBuffer *buffer, GstVideoFormat format,
     void *data);
 
 
 #define GST_GL_VIDEO_CAPS \
   "video/x-raw-gl," \
-  "format=(int)[0,10]," \
+  "format=(int)1," \
+  "is_yuv=(boolean)FALSE," \
   "width=(int)[1,2048]," \
   "height=(int)[1,2048]," \
   "pixel-aspect-ratio=(fraction)1/1," \
   "framerate=(fraction)[0/1,100/1]"
 
+GstGLBufferFormat gst_gl_buffer_format_from_video_format (GstVideoFormat format);
+int gst_gl_buffer_format_get_size (GstGLBufferFormat format, int width,
+    int height);
+gboolean gst_gl_buffer_format_parse_caps (GstCaps *caps, GstGLBufferFormat *format,
+    int *width, int *height);
+
 
 #endif
 
index 6d93c88..f0995c1 100644 (file)
@@ -57,15 +57,17 @@ gst_gl_display_finalize (GObject * object)
 {
   GstGLDisplay *display = GST_GL_DISPLAY (object);
 
-  if (display->assigned_window == None) {
+  GST_DEBUG ("finalize %p", object);
+
+  if (display->window != None) {
     XDestroyWindow (display->display, display->window);
   }
   if (display->context) {
     glXDestroyContext (display->display, display->context);
   }
-  if (display->visinfo) {
-    XFree (display->visinfo);
-  }
+  //if (display->visinfo) {
+  //  XFree (display->visinfo);
+  //}
   if (display->display) {
     XCloseDisplay (display->display);
   }
@@ -165,11 +167,28 @@ 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 = glXChooseVisual (display->display, scrnum, attrib);
-  if (visinfo == NULL) {
-    GST_DEBUG ("No usable visual");
-    return FALSE;
+    visinfo += i;
+  }
+#endif
+
+  if (1) {
+    visinfo = glXChooseVisual (display->display, scrnum, attrib);
+    if (visinfo == NULL) {
+      GST_DEBUG ("No usable visual");
+      return FALSE;
+    }
   }
 
   display->visinfo = visinfo;
@@ -185,6 +204,8 @@ gst_gl_display_check_features (GstGLDisplay * display)
 
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect;
 
+  GST_ERROR ("creating window with visual %ld", visinfo->visualid);
+
   window = XCreateWindow (display->display, root, 0, 0,
       100, 100, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr);
 
@@ -245,8 +266,16 @@ gst_gl_display_can_handle_type (GstGLDisplay * display, GstVideoFormat type)
 void
 gst_gl_display_lock (GstGLDisplay * display)
 {
+  gboolean ret;
+
+  g_assert (display->window != None);
+  g_assert (display->context != NULL);
+
   g_mutex_lock (display->lock);
-  glXMakeCurrent (display->display, display->window, display->context);
+  ret = glXMakeCurrent (display->display, display->window, display->context);
+  if (!ret) {
+    g_warning ("glxMakeCurrent failed");
+  }
   gst_gl_display_check_error (display, __LINE__);
 }
 
@@ -265,7 +294,10 @@ gst_gl_display_init_tmp_window (GstGLDisplay * display)
   int scrnum;
   int mask;
   Window root;
+  Window parent_window;
   Screen *screen;
+  int width;
+  int height;
 
   GST_DEBUG ("creating temp window");
 
@@ -277,20 +309,29 @@ gst_gl_display_init_tmp_window (GstGLDisplay * display)
   attr.border_pixel = 0;
   attr.colormap = XCreateColormap (display->display, root,
       display->visinfo->visual, AllocNone);
-  attr.override_redirect = False;
-#if 0
-  if (display->parent_window) {
+  if (display->parent_window != None) {
+    XWindowAttributes parent_attr;
+
     attr.override_redirect = True;
+    parent_window = display->parent_window;
+
+    XGetWindowAttributes (display->display, parent_window, &parent_attr);
+    width = parent_attr.width;
+    height = parent_attr.height;
+  } else {
+    attr.override_redirect = False;
+    parent_window = root;
+    width = 100;
+    height = 100;
   }
-#endif
 
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect;
 
   display->window = XCreateWindow (display->display,
-      root, 0, 0, 100, 100,
+      parent_window, 0, 0, width, height,
       0, display->visinfo->depth, InputOutput,
       display->visinfo->visual, mask, &attr);
-  //XMapWindow (display->display, display->window);
+  XMapWindow (display->display, display->window);
   XSync (display->display, FALSE);
 }
 
@@ -305,6 +346,7 @@ 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);
@@ -316,6 +358,18 @@ gst_gl_display_set_window (GstGLDisplay * display, Window window)
       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);
 }
@@ -327,6 +381,10 @@ gst_gl_display_update_attributes (GstGLDisplay * display)
 
   if (display->window != None) {
     XGetWindowAttributes (display->display, display->window, &attr);
+
+    GST_DEBUG ("window visual %ld display visual %ld",
+        attr.visual->visualid, display->visinfo->visual->visualid);
+
     display->win_width = attr.width;
     display->win_height = attr.height;
   } else {
@@ -670,7 +728,7 @@ gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type,
 
   gst_gl_display_update_attributes (display);
 
-  //glXSwapIntervalSGI (1);
+  glXSwapIntervalSGI (1);
   glViewport (0, 0, display->win_width, display->win_height);
 
   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
index 677c569..907f2c8 100644 (file)
@@ -46,7 +46,8 @@ struct _GstGLDisplay {
   gboolean have_color_matrix;
 
   Window window;
-  Window assigned_window;
+  //Window assigned_window;
+  Window parent_window;
 
   int win_width;
   int win_height;