diff options
author | David Schleef <ds@schleef.org> | 2007-12-21 00:03:11 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2007-12-21 00:03:11 +0000 |
commit | bb4e1d10e99c206fdf0ca22a43ef20efa24236ef (patch) | |
tree | 5d99e25822404edf4c91fd1e96ee33be00cee66b /sys/glsink/gstglbuffer.c | |
parent | 1bc2202132e729b40e002eb98520ee7b2a788149 (diff) | |
download | gst-plugins-bad-bb4e1d10e99c206fdf0ca22a43ef20efa24236ef.tar.gz gst-plugins-bad-bb4e1d10e99c206fdf0ca22a43ef20efa24236ef.tar.bz2 gst-plugins-bad-bb4e1d10e99c206fdf0ca22a43ef20efa24236ef.zip |
sys/glsink/: Switch to using framebuffer_objects instead of GLXPixmaps, because that's what my driver supports. Remo...
Original commit message from CVS:
* sys/glsink/Makefile.am:
* sys/glsink/glextensions.c:
* sys/glsink/glextensions.h:
* 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:
* sys/glsink/gstopengl.c:
Switch to using framebuffer_objects instead of GLXPixmaps,
because that's what my driver supports. Remove GLDrawable,
since GstGLDisplay now has a default drawable and context.
Diffstat (limited to 'sys/glsink/gstglbuffer.c')
-rw-r--r-- | sys/glsink/gstglbuffer.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/sys/glsink/gstglbuffer.c b/sys/glsink/gstglbuffer.c new file mode 100644 index 00000000..04421ce7 --- /dev/null +++ b/sys/glsink/gstglbuffer.c @@ -0,0 +1,239 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gstglbuffer.h> +#include <glvideo.h> +#include "glextensions.h" + +#include <string.h> + +static GObjectClass *gst_gl_buffer_parent_class; + +static void +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; + default: + g_assert_not_reached (); + break; + } + gst_gl_display_unlock (buffer->display); + g_object_unref (buffer->display); + + GST_MINI_OBJECT_CLASS (gst_gl_buffer_parent_class)-> + finalize (GST_MINI_OBJECT (buffer)); +} + +static void +gst_gl_buffer_init (GstGLBuffer * buffer, gpointer g_class) +{ + +} + +static void +gst_gl_buffer_class_init (gpointer g_class, gpointer class_data) +{ + GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); + + gst_gl_buffer_parent_class = g_type_class_peek_parent (g_class); + + mini_object_class->finalize = (GstMiniObjectFinalizeFunction) + gst_gl_buffer_finalize; +} + + +GType +gst_gl_buffer_get_type (void) +{ + static GType _gst_gl_buffer_type; + + if (G_UNLIKELY (_gst_gl_buffer_type == 0)) { + static const GTypeInfo info = { + sizeof (GstBufferClass), + NULL, + NULL, + gst_gl_buffer_class_init, + NULL, + NULL, + sizeof (GstGLBuffer), + 0, + (GInstanceInitFunc) gst_gl_buffer_init, + NULL + }; + _gst_gl_buffer_type = g_type_register_static (GST_TYPE_BUFFER, + "GstGLBuffer", &info, 0); + } + return _gst_gl_buffer_type; +} + + +GstGLBuffer * +gst_gl_buffer_new (GstGLDisplay * display, GstVideoFormat format, + int width, int height) +{ + GstGLBuffer *buffer; + XGCValues values = { 0 }; + + g_return_val_if_fail (format == GST_VIDEO_FORMAT_BGRx, 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->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: + { + gst_gl_display_lock (buffer->display); + + 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); + + + + gst_gl_display_unlock (buffer->display); + break; + } + default: + g_assert_not_reached (); + } + + return buffer; +} + +void +gst_gl_buffer_upload (GstGLBuffer * buffer, 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; + + visual = DefaultVisual (display, 0); + depth = 32; + bpp = 32; + + image = XCreateImage (display, visual, depth, ZPixmap, 0, NULL, + buffer->width, buffer->height, bpp, 0); + GST_DEBUG ("image %p", image); + image->data = data; + + XPutImage (display, buffer->pixmap, buffer->gc, + image, 0, 0, 0, 0, buffer->width, buffer->height); + + 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); + //glWindowPos2iARB(0, 0); + glDrawPixels (buffer->width, buffer->height, GL_RGBA, + GL_UNSIGNED_BYTE, data); + + glDeleteFramebuffersEXT (1, &fbo); + + break; + } + default: + g_assert_not_reached (); + } + + gst_gl_display_unlock (buffer->display); +} + + +void +gst_gl_buffer_download (GstGLBuffer * buffer, void *data) +{ + gst_gl_display_lock (buffer->display); + + 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); + + glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); + glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA, + GL_UNSIGNED_BYTE, data); + + glDeleteFramebuffersEXT (1, &fbo); + + break; + } + default: + g_assert_not_reached (); + } + + gst_gl_display_unlock (buffer->display); +} |