[112/906] git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@552 93df14bb-0f41-7a43-8087-d3e2a2f0e464

This commit is contained in:
Julien Isorce 2008-06-28 15:38:41 +00:00 committed by Tim-Philipp Müller
parent edda6cc72d
commit 8807e62119
2 changed files with 318 additions and 107 deletions

View file

@ -28,6 +28,7 @@
static void gst_gl_display_finalize (GObject * object); static void gst_gl_display_finalize (GObject * object);
static gpointer gst_gl_display_glutThreadFunc (GstGLDisplay* display); static gpointer gst_gl_display_glutThreadFunc (GstGLDisplay* display);
static void gst_gl_display_glutCreateWindow (GstGLDisplay* display); static void gst_gl_display_glutCreateWindow (GstGLDisplay* display);
static void gst_gl_display_glutInitUpload (GstGLDisplay* display);
static void gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display); static void gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display);
static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display); static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display);
static void gst_gl_display_glutUseFBO (GstGLDisplay *display); static void gst_gl_display_glutUseFBO (GstGLDisplay *display);
@ -98,6 +99,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
{ {
display->mutex = g_mutex_new (); display->mutex = g_mutex_new ();
display->texturePool = g_queue_new (); display->texturePool = g_queue_new ();
display->cond_init_upload = g_cond_new ();
display->cond_make = g_cond_new (); display->cond_make = g_cond_new ();
display->cond_fill = g_cond_new (); display->cond_fill = g_cond_new ();
display->cond_clear = g_cond_new (); display->cond_clear = g_cond_new ();
@ -117,6 +119,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
display->textureFBO = 0; display->textureFBO = 0;
display->textureFBOWidth = 0; display->textureFBOWidth = 0;
display->textureFBOHeight = 0; display->textureFBOHeight = 0;
display->upload_video_format = 0;
display->requestedFBO = 0; display->requestedFBO = 0;
display->requestedDepthBuffer = 0; display->requestedDepthBuffer = 0;
@ -180,6 +183,8 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
display->clientDrawCallback = NULL; display->clientDrawCallback = NULL;
display->title = g_string_new ("OpenGL renderer "); display->title = g_string_new ("OpenGL renderer ");
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_GLSL;
display->GLSLProgram_YUY2 = 0; display->GLSLProgram_YUY2 = 0;
display->GLSLProgram_UYVY = 0; display->GLSLProgram_UYVY = 0;
display->GLSLProgram_I420_YV12 = 0; display->GLSLProgram_I420_YV12 = 0;
@ -341,6 +346,10 @@ gst_gl_display_finalize (GObject *object)
g_mutex_free (display->mutex); g_mutex_free (display->mutex);
display->mutex = NULL; display->mutex = NULL;
} }
if (display->cond_init_upload) {
g_cond_free (display->cond_init_upload);
display->cond_init_upload = NULL;
}
if (display->cond_make) { if (display->cond_make) {
g_cond_free (display->cond_make); g_cond_free (display->cond_make);
display->cond_make = NULL; display->cond_make = NULL;
@ -437,9 +446,9 @@ gst_gl_display_glutThreadFunc (GstGLDisplay *display)
gst_gl_display_glutCreateWindow (display); gst_gl_display_glutCreateWindow (display);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
g_print ("Glut mainLoop start\n"); g_print ("gl mainLoop started\n");
glutMainLoop (); glutMainLoop ();
g_print ("Glut mainLoop exited\n"); g_print ("gl mainLoop exited\n");
return NULL; return NULL;
} }
@ -474,7 +483,10 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
//Init glew //Init glew
err = glewInit(); err = glewInit();
if (err != GLEW_OK) if (err != GLEW_OK)
{
GST_DEBUG ("Error: %s", glewGetErrorString(err)); GST_DEBUG ("Error: %s", glewGetErrorString(err));
display->isAlive = FALSE;
}
else else
{ {
//OpenGL > 2.1.0 and Glew > 1.5.0 //OpenGL > 2.1.0 and Glew > 1.5.0
@ -500,17 +512,43 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
if ((opengl_version_major < 1 && opengl_version_minor < 4) || if ((opengl_version_major < 1 && opengl_version_minor < 4) ||
(glew_version_major < 1 && glew_version_minor < 4) ) (glew_version_major < 1 && glew_version_minor < 4) )
{ {
//turn off the pipeline, the old drivers are not yet supported
g_print ("Required OpenGL >= 1.4.0 and Glew >= 1.4.0\n"); g_print ("Required OpenGL >= 1.4.0 and Glew >= 1.4.0\n");
g_assert_not_reached (); display->isAlive = FALSE;
} }
} }
//setup callbacks
glutReshapeFunc (gst_gl_display_onReshape);
glutDisplayFunc (gst_gl_display_draw);
glutCloseFunc (gst_gl_display_onClose);
//insert glut context to the map
display->glutWinId = glutWinId;
g_hash_table_insert (gst_gl_display_map, GUINT_TO_POINTER (glutWinId), display);
//check glut id validity
g_assert (glutGetWindow() == glutWinId);
GST_DEBUG ("Context %d initialized", display->glutWinId);
//release display constructor
g_cond_signal (display->cond_create);
}
/* Called in the gl thread */
static void
gst_gl_display_glutInitUpload (GstGLDisplay *display)
{
glutSetWindow (display->glutWinId);
//Frame buffer object is a requirement for every cases
if (GLEW_EXT_framebuffer_object) if (GLEW_EXT_framebuffer_object)
{ {
//a texture must be attached to the FBO //a texture must be attached to the FBO
guint fake_texture = 0; guint fake_texture = 0;
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", glutWinId); g_print ("Context %d, EXT_framebuffer_object supported: yes\n", display->glutWinId);
//-- init intput frame buffer object (video -> GL) //-- init intput frame buffer object (video -> GL)
@ -524,7 +562,7 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
display->textureFBOWidth, display->textureFBOHeight); display->textureFBOWidth, display->textureFBOHeight);
//setup a texture to render to //a fake texture is attached to the upload FBO (cannot init without it)
glGenTextures (1, &fake_texture); glGenTextures (1, &fake_texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
@ -547,56 +585,120 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteTextures (1, &fake_texture); glDeleteTextures (1, &fake_texture);
} }
else else
{ {
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: no", glutWinId); //turn off the pipeline because Frame buffer object is a requirement
g_assert_not_reached (); g_print ("Context %d, EXT_framebuffer_object supported: no\n", display->glutWinId);
display->isAlive = FALSE;
} }
//check if fragment program is available, then load them switch (display->upload_video_format)
if (GLEW_ARB_vertex_program) {
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
//color space conversion is not needed
break;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
case GST_VIDEO_FORMAT_AYUV:
//color space conversion is needed
{
//check if fragment shader is available, then load them
if (GLEW_ARB_fragment_shader)
{
g_print ("Context %d, ARB_fragment_shader supported: yes\n", display->glutWinId);
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_GLSL;
switch (display->upload_video_format)
{
case GST_VIDEO_FORMAT_YUY2:
{ {
gchar program[2048]; gchar program[2048];
GST_DEBUG ("Context %d, ARB_fragment_program supported: yes", glutWinId);
//from video to texture
sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a'); sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a');
display->GLSLProgram_YUY2 = gst_gl_display_loadGLSLprogram (program); display->GLSLProgram_YUY2 = gst_gl_display_loadGLSLprogram (program);
}
break;
case GST_VIDEO_FORMAT_UYVY:
{
gchar program[2048];
sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r'); sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r');
display->GLSLProgram_UYVY = gst_gl_display_loadGLSLprogram (program); display->GLSLProgram_UYVY = gst_gl_display_loadGLSLprogram (program);
}
break;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
display->GLSLProgram_I420_YV12 = gst_gl_display_loadGLSLprogram (display->textFProgram_I420_YV12); display->GLSLProgram_I420_YV12 = gst_gl_display_loadGLSLprogram (display->textFProgram_I420_YV12);
break;
case GST_VIDEO_FORMAT_AYUV:
display->GLSLProgram_AYUV = gst_gl_display_loadGLSLprogram (display->textFProgram_AYUV); display->GLSLProgram_AYUV = gst_gl_display_loadGLSLprogram (display->textFProgram_AYUV);
break;
default:
g_assert_not_reached ();
}
}
//check if YCBCR MESA is available
else if (GLEW_MESA_ycbcr_texture)
{
//GLSL and Color Matrix are not available on your drivers, switch to YCBCR MESA
g_print ("Context %d, ARB_fragment_shader supported: no\n", display->glutWinId);
g_print ("Context %d, GLEW_ARB_imaging supported: no\n", display->glutWinId);
g_print ("Context %d, GLEW_MESA_ycbcr_texture supported: yes\n", display->glutWinId);
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MESA;
switch (display->upload_video_format)
{
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
break;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
case GST_VIDEO_FORMAT_AYUV:
//turn off the pipeline because
//MESA only support YUY2 and UYVY
display->isAlive = FALSE;
break;
default:
g_assert_not_reached ();
}
}
//check if color matrix is available
else if (GLEW_ARB_imaging)
{
//GLSL is not available on your drivers, switch to Color Matrix
g_print ("Context %d, ARB_fragment_shader supported: no\n", display->glutWinId);
g_print ("Context %d, GLEW_ARB_imaging supported: yes\n", display->glutWinId);
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MATRIX;
} }
else else
{ {
GST_DEBUG ("Context %d, ARB_fragment_program supported: no", glutWinId); g_print ("Context %d, ARB_fragment_shader supported: no\n", display->glutWinId);
g_print ("Context %d, GLEW_ARB_imaging supported: no\n", display->glutWinId);
g_print ("Context %d, GLEW_MESA_ycbcr_texture supported: no\n", display->glutWinId);
//turn off the pipeline because colorspace conversion is not possible
display->isAlive = FALSE;
}
}
break;
default:
g_assert_not_reached (); g_assert_not_reached ();
} }
//setup callbacks g_cond_signal (display->cond_init_upload);
glutReshapeFunc (gst_gl_display_onReshape);
glutDisplayFunc (gst_gl_display_draw);
glutCloseFunc (gst_gl_display_onClose);
//insert glut context to the map
display->glutWinId = glutWinId;
g_hash_table_insert (gst_gl_display_map, GUINT_TO_POINTER (glutWinId), display);
//check glut id validity
g_assert (glutGetWindow() == glutWinId);
GST_DEBUG ("Context %d initialized", display->glutWinId);
//release display constructor
g_cond_signal (display->cond_create);
} }
@ -686,7 +788,7 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
g_assert_not_reached (); g_assert_not_reached ();
} }
if (GLEW_ARB_vertex_program) if (GLEW_ARB_fragment_shader)
{ {
gchar program[2048]; gchar program[2048];
@ -1082,6 +1184,9 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg)
case GST_GL_DISPLAY_ACTION_RESHAPE: case GST_GL_DISPLAY_ACTION_RESHAPE:
gst_gl_display_glutReshapeWindow (msg->display); gst_gl_display_glutReshapeWindow (msg->display);
break; break;
case GST_GL_DISPLAY_ACTION_INIT_UPLOAD:
gst_gl_display_glutInitUpload (msg->display);
break;
case GST_GL_DISPLAY_ACTION_PREPARE: case GST_GL_DISPLAY_ACTION_PREPARE:
gst_gl_display_glutPrepareTexture (msg->display); gst_gl_display_glutPrepareTexture (msg->display);
break; break;
@ -1140,6 +1245,7 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg)
case GST_GL_DISPLAY_ACTION_DESTROY: case GST_GL_DISPLAY_ACTION_DESTROY:
case GST_GL_DISPLAY_ACTION_VISIBLE: case GST_GL_DISPLAY_ACTION_VISIBLE:
case GST_GL_DISPLAY_ACTION_RESHAPE: case GST_GL_DISPLAY_ACTION_RESHAPE:
case GST_GL_DISPLAY_ACTION_INIT_UPLOAD:
case GST_GL_DISPLAY_ACTION_PREPARE: case GST_GL_DISPLAY_ACTION_PREPARE:
case GST_GL_DISPLAY_ACTION_CHANGE: case GST_GL_DISPLAY_ACTION_CHANGE:
case GST_GL_DISPLAY_ACTION_CLEAR: case GST_GL_DISPLAY_ACTION_CLEAR:
@ -1282,6 +1388,20 @@ gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height)
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
} }
/* Called by gst gl elements */
void
gst_gl_display_init_upload (GstGLDisplay* display, GstVideoFormat video_format,
guint gl_width, guint gl_height)
{
gst_gl_display_lock (display);
display->upload_video_format = video_format;
display->textureFBOWidth = gl_width;
display->textureFBOHeight = gl_height;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_INIT_UPLOAD, display);
g_cond_wait (display->cond_init_upload, display->mutex);
gst_gl_display_unlock (display);
}
/* Called by gstglbuffer */ /* Called by gstglbuffer */
void void
@ -1505,6 +1625,10 @@ gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId)
display->textureFBOWidth, display->textureFBOHeight, display->textureFBOWidth, display->textureFBOHeight,
winId, winId,
TRUE); TRUE);
//init colorspace conversion if needed
gst_gl_display_init_upload (display, display->upload_video_format,
display->textureFBOWidth, display->textureFBOHeight);
} }
@ -1670,7 +1794,10 @@ void gst_gl_display_make_texture (GstGLDisplay* display)
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY: switch (display->colorspace_conversion)
{
case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
width, height, width, height,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
@ -1682,6 +1809,40 @@ void gst_gl_display_make_texture (GstGLDisplay* display)
width, height, width, height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA,
width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL);
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_UYVY:
switch (display->colorspace_conversion)
{
case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
width, height,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
gst_gl_display_gen_texture (display, &display->currentTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
break;
case GST_GL_DISPLAY_CONVERSION_MESA:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA,
width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL);
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
@ -1742,7 +1903,10 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY: switch (display->colorspace_conversion)
{
case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
@ -1751,6 +1915,37 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
GST_ROUND_UP_2 (width) / 2, height, GST_ROUND_UP_2 (width) / 2, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
display->currentVideo_format = GST_VIDEO_FORMAT_RGBx;
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_UYVY:
switch (display->colorspace_conversion)
{
case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
break;
case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
display->currentVideo_format = GST_VIDEO_FORMAT_RGBx;
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
{ {

View file

@ -41,12 +41,21 @@
typedef struct _GstGLDisplay GstGLDisplay; typedef struct _GstGLDisplay GstGLDisplay;
typedef struct _GstGLDisplayClass GstGLDisplayClass; typedef struct _GstGLDisplayClass GstGLDisplayClass;
//Color space conversion metthod
typedef enum {
GST_GL_DISPLAY_CONVERSION_GLSL, //ARB_fragment_shade
GST_GL_DISPLAY_CONVERSION_MATRIX, //ARB_imaging
GST_GL_DISPLAY_CONVERSION_MESA, //MESA_ycbcr_texture
} GstGLDisplayConversion;
//Message type //Message type
typedef enum { typedef enum {
GST_GL_DISPLAY_ACTION_CREATE, GST_GL_DISPLAY_ACTION_CREATE,
GST_GL_DISPLAY_ACTION_DESTROY, GST_GL_DISPLAY_ACTION_DESTROY,
GST_GL_DISPLAY_ACTION_VISIBLE, GST_GL_DISPLAY_ACTION_VISIBLE,
GST_GL_DISPLAY_ACTION_RESHAPE, GST_GL_DISPLAY_ACTION_RESHAPE,
GST_GL_DISPLAY_ACTION_INIT_UPLOAD,
GST_GL_DISPLAY_ACTION_PREPARE, GST_GL_DISPLAY_ACTION_PREPARE,
GST_GL_DISPLAY_ACTION_CHANGE, GST_GL_DISPLAY_ACTION_CHANGE,
GST_GL_DISPLAY_ACTION_CLEAR, GST_GL_DISPLAY_ACTION_CLEAR,
@ -63,7 +72,7 @@ typedef enum {
} GstGLDisplayAction; } GstGLDisplayAction;
//Message to communicate with the glut thread //Message to communicate with the gl thread
typedef struct _GstGLDisplayMsg { typedef struct _GstGLDisplayMsg {
GstGLDisplayAction action; GstGLDisplayAction action;
gint glutWinId; gint glutWinId;
@ -92,6 +101,7 @@ struct _GstGLDisplay {
GQueue* texturePool; GQueue* texturePool;
GCond* cond_init_upload;
GCond* cond_make; GCond* cond_make;
GCond* cond_fill; GCond* cond_fill;
GCond* cond_clear; GCond* cond_clear;
@ -120,6 +130,7 @@ struct _GstGLDisplay {
GLuint textureFBO; GLuint textureFBO;
GLuint textureFBOWidth; GLuint textureFBOWidth;
GLuint textureFBOHeight; GLuint textureFBOHeight;
GstVideoFormat upload_video_format;
//filter frame buffer object (GL -> GL) //filter frame buffer object (GL -> GL)
GLuint requestedFBO; GLuint requestedFBO;
@ -179,6 +190,9 @@ struct _GstGLDisplay {
GLuint recordedTextureWidth; GLuint recordedTextureWidth;
GLuint recordedTextureHeight; GLuint recordedTextureHeight;
//colorspace conversion method
GstGLDisplayConversion colorspace_conversion;
//from video to texture //from video to texture
gchar* textFProgram_YUY2_UYVY; gchar* textFProgram_YUY2_UYVY;
@ -235,6 +249,8 @@ void gst_gl_display_setClientReshapeCallback (GstGLDisplay* display, CRCB cb);
void gst_gl_display_setClientDrawCallback (GstGLDisplay* display, CDCB cb); void gst_gl_display_setClientDrawCallback (GstGLDisplay* display, CDCB cb);
void gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible); void gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible);
void gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height); void gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height);
void gst_gl_display_init_upload (GstGLDisplay* display, GstVideoFormat video_format,
guint gl_width, guint gl_height);
void gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture); void gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture);
void gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format, void gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format,
gint video_width, gint video_height, gpointer data, gint video_width, gint video_height, gpointer data,