sys/glsink/: Remove code that handles non-texture buffers. Add a
authorDavid Schleef <ds@schleef.org>
Thu, 27 Dec 2007 00:52:23 +0000 (00:52 +0000)
committerDavid Schleef <ds@schleef.org>
Thu, 27 Dec 2007 00:52:23 +0000 (00:52 +0000)
Original commit message from CVS:
* sys/glsink/BUGS:
* sys/glsink/Makefile.am:
* sys/glsink/gstglbuffer.c:
* sys/glsink/gstglbuffer.h:
* sys/glsink/gstglconvert.c:
* sys/glsink/gstgldisplay.c:
* sys/glsink/gstglfilter.c:
* sys/glsink/gstglfilter.h:
* sys/glsink/gstglfilterexample.c:
* sys/glsink/gstgltestsrc.c:
* sys/glsink/gstglupload.c:
* sys/glsink/gstopengl.c:
Remove code that handles non-texture buffers.  Add a
GstGLBufferFormat type that corresponds to how to use the
texture, not the original video format.  Convert gstflfilter.c
into a base class, add glfilterexample and glconvert elements.
* sys/glsink/color_matrix.c:
Minor ramblings about color conversion matrices.

14 files changed:
ChangeLog
sys/glsink/BUGS [new file with mode: 0644]
sys/glsink/Makefile.am
sys/glsink/color_matrix.c [new file with mode: 0644]
sys/glsink/gstglbuffer.c
sys/glsink/gstglbuffer.h
sys/glsink/gstglconvert.c [new file with mode: 0644]
sys/glsink/gstgldisplay.c
sys/glsink/gstglfilter.c
sys/glsink/gstglfilter.h [new file with mode: 0644]
sys/glsink/gstglfilterexample.c [new file with mode: 0644]
sys/glsink/gstgltestsrc.c
sys/glsink/gstglupload.c
sys/glsink/gstopengl.c

index d9b44041414186bf0b930be5894798b2b076a3e1..6b072881e76bb01ff80290a856eb14cf38d84e83 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2007-12-26  David Schleef  <ds@schleef.org>
+
+       * sys/glsink/BUGS:
+       * sys/glsink/Makefile.am:
+       * sys/glsink/gstglbuffer.c:
+       * sys/glsink/gstglbuffer.h:
+       * sys/glsink/gstglconvert.c:
+       * sys/glsink/gstgldisplay.c:
+       * sys/glsink/gstglfilter.c:
+       * sys/glsink/gstglfilter.h:
+       * sys/glsink/gstglfilterexample.c:
+       * sys/glsink/gstgltestsrc.c:
+       * sys/glsink/gstglupload.c:
+       * sys/glsink/gstopengl.c:
+         Remove code that handles non-texture buffers.  Add a
+         GstGLBufferFormat type that corresponds to how to use the
+         texture, not the original video format.  Convert gstflfilter.c
+         into a base class, add glfilterexample and glconvert elements.
+       * sys/glsink/color_matrix.c:
+         Minor ramblings about color conversion matrices.
+
 2007-12-24  David Schleef  <ds@schleef.org>
 
        * sys/glsink/Makefile.am:
diff --git a/sys/glsink/BUGS b/sys/glsink/BUGS
new file mode 100644 (file)
index 0000000..795d352
--- /dev/null
@@ -0,0 +1,19 @@
+
+known issues:
+
+  - negotiation is shite.  I don't want to know about any failed
+    negotiations or failed prerolls.
+
+  - teardown sometimes fails.
+
+  - sharing a GL context among a bunch of elements that stomp all
+    over it is potential fail.
+
+
+intel driver:
+
+  - rendering to texture ignores the color matrix.  This causes any
+    YUV->RGB conversion to fail.
+
+  - YUY2 and UYVY conversions in the driver use the wrong matrix.
+
index b4f72c9272142567864ed7bd1377eb40a8b15fd4..6cb9dd10b6425489257e620688441f4716dc8636 100644 (file)
@@ -1,6 +1,11 @@
 
 plugin_LTLIBRARIES = libgstglimagesink.la
 
+noinst_PROGRAMS = color_matrix
+
+AM_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)
+AM_LIBS = $(GST_BASE_LIBS)
+
 libgstglimagesink_la_SOURCES = \
        glimagesink.c \
        gstgldisplay.c \
@@ -11,7 +16,9 @@ libgstglimagesink_la_SOURCES = \
        gstgldownload.c \
        gstgltestsrc.c \
        gltestsrc.c \
-       gstglfilter.c
+       gstglfilter.c \
+       gstglfilterexample.c \
+       gstglconvert.c
 libgstglimagesink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(GST_BASE_CFLAGS) \
        $(GST_PLUGINS_BASE_CFLAGS)
 libgstglimagesink_la_LIBADD = $(X_LIBS) $(XSHM_LIBS) -lGL \
@@ -25,4 +32,5 @@ noinst_HEADERS = \
        glextensions.h \
        gstgltestsrc.h \
        gltestsrc.h \
