From ff954bcaffe397534988c0a8eda7b5c66f42dd7c Mon Sep 17 00:00:00 2001 From: David Schleef Date: Mon, 24 Dec 2007 20:53:55 +0000 Subject: [PATCH] [042/906] * sys/glsink/glimagesink.c: * sys/glsink/glimagesink.h: * sys/glsink/glvideo.c: * sys/glsink/glvideo.h: * sys/glsink/gstglbuffer.c: * sys/glsink/gstglbuffer.h: * sys/glsink/gstgldownload.c: * sys/glsink/gstglfilter.c: * sys/glsink/gstglupload.c: Rewrite a bunch of code to use textures as the intermediate instead of renderbuffers. upload, download, filtering all work. --- gst-libs/gst/gl/gstglbuffer.c | 37 ++++++++- gst-libs/gst/gl/gstglbuffer.h | 4 +- gst/gl/glimagesink.c | 26 +----- gst/gl/glimagesink.h | 2 +- gst/gl/glvideo.c | 184 +++++++++++++++++++++++++++++++++++------- gst/gl/glvideo.h | 19 ++--- gst/gl/gstgldownload.c | 6 +- gst/gl/gstglfilter.c | 113 ++++++++++++-------------- gst/gl/gstglupload.c | 8 +- 9 files changed, 262 insertions(+), 137 deletions(-) diff --git a/gst-libs/gst/gl/gstglbuffer.c b/gst-libs/gst/gl/gstglbuffer.c index da4093d..f85179b 100644 --- a/gst-libs/gst/gl/gstglbuffer.c +++ b/gst-libs/gst/gl/gstglbuffer.c @@ -27,6 +27,9 @@ gst_gl_buffer_finalize (GstGLBuffer * buffer) 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; @@ -88,14 +91,14 @@ gst_gl_buffer_new (GstGLDisplay * display, GstVideoFormat format, GstGLBuffer *buffer; XGCValues values = { 0 }; - g_return_val_if_fail (format == GST_VIDEO_FORMAT_RGB, NULL); + 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_RBO; + buffer->type = GST_GL_BUFFER_TEXTURE; buffer->width = width; buffer->height = height; @@ -147,6 +150,8 @@ gst_gl_buffer_new (GstGLDisplay * display, GstVideoFormat format, gst_gl_display_unlock (buffer->display); break; } + case GST_GL_BUFFER_TEXTURE: + break; default: g_assert_not_reached (); } @@ -236,6 +241,11 @@ gst_gl_buffer_upload (GstGLBuffer * buffer, void *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); + break; default: g_assert_not_reached (); } @@ -287,6 +297,29 @@ gst_gl_buffer_download (GstGLBuffer * buffer, void *data) break; } + case GST_GL_BUFFER_TEXTURE: + { + unsigned int fbo; + + glGenFramebuffersEXT (1, &fbo); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); + + 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); + + g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == + GL_FRAMEBUFFER_COMPLETE_EXT); + + glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA, + GL_UNSIGNED_BYTE, data); + + glDeleteFramebuffersEXT (1, &fbo); + } + break; default: g_assert_not_reached (); } diff --git a/gst-libs/gst/gl/gstglbuffer.h b/gst-libs/gst/gl/gstglbuffer.h index 969f216..3bb4437 100644 --- a/gst-libs/gst/gl/gstglbuffer.h +++ b/gst-libs/gst/gl/gstglbuffer.h @@ -17,7 +17,8 @@ typedef struct _GstGLBuffer GstGLBuffer; typedef enum { GST_GL_BUFFER_UNKNOWN, GST_GL_BUFFER_XIMAGE, - GST_GL_BUFFER_RBO + GST_GL_BUFFER_RBO, + GST_GL_BUFFER_TEXTURE } GstGLBufferType; struct _GstGLBuffer { @@ -31,6 +32,7 @@ struct _GstGLBuffer { GC gc; GLuint rbo; + GLuint texture; int width; int height; diff --git a/gst/gl/glimagesink.c b/gst/gl/glimagesink.c index 560a523..5f94c91 100644 --- a/gst/gl/glimagesink.c +++ b/gst/gl/glimagesink.c @@ -410,31 +410,7 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) glimage_sink->par_n = par_n; glimage_sink->par_d = par_d; - switch (format) { - case GST_VIDEO_FORMAT_YUY2: - glimage_sink->type = GST_GL_IMAGE_TYPE_YUY2; - break; - case GST_VIDEO_FORMAT_UYVY: - glimage_sink->type = GST_GL_IMAGE_TYPE_UYVY; - break; - case GST_VIDEO_FORMAT_AYUV: - glimage_sink->type = GST_GL_IMAGE_TYPE_AYUV; - break; - case GST_VIDEO_FORMAT_RGBx: - glimage_sink->type = GST_GL_IMAGE_TYPE_RGBx; - break; - case GST_VIDEO_FORMAT_BGRx: - glimage_sink->type = GST_GL_IMAGE_TYPE_BGRx; - break; - case GST_VIDEO_FORMAT_xRGB: - glimage_sink->type = GST_GL_IMAGE_TYPE_xRGB; - break; - case GST_VIDEO_FORMAT_xBGR: - glimage_sink->type = GST_GL_IMAGE_TYPE_xBGR; - break; - default: - break; - } + glimage_sink->type = format; #if 0 if (!glimage_sink->window) { diff --git a/gst/gl/glimagesink.h b/gst/gl/glimagesink.h index 7eee7f3..ff60955 100644 --- a/gst/gl/glimagesink.h +++ b/gst/gl/glimagesink.h @@ -58,7 +58,7 @@ struct _GstGLImageSink int par_n, par_d; GstGLDisplay *display; - GstGLImageType type; + GstVideoFormat type; XID window_id; }; diff --git a/gst/gl/glvideo.c b/gst/gl/glvideo.c index 8bc8f9f..b574a15 100644 --- a/gst/gl/glvideo.c +++ b/gst/gl/glvideo.c @@ -224,18 +224,18 @@ gst_gl_display_check_features (GstGLDisplay * display) } gboolean -gst_gl_display_can_handle_type (GstGLDisplay * display, GstGLImageType type) +gst_gl_display_can_handle_type (GstGLDisplay * display, GstVideoFormat type) { switch (type) { - case GST_GL_IMAGE_TYPE_RGBx: - case GST_GL_IMAGE_TYPE_BGRx: - case GST_GL_IMAGE_TYPE_xRGB: - case GST_GL_IMAGE_TYPE_xBGR: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: return TRUE; - case GST_GL_IMAGE_TYPE_YUY2: - case GST_GL_IMAGE_TYPE_UYVY: + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: return display->have_ycbcr_texture; - case GST_GL_IMAGE_TYPE_AYUV: + case GST_VIDEO_FORMAT_AYUV: return display->have_color_matrix; default: return FALSE; @@ -360,9 +360,68 @@ 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) +{ + GLuint texture; + + glGenTextures (1, &texture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + switch (type) { + case GST_VIDEO_FORMAT_RGBx: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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: + 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: + 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: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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; + default: + g_assert_not_reached (); + } + + return texture; +} + static void -draw_rect_texture (GstGLDisplay * display, GstGLImageType type, +draw_rect_texture (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height) { GLuint texture; @@ -371,52 +430,57 @@ draw_rect_texture (GstGLDisplay * display, GstGLImageType type, #ifdef GL_TEXTURE_RECTANGLE_ARB glEnable (GL_TEXTURE_RECTANGLE_ARB); - glGenTextures (1, &texture); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + //glGenTextures (1, &texture); + //glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + texture = gst_gl_display_upload_texture_rectangle (display, type, + data, width, height); + 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 0 switch (type) { - case GST_GL_IMAGE_TYPE_RGBx: + case GST_VIDEO_FORMAT_RGBx: glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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_IMAGE_TYPE_BGRx: + case GST_VIDEO_FORMAT_BGRx: glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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_GL_IMAGE_TYPE_xRGB: + case GST_VIDEO_FORMAT_xRGB: glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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_GL_IMAGE_TYPE_xBGR: + case GST_VIDEO_FORMAT_xBGR: glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, 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_GL_IMAGE_TYPE_YUY2: + case GST_VIDEO_FORMAT_YUY2: 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_IMAGE_TYPE_UYVY: + case GST_VIDEO_FORMAT_UYVY: 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_GL_IMAGE_TYPE_AYUV: + case GST_VIDEO_FORMAT_AYUV: glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, @@ -427,7 +491,7 @@ draw_rect_texture (GstGLDisplay * display, GstGLImageType type, } #ifdef GL_POST_COLOR_MATRIX_RED_BIAS - if (type == GST_GL_IMAGE_TYPE_AYUV) { + if (type == GST_VIDEO_FORMAT_AYUV) { const double matrix[16] = { 1, 1, 1, 0, 0, -0.344 * 1, 1.770 * 1, 0, @@ -441,6 +505,7 @@ draw_rect_texture (GstGLDisplay * display, GstGLImageType type, glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2); } #endif +#endif glColor4f (1, 0, 1, 1); glBegin (GL_QUADS); @@ -463,7 +528,7 @@ draw_rect_texture (GstGLDisplay * display, GstGLImageType type, } static void -draw_pow2_texture (GstGLDisplay * display, GstGLImageType type, +draw_pow2_texture (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height) { int pow2_width; @@ -487,43 +552,43 @@ draw_pow2_texture (GstGLDisplay * display, GstGLImageType type, glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); switch (type) { - case GST_GL_IMAGE_TYPE_RGBx: + case GST_VIDEO_FORMAT_RGBx: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); break; - case GST_GL_IMAGE_TYPE_BGRx: + case GST_VIDEO_FORMAT_BGRx: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, data); break; - case GST_GL_IMAGE_TYPE_xRGB: + case GST_VIDEO_FORMAT_xRGB: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); break; - case GST_GL_IMAGE_TYPE_xBGR: + case GST_VIDEO_FORMAT_xBGR: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); break; - case GST_GL_IMAGE_TYPE_YUY2: + case GST_VIDEO_FORMAT_YUY2: glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); break; - case GST_GL_IMAGE_TYPE_UYVY: + case GST_VIDEO_FORMAT_UYVY: glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); break; - case GST_GL_IMAGE_TYPE_AYUV: + case GST_VIDEO_FORMAT_AYUV: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, @@ -534,7 +599,7 @@ draw_pow2_texture (GstGLDisplay * display, GstGLImageType type, } #ifdef GL_POST_COLOR_MATRIX_RED_BIAS - if (type == GST_GL_IMAGE_TYPE_AYUV) { + if (type == GST_VIDEO_FORMAT_AYUV) { const double matrix[16] = { 1, 1, 1, 0, 0, -0.344 * 1, 1.770 * 1, 0, @@ -570,7 +635,7 @@ draw_pow2_texture (GstGLDisplay * display, GstGLImageType type, } void -gst_gl_display_draw_image (GstGLDisplay * display, GstGLImageType type, +gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height) { g_return_if_fail (data != NULL); @@ -742,3 +807,64 @@ gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, gst_gl_display_unlock (display); } + +void +gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, + int width, int height) +{ + g_return_if_fail (width > 0); + g_return_if_fail (height > 0); + g_return_if_fail (texture != None); + + gst_gl_display_lock (display); + + g_assert (display->window != None); + g_assert (display->context != NULL); + + gst_gl_display_update_attributes (display); + + 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, 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); + gst_gl_display_check_error (display, __LINE__); + 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__); + + glXSwapBuffers (display->display, display->window); + + gst_gl_display_unlock (display); +} diff --git a/gst/gl/glvideo.h b/gst/gl/glvideo.h index 4fb3761..677c569 100644 --- a/gst/gl/glvideo.h +++ b/gst/gl/glvideo.h @@ -5,16 +5,7 @@ #include #include #include - -typedef enum { - GST_GL_IMAGE_TYPE_RGBx, - GST_GL_IMAGE_TYPE_BGRx, - GST_GL_IMAGE_TYPE_xRGB, - GST_GL_IMAGE_TYPE_xBGR, - GST_GL_IMAGE_TYPE_YUY2, - GST_GL_IMAGE_TYPE_UYVY, - GST_GL_IMAGE_TYPE_AYUV, -} GstGLImageType; +#include typedef struct _GstGLDisplay GstGLDisplay; typedef struct _GstGLDisplayClass GstGLDisplayClass; @@ -73,17 +64,21 @@ GstGLDisplay *gst_gl_display_new (void); gboolean gst_gl_display_connect (GstGLDisplay *display, const char *display_name); gboolean gst_gl_display_can_handle_type (GstGLDisplay *display, - GstGLImageType type); + GstVideoFormat type); void gst_gl_display_lock (GstGLDisplay *display); void gst_gl_display_unlock (GstGLDisplay *display); void gst_gl_display_set_window (GstGLDisplay *display, Window window); void gst_gl_display_update_attributes (GstGLDisplay *display); void gst_gl_display_clear (GstGLDisplay *display); -void gst_gl_display_draw_image (GstGLDisplay * display, GstGLImageType type, +void gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, void *data, int width, int height); void gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, int width, int height); +void gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, + int width, int height); 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); #endif diff --git a/gst/gl/gstgldownload.c b/gst/gl/gstgldownload.c index 5c7bbed..eb7ac74 100644 --- a/gst/gl/gstgldownload.c +++ b/gst/gl/gstgldownload.c @@ -71,7 +71,7 @@ static GstStaticPadTemplate gst_gl_download_src_pad_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx) ); static GstStaticPadTemplate gst_gl_download_sink_pad_template = @@ -178,13 +178,13 @@ gst_gl_download_reset (GstGLDownload * download) g_object_unref (download->display); download->display = NULL; } - download->format = GST_VIDEO_FORMAT_RGB; + download->format = GST_VIDEO_FORMAT_RGBx; } static gboolean gst_gl_download_start (GstGLDownload * download) { - download->format = GST_VIDEO_FORMAT_RGB; + download->format = GST_VIDEO_FORMAT_RGBx; return TRUE; } diff --git a/gst/gl/gstglfilter.c b/gst/gl/gstglfilter.c index c2b91f4..f6386dc 100644 --- a/gst/gl/gstglfilter.c +++ b/gst/gl/gstglfilter.c @@ -25,6 +25,7 @@ #include #include #include +#include "glextensions.h" #define GST_CAT_DEFAULT gst_gl_filter_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -178,7 +179,7 @@ gst_gl_filter_reset (GstGLFilter * filter) g_object_unref (filter->display); filter->display = NULL; } - filter->format = GST_VIDEO_FORMAT_BGRx; + filter->format = GST_VIDEO_FORMAT_RGBx; } static gboolean @@ -186,7 +187,7 @@ gst_gl_filter_start (GstGLFilter * filter) { gboolean ret; - filter->format = GST_VIDEO_FORMAT_BGRx; + filter->format = GST_VIDEO_FORMAT_RGBx; filter->display = gst_gl_display_new (); ret = gst_gl_display_connect (filter->display, NULL); @@ -335,81 +336,73 @@ dump_fbconfigs (Display * display) static gboolean gst_gl_filter_transform (GstGLBuffer * outbuf, GstGLBuffer * inbuf) { - GstGLDisplay *display; - -#if 0 - int pixmapAttribs[] = { - GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_RECTANGLE_EXT, - GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, - None - }; -#endif - GLXFBConfig *fbconfigs; - int n; - int i; - GLXDrawable glxpixmap; - GLXContext context = 0; - int fb_index = 0; - int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None - }; - XVisualInfo *visinfo; + GstGLDisplay *display = inbuf->display; + unsigned int fbo; - display = outbuf->display; gst_gl_display_lock (display); - //context = glXCreateContext (display->display, visinfo, NULL, True); + glGenFramebuffersEXT (1, &fbo); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); - dump_fbconfigs (display->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); - fbconfigs = glXGetFBConfigs (display->display, display->screen_num, &n); - for (i = 0; i < n; i++) { - XVisualInfo *visinfo; - int value; + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, outbuf->texture, 0); - GST_DEBUG ("fbconfig %d", i); + glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); + glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); - visinfo = glXGetVisualFromFBConfig (display->display, fbconfigs[i]); - GST_DEBUG ("visinfo %p", visinfo); + g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == + GL_FRAMEBUFFER_COMPLETE_EXT); - glXGetFBConfigAttrib (display->display, fbconfigs[i], - GLX_DRAWABLE_TYPE, &value); - if (!(value & GLX_WINDOW_BIT)) { - GST_DEBUG ("GLX_DRAWABLE_TYPE doesn't have GLX_WINDOW_BIT set"); - continue; - } + glViewport (0, 0, outbuf->width, outbuf->height); - glXGetFBConfigAttrib (display->display, fbconfigs[i], - GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value); - if (!(value & GLX_TEXTURE_2D_BIT_EXT)) { - GST_DEBUG - ("GLX_BIND_TO_TEXTURE_TARGETS_EXT doesn't have GLX_TEXTURE_2D_BIT_EXT set"); - continue; - } + glClearColor (0.3, 0.3, 0.3, 1.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glXGetFBConfigAttrib (display->display, fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, &value); - GST_DEBUG ("GLX_BIND_TO_TEXTURE_RGBA_EXT %d", value); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); - } + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); - fb_index = 0; + glDisable (GL_CULL_FACE); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); -#if 0 - { - pb = glXCreatePbuffer (display->display, fbconfigs[fb_index], attribs); - } -#endif + glColor4f (1, 1, 1, 1); + + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, inbuf->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); - XSync (display->display, False); - visinfo = glXChooseVisual (display->display, 0, attrib); - glxpixmap = glXCreateGLXPixmap (display->display, visinfo, outbuf->pixmap); + 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 (); - XSync (display->display, False); + glFlush (); - glXMakeCurrent (display->display, glxpixmap, context); + glDeleteFramebuffersEXT (1, &fbo); - glXMakeCurrent (display->display, None, NULL); gst_gl_display_unlock (display); return TRUE; diff --git a/gst/gl/gstglupload.c b/gst/gl/gstglupload.c index 1b0d78f..5f9ffa7 100644 --- a/gst/gl/gstglupload.c +++ b/gst/gl/gstglupload.c @@ -80,7 +80,7 @@ static GstStaticPadTemplate gst_gl_upload_sink_pad_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx) ); enum @@ -178,7 +178,7 @@ gst_gl_upload_reset (GstGLUpload * upload) g_object_unref (upload->display); upload->display = NULL; } - upload->format = GST_VIDEO_FORMAT_RGB; + upload->format = GST_VIDEO_FORMAT_RGBx; upload->peek = TRUE; } @@ -187,7 +187,7 @@ gst_gl_upload_start (GstGLUpload * upload) { gboolean ret; - upload->format = GST_VIDEO_FORMAT_RGB; + upload->format = GST_VIDEO_FORMAT_RGBx; upload->display = gst_gl_display_new (); ret = gst_gl_display_connect (upload->display, NULL); @@ -253,7 +253,7 @@ gst_gl_upload_chain (GstPad * pad, GstBuffer * buf) gst_buffer_unref (buf); if (upload->peek) { - gst_gl_display_draw_rbo (outbuf->display, outbuf->rbo, + gst_gl_display_draw_texture (outbuf->display, outbuf->texture, outbuf->width, outbuf->height); } -- 2.7.4