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

This commit is contained in:
Julien Isorce 2008-06-21 21:38:42 +00:00 committed by Matthew Waters
parent 04946b3f1d
commit e7f5afee87
17 changed files with 337 additions and 393 deletions

View file

@ -30,8 +30,7 @@ static void
gst_gl_buffer_finalize (GstGLBuffer* buffer)
{
//wait clear textures end, blocking call
gst_gl_display_clearTexture (buffer->display, buffer->texture,
buffer->texture_u, buffer->texture_v);
gst_gl_display_clearTexture (buffer->display, buffer->texture);
g_object_unref (buffer->display);
@ -43,15 +42,10 @@ static void
gst_gl_buffer_init (GstGLBuffer* buffer, gpointer g_class)
{
buffer->display = NULL;
buffer->video_format = 0;
buffer->width = 0;
buffer->height = 0;
buffer->texture = 0;
buffer->texture_u = 0;
buffer->texture_v = 0;
buffer->widthGL = 0;
buffer->heightGL = 0;
buffer->textureGL = 0;
}
static void
@ -92,57 +86,43 @@ gst_gl_buffer_get_type (void)
GstGLBuffer*
gst_gl_buffer_new_from_video_format (GstGLDisplay* display,
GstVideoFormat video_format, gint context_width, gint context_height,
gint widthGL, gint heightGL,
gint width, gint height)
gst_gl_buffer_new (GstGLDisplay* display,
gint gl_width, gint gl_height)
{
GstGLBuffer *buffer;
GstGLBuffer* gl_buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
//g_return_val_if_fail (video_format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
g_return_val_if_fail (display != NULL, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
gl_buffer->display = g_object_ref (display);
gl_buffer->width = gl_width;
gl_buffer->height = gl_height;
buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
//it does not depends on the video format because gl buffer has always one texture.
//the one attached to the upload FBO
GST_BUFFER_SIZE (gl_buffer) = gst_gl_buffer_get_size (gl_width, gl_height);
buffer->display = g_object_ref (display);
buffer->width = width;
buffer->height = height;
buffer->video_format = video_format;
buffer->widthGL = widthGL;
buffer->heightGL = heightGL;
GST_BUFFER_SIZE (buffer) = gst_gl_buffer_format_get_size (video_format, context_width, context_height);
//blocking call, request a texture and attach it to the upload FBO
gst_gl_display_prepare_texture (gl_buffer->display, &gl_buffer->texture) ;
//blocking call, init texture
if (video_format != GST_VIDEO_FORMAT_UNKNOWN)
gst_gl_display_textureRequested (buffer->display, buffer->video_format,
buffer->width, buffer->height,
&buffer->texture, &buffer->texture_u, &buffer->texture_v) ;
return buffer;
return gl_buffer;
}
int
gst_gl_buffer_format_get_size (GstVideoFormat format, int width, int height)
gint
gst_gl_buffer_get_size (gint width, gint height)
{
/* this is not strictly true, but it's used for compatibility with
* queue and BaseTransform */
return width * height * 4;
//this is not strictly true, but it's used for compatibility with
//queue and BaseTransform
return width * height * 4;
}
gboolean
gst_gl_buffer_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
gint* width, gint* height)
gst_gl_buffer_parse_caps (GstCaps* caps, gint* width, gint* height)
{
GstStructure *structure;
gboolean ret;
GstStructure* structure = gst_caps_get_structure (caps, 0);
gboolean ret = gst_structure_has_name (structure, "video/x-raw-gl");
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_has_name (structure, "video/x-raw-gl"))
return FALSE;
if (!ret)
return ret;
ret = gst_structure_get_int (structure, "width", width);
ret &= gst_structure_get_int (structure, "height", height);

View file

@ -33,24 +33,19 @@ typedef struct _GstGLBuffer GstGLBuffer;
#define GST_IS_GL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GL_BUFFER))
#define GST_GL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GL_BUFFER, GstGLBuffer))
//A gl buffer has only one texture.
//Note that when a gl buffer is created by the upload filter,
//the colorspace conversion is made using a FBO.
//And so the texture attached to this FBO is the one managed by the gl buffer.
struct _GstGLBuffer {
GstBuffer buffer;
GstGLDisplay *display;
GstVideoFormat video_format;
gint width;
gint height;
GLuint texture;
GLuint texture_u;
GLuint texture_v;
gint widthGL;
gint heightGL;
GLuint textureGL;
};
GType gst_gl_buffer_get_type (void);
@ -58,13 +53,9 @@ GType gst_gl_buffer_get_type (void);
#define gst_gl_buffer_ref(x) ((GstGLBuffer *)(gst_buffer_ref((GstBuffer *)(x))))
#define gst_gl_buffer_unref(x) (gst_buffer_unref((GstBuffer *)(x)))
GstGLBuffer* gst_gl_buffer_new_from_video_format (GstGLDisplay* display, GstVideoFormat format,
gint context_width, gint context_height,
gint widthGL, gint heightGL,
gint width, gint height);
gint gst_gl_buffer_format_get_size (GstVideoFormat format, gint width, gint height);
gboolean gst_gl_buffer_format_parse_caps (GstCaps* caps, GstVideoFormat* format,
gint* width, gint* height);
GstGLBuffer* gst_gl_buffer_new (GstGLDisplay* display, gint gl_width, gint gl_height);
gint gst_gl_buffer_get_size (gint width, gint height);
gboolean gst_gl_buffer_parse_caps (GstCaps* caps, gint* width, gint* height);
#define GST_GL_VIDEO_CAPS \

View file

@ -57,6 +57,8 @@ void gst_gl_display_fill_texture (GstGLDisplay* display);
void gst_gl_display_draw_texture (GstGLDisplay* display);
void gst_gl_display_draw_graphic (GstGLDisplay* display);
void gst_gl_display_fill_video (GstGLDisplay* display);
void gst_gl_display_gen_texture (GstGLDisplay* display, guint* pTexture);
void gst_gl_display_del_texture (GstGLDisplay* display, guint* pTexture);
GLhandleARB gst_gl_display_loadGLSLprogram (gchar* textFProgram);
void checkFramebufferStatus(void);
GST_BOILERPLATE (GstGLDisplay, gst_gl_display, GObject, G_TYPE_OBJECT);
@ -123,7 +125,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
display->requestedFBO = 0;
display->requestedDepthBuffer = 0;
display->requestedTextureFBO = 0;
display->requestedTextureFBOWidth = 0;
display->requestedTextureFBOHeight = 0;
display->usedFBO = 0;
@ -140,37 +141,22 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
display->inputTexture = 0;
display->rejectedFBO = 0;
display->rejectedDepthBuffer = 0;
display->rejectedTextureFBO = 0;
display->displayedTexture = 0;
display->displayedTextureWidth = 0;
display->displayedTextureHeight = 0;
display->requestedTexture = 0;
display->requestedTexture_u = 0;
display->requestedTexture_v = 0;
display->requestedVideo_format = 0;
display->requestedTextureWidth = 0;
display->requestedTextureHeight = 0;
display->candidateTexture = 0;
display->candidateTexture_u = 0;
display->candidateTexture_v = 0;
display->candidateVideo_format = 0;
display->candidateTextureWidth = 0;
display->candidateTextureHeight = 0;
display->candidateData = NULL;
display->preparedTexture = 0;
display->currentTexture = 0;
display->currentTexture_u = 0;
display->currentTexture_v = 0;
display->currentVideo_format = 0;
display->currentTextureWidth = 0;
display->currentTextureHeight = 0;
display->currentVideo_format = 0;
display->currentData = NULL;
display->textureTrash = 0;
display->textureTrash_u = 0;
display->textureTrash_v = 0;
display->videoFBO = 0;
display->videoDepthBuffer = 0;
@ -497,10 +483,10 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
{
//OpenGL > 2.1.0 and Glew > 1.5.0
GString* opengl_version = g_string_truncate (g_string_new ((gchar*) glGetString (GL_VERSION)), 3);
gint opengl_version_major = 0.;
gint opengl_version_major = 0;
gint opengl_version_minor = 0;
GString* glew_version = g_string_truncate (g_string_new ((gchar*) glewGetString (GLEW_VERSION)), 3);
gint glew_version_major = 0.;
gint glew_version_major = 0;
gint glew_version_minor = 0;
sscanf(opengl_version->str, "%d.%d", &opengl_version_major, &opengl_version_minor);
@ -525,6 +511,9 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
if (GLEW_EXT_framebuffer_object)
{
//a texture must be attached to the FBO
guint fake_texture = 0;
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", glutWinId);
//-- init intput frame buffer object (video -> GL)
@ -540,29 +529,29 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
display->textureFBOWidth, display->textureFBOHeight);
//setup a texture to render to
glGenTextures (1, &display->textureFBO);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->textureFBO);
glGenTextures (1, &fake_texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->textureFBOWidth, display->textureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//attach the texture to the FBO to renderer to
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, display->textureFBO, 0);
GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0);
//attach the depth render buffer to the FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, display->depthBuffer);
checkFramebufferStatus();
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
//unbind the FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteTextures (1, &fake_texture);
}
else
{
@ -621,7 +610,6 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
{
glutSetWindow (display->glutWinId);
if (GLEW_EXT_framebuffer_object)
{
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", display->glutWinId);
@ -657,6 +645,8 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, display->graphicDepthBuffer);
checkFramebufferStatus();
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
@ -772,7 +762,9 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
static void
gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
{
//a texture must be attached to the FBO
guint fake_texture = 0;
glutSetWindow (display->glutWinId);
//-- generate frame buffer object
@ -788,18 +780,14 @@ gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
display->requestedTextureFBOWidth, display->requestedTextureFBOHeight);
//setup a texture to render to
glGenTextures (1, &display->requestedTextureFBO);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->requestedTextureFBO);
glGenTextures (1, &fake_texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->requestedTextureFBOWidth, display->requestedTextureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//attach the texture to the FBO to renderer to
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, display->requestedTextureFBO, 0);
GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0);
//attach the depth render buffer to the FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
@ -811,6 +799,8 @@ gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
//unbind the FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteTextures (1, &fake_texture);
g_cond_signal (display->cond_generateFBO);
}
@ -824,6 +814,19 @@ gst_gl_display_glutUseFBO (GstGLDisplay *display)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO);
//setup a texture to render to
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->usedTextureFBO);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->usedTextureFBOWidth, display->usedTextureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//attach the texture to the FBO to renderer to
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, display->usedTextureFBO, 0);
glPushAttrib(GL_VIEWPORT_BIT);
glMatrixMode(GL_PROJECTION);
@ -872,12 +875,24 @@ gst_gl_display_glutUseFBO2 (GstGLDisplay *display)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO);
//setup a texture to render to
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->usedTextureFBO);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->usedTextureFBOWidth, display->usedTextureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//attach the texture to the FBO to renderer to
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, display->usedTextureFBO, 0);
glPushAttrib(GL_VIEWPORT_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//gluPerspective(45, (gfloat)display->usedTextureFBOWidth/(gfloat)display->usedTextureFBOHeight, 0.1, 100);
gluOrtho2D(0.0, display->usedTextureFBOWidth, 0.0, display->usedTextureFBOHeight);
glMatrixMode(GL_MODELVIEW);
@ -919,10 +934,8 @@ gst_gl_display_glutDestroyFBO (GstGLDisplay* display)
glDeleteFramebuffersEXT (1, &display->rejectedFBO);
glDeleteRenderbuffersEXT(1, &display->rejectedDepthBuffer);
glDeleteTextures (1, &display->rejectedTextureFBO);
display->rejectedFBO = 0;
display->rejectedDepthBuffer = 0;
display->rejectedTextureFBO = 0;
g_cond_signal (display->cond_destroyFBO);
}
@ -970,7 +983,6 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
glDeleteFramebuffersEXT (1, &display->fbo);
glDeleteRenderbuffersEXT(1, &display->depthBuffer);
glDeleteTextures (1, &display->textureFBO);
glDeleteFramebuffersEXT (1, &display->graphicFBO);
glDeleteRenderbuffersEXT(1, &display->graphicDepthBuffer);
@ -986,15 +998,8 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
while (g_queue_get_length (display->texturePool))
{
GstGLDisplayTex* tex = g_queue_pop_head (display->texturePool);
//delete textures
glDeleteTextures (1, &tex->texture);
if (tex->texture_u) {
glDeleteTextures (1, &tex->texture_u);
}
if (tex->texture_v) {
glDeleteTextures (1, &tex->texture_v);
}
g_free (tex);
}
g_hash_table_remove (gst_gl_display_map, GINT_TO_POINTER (display->glutWinId));
@ -1036,7 +1041,8 @@ static void
gst_gl_display_glutPrepareTexture (GstGLDisplay * display)
{
glutSetWindow (display->glutWinId);
gst_gl_display_make_texture (display);
//setup a texture to render to (this one will be in a gl buffer)
gst_gl_display_gen_texture (display, &display->preparedTexture);
g_cond_signal (display->cond_make);
}
@ -1046,6 +1052,7 @@ static void
gst_gl_display_glutUpdateTexture (GstGLDisplay * display)
{
glutSetWindow (display->glutWinId);
gst_gl_display_make_texture (display);
gst_gl_display_fill_texture (display);
gst_gl_display_draw_texture (display);
g_cond_signal (display->cond_fill);
@ -1054,25 +1061,10 @@ gst_gl_display_glutUpdateTexture (GstGLDisplay * display)
/* Called by the idle function */
static void
gst_gl_display_glutCleanTexture (GstGLDisplay * display)
gst_gl_display_glutCleanTexture (GstGLDisplay* display)
{
GstGLDisplayTex* tex = NULL;
glutSetWindow (display->glutWinId);
//contructuct a texture pool element
tex = g_new0 (GstGLDisplayTex, 1);
tex->texture = display->textureTrash;
tex->texture_u = display->textureTrash_u;
tex->texture_v = display->textureTrash_v;
display->textureTrash = 0;
display->textureTrash_u = 0;
display->textureTrash_v = 0;
//add tex to the pool, it makes texture allocation reusable
g_queue_push_tail (display->texturePool, tex);
gst_gl_display_del_texture (display, &display->textureTrash);
g_cond_signal (display->cond_clear);
}
@ -1348,55 +1340,40 @@ gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height)
/* Called by gstglbuffer */
void
gst_gl_display_textureRequested (GstGLDisplay* display, GstVideoFormat video_format,
gint width, gint height, guint* texture,
guint* texture_u, guint* texture_v)
gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture)
{
gst_gl_display_lock (display);
display->requestedVideo_format = video_format;
display->requestedTextureWidth = width;
display->requestedTextureHeight = height;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_PREPARE, display);
g_cond_wait (display->cond_make, display->mutex);
*texture = display->requestedTexture;
*texture_u = display->requestedTexture_u;
*texture_v = display->requestedTexture_v;
*pTexture = display->preparedTexture;
gst_gl_display_unlock (display);
}
/* Called by gst_gl elements */
void
gst_gl_display_textureChanged (GstGLDisplay* display, GstVideoFormat video_format,
GLuint texture, GLuint texture_u, GLuint texture_v,
gint width, gint height, gpointer data, GLuint* outputTexture)
gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format,
gint video_width, gint video_height, gpointer data,
guint gl_width, guint gl_height, guint pTexture)
{
gst_gl_display_lock (display);
display->candidateTexture = texture;
display->candidateTexture_u = texture_u;
display->candidateTexture_v = texture_v;
display->candidateVideo_format = video_format;
display->candidateTextureWidth = width;
display->candidateTextureHeight = height;
display->candidateData = data;
display->currentTextureWidth = video_width;
display->currentTextureHeight = video_height;
display->currentVideo_format = video_format;
display->currentData = data;
display->textureFBO = pTexture;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CHANGE, display);
g_cond_wait (display->cond_fill, display->mutex);
//Here texture width and height are always the same than the fbo
if (outputTexture)
*outputTexture = display->textureFBO;
gst_gl_display_unlock (display);
}
/* Called by gstglbuffer */
void
gst_gl_display_clearTexture (GstGLDisplay* display, guint texture,
guint texture_u, guint texture_v)
gst_gl_display_clearTexture (GstGLDisplay* display, guint texture)
{
gst_gl_display_lock (display);
display->textureTrash = texture;
display->textureTrash_u = texture_u;
display->textureTrash_v = texture_v;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CLEAR, display);
g_cond_wait (display->cond_clear, display->mutex);
gst_gl_display_unlock (display);
@ -1446,7 +1423,7 @@ gst_gl_display_postRedisplay (GstGLDisplay* display, GLuint texture, gint width
/* Called by gst_gl elements */
void
gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
guint* fbo, guint* depthbuffer, guint* texture)
guint* fbo, guint* depthbuffer)
{
gst_gl_display_lock (display);
display->requestedTextureFBOWidth = width;
@ -1455,7 +1432,6 @@ gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
g_cond_wait (display->cond_generateFBO, display->mutex);
*fbo = display->requestedFBO;
*depthbuffer = display->requestedDepthBuffer;
*texture = display->requestedTextureFBO;
gst_gl_display_unlock (display);
}
@ -1497,6 +1473,8 @@ gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textur
display->usedTextureFBOWidth = textureFBOWidth;
display->usedTextureFBOHeight = textureFBOheight;
display->glsceneFBO_cb2 = cb2;
display->p1 = p1;
display->p2 = p2;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO2, display);
g_cond_wait (display->cond_useFBO2, display->mutex);
gst_gl_display_unlock (display);
@ -1506,12 +1484,11 @@ gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textur
/* Called by gst_gl elements */
void
gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
guint depthbuffer, guint texture)
guint depthbuffer)
{
gst_gl_display_lock (display);
display->rejectedFBO = fbo;
display->rejectedDepthBuffer = depthbuffer;
display->rejectedTextureFBO = texture;
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELFBO, display);
g_cond_wait (display->cond_destroyFBO, display->mutex);
gst_gl_display_unlock (display);
@ -1718,23 +1695,17 @@ void gst_gl_display_onClose (void)
}
/* called by gst_gl_display_glutPrepareTexture (in the glut thread) */
void gst_gl_display_make_texture (GstGLDisplay * display)
/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */
void gst_gl_display_make_texture (GstGLDisplay* display)
{
GstGLDisplayTex* tex = NULL;
gint width = display->currentTextureWidth;
gint height = display->currentTextureHeight;
gst_gl_display_gen_texture (display, &display->currentTexture);
//check if there is a tex available in the pool
if (g_queue_get_length (display->texturePool))
tex = g_queue_pop_head (display->texturePool);
//one tex is available
if (tex)
display->requestedTexture = tex->texture;
else
glGenTextures (1, &display->requestedTexture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->requestedTexture);
switch (display->requestedVideo_format) {
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture);
switch (display->currentVideo_format)
{
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
@ -1745,82 +1716,68 @@ void gst_gl_display_make_texture (GstGLDisplay * display)
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_AYUV:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
display->requestedTextureWidth, display->requestedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
display->requestedTextureWidth, display->requestedTextureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
break;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
display->requestedTextureWidth, display->requestedTextureHeight,
width, height,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
//one tex is available
if (tex)
display->requestedTexture_u = tex->texture_u;
else
glGenTextures (1, &display->requestedTexture_u);
gst_gl_display_gen_texture (display, &display->currentTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->requestedTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->requestedTextureWidth, display->requestedTextureHeight,
width, height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
break;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
display->requestedTextureWidth, display->requestedTextureHeight,
width, height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
//one tex is available
if (tex)
display->requestedTexture_u = tex->texture_u;
else
glGenTextures (1, &display->requestedTexture_u);
gst_gl_display_gen_texture (display, &display->currentTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->requestedTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (display->requestedTextureWidth) / 2,
GST_ROUND_UP_2 (display->requestedTextureHeight) / 2,
GST_ROUND_UP_2 (width) / 2,
GST_ROUND_UP_2 (height) / 2,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
//one tex is available
if (tex)
display->requestedTexture_v = tex->texture_v;
else
glGenTextures (1, &display->requestedTexture_v);
gst_gl_display_gen_texture (display, &display->currentTexture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->requestedTexture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_v);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (display->requestedTextureWidth) / 2,
GST_ROUND_UP_2 (display->requestedTextureHeight) / 2,
GST_ROUND_UP_2 (width) / 2,
GST_ROUND_UP_2 (height) / 2,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
break;
default:
g_assert_not_reached ();
}
if (tex)
g_free (tex);
}
/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */
void
gst_gl_display_fill_texture (GstGLDisplay * display)
{
GstVideoFormat video_format = display->candidateVideo_format;
gint width = display->candidateTextureWidth;
gint height = display->candidateTextureHeight;
gpointer data = display->candidateData;
gint width = display->currentTextureWidth;
gint height = display->currentTextureHeight;
GstVideoFormat video_format = display->currentVideo_format;
gpointer data = display->currentData;
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->candidateTexture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture);
switch (video_format) {
case GST_VIDEO_FORMAT_RGBx:
@ -1845,7 +1802,7 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->candidateTexture_u);
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);
@ -1873,14 +1830,14 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->candidateTexture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
(guint8 *) data +
gst_video_format_get_component_offset (video_format, offsetU, width, height));
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->candidateTexture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture_v);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
@ -1891,15 +1848,6 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
default:
g_assert_not_reached ();
}
//candidate textures can now be used
display->currentTexture = display->candidateTexture;
display->currentTexture_u = display->candidateTexture_u;
display->currentTexture_v = display->candidateTexture_v;
display->currentVideo_format = display->candidateVideo_format;
display->currentTextureWidth = display->candidateTextureWidth;
display->currentTextureHeight = display->candidateTextureHeight;
}
@ -1909,6 +1857,18 @@ gst_gl_display_draw_texture (GstGLDisplay* display)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->fbo);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->textureFBO);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
display->textureFBOWidth, display->textureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//attach the texture to the FBO to renderer to
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, display->textureFBO, 0);
glPushAttrib(GL_VIEWPORT_BIT);
glMatrixMode(GL_PROJECTION);
@ -2079,6 +2039,12 @@ gst_gl_display_draw_texture (GstGLDisplay* display)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
checkFramebufferStatus();
gst_gl_display_del_texture (display, &display->currentTexture);
if (display->currentTexture_u)
gst_gl_display_del_texture (display, &display->currentTexture_u);
if (display->currentTexture_v)
gst_gl_display_del_texture (display, &display->currentTexture_v);
}
@ -2381,6 +2347,42 @@ gst_gl_display_fill_video (GstGLDisplay* display)
}
/* Generate a texture if no one is available in the pool */
void
gst_gl_display_gen_texture (GstGLDisplay* display, guint* pTexture)
{
//check if there is a texture available in the pool
GstGLDisplayTex* tex = g_queue_pop_head (display->texturePool);
if (tex)
{
*pTexture = tex->texture;
g_free (tex);
}
//otherwise one more texture is generated
//note that this new texture is added in the pool
//only after being used
else
glGenTextures (1, pTexture);
}
/* Delete a texture, actually the texture is just added to the pool */
void
gst_gl_display_del_texture (GstGLDisplay* display, guint* pTexture)
{
//Each existing texture is destroyed only when the pool is destroyed
//The pool of textures is deleted in the GstGLDisplay destructor
//contruct a texture pool element
GstGLDisplayTex* tex = g_new0 (GstGLDisplayTex, 1);
tex->texture = *pTexture;
*pTexture = 0;
//add tex to the pool, it makes texture allocation reusable
g_queue_push_tail (display->texturePool, tex);
}
/* called by gst_gl_display_glutCreateWindow (in the glut thread) */
GLhandleARB
gst_gl_display_loadGLSLprogram (gchar* textFProgram)
@ -2427,10 +2429,10 @@ checkFramebufferStatus(void)
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
GST_DEBUG("GL_FRAMEBUFFER_UNSUPPORTED_EXT");
g_print ("GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
break;
default:
GST_DEBUG("General FBO error");
g_print ("General FBO error\n");
}
}