-       gstglbuffer.h
+       gstglbuffer.h \
+       gstglfilter.h
diff --git a/sys/glsink/color_matrix.c b/sys/glsink/color_matrix.c
new file mode 100644 (file)
index 0000000..255184f
--- /dev/null
@@ -0,0 +1,243 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <string.h>
+
+typedef struct
+{
+  double comp[3];
+} Color;
+
+typedef struct
+{
+  Color pre_offset;
+  double matrix[3][3];
+  Color post_offset;
+} ColorMatrix;
+
+
+/* convert uint8 RGB values to float */
+ColorMatrix rgb255_to_rgb = {
+  {{0, 0, 0}},
+  {{(1 / 255.0), 0, 0},
+      {0, (1 / 255.0), 0},
+      {0, 0, (1 / 255.0)}},
+  {{0, 0, 0}}
+};
+ColorMatrix rgb_to_rgb255;
+
+/* convert uint8 YUV values to float as per ITU-R.601
+ * technically, Y, Cr, Cb to E_Y, E_C_B, E_C_R */
+ColorMatrix ycbcr601_to_yuv = {
+  {{-16, -128, -128}},
+  {{(1 / 219.0), 0, 0},
+      {0, (1 / 224.0), 0},
+      {0, 0, (1 / 224.0)}},
+  {{0, 0, 0}}
+};
+ColorMatrix yuv_to_ycbcr601;
+
+/* convert RGB to YUV as per ITU-R.601
+ * technically, E_R, E_G, E_B to E_Y, E_C_B, E_C_R */
+ColorMatrix rgb_to_yuv = {
+  {{0, 0, 0}},
+  {{0.299, 0.587, 0.114},
+      {0.500, -0.419, -0.081},
+      {-0.169, -0.331, 0.500}},
+  {{0, 0, 0}}
+};
+ColorMatrix yuv_to_rgb;
+
+ColorMatrix compress = {
+  {{0, 0, 0}},
+  {{0.50, 0, 0},
+      {0, 0.5, 0},
+      {0, 0, 0.500}},
+  {{0.25, 0.25, 0.25}}
+};
+
+/* red mask */
+ColorMatrix red_mask = {
+  {{0, 0, 0}},
+  {{1, 1, 1},
+      {0, 0, 0},
+      {0, 0, 0}},
+  {{0, 0, 0}}
+};
+
+double colors[][3] = {
+  {0, 0, 0},
+  {255, 0, 0},
+  {0, 255, 0},
+  {0, 0, 255}
+};
+
+
+void
+color_dump (const double *a)
+{
+  printf (" %g, %g, %g\n", a[0], a[1], a[2]);
+}
+
+void
+color_matrix_dump (ColorMatrix * m)
+{
+  printf ("pre: %g, %g, %g\n",
+      m->pre_offset.comp[0], m->pre_offset.comp[1], m->pre_offset.comp[2]);
+  printf ("  %g, %g, %g\n", m->matrix[0][0], m->matrix[0][1], m->matrix[0][2]);
+  printf ("  %g, %g, %g\n", m->matrix[1][0], m->matrix[1][1], m->matrix[1][2]);
+  printf ("  %g, %g, %g\n", m->matrix[2][0], m->matrix[2][1], m->matrix[2][2]);
+  printf ("post: %g, %g, %g\n",
+      m->post_offset.comp[0], m->post_offset.comp[1], m->post_offset.comp[2]);
+}
+
+void
+color_matrix_apply_color (Color * a, const ColorMatrix * b)
+{
+  Color d;
+  int i;
+
+  a->comp[0] += b->pre_offset.comp[0];
+  a->comp[1] += b->pre_offset.comp[1];
+  a->comp[2] += b->pre_offset.comp[2];
+
+  for (i = 0; i < 3; i++) {
+    d.comp[i] = a->comp[0] * b->matrix[i][0];
+    d.comp[i] += a->comp[1] * b->matrix[i][1];
+    d.comp[i] += a->comp[2] * b->matrix[i][2];
+  }
+
+  d.comp[0] += b->post_offset.comp[0];
+  d.comp[1] += b->post_offset.comp[1];
+  d.comp[2] += b->post_offset.comp[2];
+
+  *a = d;
+}
+
+void
+color_matrix_init (ColorMatrix * a)
+{
+  memset (a, 0, sizeof (*a));
+  a->matrix[0][0] = 1.0;
+  a->matrix[1][1] = 1.0;
+  a->matrix[2][2] = 1.0;
+}
+
+void
+color_matrix_apply (ColorMatrix * a, ColorMatrix * b)
+{
+  ColorMatrix d;
+  int i, j;
+
+  d.pre_offset = a->pre_offset;
+
+  d.post_offset = a->post_offset;
+  color_matrix_apply_color (&d.post_offset, b);
+
+  for (j = 0; j < 3; j++) {
+    for (i = 0; i < 3; i++) {
+      d.matrix[i][j] =
+          a->matrix[i][0] * b->matrix[0][j] +
+          a->matrix[i][1] * b->matrix[1][j] + a->matrix[i][2] * b->matrix[2][j];
+    }
+  }
+
+  *a = d;
+}
+
+void
+color_matrix_invert (ColorMatrix * a, ColorMatrix * b)
+{
+  int i, j;
+  double det;
+
+  a->post_offset.comp[0] = -b->pre_offset.comp[0];
+  a->post_offset.comp[1] = -b->pre_offset.comp[1];
+  a->post_offset.comp[2] = -b->pre_offset.comp[2];
+
+  for (j = 0; j < 3; j++) {
+    for (i = 0; i < 3; i++) {
+      a->matrix[j][i] =
+          b->matrix[(i + 1) % 3][(j + 1) % 3] * b->matrix[(i + 2) % 3][(j +
+              2) % 3] - b->matrix[(i + 1) % 3][(j + 2) % 3] * b->matrix[(i +
+              2) % 3][(j + 1) % 3];
+    }
+  }
+
+  det = a->matrix[0][0] * b->matrix[0][0];
+  det += a->matrix[0][1] * b->matrix[1][0];
+  det += a->matrix[0][2] * b->matrix[2][0];
+
+  for (j = 0; j < 3; j++) {
+    for (i = 0; i < 3; i++) {
+      a->matrix[j][i] /= det;
+    }
+  }
+
+  a->pre_offset.comp[0] = -b->post_offset.comp[0];
+  a->pre_offset.comp[1] = -b->post_offset.comp[1];
+  a->pre_offset.comp[2] = -b->post_offset.comp[2];
+}
+
+void
+init (void)
+{
+  color_matrix_invert (&yuv_to_rgb, &rgb_to_yuv);
+  color_matrix_invert (&yuv_to_ycbcr601, &ycbcr601_to_yuv);
+  color_matrix_invert (&rgb_to_rgb255, &rgb255_to_rgb);
+#if 0
+  color_matrix_dump (&yuv_to_rgb);
+  color_matrix_dump (&yuv_to_ycbcr601);
+  color_matrix_dump (&rgb_to_rgb255);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+  ColorMatrix want;
+  ColorMatrix actual;
+  ColorMatrix actual_inv;
+  ColorMatrix a;
+
+  init ();
+
+#if 0
+  int i;
+
+  for (i = 0; i < 4; i++) {
+    double color[3];
+
+    printf ("%d:\n", i);
+
+    color_copy (color, colors[i]);
+    color_matrix_apply_color (color, &rgb255_to_rgb);
+    color_matrix_apply_color (color, &rgb_to_yuv);
+    color_dump (color);
+  }
+#endif
+
+  color_matrix_init (&want);
+  color_matrix_apply (&want, &ycbcr601_to_yuv);
+  color_matrix_apply (&want, &yuv_to_rgb);
+  color_matrix_apply (&want, &compress);
+  color_matrix_apply (&want, &compress);
+  //color_matrix_apply (&want, &compress);
+
+  color_matrix_init (&actual);
+  color_matrix_apply (&actual, &rgb255_to_rgb);
+
+  /* calc X such that actual * X = want */
+
+  color_matrix_invert (&actual_inv, &actual);
+
+  a = actual_inv;
+  color_matrix_apply (&a, &want);
+
+  color_matrix_dump (&a);
+
+
+  return 0;
+}
index 048ad9937df5f682d12c003a6e46339e81c96b6b..e3e9df6ba331b53965b6a72a0fe9053539f2887c 100644 (file)
@@ -18,22 +18,14 @@ gst_gl_buffer_finalize (GstGLBuffer * buffer)
 {
   gst_gl_display_lock (buffer->display);
 
-  switch (buffer->type) {
-    case GST_GL_BUFFER_XIMAGE:
-      GST_DEBUG ("freeing pixmap %ld", buffer->pixmap);
-      XFreeGC (buffer->display->display, buffer->gc);
-      XFreePixmap (buffer->display->display, buffer->pixmap);
-      break;
-    case GST_GL_BUFFER_RBO:
-      glDeleteRenderbuffersEXT (1, &buffer->rbo);
-      break;
-    case GST_GL_BUFFER_TEXTURE:
-      glDeleteTextures (1, &buffer->texture);
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
+  glDeleteTextures (1, &buffer->texture);
+  if (buffer->texture_u) {
+    glDeleteTextures (1, &buffer->texture_u);
+  }
+  if (buffer->texture_v) {
+    glDeleteTextures (1, &buffer->texture_v);
   }
+
   gst_gl_display_unlock (buffer->display);
   g_object_unref (buffer->display);
 
@@ -85,215 +77,194 @@ gst_gl_buffer_get_type (void)
 
 
 GstGLBuffer *
-gst_gl_buffer_new (GstGLDisplay * display, GstVideoFormat format,
+gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
     int width, int height)
 {
   GstGLBuffer *buffer;
-  XGCValues values = { 0 };
 
-  g_return_val_if_fail (format == GST_VIDEO_FORMAT_RGBx, NULL);
   g_return_val_if_fail (width > 0, NULL);
   g_return_val_if_fail (height > 0, NULL);
 
   buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
 
   buffer->display = g_object_ref (display);
-  buffer->type = GST_GL_BUFFER_TEXTURE;
-
   buffer->width = width;
   buffer->height = height;
 
-  switch (buffer->type) {
-    case GST_GL_BUFFER_XIMAGE:
-    {
-      buffer->pixmap = XCreatePixmap (display->display,
-          DefaultRootWindow (display->display), width, height, 32);
-      XSync (display->display, False);
-
-      buffer->gc = XCreateGC (display->display, buffer->pixmap, 0, &values);
-
-      GST_DEBUG ("new pixmap %dx%d xid %ld", width, height, buffer->pixmap);
-      break;
-    }
-    case GST_GL_BUFFER_RBO:
-    {
-      GLuint fbo;
-
-      gst_gl_display_lock (buffer->display);
-
-      glGenFramebuffersEXT (1, &fbo);
-      glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
-
-      glGenRenderbuffersEXT (1, &buffer->rbo);
-      glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, buffer->rbo);
-
-      glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT,
-          GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, buffer->rbo);
-      glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_RGB,
-          buffer->width, buffer->height);
-
-      glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
-      glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
-      g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
-          GL_FRAMEBUFFER_COMPLETE_EXT);
-
-      glDeleteFramebuffersEXT (1, &fbo);
-
-      gst_gl_display_unlock (buffer->display);
+  gst_gl_display_lock (buffer->display);
+  glGenTextures (1, &buffer->texture);
+  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
+  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);
       break;
