summaryrefslogtreecommitdiffstats
path: root/sys/glsink/glvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/glsink/glvideo.c')
-rw-r--r--sys/glsink/glvideo.c242
1 files changed, 214 insertions, 28 deletions
diff --git a/sys/glsink/glvideo.c b/sys/glsink/glvideo.c
index 169f41c6..409935c3 100644
--- a/sys/glsink/glvideo.c
+++ b/sys/glsink/glvideo.c
@@ -113,14 +113,26 @@ glv_display_check_features (GLVideoDisplay * display)
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &display->max_texture_size);
extstring = (const char *) glGetString (GL_EXTENSIONS);
+
+ display->have_ycbcr_texture = FALSE;
#ifdef GL_YCBCR_MESA
if (strstr (extstring, "GL_MESA_ycbcr_texture")) {
display->have_ycbcr_texture = TRUE;
- } else {
- display->have_ycbcr_texture = FALSE;
}
-#else
- display->have_ycbcr_texture = FALSE;
+#endif
+
+ display->have_color_matrix = FALSE;
+#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
+ if (strstr (extstring, "GL_SGI_color_matrix")) {
+ display->have_color_matrix = TRUE;
+ }
+#endif
+
+ display->have_texture_rectangle = FALSE;
+#ifdef GL_TEXTURE_RECTANGLE_ARB
+ if (strstr (extstring, "GL_ARB_texture_rectangle")) {
+ display->have_texture_rectangle = TRUE;
+ }
#endif
glXMakeCurrent (display->display, None, NULL);
@@ -129,6 +141,25 @@ glv_display_check_features (GLVideoDisplay * display)
return TRUE;
}
+gboolean
+glv_display_can_handle_type (GLVideoDisplay * display, GLVideoImageType type)
+{
+ switch (type) {
+ case GLVIDEO_IMAGE_TYPE_RGBx:
+ case GLVIDEO_IMAGE_TYPE_BGRx:
+ case GLVIDEO_IMAGE_TYPE_xRGB:
+ case GLVIDEO_IMAGE_TYPE_xBGR:
+ return TRUE;
+ case GLVIDEO_IMAGE_TYPE_YUY2:
+ case GLVIDEO_IMAGE_TYPE_UYVY:
+ return display->have_ycbcr_texture;
+ case GLVIDEO_IMAGE_TYPE_AYUV:
+ return display->have_color_matrix;
+ default:
+ return FALSE;
+ }
+}
+
void
glv_display_free (GLVideoDisplay * display)
{
@@ -292,34 +323,14 @@ glv_drawable_clear (GLVideoDrawable * drawable)
-void
-glv_drawable_draw_image (GLVideoDrawable * drawable, GLVideoImageType type,
+static void
+draw_rect_texture (GLVideoDrawable * drawable, GLVideoImageType type,
void *data, int width, int height)
{
- g_return_if_fail (data != NULL);
- g_return_if_fail (width > 0);
- g_return_if_fail (height > 0);
-
- glv_drawable_lock (drawable);
-
- glv_drawable_update_attributes (drawable);
-
- glViewport (0, 0, drawable->win_width, drawable->win_height);
+ GST_DEBUG ("using rectangular texture");
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
-
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
-
- glDisable (GL_CULL_FACE);
+#ifdef GL_TEXTURE_RECTANGLE_ARB
glEnable (GL_TEXTURE_RECTANGLE_ARB);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-
- glColor4f (1, 1, 1, 1);
-
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 1);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -340,6 +351,18 @@ glv_drawable_draw_image (GLVideoDrawable * drawable, GLVideoImageType type,
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
+ case GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_YUY2:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
@@ -352,10 +375,32 @@ glv_drawable_draw_image (GLVideoDrawable * drawable, GLVideoImageType type,
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
break;
+ case GLVIDEO_IMAGE_TYPE_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 ();
}
+#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
+ if (type == GLVIDEO_IMAGE_TYPE_AYUV) {
+ const double matrix[16] = {
+ 1, 1, 1, 0,
+ 0, -0.344 * 1, 1.770 * 1, 0,
+ 1.403 * 1, -0.714 * 1, 0, 0,
+ 0, 0, 0, 1
+ };
+ glMatrixMode (GL_COLOR);
+ glLoadMatrixd (matrix);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2);
+ }
+#endif
+
glColor4f (1, 0, 1, 1);
glBegin (GL_QUADS);
@@ -370,6 +415,147 @@ glv_drawable_draw_image (GLVideoDrawable * drawable, GLVideoImageType type,
glTexCoord2f (width, height);
glVertex3f (1.0, -1.0, 0);
glEnd ();
+#else
+ g_assert_not_reached ();
+#endif
+}
+
+static void
+draw_pow2_texture (GLVideoDrawable * drawable, GLVideoImageType type,
+ void *data, int width, int height)
+{
+ int pow2_width;
+ int pow2_height;
+ double x, y;
+
+ GST_DEBUG ("using power-of-2 texture");
+
+ for (pow2_height = 64;
+ pow2_height < height && pow2_height > 0; pow2_height <<= 1);
+ for (pow2_width = 64; pow2_width < width && pow2_width > 0; pow2_width <<= 1);
+
+ glEnable (GL_TEXTURE_2D);
+ glBindTexture (GL_TEXTURE_2D, 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_CLAMP);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ switch (type) {
+ case GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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 GLVIDEO_IMAGE_TYPE_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,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
+ if (type == GLVIDEO_IMAGE_TYPE_AYUV) {
+ const double matrix[16] = {
+ 1, 1, 1, 0,
+ 0, -0.344 * 1, 1.770 * 1, 0,
+ 1.403 * 1, -0.714 * 1, 0, 0,
+ 0, 0, 0, 1
+ };
+ glMatrixMode (GL_COLOR);
+ glLoadMatrixd (matrix);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2);
+ glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2);
+ }
+#endif
+
+ glColor4f (1, 0, 1, 1);
+ glBegin (GL_QUADS);
+
+ glNormal3f (0, 0, -1);
+
+ x = (double) width / pow2_width;
+ y = (double) height / pow2_height;
+
+ glTexCoord2f (x, 0);
+ glVertex3f (1.0, 1.0, 0);
+ glTexCoord2f (0, 0);
+ glVertex3f (-1.0, 1.0, 0);
+ glTexCoord2f (0, y);
+ glVertex3f (-1.0, -1.0, 0);
+ glTexCoord2f (x, y);
+ glVertex3f (1.0, -1.0, 0);
+ glEnd ();
+}
+
+void
+glv_drawable_draw_image (GLVideoDrawable * drawable, GLVideoImageType type,
+ void *data, int width, int height)
+{
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+
+ glv_drawable_lock (drawable);
+
+ glv_drawable_update_attributes (drawable);
+
+ glViewport (0, 0, drawable->win_width, drawable->win_height);
+
+ 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);
+
+ if (drawable->display->have_texture_rectangle) {
+ draw_rect_texture (drawable, type, data, width, height);
+ } else {
+ draw_pow2_texture (drawable, type, data, width, height);
+ }
glFlush ();
glXSwapBuffers (drawable->display->display, drawable->window);