View file

@ -74,8 +74,6 @@ typedef struct _GstGLDisplayMsg {
//Texture pool elements
typedef struct _GstGLDisplayTex {
GLuint texture;
GLuint texture_u;
GLuint texture_v;
} GstGLDisplayTex;
@ -133,9 +131,9 @@ struct _GstGLDisplay {
//filter frame buffer object (GL -> GL)
GLuint requestedFBO;
GLuint requestedDepthBuffer;
GLuint requestedTextureFBO;
GLuint requestedTextureFBOWidth;
GLuint requestedTextureFBOHeight;
GLuint usedFBO;
GLuint usedDepthBuffer;
GLuint usedTextureFBO;
@ -150,38 +148,23 @@ struct _GstGLDisplay {
GLuint inputTexture;
GLuint rejectedFBO;
GLuint rejectedDepthBuffer;
GLuint rejectedTextureFBO;
//displayed texture
GLuint displayedTexture;
GLuint displayedTextureWidth;
GLuint displayedTextureHeight;
GLuint requestedTexture;
GLuint requestedTexture_u;
GLuint requestedTexture_v;
GstVideoFormat requestedVideo_format;
GLuint requestedTextureWidth;
GLuint requestedTextureHeight;
GLuint candidateTexture;
GLuint candidateTexture_u;
GLuint candidateTexture_v;
GstVideoFormat candidateVideo_format;
GLuint candidateTextureWidth;
GLuint candidateTextureHeight;
gpointer candidateData;
GLuint preparedTexture;
GLuint currentTexture;
GLuint currentTexture_u;
GLuint currentTexture_v;
GstVideoFormat currentVideo_format;
GLuint currentTextureWidth;
GLuint currentTextureHeight;
GstVideoFormat currentVideo_format;
gpointer currentData;
GLuint textureTrash;
GLuint textureTrash_u;
GLuint textureTrash_v;
//output frame buffer object (GL -> video)
GLuint videoFBO;
@ -257,20 +240,17 @@ void gst_gl_display_setClientReshapeCallback (GstGLDisplay* display, CRCB cb);
void gst_gl_display_setClientDrawCallback (GstGLDisplay* display, CDCB cb);
void gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible);
void gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height);
void gst_gl_display_textureRequested (GstGLDisplay* display, GstVideoFormat format,
gint width, gint height, guint* texture,
guint* texture_u, guint* texture_v);
void gst_gl_display_textureChanged (GstGLDisplay* display, GstVideoFormat video_format,
GLuint texture, GLuint texture_u, GLuint texture_v,
gint width, gint height, gpointer data, GLuint* outputTexture);
void gst_gl_display_clearTexture (GstGLDisplay* display, guint texture,
guint texture_u, guint texture_v);
void gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture);
void gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format,
gint video_width, gint video_height, gpointer data,
guint gl_width, guint gl_height, guint pTexture);
void gst_gl_display_clearTexture (GstGLDisplay* display, guint texture);
void gst_gl_display_videoChanged (GstGLDisplay* display, GstVideoFormat video_format,
gint width, gint height, GLuint recordedTexture, gpointer data);
gboolean gst_gl_display_postRedisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
void gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
guint* fbo, guint* depthbuffer, guint* texture);
guint* fbo, guint* depthbuffer);
void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
guint fbo, guint depthbuffer, guint textureFBO, GLCB cb,
guint inputTextureWidth, guint inputTextureHeight, guint inputTexture,
@ -279,7 +259,7 @@ void gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint t
guint fbo, guint depthbuffer, guint textureFBO, GLCB2 cb,
gpointer* p1, gpointer* p2);
void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
guint depthbuffer, guint texture);
guint depthbuffer);
void gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height);
void gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader);
void gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader);