-    }
-    case GST_GL_BUFFER_TEXTURE:
+    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);
       break;
     default:
-      g_assert_not_reached ();
+      g_warning ("GL buffer format not handled");
   }
 
+  gst_gl_display_unlock (buffer->display);
+
   return buffer;
 }
 
-void
-gst_gl_buffer_upload (GstGLBuffer * buffer, void *data)
+GstGLBuffer *
+gst_gl_buffer_new_from_data (GstGLDisplay * display, GstVideoFormat format,
+    int width, int height, void *data)
 {
-  Display *display = buffer->display->display;
-
-  GST_DEBUG ("uploading %p %dx%d", data, buffer->width, buffer->height);
-
-  gst_gl_display_lock (buffer->display);
-
-  switch (buffer->type) {
-    case GST_GL_BUFFER_XIMAGE:
-    {
-      XImage *image;
-      Visual *visual;
-      int depth;
-      int bpp;
+  GstGLBuffer *buffer;
+  int comp;
 
-      visual = DefaultVisual (display, 0);
-      depth = 32;
-      bpp = 32;
+  g_return_val_if_fail (width > 0, NULL);
+  g_return_val_if_fail (height > 0, NULL);
+  g_return_val_if_fail (data != NULL, NULL);
 
-      image = XCreateImage (display, visual, depth, ZPixmap, 0, NULL,
-          buffer->width, buffer->height, bpp, 0);
-      GST_DEBUG ("image %p", image);
-      image->data = data;
+  GST_DEBUG ("uploading %p %dx%d", data, width, height);
 
-      XPutImage (display, buffer->pixmap, buffer->gc,
-          image, 0, 0, 0, 0, buffer->width, buffer->height);
+  buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
+  buffer->display = g_object_ref (display);
+  buffer->width = width;
+  buffer->height = height;
 
-      XDestroyImage (image);
+  gst_gl_display_lock (buffer->display);
+  glGenTextures (1, &buffer->texture);
+  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
+
+  switch (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_GL_BUFFER_RBO:
-    {
-      unsigned int fbo;
-
-      g_assert (glIsRenderbufferEXT (buffer->rbo));
-
-      glGenFramebuffersEXT (1, &fbo);
-      glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
-
-      glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT,
-          GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, buffer->rbo);
-
-      glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
-      glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
-
-      g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
-          GL_FRAMEBUFFER_COMPLETE_EXT);
-
-      gst_gl_display_check_error (buffer->display, __LINE__);
-      glWindowPos2iARB (0, 0);
-      glDrawPixels (buffer->width, buffer->height, GL_RGB,
-          GL_UNSIGNED_BYTE, data);
-
-      glDeleteFramebuffersEXT (1, &fbo);
-
-      g_assert (glIsRenderbufferEXT (buffer->rbo));
-
+    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_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_GL_BUFFER_TEXTURE:
-      buffer->texture =
-          gst_gl_display_upload_texture_rectangle (buffer->display,
-          GST_VIDEO_FORMAT_RGBx, data, buffer->width, buffer->height);
+    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));
+
+      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));
       break;
     default:
       g_assert_not_reached ();
   }
 
   gst_gl_display_unlock (buffer->display);
