diff options
Diffstat (limited to 'sys/glsink/gstgl_rgbimage.c')
-rw-r--r-- | sys/glsink/gstgl_rgbimage.c | 381 |
1 files changed, 194 insertions, 187 deletions
diff --git a/sys/glsink/gstgl_rgbimage.c b/sys/glsink/gstgl_rgbimage.c index ab856bbc..8c61e390 100644 --- a/sys/glsink/gstgl_rgbimage.c +++ b/sys/glsink/gstgl_rgbimage.c @@ -22,20 +22,21 @@ #include <GL/glx.h> #include <GL/gl.h> #include <GL/glu.h> -#include <math.h> +#include <math.h> #include "gstglsink.h" typedef struct _GstGLImageConnection GstGLImageConnection; // this contains everything to draw an image, including all necessary graphics card data. -struct _GstGLImageConnection { +struct _GstGLImageConnection +{ GstImageConnection conn; - Display *dpy; // the Xlib drawing context - GLXContext ctx; // The GLX drawing context + Display *dpy; // the Xlib drawing context + GLXContext ctx; // The GLX drawing context gint w, h; gint bpp; - + int rgbatex_id; unsigned char *m_memory; }; @@ -51,49 +52,56 @@ struct _GstGLImage GstGLImageConnection *conn; }; -static GstGLImageInfo * gst_gl_rgbimage_info (GstImageInfo *info); -static GstGLImageConnection * gst_gl_rgbimage_connection (GstImageConnection *conn); - -static GstCaps * gst_gl_rgbimage_get_caps (GstImageInfo *info); -static GstImageConnection * gst_gl_rgbimage_set_caps (GstImageInfo *info, GstCaps *caps); -static GstImageData * gst_gl_rgbimage_get_image (GstImageInfo *info, GstImageConnection *conn); -static void gst_gl_rgbimage_put_image (GstImageInfo *info, GstImageData *image); -static void gst_gl_rgbimage_free_image (GstImageData *image); -static void gst_gl_rgbimage_open_conn (GstImageConnection *conn, GstImageInfo *info); -static void gst_gl_rgbimage_close_conn (GstImageConnection *conn, GstImageInfo *info); -static void gst_gl_rgbimage_free_conn (GstImageConnection *conn); - -GstImagePlugin* get_gl_rgbimage_plugin(void) +static GstGLImageInfo *gst_gl_rgbimage_info (GstImageInfo * info); +static GstGLImageConnection *gst_gl_rgbimage_connection (GstImageConnection * + conn); + +static GstCaps *gst_gl_rgbimage_get_caps (GstImageInfo * info); +static GstImageConnection *gst_gl_rgbimage_set_caps (GstImageInfo * info, + GstCaps * caps); +static GstImageData *gst_gl_rgbimage_get_image (GstImageInfo * info, + GstImageConnection * conn); +static void gst_gl_rgbimage_put_image (GstImageInfo * info, + GstImageData * image); +static void gst_gl_rgbimage_free_image (GstImageData * image); +static void gst_gl_rgbimage_open_conn (GstImageConnection * conn, + GstImageInfo * info); +static void gst_gl_rgbimage_close_conn (GstImageConnection * conn, + GstImageInfo * info); +static void gst_gl_rgbimage_free_conn (GstImageConnection * conn); + +GstImagePlugin * +get_gl_rgbimage_plugin (void) { static GstImagePlugin plugin = { gst_gl_rgbimage_get_caps, - gst_gl_rgbimage_set_caps, - gst_gl_rgbimage_get_image, - gst_gl_rgbimage_put_image, - gst_gl_rgbimage_free_image}; + gst_gl_rgbimage_set_caps, + gst_gl_rgbimage_get_image, + gst_gl_rgbimage_put_image, + gst_gl_rgbimage_free_image + }; return &plugin; } static GstGLImageInfo * -gst_gl_rgbimage_info (GstImageInfo *info) +gst_gl_rgbimage_info (GstImageInfo * info) { - if (info == NULL || info->id != GST_MAKE_FOURCC ('X', 'l', 'i', 'b')) - { + if (info == NULL || info->id != GST_MAKE_FOURCC ('X', 'l', 'i', 'b')) { return NULL; } return (GstGLImageInfo *) info; } static GstGLImageConnection * -gst_gl_rgbimage_connection (GstImageConnection *conn) +gst_gl_rgbimage_connection (GstImageConnection * conn) { if (conn == NULL || conn->free_conn != gst_gl_rgbimage_free_conn) - return NULL; + return NULL; return (GstGLImageConnection *) conn; } GstCaps * -gst_gl_rgbimage_get_caps (GstImageInfo *info) +gst_gl_rgbimage_get_caps (GstImageInfo * info) { GstCaps *caps = NULL; Visual *visual; @@ -101,13 +109,15 @@ gst_gl_rgbimage_get_caps (GstImageInfo *info) XWindowAttributes attrib; XImage *ximage; GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); - - g_warning("rgbimage get caps called, context %p, endianness %d !\n", glXGetCurrentContext(), G_BIG_ENDIAN); + + g_warning ("rgbimage get caps called, context %p, endianness %d !\n", + glXGetCurrentContext (), G_BIG_ENDIAN); /* we don't handle this image information */ - if (xinfo == NULL) return NULL; + if (xinfo == NULL) + return NULL; + + XGetWindowAttributes (xinfo->dpy, xinfo->win, &attrib); - XGetWindowAttributes(xinfo->dpy, xinfo->win, &attrib); - visual = attrib.visual; if (attrib.depth <= 8) xpad = 8; @@ -115,42 +125,37 @@ gst_gl_rgbimage_get_caps (GstImageInfo *info) xpad = 16; else xpad = 32; - + // create a temporary image - ximage = XCreateImage (xinfo->dpy, visual, attrib.depth, ZPixmap, 0, NULL, - 100, 100, xpad, (attrib.depth + 7) / 8 * 100); + ximage = XCreateImage (xinfo->dpy, visual, attrib.depth, ZPixmap, 0, NULL, + 100, 100, xpad, (attrib.depth + 7) / 8 * 100); if (ximage != NULL) { - caps = - GST_CAPS_NEW ( - "forcing Video RGB", - "video/x-raw-rgb", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), - "depth", GST_PROPS_INT(24), - "bpp", GST_PROPS_INT(24), - "red_mask", GST_PROPS_INT(0xff), - "green_mask", GST_PROPS_INT(0xff00), - "blue_mask", GST_PROPS_INT(0xff0000), - "endianness", GST_PROPS_INT(G_BIG_ENDIAN), /*= 1234/4321 (INT) <- endianness */ - - "width", GST_PROPS_INT_RANGE (0, TEX_XSIZE), /* can't have videos larger than TEX_SIZE */ - "height", GST_PROPS_INT_RANGE (0, TEX_YSIZE) - ); + caps = + GST_CAPS_NEW ("forcing Video RGB", "video/x-raw-rgb", "format", + GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), "depth", GST_PROPS_INT (24), + "bpp", GST_PROPS_INT (24), "red_mask", GST_PROPS_INT (0xff), + "green_mask", GST_PROPS_INT (0xff00), "blue_mask", + GST_PROPS_INT (0xff0000), "endianness", GST_PROPS_INT (G_BIG_ENDIAN), + /*= 1234/4321 (INT) <- endianness */ + "width", GST_PROPS_INT_RANGE (0, TEX_XSIZE), /* can't have videos larger than TEX_SIZE */ + "height", GST_PROPS_INT_RANGE (0, TEX_YSIZE) + ); XDestroyImage (ximage); } - + printf ("GL_RGBImage: returning caps at %p", caps); return caps; } -static GstImageConnection * -gst_gl_rgbimage_set_caps (GstImageInfo *info, GstCaps *caps) +static GstImageConnection * +gst_gl_rgbimage_set_caps (GstImageInfo * info, GstCaps * caps) { - g_warning("in set_caps !\n"); + g_warning ("in set_caps !\n"); GstGLImageConnection *new = NULL; Visual *visual; XWindowAttributes attrib; - GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); + GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); guint32 format; gint depth; gint endianness; @@ -158,26 +163,25 @@ gst_gl_rgbimage_set_caps (GstImageInfo *info, GstCaps *caps) gint width, height, bpp; /* check if this is the right image info */ - if (xinfo == NULL) return NULL; - - XGetWindowAttributes(xinfo->dpy, xinfo->win, &attrib); - + if (xinfo == NULL) + return NULL; + + XGetWindowAttributes (xinfo->dpy, xinfo->win, &attrib); + visual = attrib.visual; gst_caps_get (caps, - "format", &format, - "depth", &depth, - "endianness", &endianness, - "red_mask", &red_mask, - "green_mask", &green_mask, - "blue_mask", &blue_mask, - "width", &width, - "height", &height, - "bpp", &bpp, - NULL); - + "format", &format, + "depth", &depth, + "endianness", &endianness, + "red_mask", &red_mask, + "green_mask", &green_mask, + "blue_mask", &blue_mask, + "width", &width, "height", &height, "bpp", &bpp, NULL); + /* check if the caps are ok */ - if (format != GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) return NULL; + if (format != GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) + return NULL; /* if (gst_caps_get_int (caps, "bpp") != ???) return NULL; */ //if (depth != attrib.depth) return NULL; //if (endianness != ((ImageByteOrder (xinfo->dpy) == LSBFirst) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN)) return NULL; @@ -185,7 +189,7 @@ gst_gl_rgbimage_set_caps (GstImageInfo *info, GstCaps *caps) //if (green_mask != visual->green_mask) return NULL; //if (blue_mask != visual->blue_mask) return NULL; GST_DEBUG ("GL_RGBImage: caps %p are ok, creating image", caps); - + new = g_new (GstGLImageConnection, 1); new->conn.open_conn = gst_gl_rgbimage_open_conn; new->conn.close_conn = gst_gl_rgbimage_close_conn; @@ -195,34 +199,35 @@ gst_gl_rgbimage_set_caps (GstImageInfo *info, GstCaps *caps) new->w = width; new->h = height; new->bpp = bpp; - + return (GstImageConnection *) new; } static GstImageData * -gst_gl_rgbimage_get_image (GstImageInfo *info, GstImageConnection *conn) +gst_gl_rgbimage_get_image (GstImageInfo * info, GstImageConnection * conn) { GstGLImage *image; + //XWindowAttributes attrib; - GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); - GstGLImageConnection *xconn = gst_gl_rgbimage_connection (conn); - + GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); + GstGLImageConnection *xconn = gst_gl_rgbimage_connection (conn); + image = g_new (GstGLImage, 1); /* checks */ - if (xinfo == NULL) return NULL; - if (xconn == NULL) return NULL; - if (xinfo->dpy != xconn->dpy) - { + if (xinfo == NULL) + return NULL; + if (xconn == NULL) + return NULL; + if (xinfo->dpy != xconn->dpy) { g_warning ("XImage: wrong x display specified in 'get_image'\n"); return NULL; } image->conn = xconn; image->data.size = xconn->w * xconn->h * 4; - image->data.data = g_malloc(image->data.size); - if (image->data.data == NULL) - { + image->data.data = g_malloc (image->data.size); + if (image->data.data == NULL) { g_warning ("GL_RGBImage: data allocation failed!"); g_free (image); return NULL; @@ -233,160 +238,162 @@ gst_gl_rgbimage_get_image (GstImageInfo *info, GstImageConnection *conn) static void -gst_gl_rgbimage_put_image (GstImageInfo *info, GstImageData *image) +gst_gl_rgbimage_put_image (GstImageInfo * info, GstImageData * image) { float xmax, ymax; GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); GstGLImage *im = (GstGLImage *) image; - int img_width = im->conn->w; - int img_height = im->conn->h; + int img_width = im->conn->w; + int img_height = im->conn->h; g_assert (xinfo != NULL); // both upload the video, and redraw the screen - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0.0, 0.0, -5.0); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + glTranslatef (0.0, 0.0, -5.0); - glEnable(GL_TEXTURE_2D); + glEnable (GL_TEXTURE_2D); - if (xinfo->info.demo) - { - glTranslatef(0.0, 0.0, -5.0); // make it avoid the clipping plane, zoom 2.0 instead - glRotatef(180.0*sin(xinfo->rotX),1,0,0); - glRotatef(180.0*cos(xinfo->rotY),0,1,0); + if (xinfo->info.demo) { + glTranslatef (0.0, 0.0, -5.0); // make it avoid the clipping plane, zoom 2.0 instead + glRotatef (180.0 * sin (xinfo->rotX), 1, 0, 0); + glRotatef (180.0 * cos (xinfo->rotY), 0, 1, 0); - xinfo->rotX += 0.01; - xinfo->rotY -= 0.015; - float zoom = xinfo->zoom; - glScalef(zoom,zoom,zoom); + xinfo->rotX += 0.01; + xinfo->rotY -= 0.015; + float zoom = xinfo->zoom; - if (xinfo->zoom > 2.0) - xinfo->zoomdir = -0.01; + glScalef (zoom, zoom, zoom); - if (xinfo->zoom < 1.0) - xinfo->zoomdir = 0.01; + if (xinfo->zoom > 2.0) + xinfo->zoomdir = -0.01; - xinfo->zoom += xinfo->zoomdir; - } + if (xinfo->zoom < 1.0) + xinfo->zoomdir = 0.01; + xinfo->zoom += xinfo->zoomdir; + } //Draws the surface rectangle - glBindTexture(GL_TEXTURE_2D, im->conn->rgbatex_id); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, im->conn->w, im->conn->h, GL_RGB, - GL_UNSIGNED_BYTE, im->data.data); - xmax = (float)im->conn->w/TEX_XSIZE; - ymax = (float)im->conn->h/TEX_YSIZE; + glBindTexture (GL_TEXTURE_2D, im->conn->rgbatex_id); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, im->conn->w, im->conn->h, GL_RGB, + GL_UNSIGNED_BYTE, im->data.data); + xmax = (float) im->conn->w / TEX_XSIZE; + ymax = (float) im->conn->h / TEX_YSIZE; - float aspect = img_width/(float)img_height; + float aspect = img_width / (float) img_height; float hor = aspect; - glColor4f(1,1,1,1); - glBegin(GL_QUADS); - - glNormal3f(0, -1, 0); - - glTexCoord2f(xmax, 0); - glVertex3f(hor,1,0); - - glTexCoord2f(0, 0); - glVertex3f(-hor,1,0); - - glTexCoord2f(0, ymax); - glVertex3f(-hor,-1,0); - - glTexCoord2f(xmax, ymax); - glVertex3f(hor,-1,0); - glEnd(); - - if (xinfo->info.dumpvideo) - { - static int framenr = 0; - char capfilename[255]; - static guint8 *cap_image_data = NULL, *cap_image_data2 = NULL; - int i; - - // hmmmm, is this reentrant ?! - if (cap_image_data == NULL) - cap_image_data = (guint8 *)malloc(img_width * img_height * 3); - - if (cap_image_data2 == NULL) - cap_image_data2 = (guint8 *)malloc(img_width * img_height * 3); - - printf("Recording frame #%d\n", framenr); - glReadPixels(0,0,img_width,img_height,GL_RGB,GL_UNSIGNED_BYTE,cap_image_data); - // invert the pixels - for (i = 0; i < img_height; i++) - memcpy(cap_image_data2 + i * img_width * 3, cap_image_data + (img_height-1-i) * img_width * 3, img_width*3); - - sprintf(capfilename, "cap%04d.ppm", framenr); - FILE *outfile = fopen(capfilename, "wb"); - if (outfile != NULL) - { - fprintf(outfile, "P6\n"); - fprintf(outfile,"# created by raw_zb\n"); - fprintf(outfile,"%d %d\n",img_width,img_height); - fprintf(outfile,"255\n"); - fwrite(cap_image_data2, sizeof(char), img_width*img_height*3, outfile); - fclose(outfile); - } - framenr++; + glColor4f (1, 1, 1, 1); + glBegin (GL_QUADS); + + glNormal3f (0, -1, 0); + + glTexCoord2f (xmax, 0); + glVertex3f (hor, 1, 0); + + glTexCoord2f (0, 0); + glVertex3f (-hor, 1, 0); + + glTexCoord2f (0, ymax); + glVertex3f (-hor, -1, 0); + + glTexCoord2f (xmax, ymax); + glVertex3f (hor, -1, 0); + glEnd (); + + if (xinfo->info.dumpvideo) { + static int framenr = 0; + char capfilename[255]; + static guint8 *cap_image_data = NULL, *cap_image_data2 = NULL; + int i; + + // hmmmm, is this reentrant ?! + if (cap_image_data == NULL) + cap_image_data = (guint8 *) malloc (img_width * img_height * 3); + + if (cap_image_data2 == NULL) + cap_image_data2 = (guint8 *) malloc (img_width * img_height * 3); + + printf ("Recording frame #%d\n", framenr); + glReadPixels (0, 0, img_width, img_height, GL_RGB, GL_UNSIGNED_BYTE, + cap_image_data); + // invert the pixels + for (i = 0; i < img_height; i++) + memcpy (cap_image_data2 + i * img_width * 3, + cap_image_data + (img_height - 1 - i) * img_width * 3, img_width * 3); + + sprintf (capfilename, "cap%04d.ppm", framenr); + FILE *outfile = fopen (capfilename, "wb"); + + if (outfile != NULL) { + fprintf (outfile, "P6\n"); + fprintf (outfile, "# created by raw_zb\n"); + fprintf (outfile, "%d %d\n", img_width, img_height); + fprintf (outfile, "255\n"); + fwrite (cap_image_data2, sizeof (char), img_width * img_height * 3, + outfile); + fclose (outfile); } + framenr++; + } - glXSwapBuffers(xinfo->dpy, xinfo->win); + glXSwapBuffers (xinfo->dpy, xinfo->win); } void -gst_gl_rgbimage_free_image (GstImageData *image) +gst_gl_rgbimage_free_image (GstImageData * image) { GstGLImage *im = (GstGLImage *) image; - g_warning ("gst_gl_rgbimage_free_image doesn't do anything yet -> freeing image\n"); + g_warning + ("gst_gl_rgbimage_free_image doesn't do anything yet -> freeing image\n"); g_free (im->data.data); g_free (im); } /* Creates an OpenGL texture to upload the picture over */ static void -gst_gl_rgbimage_open_conn (GstImageConnection *conn, GstImageInfo *info) +gst_gl_rgbimage_open_conn (GstImageConnection * conn, GstImageInfo * info) { - g_warning("Opening RGB Connection; classic OpenGL 1.2 renderer."); + g_warning ("Opening RGB Connection; classic OpenGL 1.2 renderer."); //GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); GstGLImageConnection *xconn = gst_gl_rgbimage_connection (conn); - glGenTextures(1, &xconn->rgbatex_id); - glBindTexture(GL_TEXTURE_2D, xconn->rgbatex_id); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_XSIZE, TEX_YSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glGenTextures (1, &xconn->rgbatex_id); + glBindTexture (GL_TEXTURE_2D, xconn->rgbatex_id); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, TEX_XSIZE, TEX_YSIZE, 0, GL_RGBA, + GL_UNSIGNED_BYTE, NULL); } /* Deletes the creates OpenGL textures */ -static void -gst_gl_rgbimage_close_conn (GstImageConnection *conn, GstImageInfo *info) +static void +gst_gl_rgbimage_close_conn (GstImageConnection * conn, GstImageInfo * info) { GstGLImageConnection *xconn = gst_gl_rgbimage_connection (conn); + //GstGLImageInfo *xinfo = gst_gl_rgbimage_info (info); - glDeleteTextures(1, &xconn->rgbatex_id); - } + glDeleteTextures (1, &xconn->rgbatex_id); +} static void -gst_gl_rgbimage_free_conn (GstImageConnection *conn) +gst_gl_rgbimage_free_conn (GstImageConnection * conn) { GstGLImageConnection *xconn = gst_gl_rgbimage_connection (conn); - + g_assert (xconn != NULL); - + g_free (xconn); } - - |