View file

@ -157,16 +157,14 @@ gst_gl_filter_reset (GstGLFilter* filter)
{
//blocking call, delete the FBO
gst_gl_display_rejectFBO (filter->display, filter->fbo,
filter->depthbuffer, filter->texture);
filter->depthbuffer);
g_object_unref (filter->display);
filter->display = NULL;
}
filter->video_format = GST_VIDEO_FORMAT_UNKNOWN;
filter->width = 0;
filter->height = 0;
filter->fbo = 0;
filter->depthbuffer = 0;
filter->texture = 0;
}
static gboolean
@ -221,14 +219,13 @@ static gboolean
gst_gl_filter_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
guint* size)
{
gboolean ret;
GstVideoFormat video_format;
gint width;
gint height;
gboolean ret = FALSE;
gint width = 0;
gint height = 0;
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret)
*size = gst_gl_buffer_format_get_size (video_format, width, height);
*size = gst_gl_buffer_get_size (width, height);
return TRUE;
}
@ -251,17 +248,14 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans,
//blocking call, generate a FBO
gst_gl_display_requestFBO (filter->display, filter->width, filter->height,
&filter->fbo, &filter->depthbuffer, &filter->texture);
&filter->fbo, &filter->depthbuffer);
if (filter_class->onInitFBO)
filter_class->onInitFBO (filter);
}
gl_outbuf = gst_gl_buffer_new_from_video_format (filter->display,
filter->video_format,
filter->width, filter->height,
filter->width, filter->height,
gl_inbuf->width, gl_inbuf->height);
gl_outbuf = gst_gl_buffer_new (filter->display,
filter->width, filter->height);
*buf = GST_BUFFER (gl_outbuf);
gst_buffer_set_caps (*buf, caps);
@ -277,8 +271,7 @@ gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps,
gboolean ret = FALSE;
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter);
ret = gst_gl_buffer_format_parse_caps (outcaps, &filter->video_format,
&filter->width, &filter->height);
ret = gst_gl_buffer_parse_caps (outcaps, &filter->width, &filter->height);
if (filter_class->set_caps)
filter_class->set_caps (filter, incaps, outcaps);