+
+  return buffer;
 }
 
 
 void
 gst_gl_buffer_download (GstGLBuffer * buffer, void *data)
 {
-  gst_gl_display_lock (buffer->display);
+  GLuint fbo;
 
   GST_DEBUG ("downloading");
 
-  switch (buffer->type) {
-    case GST_GL_BUFFER_XIMAGE:
-    {
-      XImage *image;
-
-      image = XGetImage (buffer->display->display, buffer->pixmap,
-          0, 0, buffer->width, buffer->height, 0xffffffff, ZPixmap);
-
-      memcpy (data, image->data, buffer->width * buffer->height * 4);
-
-      XDestroyImage (image);
-      break;
-    }
-    case GST_GL_BUFFER_RBO:
-    {
-      unsigned int fbo;
-
-      glGenFramebuffersEXT (1, &fbo);
-      glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
-
-      glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT,
-          GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, buffer->rbo);
-
-      glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
-      glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
-
-      g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
-          GL_FRAMEBUFFER_COMPLETE_EXT);
-
-      glReadPixels (0, 0, buffer->width, buffer->height / 2, GL_RGBA,
-          GL_UNSIGNED_BYTE, data);
-
-      glDeleteFramebuffersEXT (1, &fbo);
+  gst_gl_display_lock (buffer->display);
 
-      break;
-    }
-    case GST_GL_BUFFER_TEXTURE:
-    {
-      unsigned int fbo;
+  glGenFramebuffersEXT (1, &fbo);
+  glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
 
-      glGenFramebuffersEXT (1, &fbo);
-      glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
+  glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
+      GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, buffer->texture, 0);
 
-      glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
-          GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB,
-          buffer->texture, 0);
+  glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
+  glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
 
-      glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
-      glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
+  g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
+      GL_FRAMEBUFFER_COMPLETE_EXT);
 