View file

@ -54,12 +54,11 @@ struct _GstGLFilter
GstPad *sinkpad;
GstGLDisplay *display;
GstVideoFormat video_format;
gint width;
gint height;
guint fbo;
guint depthbuffer;
guint texture;
};
struct _GstGLFilterClass

View file

@ -104,9 +104,9 @@ gst_gl_colorscale_base_init (gpointer klass)
}
static void
gst_gl_colorscale_class_init (GstGLColorscaleClass * klass)
gst_gl_colorscale_class_init (GstGLColorscaleClass* klass)
{
GObjectClass *gobject_class;
GObjectClass* gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_colorscale_set_property;
@ -123,7 +123,7 @@ gst_gl_colorscale_class_init (GstGLColorscaleClass * klass)
}
static void
gst_gl_colorscale_init (GstGLColorscale* colorscale, GstGLColorscaleClass * klass)
gst_gl_colorscale_init (GstGLColorscale* colorscale, GstGLColorscaleClass* klass)
{
gst_gl_colorscale_reset (colorscale);
}
@ -370,15 +370,15 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
{
GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt);
gboolean ret = FALSE;
static gint glcontext_y = 0;
static gint y_pos = 0;
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
ret = gst_video_format_parse_caps (outcaps, &colorscale->outVideo_format,
&colorscale->outWidth, &colorscale->outHeight);
ret = gst_video_format_parse_caps (outcaps, &colorscale->output_video_format,
&colorscale->output_video_width, &colorscale->output_video_height);
ret |= gst_video_format_parse_caps (incaps, &colorscale->inVideo_format,
&colorscale->inWidth, &colorscale->inHeight);
ret |= gst_video_format_parse_caps (incaps, &colorscale->input_video_format,
&colorscale->input_video_width, &colorscale->input_video_height);
if (!ret)
{
@ -390,12 +390,13 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
//init unvisible opengl context
gst_gl_display_initGLContext (colorscale->display,
50, glcontext_y++ * (colorscale->inHeight+50) + 50,
colorscale->inWidth, colorscale->inHeight,
colorscale->inWidth, colorscale->inHeight, 0, FALSE);
50, y_pos++ * (colorscale->output_video_height+50) + 50,
colorscale->output_video_width, colorscale->output_video_height,
colorscale->output_video_width, colorscale->output_video_height, 0, FALSE);
//blocking call
gst_gl_display_initDonwloadFBO (colorscale->display, colorscale->outWidth, colorscale->outHeight);
gst_gl_display_initDonwloadFBO (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height);
return ret;
}
@ -412,11 +413,9 @@ gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl"))
{
GstVideoFormat video_format;
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret)
*size = gst_gl_buffer_format_get_size (video_format, width, height);
*size = gst_gl_buffer_get_size (width, height);
}
else
{
@ -437,26 +436,26 @@ gst_gl_colorscale_transform (GstBaseTransform* trans, GstBuffer* inbuf,
GstGLColorscale* colorscale = GST_GL_COLORSCALE (trans);
//blocking call
GstGLBuffer* gl_tembuf = gst_gl_buffer_new_from_video_format (colorscale->display,
colorscale->inVideo_format,
colorscale->outWidth, colorscale->outHeight,
colorscale->inWidth, colorscale->inHeight,
colorscale->inWidth, colorscale->inHeight);
GstGLBuffer* gl_temp_buffer = gst_gl_buffer_new (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height);
GST_DEBUG ("input size %p size %d",
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
//blocking call
gst_gl_display_textureChanged(colorscale->display, colorscale->inVideo_format,
gl_tembuf->texture, gl_tembuf->texture_u, gl_tembuf->texture_v,
gl_tembuf->width, gl_tembuf->height, GST_BUFFER_DATA (inbuf), &gl_tembuf->textureGL);
gst_gl_display_do_upload (colorscale->display, colorscale->input_video_format,
colorscale->input_video_width, colorscale->input_video_height, GST_BUFFER_DATA (inbuf),
gl_temp_buffer->width, gl_temp_buffer->height, gl_temp_buffer->texture);
GST_DEBUG ("output size %p size %d",
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
//blocking call
gst_gl_display_videoChanged(colorscale->display, colorscale->outVideo_format,
gl_tembuf->width, gl_tembuf->height, gl_tembuf->textureGL, GST_BUFFER_DATA (outbuf));
gst_gl_display_videoChanged(colorscale->display, colorscale->output_video_format,
gl_temp_buffer->width, gl_temp_buffer->height, gl_temp_buffer->texture,
GST_BUFFER_DATA (outbuf));
gst_buffer_unref (gl_temp_buffer);
return GST_FLOW_OK;
}

View file

@ -48,12 +48,14 @@ struct _GstGLColorscale
GstPad *sinkpad;
GstGLDisplay *display;
GstVideoFormat inVideo_format;
gint inWidth;
gint inHeight;
GstVideoFormat outVideo_format;
gint outWidth;
gint outHeight;
GstVideoFormat input_video_format;
gint input_video_width;
gint input_video_height;
GstVideoFormat output_video_format;
gint output_video_width;
gint output_video_height;
};
struct _GstGLColorscaleClass

View file

@ -270,11 +270,9 @@ gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl"))
{
GstVideoFormat video_format;
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret)
*size = gst_gl_buffer_format_get_size (video_format, width, height);
*size = gst_gl_buffer_get_size (width, height);
}
else
{
@ -309,7 +307,7 @@ gst_gl_download_transform (GstBaseTransform* trans, GstBuffer* inbuf,
//blocking call
gst_gl_display_videoChanged(download->display, download->video_format,
gl_inbuf->width, gl_inbuf->height, gl_inbuf->textureGL, GST_BUFFER_DATA (outbuf));
gl_inbuf->width, gl_inbuf->height, gl_inbuf->texture, GST_BUFFER_DATA (outbuf));
return GST_FLOW_OK;
}

View file

@ -56,6 +56,7 @@ static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter,
static void gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter);
static gboolean gst_gl_filter_app_filter (GstGLFilter* filter,
GstGLBuffer* inbuf, GstGLBuffer* outbuf);
static void gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader);
static void
@ -164,14 +165,39 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
{
//GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter);
outbuf->width = inbuf->width;
outbuf->height = inbuf->height;
outbuf->texture = inbuf->texture;
outbuf->texture_u = inbuf->texture_u;
outbuf->texture_v = inbuf->texture_v;
outbuf->widthGL = inbuf->widthGL;
outbuf->heightGL = inbuf->heightGL;
outbuf->textureGL = inbuf->textureGL;
//blocking call, use a FBO
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback,
inbuf->width, inbuf->height, inbuf->texture, 0);
return TRUE;
}
//opengl scene, params: input texture (not the output filter->texture)
static void
gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader)
{
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_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glBegin (GL_QUADS);
glTexCoord2i (0, 0);
glVertex2f (-1.0f, -1.0f);
glTexCoord2i (width, 0);
glVertex2f (1.0f, -1.0f);
glTexCoord2i (width, height);
glVertex2f (1.0f, 1.0f);
glTexCoord2i (0, height);
glVertex2f (-1.0f, 1.0f);
glEnd ();
}