-      g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
-          GL_FRAMEBUFFER_COMPLETE_EXT);
+  /* needs 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);
 
-      glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
-          GL_UNSIGNED_BYTE, data);
+  glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
+      GL_UNSIGNED_BYTE, data);
 
-      glDeleteFramebuffersEXT (1, &fbo);
-    }
-      break;
-    default:
-      g_assert_not_reached ();
-  }
+  glDeleteFramebuffersEXT (1, &fbo);
 
   gst_gl_display_unlock (buffer->display);
 }
index e24b70f0721d021a111d07c267784107f6c6f47a..1d29aebf3624882aad47d0ac5e09b3170f045b82 100644 (file)
@@ -14,24 +14,25 @@ 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_UNKNOWN,
-  GST_GL_BUFFER_XIMAGE,
-  GST_GL_BUFFER_RBO,
-  GST_GL_BUFFER_TEXTURE
-} GstGLBufferType;
+  GST_GL_BUFFER_FORMAT_RGBA,
+  GST_GL_BUFFER_FORMAT_RGB,
+  GST_GL_BUFFER_FORMAT_YUYV,
+  GST_GL_BUFFER_FORMAT_PLANAR444,
+  GST_GL_BUFFER_FORMAT_PLANAR422,
+  GST_GL_BUFFER_FORMAT_PLANAR420
+} GstGLBufferFormat;
 
 struct _GstGLBuffer {
   GstBuffer buffer;
 
   GstGLDisplay *display;
 
-  GstGLBufferType type;
+  GstGLBufferFormat format;
+  gboolean is_yuv;
 
-  XID pixmap;
-  GC gc;
-
-  GLuint rbo;
   GLuint texture;
+  GLuint texture_u;
+  GLuint texture_v;
 
   int width;
   int height;
@@ -39,9 +40,10 @@ struct _GstGLBuffer {
 
 GType gst_gl_buffer_get_type (void);
 
-GstGLBuffer * gst_gl_buffer_new (GstGLDisplay *display, GstVideoFormat format,
-    int width, int height);
-void gst_gl_buffer_upload (GstGLBuffer *buffer, void *data);
+GstGLBuffer * gst_gl_buffer_new (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);
 void gst_gl_buffer_download (GstGLBuffer *buffer, void *data);
 
 #endif
diff --git a/sys/glsink/gstglconvert.c b/sys/glsink/gstglconvert.c
new file mode 100644 (file)
index 0000000..57daec5
--- /dev/null
@@ -0,0 +1,253 @@
+/* 
+ * GStreamer
+ * Copyright (C) 2007 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gstglbuffer.h>
+#include <gstglfilter.h>
+#include "glextensions.h"
+
+#define GST_CAT_DEFAULT gst_gl_convert_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define GST_TYPE_GL_CONVERT            (gst_gl_convert_get_type())
+#define GST_GL_CONVERT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_CONVERT,GstGLConvert))
+#define GST_IS_GL_CONVERT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_CONVERT))
+#define GST_GL_CONVERT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_CONVERT,GstGLConvertClass))
+#define GST_IS_GL_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_CONVERT))
+#define GST_GL_CONVERT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_CONVERT,GstGLConvertClass))
+typedef struct _GstGLConvert GstGLConvert;
+typedef struct _GstGLConvertClass GstGLConvertClass;
+
+struct _GstGLConvert
+{
+  GstGLFilter filter;
+
+  /* < private > */
+
+};
+
+struct _GstGLConvertClass
+{
+  GstGLFilterClass filter_class;
+};
+
+static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
+    "Filter/Effect",
+    "FIXME GL conversion filter",
+    "FIXME <fixme@fixme.com>");
+
+#if 0
+#define GST_GL_VIDEO_CAPS "video/x-raw-gl"
+
+static GstStaticPadTemplate gst_gl_convert_src_pad_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
+    );
+
+static GstStaticPadTemplate gst_gl_convert_sink_pad_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
+    );
+#endif
+
+enum
+{
+  PROP_0
+};
+
+#define DEBUG_INIT(bla) \
+  GST_DEBUG_CATEGORY_INIT (gst_gl_convert_debug, "glconvert", 0, "glconvert element");
+
+GST_BOILERPLATE_FULL (GstGLConvert, gst_gl_convert, GstGLFilter,
+    GST_TYPE_GL_FILTER, DEBUG_INIT);
+
+static void gst_gl_convert_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_gl_convert_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static void gst_gl_convert_reset (GstGLConvert * filter);
+static gboolean gst_gl_convert_transform (GstGLFilter * filter,
+    GstGLBuffer * outbuf, GstGLBuffer * inbuf);
+static gboolean gst_gl_convert_start (GstGLFilter * _filter);
+static gboolean gst_gl_convert_stop (GstGLFilter * _filter);
+
+
+static void
+gst_gl_convert_base_init (gpointer klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_set_details (element_class, &element_details);
+
+#if 0
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_gl_convert_src_pad_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_gl_convert_sink_pad_template));
+#endif
+}
+
+static void
+gst_gl_convert_class_init (GstGLConvertClass * klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gobject_class->set_property = gst_gl_convert_set_property;
+  gobject_class->get_property = gst_gl_convert_get_property;
+
+  GST_GL_FILTER_CLASS (klass)->transform = gst_gl_convert_transform;
+  GST_GL_FILTER_CLASS (klass)->start = gst_gl_convert_start;
+  GST_GL_FILTER_CLASS (klass)->stop = gst_gl_convert_stop;
+}
+
+static void
+gst_gl_convert_init (GstGLConvert * filter, GstGLConvertClass * klass)
+{
+  gst_gl_convert_reset (filter);
+}
+
+static void
+gst_gl_convert_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  //GstGLConvert *filter = GST_GL_CONVERT (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_gl_convert_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  //GstGLConvert *filter = GST_GL_CONVERT (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_gl_convert_reset (GstGLConvert * filter)
+{
+
+}
+
+static gboolean
+gst_gl_convert_start (GstGLFilter * _filter)
+{
+  //GstGLConvert *convert = GST_GL_CONVERT(_filter);
+
+  return TRUE;
+}
+
+static gboolean
+gst_gl_convert_stop (GstGLFilter * _filter)
+{
+  GstGLConvert *convert = GST_GL_CONVERT (_filter);
+
+  gst_gl_convert_reset (convert);
+
+  return TRUE;
+}
+
+static gboolean
+gst_gl_convert_transform (GstGLFilter * filter, GstGLBuffer * outbuf,
+    GstGLBuffer * inbuf)
+{
+  //GstGLConvert *convert = GST_GL_CONVERT(filter);
+
+  glDisable (GL_CULL_FACE);
+  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+  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 (inbuf->is_yuv) {
+#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
+    const double matrix[16] = {
+      1.16438, 1.6321, -0.00107909, 0,
+      1.13839, -0.813005, -0.39126, 0,
+      1.13839, 0.00112726, 2.01741, 0,
+      0, 0, 0, 1
+    };
+
+    GST_DEBUG ("applying YUV->RGB conversion");
+
+    glMatrixMode (GL_COLOR);
+    glLoadMatrixd (matrix);
+
+    /* same */
+    glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -0.873494);
+    glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0.531435);
+    glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.08629);
+#else
+    g_assert_not_reached ();
+#endif
+  }
+
+  glColor4f (1, 0, 1, 1);
+
+  glBegin (GL_QUADS);
+  glNormal3f (0, 0, -1);
+  glTexCoord2f (inbuf->width, 0);
+  glVertex3f (1.0, -1.0, 0);
+  glTexCoord2f (0, 0);
+  glVertex3f (-1.0, -1.0, 0);
+  glTexCoord2f (0, inbuf->height);
+  glVertex3f (-1.0, 1.0, 0);
+  glTexCoord2f (inbuf->width, inbuf->height);
+  glVertex3f (1.0, 1.0, 0);
+  glEnd ();
+
+  if (inbuf->is_yuv) {
+#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
+    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);
+#else
+    g_assert_not_reached ();
+#endif
+  }
+
+  return TRUE;
+}
index 4378c04dea81ae3bfe2a379f0c54d2c65a77bef5..6d93c8896e4b015c989281fe626bdd2111efc51a 100644 (file)
@@ -430,8 +430,6 @@ draw_rect_texture (GstGLDisplay * display, GstVideoFormat type,
 
 #ifdef GL_TEXTURE_RECTANGLE_ARB
   glEnable (GL_TEXTURE_RECTANGLE_ARB);
-  //glGenTextures (1, &texture);
-  //glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
 
   texture = gst_gl_display_upload_texture_rectangle (display, type,
       data, width, height);
index d5c3f60e5bed5bd04da5b738ffd94e478a410728..3efa396b7fc0c099f1b201668a45bb050e56044e 100644 (file)
 #include <gst/gst.h>
 #include <gst/video/video.h>
 #include <gstglbuffer.h>
+#include <gstglfilter.h>
 #include "glextensions.h"
 
 #define GST_CAT_DEFAULT gst_gl_filter_debug
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
 
-#define GST_TYPE_GL_FILTER            (gst_gl_filter_get_type())
-#define GST_GL_FILTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER,GstGLFilter))
-#define GST_IS_GL_FILTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER))
-#define GST_GL_FILTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
-#define GST_IS_GL_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER))
-#define GST_GL_FILTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
-typedef struct _GstGLFilter GstGLFilter;
-typedef struct _GstGLFilterClass GstGLFilterClass;
-
-typedef void (*GstGLFilterProcessFunc) (GstGLFilter *, guint8 *, guint);
-
-struct _GstGLFilter
-{
-  GstElement element;
-
-  GstPad *srcpad;
-  GstPad *sinkpad;
-
-  /* < private > */
-
-  GstGLDisplay *display;
-  GstVideoFormat format;
-  int width;
-  int height;
-};
-
-struct _GstGLFilterClass
-{
-  GstElementClass element_class;
-};
-
-static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
-    "Filter/Effect",
-    "FIXME example filter",
-    "FIXME <fixme@fixme.com>");
 
 #define GST_GL_VIDEO_CAPS "video/x-raw-gl"
 
@@ -82,11 +48,6 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
     );
 
-enum
-{
-  PROP_0
-};
-
 #define DEBUG_INIT(bla) \
   GST_DEBUG_CATEGORY_INIT (gst_gl_filter_debug, "glfilter", 0, "glfilter element");
 
@@ -103,8 +64,8 @@ static void gst_gl_filter_reset (GstGLFilter * filter);
 static GstStateChangeReturn
 gst_gl_filter_change_state (GstElement * element, GstStateChange transition);
 static gboolean gst_gl_filter_sink_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_gl_filter_transform (GstGLBuffer * outbuf,
-    GstGLBuffer * inbuf);
+static gboolean gst_gl_filter_do_transform (GstGLFilter * filter,
+    GstGLBuffer * outbuf, GstGLBuffer * inbuf);
 
 
 static void
@@ -112,8 +73,6 @@ gst_gl_filter_base_init (gpointer klass)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_set_details (element_class, &element_details);
-
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_gl_filter_src_pad_template));
   gst_element_class_add_pad_template (element_class,
@@ -179,17 +138,26 @@ gst_gl_filter_reset (GstGLFilter * filter)
     g_object_unref (filter->display);
     filter->display = NULL;
   }
-  filter->format = GST_VIDEO_FORMAT_RGBx;
+  filter->format = GST_GL_BUFFER_FORMAT_RGB;
 }
 
 static gboolean
 gst_gl_filter_start (GstGLFilter * filter)
 {
+  GstGLFilterClass *filter_class;
   gboolean ret;
 
-  filter->format = GST_VIDEO_FORMAT_RGBx;
+  filter_class = GST_GL_FILTER_GET_CLASS (filter);
+
+  filter->format = GST_GL_BUFFER_FORMAT_RGB;
   filter->display = gst_gl_display_new ();
   ret = gst_gl_display_connect (filter->display, NULL);
+  if (!ret)
+    return FALSE;
+
+  if (filter_class->start) {
+    ret = filter_class->start (filter);
+  }
 
   return ret;
 }
@@ -197,8 +165,20 @@ gst_gl_filter_start (GstGLFilter * filter)
 static gboolean
 gst_gl_filter_stop (GstGLFilter * filter)
 {
+  GstGLFilterClass *filter_class;
+  gboolean ret;
+
+  filter_class = GST_GL_FILTER_GET_CLASS (filter);
+
   gst_gl_filter_reset (filter);
 
+  if (filter_class->stop) {
+    ret = filter_class->stop (filter);
+  }
+
+  g_object_unref (filter->display);
+  filter->display = NULL;
+
   return TRUE;
 }
 
@@ -218,7 +198,7 @@ gst_gl_filter_sink_setcaps (GstPad * pad, GstCaps * caps)
   if (!ret)
     return FALSE;
 
-  GST_ERROR ("setcaps %d %d", filter->width, filter->height);
+  GST_DEBUG ("setcaps %d %d", filter->width, filter->height);
 
   ret = gst_pad_set_caps (filter->srcpad, caps);
 
@@ -242,7 +222,7 @@ gst_gl_filter_chain (GstPad * pad, GstBuffer * buf)
       GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
   gst_buffer_set_caps (GST_BUFFER (outbuf), GST_PAD_CAPS (filter->srcpad));
 
-  gst_gl_filter_transform (outbuf, inbuf);
+  gst_gl_filter_do_transform (filter, outbuf, inbuf);
 
   gst_pad_push (filter->srcpad, GST_BUFFER (outbuf));
 
@@ -292,65 +272,21 @@ gst_gl_filter_change_state (GstElement * element, GstStateChange transition)
   return ret;
 }
 
-void
-dump_fbconfigs (Display * display)
-{
-  GLXFBConfig *fbconfigs;
-  int n;
-  int i;
-  int j;
-  int ret;
-  int value;
-  struct
-  {
-    int attr;
-    char *name;
-  } list[] = {
-    {
-    GLX_DRAWABLE_TYPE, "drawable type"}, {
-    GLX_BIND_TO_TEXTURE_TARGETS_EXT, "bind to texture targets"}, {
-    GLX_BIND_TO_TEXTURE_RGBA_EXT, "bind to texture rgba"}, {
-    GLX_MAX_PBUFFER_WIDTH, "max pbuffer width"}, {
-    GLX_MAX_PBUFFER_HEIGHT, "max pbuffer height"}, {
-    GLX_MAX_PBUFFER_PIXELS, "max pbuffer pixels"}, {
-    GLX_RENDER_TYPE, "render type"}, {
-    0, 0}
-  };
-
-  g_print ("screen count: %d\n", ScreenCount (display));
-
-  fbconfigs = glXGetFBConfigs (display, 0, &n);
-  for (i = 0; i < n; i++) {
-    g_print ("%d:\n", i);
-    for (j = 0; list[j].attr; j++) {
-      ret = glXGetFBConfigAttrib (display, fbconfigs[i], list[j].attr, &value);
-      if (ret != Success) {
-        g_print ("%s: failed\n", list[j].name);
-      } else {
-        g_print ("%s: %d\n", list[j].name, value);
-      }
-    }
-  }
-
-}
-
 static gboolean
-gst_gl_filter_transform (GstGLBuffer * outbuf, GstGLBuffer * inbuf)
+gst_gl_filter_do_transform (GstGLFilter * filter,
+    GstGLBuffer * outbuf, GstGLBuffer * inbuf)
 {
   GstGLDisplay *display = inbuf->display;
+  GstGLFilterClass *filter_class;
   unsigned int fbo;
 
+  filter_class = GST_GL_FILTER_GET_CLASS (filter);
+
   gst_gl_display_lock (display);
 
   glGenFramebuffersEXT (1, &fbo);
   glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
 
-  /* FIXME: This should be part of buffer creation */
-  glGenTextures (1, &outbuf->texture);
-  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, outbuf->texture);
-  glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-      outbuf->width, outbuf->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
   glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
       GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, outbuf->texture, 0);
 
@@ -379,6 +315,9 @@ gst_gl_filter_transform (GstGLBuffer * outbuf, GstGLBuffer * inbuf)
   glEnable (GL_TEXTURE_RECTANGLE_ARB);
   glBindTexture (GL_TEXTURE_RECTANGLE_ARB, inbuf->texture);
 
+  filter_class->transform (filter, outbuf, inbuf);
+
+#if 0
   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);
@@ -399,6 +338,7 @@ gst_gl_filter_transform (GstGLBuffer * outbuf, GstGLBuffer * inbuf)
   glTexCoord2f (inbuf->width, inbuf->height);
   glVertex3f (1.0, 1.0, 0);
   glEnd ();
+#endif
 
   glFlush ();
 