View file

@ -114,17 +114,10 @@ gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
{
//GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE(filter);
//blocking call, generate a FBO
//blocking call, use a FBO
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_cube_callback,
inbuf->width, inbuf->height, inbuf->textureGL, 0);
outbuf->width = inbuf->width;
outbuf->height = inbuf->height;
outbuf->texture = inbuf->texture;
outbuf->texture_u = inbuf->texture_u;
outbuf->texture_v = inbuf->texture_v;
outbuf->textureGL = filter->texture;
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_cube_callback,
inbuf->width, inbuf->height, inbuf->texture, 0);
return TRUE;
}

View file

@ -170,15 +170,8 @@ gst_gl_filter_edge_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
//blocking call, generate a FBO
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_edge_callback,
inbuf->width, inbuf->height, inbuf->textureGL, edge_filter->handleShader);
outbuf->width = inbuf->width;
outbuf->height = inbuf->height;
outbuf->texture = inbuf->texture;
outbuf->texture_u = inbuf->texture_u;
outbuf->texture_v = inbuf->texture_v;
outbuf->textureGL = filter->texture;
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_edge_callback,
inbuf->width, inbuf->height, inbuf->texture, edge_filter->handleShader);
return TRUE;
}
@ -214,7 +207,6 @@ gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleA
glTexCoord2i (width, height);
glVertex2f (1.0f, 1.0f);
glTexCoord2i (0, height);
glVertex2f (-1.0f, 1.0f);
glVertex2f (-1.0f, 1.0f);
glEnd ();
}

View file

@ -444,15 +444,13 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
}
//blocking call
gl_buffer = gst_gl_buffer_new_from_video_format (glimage_sink->display,
glimage_sink->format, glimage_sink->width, glimage_sink->height,
glimage_sink->width, glimage_sink->height,
gl_buffer = gst_gl_buffer_new (glimage_sink->display,
glimage_sink->width, glimage_sink->height);
//blocking call
gst_gl_display_textureChanged(glimage_sink->display, glimage_sink->format,
gl_buffer->texture, gl_buffer->texture_u, gl_buffer->texture_v,
gl_buffer->width, gl_buffer->height, GST_BUFFER_DATA (buf), &gl_buffer->textureGL);
gst_gl_display_do_upload(glimage_sink->display, glimage_sink->format,
glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf),
gl_buffer->width, gl_buffer->height, gl_buffer->texture);
//gl_buffer is created in this block, so the gl buffer is already referenced
}
@ -469,7 +467,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
//redisplay opengl scene
isAlive = gst_gl_display_postRedisplay (glimage_sink->display,
gl_buffer->textureGL, gl_buffer->widthGL, gl_buffer->heightGL);
gl_buffer->texture, gl_buffer->width, gl_buffer->height);
if (isAlive)
return GST_FLOW_OK;