diff --git a/sys/glsink/gstglfilter.h b/sys/glsink/gstglfilter.h
new file mode 100644 (file)
index 0000000..01b915f
--- /dev/null
@@ -0,0 +1,68 @@
+/* 
+ * GStreamer
+ * Copyright (C) 2007 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_GL_FILTER_H_
+#define _GST_GL_FILTER_H_
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gstglbuffer.h>
+
+#define GST_TYPE_GL_FILTER            (gst_gl_filter_get_type())
+#define GST_GL_FILTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER,GstGLFilter))
+#define GST_IS_GL_FILTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER))
+#define GST_GL_FILTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
+#define GST_IS_GL_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER))
+#define GST_GL_FILTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
+typedef struct _GstGLFilter GstGLFilter;
+typedef struct _GstGLFilterClass GstGLFilterClass;
+
+typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter,
+    GstGLBuffer *outbuf, GstGLBuffer *inbuf);
+typedef gboolean (*GstGLFilterStartFunc) (GstGLFilter *filter);
+typedef gboolean (*GstGLFilterStopFunc) (GstGLFilter *filter);
+
+struct _GstGLFilter
+{
+  GstElement element;
+
+  GstPad *srcpad;
+  GstPad *sinkpad;
+
+  /* < private > */
+
+  GstGLDisplay *display;
+  GstGLBufferFormat format;
+  int width;
+  int height;
+};
+
+struct _GstGLFilterClass
+{
+  GstElementClass element_class;
+  GstGLFilterProcessFunc transform;
+  GstGLFilterStartFunc start;
+  GstGLFilterStopFunc stop;
+};
+
+GType gst_gl_filter_get_type(void);
+
+#endif
+
diff --git a/sys/glsink/gstglfilterexample.c b/sys/glsink/gstglfilterexample.c
new file mode 100644 (file)
index 0000000..6a513b3
--- /dev/null
@@ -0,0 +1,243 @@
+/* 
+ * GStreamer
+ * Copyright (C) 2007 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gstglbuffer.h>
+#include <gstglfilter.h>
+#include "glextensions.h"
+#include <string.h>
+
+#define GST_CAT_DEFAULT gst_gl_filter_example_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define GST_TYPE_GL_FILTER_EXAMPLE            (gst_gl_filter_example_get_type())
+#define GST_GL_FILTER_EXAMPLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExample))
+#define GST_IS_GL_FILTER_EXAMPLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER_EXAMPLE))
+#define GST_GL_FILTER_EXAMPLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExampleClass))
+#define GST_IS_GL_FILTER_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER_EXAMPLE))
+#define GST_GL_FILTER_EXAMPLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExampleClass))
+typedef struct _GstGLFilterExample GstGLFilterExample;
+typedef struct _GstGLFilterExampleClass GstGLFilterExampleClass;
+
+struct _GstGLFilterExample
+{
+  GstGLFilter filter;
+
+  /* < private > */
+
+};
+
+struct _GstGLFilterExampleClass
+{
+  GstGLFilterClass filter_class;
+};
+
+static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
+    "Filter/Effect",
+    "FIXME example filter",
+    "FIXME <fixme@fixme.com>");
+
+#if 0
+#define GST_GL_VIDEO_CAPS "video/x-raw-gl"
+
+static GstStaticPadTemplate gst_gl_filter_example_src_pad_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
+    );
+
+static GstStaticPadTemplate gst_gl_filter_example_sink_pad_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
+    );
+#endif
+
+enum
+{
+  PROP_0
+};
+
+#define DEBUG_INIT(bla) \
+  GST_DEBUG_CATEGORY_INIT (gst_gl_filter_example_debug, "glfilterexample", 0, "glfilterexample element");
+
+GST_BOILERPLATE_FULL (GstGLFilterExample, gst_gl_filter_example, GstGLFilter,
+    GST_TYPE_GL_FILTER, DEBUG_INIT);
+
+static void gst_gl_filter_example_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_gl_filter_example_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static void gst_gl_filter_example_reset (GstGLFilterExample * filter);
+static gboolean gst_gl_filter_example_transform (GstGLFilter * filter,
+    GstGLBuffer * outbuf, GstGLBuffer * inbuf);
+static gboolean gst_gl_filter_example_start (GstGLFilter * filter);
+static gboolean gst_gl_filter_example_stop (GstGLFilter * filter);
+
+
+static void
+gst_gl_filter_example_base_init (gpointer klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_set_details (element_class, &element_details);
+
+#if 0
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_gl_filter_example_src_pad_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_gl_filter_example_sink_pad_template));
+#endif
+}
+
+static void
+gst_gl_filter_example_class_init (GstGLFilterExampleClass * klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gobject_class->set_property = gst_gl_filter_example_set_property;
+  gobject_class->get_property = gst_gl_filter_example_get_property;
+
+  GST_GL_FILTER_CLASS (klass)->transform = gst_gl_filter_example_transform;
+  GST_GL_FILTER_CLASS (klass)->start = gst_gl_filter_example_start;
+  GST_GL_FILTER_CLASS (klass)->stop = gst_gl_filter_example_stop;
+}
+
+static void
+gst_gl_filter_example_init (GstGLFilterExample * filter,
+    GstGLFilterExampleClass * klass)
+{
+  gst_gl_filter_example_reset (filter);
+}
+
+static void
+gst_gl_filter_example_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  //GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_gl_filter_example_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  //GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_gl_filter_example_reset (GstGLFilterExample * filter)
+{
+
+}
+
+static gboolean
+gst_gl_filter_example_start (GstGLFilter * _filter)
+{
+  //GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE(_filter);
+
+  return TRUE;
+}
+
+static gboolean
+gst_gl_filter_example_stop (GstGLFilter * _filter)
+{
+  GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE (_filter);
+
+  gst_gl_filter_example_reset (filter);
+  return TRUE;
+}
+
+static gboolean
+gst_gl_filter_example_transform (GstGLFilter * filter, GstGLBuffer * outbuf,
+    GstGLBuffer * inbuf)
+{
+  //GstGLFilterExample *example = GST_GL_FILTER_EXAMPLE(filter);
+
+  glDisable (GL_CULL_FACE);
+  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+  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);
+
+#define GAIN 0.5
+  {
+    const double matrix[16] = {
+      0, 0, 1.0, 0,
+      0, 1.0, 0, 0,
+      1.0, 0, 0, 0,
+      0, 0, 0, 1
+    };
+
+    glMatrixMode (GL_COLOR);
+    glLoadMatrixd (matrix);
+    glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, (1 - GAIN) / 2);
+    glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (1 - GAIN) / 2);
+    glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, (1 - GAIN) / 2);
+  }
+
+  glBegin (GL_QUADS);
+  glNormal3f (0, 0, -1);
+  glTexCoord2f (inbuf->width, 0);
+  glVertex3f (0.9, -0.9, 0);
+  glTexCoord2f (0, 0);
+  glVertex3f (-1.0, -1.0, 0);
+  glTexCoord2f (0, inbuf->height);
+  glVertex3f (-1.0, 1.0, 0);
+  glTexCoord2f (inbuf->width, inbuf->height);
+  glVertex3f (1.0, 1.0, 0);
+  glEnd ();
+
+  glFlush ();
+
+  glMatrixMode (GL_COLOR);
+  glLoadIdentity ();
+  glPixelTransferf (GL_POST_COLOR_MATRIX_RED_SCALE, 1.0);
+  glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
+  glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
+  glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
+
+  return TRUE;
+}
index 66d32f6081c323bb186ae3ada8e65d22a02327a7..a5e544a6c66ddba0d15f0bd12ddf4c26a60b0c8d 100644 (file)
@@ -522,19 +522,13 @@ gst_gl_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
   GST_LOG_OBJECT (src, "creating buffer %dx%d image for frame %d",
       src->width, src->height, (gint) src->n_frames);
 