View file

@ -369,7 +369,7 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps)
gltestsrc->width, gltestsrc->height, 0, FALSE);
gst_gl_display_requestFBO (gltestsrc->display, gltestsrc->width, gltestsrc->height,
&gltestsrc->fbo, &gltestsrc->depthbuffer, &gltestsrc->texture);
&gltestsrc->fbo, &gltestsrc->depthbuffer);
}
return res;
}
@ -543,10 +543,7 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer)
GST_LOG_OBJECT (src, "creating buffer %dx%d image for frame %d",
src->width, src->height, (gint) src->n_frames);
outbuf = gst_gl_buffer_new_from_video_format (src->display,
GST_VIDEO_FORMAT_UNKNOWN,
src->width, src->height,
src->width, src->height,
outbuf = gst_gl_buffer_new (src->display,
src->width, src->height);
gst_buffer_set_caps (GST_BUFFER (outbuf),
@ -562,9 +559,8 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer)
//blocking call, generate a FBO
gst_gl_display_useFBO2 (src->display, src->width, src->height,
src->fbo, src->depthbuffer, src->texture, (GLCB2)src->make_image,
src->fbo, src->depthbuffer, outbuf->texture, (GLCB2)src->make_image,
(gpointer*)src, (gpointer*)outbuf);
outbuf->textureGL = src->texture;
GST_BUFFER_TIMESTAMP (GST_BUFFER (outbuf)) =
src->timestamp_offset + src->running_time;
@ -631,7 +627,7 @@ gst_gl_test_src_stop (GstBaseSrc* basesrc)
{
//blocking call, delete the FBO
gst_gl_display_rejectFBO (src->display, src->fbo,
src->depthbuffer, src->texture);
src->depthbuffer);
g_object_unref (src->display);
src->display = NULL;
}

View file

@ -98,7 +98,6 @@ struct _GstGLTestSrc {
guint fbo;
guint depthbuffer;
guint texture;
/* private */
GstGLDisplay *display;

View file

@ -377,54 +377,53 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
GstGLUpload* upload = GST_GL_UPLOAD (bt);
gboolean ret = FALSE;
GstVideoFormat video_format = GST_VIDEO_FORMAT_UNKNOWN;
static gint glcontext_y = 0;
static gint y_pos = 0;
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
ret = gst_video_format_parse_caps (outcaps, &video_format,
&upload->outWidth, &upload->outHeight);
&upload->gl_width, &upload->gl_height);
ret |= gst_video_format_parse_caps (incaps, &upload->video_format,
&upload->inWidth, &upload->inHeight);
&upload->video_width, &upload->video_height);
if (!ret)
{
GST_DEBUG ("bad caps");
return FALSE;
GST_DEBUG ("caps connot be parsed");
return FALSE;
}
//we have video and gl size, we can now init OpenGL stuffs
upload->display = gst_gl_display_new ();
//init unvisible opengl context
gst_gl_display_initGLContext (upload->display,
50, glcontext_y++ * (upload->inHeight+50) + 50,
upload->inWidth, upload->inHeight,
upload->inWidth, upload->inHeight, 0, FALSE);
50, y_pos++ * (upload->gl_height+50) + 50,
upload->gl_width, upload->gl_height,
upload->gl_width, upload->gl_height, 0, FALSE);
return ret;
}
static gboolean
gst_gl_upload_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
guint* size)
guint* size)
{
gboolean ret;
GstStructure *structure;
gint width;
gint height;
gboolean ret = FALSE;
GstStructure* structure = NULL;
gint width = 0;
gint height = 0;
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl"))
{
GstVideoFormat video_format;
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret)
*size = gst_gl_buffer_format_get_size (video_format, width, height);
*size = gst_gl_buffer_get_size (width, height);
}
else
{
GstVideoFormat video_format;
GstVideoFormat video_format = GST_VIDEO_FORMAT_UNKNOWN;
ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
if (ret)
@ -438,17 +437,12 @@ static GstFlowReturn
gst_gl_upload_prepare_output_buffer (GstBaseTransform* trans,
GstBuffer* input, gint size, GstCaps* caps, GstBuffer** buf)
{
GstGLUpload* upload;
GstGLBuffer* gl_outbuf;
GstGLUpload* upload = GST_GL_UPLOAD (trans);
upload = GST_GL_UPLOAD (trans);
//blocking call, request a texture and attach it to the upload FBO
GstGLBuffer* gl_outbuf = gst_gl_buffer_new (upload->display,
upload->gl_width, upload->gl_height);
//blocking call
gl_outbuf = gst_gl_buffer_new_from_video_format (upload->display,
upload->video_format,
upload->outWidth, upload->outHeight,
upload->inWidth, upload->inHeight,
upload->inWidth, upload->inHeight);
*buf = GST_BUFFER (gl_outbuf);
gst_buffer_set_caps (*buf, caps);
@ -460,18 +454,19 @@ static GstFlowReturn
gst_gl_upload_transform (GstBaseTransform* trans, GstBuffer* inbuf,
GstBuffer* outbuf)
{
GstGLUpload* upload;
GstGLUpload* upload = GST_GL_UPLOAD (trans);
GstGLBuffer* gl_outbuf = GST_GL_BUFFER (outbuf);
upload = GST_GL_UPLOAD (trans);
GST_DEBUG ("making graphic %p size %d",
GST_DEBUG ("Upload %p size %d",
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
//blocking call
gst_gl_display_textureChanged(upload->display, upload->video_format,
gl_outbuf->texture, gl_outbuf->texture_u, gl_outbuf->texture_v,
gl_outbuf->width, gl_outbuf->height, GST_BUFFER_DATA (inbuf), &gl_outbuf->textureGL);
//blocking call.
//Depending on the colorspace, video is upload into several textures.
//However, there is only one output texture. The one attached
//to the upload FBO.
gst_gl_display_do_upload (upload->display, upload->video_format,
upload->video_width, upload->video_height, GST_BUFFER_DATA (inbuf),
gl_outbuf->width, gl_outbuf->height, gl_outbuf->texture);
return GST_FLOW_OK;
}

View file

@ -48,11 +48,12 @@ struct _GstGLUpload
GstPad *sinkpad;
GstGLDisplay *display;
GstVideoFormat video_format;
gint inWidth;
gint inHeight;
gint outWidth;
gint outHeight;
gint video_width;
gint video_height;
gint gl_width;
gint gl_height;
};
struct _GstGLUploadClass