-  outbuf = gst_gl_buffer_new (src->display, GST_VIDEO_FORMAT_RGBx,
+  outbuf = gst_gl_buffer_new (src->display, GST_GL_BUFFER_FORMAT_RGB,
       src->width, src->height);
   gst_buffer_set_caps (GST_BUFFER (outbuf),
       GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
 
   gst_gl_display_lock (outbuf->display);
 
-  /* FIXME: This should be part of buffer creation */
-  glGenTextures (1, &outbuf->texture);
-  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, outbuf->texture);
-  glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
-      outbuf->width, outbuf->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
   glGenFramebuffersEXT (1, &fbo);
   glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
 
index 90f7dc2e98ffa36b8abe17f64c67dd3eb8ee48ec..3b5cbc5fa5224160a8cf105e913b5ebf0284cdcb 100644 (file)
@@ -50,7 +50,8 @@ struct _GstGLUpload
   /* < private > */
 
   GstGLDisplay *display;
-  GstVideoFormat format;
+  GstVideoFormat video_format;
+  GstGLBufferFormat format;
   int width;
   int height;
 
@@ -77,10 +78,14 @@ GST_STATIC_PAD_TEMPLATE ("src",
     );
 
 static GstStaticPadTemplate gst_gl_upload_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx)
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";"
+        GST_VIDEO_CAPS_BGRx ";"
+        GST_VIDEO_CAPS_xRGB ";"
+        GST_VIDEO_CAPS_xBGR ";"
+        GST_VIDEO_CAPS_YUV ("{ YUY2, UYVY, AYUV, YV12, I420 }"))
     );
 
 enum
@@ -178,7 +183,7 @@ gst_gl_upload_reset (GstGLUpload * upload)
     g_object_unref (upload->display);
     upload->display = NULL;
   }
-  upload->format = GST_VIDEO_FORMAT_RGBx;
+  upload->format = GST_GL_BUFFER_FORMAT_RGB;
   upload->peek = FALSE;
 }
 
@@ -187,7 +192,7 @@ gst_gl_upload_start (GstGLUpload * upload)
 {
   gboolean ret;
 
-  upload->format = GST_VIDEO_FORMAT_RGBx;
+  upload->format = GST_GL_BUFFER_FORMAT_RGB;
   upload->display = gst_gl_display_new ();
   ret = gst_gl_display_connect (upload->display, NULL);
 
@@ -206,7 +211,7 @@ static gboolean
 gst_gl_upload_sink_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstGLUpload *upload;
-  GstVideoFormat format;
+  GstVideoFormat video_format;
   int height;
   int width;
   gboolean ret;
@@ -214,15 +219,15 @@ gst_gl_upload_sink_setcaps (GstPad * pad, GstCaps * caps)
 
   upload = GST_GL_UPLOAD (gst_pad_get_parent (pad));
 
-  ret = gst_video_format_parse_caps (caps, &format, &width, &height);
+  ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
   if (!ret)
     return FALSE;
 
-  upload->format = format;
+  upload->video_format = video_format;
   upload->width = width;
   upload->height = height;
 
-  GST_ERROR ("setcaps %d %d %d", format, width, height);
+  GST_DEBUG ("setcaps %d %d %d", video_format, width, height);
 
   srccaps = gst_caps_new_simple ("video/x-raw-gl",
       "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
@@ -240,8 +245,9 @@ gst_gl_upload_chain (GstPad * pad, GstBuffer * buf)
 
   upload = GST_GL_UPLOAD (gst_pad_get_parent (pad));
 
-  outbuf = gst_gl_buffer_new (upload->display, upload->format,
-      upload->width, upload->height);
+  outbuf = gst_gl_buffer_new_from_data (upload->display,
+      upload->video_format, upload->width, upload->height,
+      GST_BUFFER_DATA (buf));
 
   gst_buffer_copy_metadata (GST_BUFFER (outbuf), buf,
       GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
@@ -249,7 +255,6 @@ gst_gl_upload_chain (GstPad * pad, GstBuffer * buf)
 
   GST_DEBUG ("uploading %p size %d", GST_BUFFER_DATA (buf),
       GST_BUFFER_SIZE (buf));
-  gst_gl_buffer_upload (outbuf, GST_BUFFER_DATA (buf));
   gst_buffer_unref (buf);
 
   if (upload->peek) {
index d44ed9f20bf24fbde819e8810f67b78ec3bb5f40..7acbe1fdc75f9a4ac28408687b7ec740ac586cae 100644 (file)
@@ -34,7 +34,8 @@
 
 GType gst_gl_upload_get_type (void);
 GType gst_gl_download_get_type (void);
-GType gst_gl_filter_get_type (void);
+GType gst_gl_filter_example_get_type (void);
+GType gst_gl_convert_get_type (void);
 GType gst_gl_test_src_get_type (void);
 
 
@@ -56,8 +57,12 @@ plugin_init (GstPlugin * plugin)
           GST_RANK_NONE, gst_gl_download_get_type ())) {
     return FALSE;
   }
-  if (!gst_element_register (plugin, "glfilter",
-          GST_RANK_NONE, gst_gl_filter_get_type ())) {
+  if (!gst_element_register (plugin, "glfilterexample",
+          GST_RANK_NONE, gst_gl_filter_example_get_type ())) {
+    return FALSE;
+  }
+  if (!gst_element_register (plugin, "glconvert",
+          GST_RANK_NONE, gst_gl_convert_get_type ())) {
     return FALSE;
   }
   if (!gst_element_register (plugin, "gltestsrc",