mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
[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:
parent
04946b3f1d
commit
e7f5afee87
17 changed files with 337 additions and 393 deletions
|
@ -30,8 +30,7 @@ static void
|
||||||
gst_gl_buffer_finalize (GstGLBuffer* buffer)
|
gst_gl_buffer_finalize (GstGLBuffer* buffer)
|
||||||
{
|
{
|
||||||
//wait clear textures end, blocking call
|
//wait clear textures end, blocking call
|
||||||
gst_gl_display_clearTexture (buffer->display, buffer->texture,
|
gst_gl_display_clearTexture (buffer->display, buffer->texture);
|
||||||
buffer->texture_u, buffer->texture_v);
|
|
||||||
|
|
||||||
g_object_unref (buffer->display);
|
g_object_unref (buffer->display);
|
||||||
|
|
||||||
|
@ -43,15 +42,10 @@ static void
|
||||||
gst_gl_buffer_init (GstGLBuffer* buffer, gpointer g_class)
|
gst_gl_buffer_init (GstGLBuffer* buffer, gpointer g_class)
|
||||||
{
|
{
|
||||||
buffer->display = NULL;
|
buffer->display = NULL;
|
||||||
buffer->video_format = 0;
|
|
||||||
buffer->width = 0;
|
buffer->width = 0;
|
||||||
buffer->height = 0;
|
buffer->height = 0;
|
||||||
buffer->texture = 0;
|
buffer->texture = 0;
|
||||||
buffer->texture_u = 0;
|
|
||||||
buffer->texture_v = 0;
|
|
||||||
buffer->widthGL = 0;
|
|
||||||
buffer->heightGL = 0;
|
|
||||||
buffer->textureGL = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -92,57 +86,43 @@ gst_gl_buffer_get_type (void)
|
||||||
|
|
||||||
|
|
||||||
GstGLBuffer*
|
GstGLBuffer*
|
||||||
gst_gl_buffer_new_from_video_format (GstGLDisplay* display,
|
gst_gl_buffer_new (GstGLDisplay* display,
|
||||||
GstVideoFormat video_format, gint context_width, gint context_height,
|
gint gl_width, gint gl_height)
|
||||||
gint widthGL, gint heightGL,
|
|
||||||
gint width, gint 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);
|
gl_buffer->display = g_object_ref (display);
|
||||||
g_return_val_if_fail (display != NULL, NULL);
|
gl_buffer->width = gl_width;
|
||||||
g_return_val_if_fail (width > 0, NULL);
|
gl_buffer->height = gl_height;
|
||||||
g_return_val_if_fail (height > 0, NULL);
|
|
||||||
|
|
||||||
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);
|
//blocking call, request a texture and attach it to the upload FBO
|
||||||
buffer->width = width;
|
gst_gl_display_prepare_texture (gl_buffer->display, &gl_buffer->texture) ;
|
||||||
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, init texture
|
return gl_buffer;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
gint
|
||||||
gst_gl_buffer_format_get_size (GstVideoFormat format, int width, int height)
|
gst_gl_buffer_get_size (gint width, gint height)
|
||||||
{
|
{
|
||||||
/* this is not strictly true, but it's used for compatibility with
|
//this is not strictly true, but it's used for compatibility with
|
||||||
* queue and BaseTransform */
|
//queue and BaseTransform
|
||||||
return width * height * 4;
|
return width * height * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_buffer_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
|
gst_gl_buffer_parse_caps (GstCaps* caps, gint* width, gint* height)
|
||||||
gint* width, gint* height)
|
|
||||||
{
|
{
|
||||||
GstStructure *structure;
|
GstStructure* structure = gst_caps_get_structure (caps, 0);
|
||||||
gboolean ret;
|
gboolean ret = gst_structure_has_name (structure, "video/x-raw-gl");
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
if (!ret)
|
||||||
|
return ret;
|
||||||
if (!gst_structure_has_name (structure, "video/x-raw-gl"))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ret = gst_structure_get_int (structure, "width", width);
|
ret = gst_structure_get_int (structure, "width", width);
|
||||||
ret &= gst_structure_get_int (structure, "height", height);
|
ret &= gst_structure_get_int (structure, "height", height);
|
||||||
|
|
|
@ -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_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))
|
#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 {
|
struct _GstGLBuffer {
|
||||||
GstBuffer buffer;
|
GstBuffer buffer;
|
||||||
|
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
|
|
||||||
GstVideoFormat video_format;
|
|
||||||
|
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLuint texture_u;
|
|
||||||
GLuint texture_v;
|
|
||||||
|
|
||||||
gint widthGL;
|
|
||||||
gint heightGL;
|
|
||||||
GLuint textureGL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_gl_buffer_get_type (void);
|
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_ref(x) ((GstGLBuffer *)(gst_buffer_ref((GstBuffer *)(x))))
|
||||||
#define gst_gl_buffer_unref(x) (gst_buffer_unref((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,
|
GstGLBuffer* gst_gl_buffer_new (GstGLDisplay* display, gint gl_width, gint gl_height);
|
||||||
gint context_width, gint context_height,
|
gint gst_gl_buffer_get_size (gint width, gint height);
|
||||||
gint widthGL, gint heightGL,
|
gboolean gst_gl_buffer_parse_caps (GstCaps* caps, gint* width, gint* height);
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
#define GST_GL_VIDEO_CAPS \
|
#define GST_GL_VIDEO_CAPS \
|
||||||
|
|
|
@ -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_texture (GstGLDisplay* display);
|
||||||
void gst_gl_display_draw_graphic (GstGLDisplay* display);
|
void gst_gl_display_draw_graphic (GstGLDisplay* display);
|
||||||
void gst_gl_display_fill_video (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);
|
GLhandleARB gst_gl_display_loadGLSLprogram (gchar* textFProgram);
|
||||||
void checkFramebufferStatus(void);
|
void checkFramebufferStatus(void);
|
||||||
GST_BOILERPLATE (GstGLDisplay, gst_gl_display, GObject, G_TYPE_OBJECT);
|
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->requestedFBO = 0;
|
||||||
display->requestedDepthBuffer = 0;
|
display->requestedDepthBuffer = 0;
|
||||||
display->requestedTextureFBO = 0;
|
|
||||||
display->requestedTextureFBOWidth = 0;
|
display->requestedTextureFBOWidth = 0;
|
||||||
display->requestedTextureFBOHeight = 0;
|
display->requestedTextureFBOHeight = 0;
|
||||||
display->usedFBO = 0;
|
display->usedFBO = 0;
|
||||||
|
@ -140,37 +141,22 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
display->inputTexture = 0;
|
display->inputTexture = 0;
|
||||||
display->rejectedFBO = 0;
|
display->rejectedFBO = 0;
|
||||||
display->rejectedDepthBuffer = 0;
|
display->rejectedDepthBuffer = 0;
|
||||||
display->rejectedTextureFBO = 0;
|
|
||||||
|
|
||||||
display->displayedTexture = 0;
|
display->displayedTexture = 0;
|
||||||
display->displayedTextureWidth = 0;
|
display->displayedTextureWidth = 0;
|
||||||
display->displayedTextureHeight = 0;
|
display->displayedTextureHeight = 0;
|
||||||
|
|
||||||
display->requestedTexture = 0;
|
display->preparedTexture = 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->currentTexture = 0;
|
display->currentTexture = 0;
|
||||||
display->currentTexture_u = 0;
|
display->currentTexture_u = 0;
|
||||||
display->currentTexture_v = 0;
|
display->currentTexture_v = 0;
|
||||||
display->currentVideo_format = 0;
|
|
||||||
display->currentTextureWidth = 0;
|
display->currentTextureWidth = 0;
|
||||||
display->currentTextureHeight = 0;
|
display->currentTextureHeight = 0;
|
||||||
|
display->currentVideo_format = 0;
|
||||||
|
display->currentData = NULL;
|
||||||
|
|
||||||
display->textureTrash = 0;
|
display->textureTrash = 0;
|
||||||
display->textureTrash_u = 0;
|
|
||||||
display->textureTrash_v = 0;
|
|
||||||
|
|
||||||
display->videoFBO = 0;
|
display->videoFBO = 0;
|
||||||
display->videoDepthBuffer = 0;
|
display->videoDepthBuffer = 0;
|
||||||
|
@ -497,10 +483,10 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
|
||||||
{
|
{
|
||||||
//OpenGL > 2.1.0 and Glew > 1.5.0
|
//OpenGL > 2.1.0 and Glew > 1.5.0
|
||||||
GString* opengl_version = g_string_truncate (g_string_new ((gchar*) glGetString (GL_VERSION)), 3);
|
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;
|
gint opengl_version_minor = 0;
|
||||||
GString* glew_version = g_string_truncate (g_string_new ((gchar*) glewGetString (GLEW_VERSION)), 3);
|
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;
|
gint glew_version_minor = 0;
|
||||||
|
|
||||||
sscanf(opengl_version->str, "%d.%d", &opengl_version_major, &opengl_version_minor);
|
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)
|
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);
|
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", glutWinId);
|
||||||
|
|
||||||
//-- init intput frame buffer object (video -> GL)
|
//-- init intput frame buffer object (video -> GL)
|
||||||
|
@ -540,29 +529,29 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
|
||||||
display->textureFBOWidth, display->textureFBOHeight);
|
display->textureFBOWidth, display->textureFBOHeight);
|
||||||
|
|
||||||
//setup a texture to render to
|
//setup a texture to render to
|
||||||
glGenTextures (1, &display->textureFBO);
|
glGenTextures (1, &fake_texture);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->textureFBO);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
||||||
display->textureFBOWidth, display->textureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
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
|
//attach the texture to the FBO to renderer to
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
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
|
//attach the depth render buffer to the FBO
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
GL_RENDERBUFFER_EXT, display->depthBuffer);
|
GL_RENDERBUFFER_EXT, display->depthBuffer);
|
||||||
|
|
||||||
|
checkFramebufferStatus();
|
||||||
|
|
||||||
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
|
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
|
||||||
GL_FRAMEBUFFER_COMPLETE_EXT);
|
GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||||
|
|
||||||
//unbind the FBO
|
//unbind the FBO
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
|
glDeleteTextures (1, &fake_texture);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -621,7 +610,6 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
|
||||||
{
|
{
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
|
|
||||||
|
|
||||||
if (GLEW_EXT_framebuffer_object)
|
if (GLEW_EXT_framebuffer_object)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", display->glutWinId);
|
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,
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
GL_RENDERBUFFER_EXT, display->graphicDepthBuffer);
|
GL_RENDERBUFFER_EXT, display->graphicDepthBuffer);
|
||||||
|
|
||||||
|
checkFramebufferStatus();
|
||||||
|
|
||||||
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
|
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
|
||||||
GL_FRAMEBUFFER_COMPLETE_EXT);
|
GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||||
|
|
||||||
|
@ -772,7 +762,9 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
|
||||||
static void
|
static void
|
||||||
gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
|
gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
|
||||||
{
|
{
|
||||||
|
//a texture must be attached to the FBO
|
||||||
|
guint fake_texture = 0;
|
||||||
|
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
|
|
||||||
//-- generate frame buffer object
|
//-- generate frame buffer object
|
||||||
|
@ -788,18 +780,14 @@ gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
|
||||||
display->requestedTextureFBOWidth, display->requestedTextureFBOHeight);
|
display->requestedTextureFBOWidth, display->requestedTextureFBOHeight);
|
||||||
|
|
||||||
//setup a texture to render to
|
//setup a texture to render to
|
||||||
glGenTextures (1, &display->requestedTextureFBO);
|
glGenTextures (1, &fake_texture);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->requestedTextureFBO);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fake_texture);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
||||||
display->requestedTextureFBOWidth, display->requestedTextureFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
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
|
//attach the texture to the FBO to renderer to
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
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
|
//attach the depth render buffer to the FBO
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
|
@ -811,6 +799,8 @@ gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
|
||||||
//unbind the FBO
|
//unbind the FBO
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
|
glDeleteTextures (1, &fake_texture);
|
||||||
|
|
||||||
g_cond_signal (display->cond_generateFBO);
|
g_cond_signal (display->cond_generateFBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,6 +814,19 @@ gst_gl_display_glutUseFBO (GstGLDisplay *display)
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO);
|
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);
|
glPushAttrib(GL_VIEWPORT_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -872,12 +875,24 @@ gst_gl_display_glutUseFBO2 (GstGLDisplay *display)
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO);
|
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);
|
glPushAttrib(GL_VIEWPORT_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
//gluPerspective(45, (gfloat)display->usedTextureFBOWidth/(gfloat)display->usedTextureFBOHeight, 0.1, 100);
|
|
||||||
gluOrtho2D(0.0, display->usedTextureFBOWidth, 0.0, display->usedTextureFBOHeight);
|
gluOrtho2D(0.0, display->usedTextureFBOWidth, 0.0, display->usedTextureFBOHeight);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
@ -919,10 +934,8 @@ gst_gl_display_glutDestroyFBO (GstGLDisplay* display)
|
||||||
|
|
||||||
glDeleteFramebuffersEXT (1, &display->rejectedFBO);
|
glDeleteFramebuffersEXT (1, &display->rejectedFBO);
|
||||||
glDeleteRenderbuffersEXT(1, &display->rejectedDepthBuffer);
|
glDeleteRenderbuffersEXT(1, &display->rejectedDepthBuffer);
|
||||||
glDeleteTextures (1, &display->rejectedTextureFBO);
|
|
||||||
display->rejectedFBO = 0;
|
display->rejectedFBO = 0;
|
||||||
display->rejectedDepthBuffer = 0;
|
display->rejectedDepthBuffer = 0;
|
||||||
display->rejectedTextureFBO = 0;
|
|
||||||
|
|
||||||
g_cond_signal (display->cond_destroyFBO);
|
g_cond_signal (display->cond_destroyFBO);
|
||||||
}
|
}
|
||||||
|
@ -970,7 +983,6 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
|
||||||
|
|
||||||
glDeleteFramebuffersEXT (1, &display->fbo);
|
glDeleteFramebuffersEXT (1, &display->fbo);
|
||||||
glDeleteRenderbuffersEXT(1, &display->depthBuffer);
|
glDeleteRenderbuffersEXT(1, &display->depthBuffer);
|
||||||
glDeleteTextures (1, &display->textureFBO);
|
|
||||||
|
|
||||||
glDeleteFramebuffersEXT (1, &display->graphicFBO);
|
glDeleteFramebuffersEXT (1, &display->graphicFBO);
|
||||||
glDeleteRenderbuffersEXT(1, &display->graphicDepthBuffer);
|
glDeleteRenderbuffersEXT(1, &display->graphicDepthBuffer);
|
||||||
|
@ -986,15 +998,8 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
|
||||||
while (g_queue_get_length (display->texturePool))
|
while (g_queue_get_length (display->texturePool))
|
||||||
{
|
{
|
||||||
GstGLDisplayTex* tex = g_queue_pop_head (display->texturePool);
|
GstGLDisplayTex* tex = g_queue_pop_head (display->texturePool);
|
||||||
|
|
||||||
//delete textures
|
|
||||||
glDeleteTextures (1, &tex->texture);
|
glDeleteTextures (1, &tex->texture);
|
||||||
if (tex->texture_u) {
|
g_free (tex);
|
||||||
glDeleteTextures (1, &tex->texture_u);
|
|
||||||
}
|
|
||||||
if (tex->texture_v) {
|
|
||||||
glDeleteTextures (1, &tex->texture_v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_remove (gst_gl_display_map, GINT_TO_POINTER (display->glutWinId));
|
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)
|
gst_gl_display_glutPrepareTexture (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
glutSetWindow (display->glutWinId);
|
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);
|
g_cond_signal (display->cond_make);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,6 +1052,7 @@ static void
|
||||||
gst_gl_display_glutUpdateTexture (GstGLDisplay * display)
|
gst_gl_display_glutUpdateTexture (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
|
gst_gl_display_make_texture (display);
|
||||||
gst_gl_display_fill_texture (display);
|
gst_gl_display_fill_texture (display);
|
||||||
gst_gl_display_draw_texture (display);
|
gst_gl_display_draw_texture (display);
|
||||||
g_cond_signal (display->cond_fill);
|
g_cond_signal (display->cond_fill);
|
||||||
|
@ -1054,25 +1061,10 @@ gst_gl_display_glutUpdateTexture (GstGLDisplay * display)
|
||||||
|
|
||||||
/* Called by the idle function */
|
/* Called by the idle function */
|
||||||
static void
|
static void
|
||||||
gst_gl_display_glutCleanTexture (GstGLDisplay * display)
|
gst_gl_display_glutCleanTexture (GstGLDisplay* display)
|
||||||
{
|
{
|
||||||
GstGLDisplayTex* tex = NULL;
|
|
||||||
|
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
|
gst_gl_display_del_texture (display, &display->textureTrash);
|
||||||
//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);
|
|
||||||
|
|
||||||
g_cond_signal (display->cond_clear);
|
g_cond_signal (display->cond_clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,55 +1340,40 @@ gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height)
|
||||||
|
|
||||||
/* Called by gstglbuffer */
|
/* Called by gstglbuffer */
|
||||||
void
|
void
|
||||||
gst_gl_display_textureRequested (GstGLDisplay* display, GstVideoFormat video_format,
|
gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture)
|
||||||
gint width, gint height, guint* texture,
|
|
||||||
guint* texture_u, guint* texture_v)
|
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
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);
|
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_PREPARE, display);
|
||||||
g_cond_wait (display->cond_make, display->mutex);
|
g_cond_wait (display->cond_make, display->mutex);
|
||||||
*texture = display->requestedTexture;
|
*pTexture = display->preparedTexture;
|
||||||
*texture_u = display->requestedTexture_u;
|
|
||||||
*texture_v = display->requestedTexture_v;
|
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Called by gst_gl elements */
|
/* Called by gst_gl elements */
|
||||||
void
|
void
|
||||||
gst_gl_display_textureChanged (GstGLDisplay* display, GstVideoFormat video_format,
|
gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format,
|
||||||
GLuint texture, GLuint texture_u, GLuint texture_v,
|
gint video_width, gint video_height, gpointer data,
|
||||||
gint width, gint height, gpointer data, GLuint* outputTexture)
|
guint gl_width, guint gl_height, guint pTexture)
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
display->candidateTexture = texture;
|
display->currentTextureWidth = video_width;
|
||||||
display->candidateTexture_u = texture_u;
|
display->currentTextureHeight = video_height;
|
||||||
display->candidateTexture_v = texture_v;
|
display->currentVideo_format = video_format;
|
||||||
display->candidateVideo_format = video_format;
|
display->currentData = data;
|
||||||
display->candidateTextureWidth = width;
|
display->textureFBO = pTexture;
|
||||||
display->candidateTextureHeight = height;
|
|
||||||
display->candidateData = data;
|
|
||||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CHANGE, display);
|
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CHANGE, display);
|
||||||
g_cond_wait (display->cond_fill, display->mutex);
|
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);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Called by gstglbuffer */
|
/* Called by gstglbuffer */
|
||||||
void
|
void
|
||||||
gst_gl_display_clearTexture (GstGLDisplay* display, guint texture,
|
gst_gl_display_clearTexture (GstGLDisplay* display, guint texture)
|
||||||
guint texture_u, guint texture_v)
|
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
display->textureTrash = texture;
|
display->textureTrash = texture;
|
||||||
display->textureTrash_u = texture_u;
|
|
||||||
display->textureTrash_v = texture_v;
|
|
||||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CLEAR, display);
|
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_CLEAR, display);
|
||||||
g_cond_wait (display->cond_clear, display->mutex);
|
g_cond_wait (display->cond_clear, display->mutex);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
@ -1446,7 +1423,7 @@ gst_gl_display_postRedisplay (GstGLDisplay* display, GLuint texture, gint width
|
||||||
/* Called by gst_gl elements */
|
/* Called by gst_gl elements */
|
||||||
void
|
void
|
||||||
gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
|
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);
|
gst_gl_display_lock (display);
|
||||||
display->requestedTextureFBOWidth = width;
|
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);
|
g_cond_wait (display->cond_generateFBO, display->mutex);
|
||||||
*fbo = display->requestedFBO;
|
*fbo = display->requestedFBO;
|
||||||
*depthbuffer = display->requestedDepthBuffer;
|
*depthbuffer = display->requestedDepthBuffer;
|
||||||
*texture = display->requestedTextureFBO;
|
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1497,6 +1473,8 @@ gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textur
|
||||||
display->usedTextureFBOWidth = textureFBOWidth;
|
display->usedTextureFBOWidth = textureFBOWidth;
|
||||||
display->usedTextureFBOHeight = textureFBOheight;
|
display->usedTextureFBOHeight = textureFBOheight;
|
||||||
display->glsceneFBO_cb2 = cb2;
|
display->glsceneFBO_cb2 = cb2;
|
||||||
|
display->p1 = p1;
|
||||||
|
display->p2 = p2;
|
||||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO2, display);
|
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO2, display);
|
||||||
g_cond_wait (display->cond_useFBO2, display->mutex);
|
g_cond_wait (display->cond_useFBO2, display->mutex);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
@ -1506,12 +1484,11 @@ gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textur
|
||||||
/* Called by gst_gl elements */
|
/* Called by gst_gl elements */
|
||||||
void
|
void
|
||||||
gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
|
gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
|
||||||
guint depthbuffer, guint texture)
|
guint depthbuffer)
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
display->rejectedFBO = fbo;
|
display->rejectedFBO = fbo;
|
||||||
display->rejectedDepthBuffer = depthbuffer;
|
display->rejectedDepthBuffer = depthbuffer;
|
||||||
display->rejectedTextureFBO = texture;
|
|
||||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELFBO, display);
|
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELFBO, display);
|
||||||
g_cond_wait (display->cond_destroyFBO, display->mutex);
|
g_cond_wait (display->cond_destroyFBO, display->mutex);
|
||||||
gst_gl_display_unlock (display);
|
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) */
|
/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */
|
||||||
void gst_gl_display_make_texture (GstGLDisplay * display)
|
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
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture);
|
||||||
if (g_queue_get_length (display->texturePool))
|
switch (display->currentVideo_format)
|
||||||
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) {
|
|
||||||
case GST_VIDEO_FORMAT_RGBx:
|
case GST_VIDEO_FORMAT_RGBx:
|
||||||
case GST_VIDEO_FORMAT_BGRx:
|
case GST_VIDEO_FORMAT_BGRx:
|
||||||
case GST_VIDEO_FORMAT_xRGB:
|
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_ABGR:
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
|
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;
|
break;
|
||||||
|
|
||||||
case GST_VIDEO_FORMAT_RGB:
|
case GST_VIDEO_FORMAT_RGB:
|
||||||
case GST_VIDEO_FORMAT_BGR:
|
case GST_VIDEO_FORMAT_BGR:
|
||||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
|
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;
|
break;
|
||||||
|
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
|
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
|
||||||
display->requestedTextureWidth, display->requestedTextureHeight,
|
width, height,
|
||||||
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
//one tex is available
|
gst_gl_display_gen_texture (display, &display->currentTexture_u);
|
||||||
if (tex)
|
|
||||||
display->requestedTexture_u = tex->texture_u;
|
|
||||||
else
|
|
||||||
glGenTextures (1, &display->requestedTexture_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,
|
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);
|
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
case GST_VIDEO_FORMAT_YV12:
|
case GST_VIDEO_FORMAT_YV12:
|
||||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
|
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
|
||||||
display->requestedTextureWidth, display->requestedTextureHeight,
|
width, height,
|
||||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
//one tex is available
|
gst_gl_display_gen_texture (display, &display->currentTexture_u);
|
||||||
if (tex)
|
|
||||||
display->requestedTexture_u = tex->texture_u;
|
|
||||||
else
|
|
||||||
glGenTextures (1, &display->requestedTexture_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,
|
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
|
||||||
GST_ROUND_UP_2 (display->requestedTextureWidth) / 2,
|
GST_ROUND_UP_2 (width) / 2,
|
||||||
GST_ROUND_UP_2 (display->requestedTextureHeight) / 2,
|
GST_ROUND_UP_2 (height) / 2,
|
||||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
//one tex is available
|
gst_gl_display_gen_texture (display, &display->currentTexture_v);
|
||||||
if (tex)
|
|
||||||
display->requestedTexture_v = tex->texture_v;
|
|
||||||
else
|
|
||||||
glGenTextures (1, &display->requestedTexture_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,
|
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
|
||||||
GST_ROUND_UP_2 (display->requestedTextureWidth) / 2,
|
GST_ROUND_UP_2 (width) / 2,
|
||||||
GST_ROUND_UP_2 (display->requestedTextureHeight) / 2,
|
GST_ROUND_UP_2 (height) / 2,
|
||||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
if (tex)
|
|
||||||
g_free (tex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */
|
/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */
|
||||||
void
|
void
|
||||||
gst_gl_display_fill_texture (GstGLDisplay * display)
|
gst_gl_display_fill_texture (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
GstVideoFormat video_format = display->candidateVideo_format;
|
gint width = display->currentTextureWidth;
|
||||||
gint width = display->candidateTextureWidth;
|
gint height = display->currentTextureHeight;
|
||||||
gint height = display->candidateTextureHeight;
|
GstVideoFormat video_format = display->currentVideo_format;
|
||||||
gpointer data = display->candidateData;
|
gpointer data = display->currentData;
|
||||||
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->candidateTexture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->currentTexture);
|
||||||
|
|
||||||
switch (video_format) {
|
switch (video_format) {
|
||||||
case GST_VIDEO_FORMAT_RGBx:
|
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,
|
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
|
||||||
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
|
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,
|
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
|
||||||
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);
|
||||||
|
@ -1873,14 +1830,14 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
|
||||||
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
|
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
|
||||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
|
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,
|
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
|
||||||
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
|
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
|
||||||
GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
||||||
(guint8 *) data +
|
(guint8 *) data +
|
||||||
gst_video_format_get_component_offset (video_format, offsetU, width, height));
|
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,
|
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
|
||||||
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
|
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
|
||||||
GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
||||||
|
@ -1891,15 +1848,6 @@ gst_gl_display_fill_texture (GstGLDisplay * display)
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
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);
|
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);
|
glPushAttrib(GL_VIEWPORT_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -2079,6 +2039,12 @@ gst_gl_display_draw_texture (GstGLDisplay* display)
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
checkFramebufferStatus();
|
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) */
|
/* called by gst_gl_display_glutCreateWindow (in the glut thread) */
|
||||||
GLhandleARB
|
GLhandleARB
|
||||||
gst_gl_display_loadGLSLprogram (gchar* textFProgram)
|
gst_gl_display_loadGLSLprogram (gchar* textFProgram)
|
||||||
|
@ -2427,10 +2429,10 @@ checkFramebufferStatus(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||||
GST_DEBUG("GL_FRAMEBUFFER_UNSUPPORTED_EXT");
|
g_print ("GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GST_DEBUG("General FBO error");
|
g_print ("General FBO error\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,6 @@ typedef struct _GstGLDisplayMsg {
|
||||||
//Texture pool elements
|
//Texture pool elements
|
||||||
typedef struct _GstGLDisplayTex {
|
typedef struct _GstGLDisplayTex {
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLuint texture_u;
|
|
||||||
GLuint texture_v;
|
|
||||||
} GstGLDisplayTex;
|
} GstGLDisplayTex;
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,9 +131,9 @@ struct _GstGLDisplay {
|
||||||
//filter frame buffer object (GL -> GL)
|
//filter frame buffer object (GL -> GL)
|
||||||
GLuint requestedFBO;
|
GLuint requestedFBO;
|
||||||
GLuint requestedDepthBuffer;
|
GLuint requestedDepthBuffer;
|
||||||
GLuint requestedTextureFBO;
|
|
||||||
GLuint requestedTextureFBOWidth;
|
GLuint requestedTextureFBOWidth;
|
||||||
GLuint requestedTextureFBOHeight;
|
GLuint requestedTextureFBOHeight;
|
||||||
|
|
||||||
GLuint usedFBO;
|
GLuint usedFBO;
|
||||||
GLuint usedDepthBuffer;
|
GLuint usedDepthBuffer;
|
||||||
GLuint usedTextureFBO;
|
GLuint usedTextureFBO;
|
||||||
|
@ -150,38 +148,23 @@ struct _GstGLDisplay {
|
||||||
GLuint inputTexture;
|
GLuint inputTexture;
|
||||||
GLuint rejectedFBO;
|
GLuint rejectedFBO;
|
||||||
GLuint rejectedDepthBuffer;
|
GLuint rejectedDepthBuffer;
|
||||||
GLuint rejectedTextureFBO;
|
|
||||||
|
|
||||||
//displayed texture
|
//displayed texture
|
||||||
GLuint displayedTexture;
|
GLuint displayedTexture;
|
||||||
GLuint displayedTextureWidth;
|
GLuint displayedTextureWidth;
|
||||||
GLuint displayedTextureHeight;
|
GLuint displayedTextureHeight;
|
||||||
|
|
||||||
GLuint requestedTexture;
|
GLuint preparedTexture;
|
||||||
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 currentTexture;
|
GLuint currentTexture;
|
||||||
GLuint currentTexture_u;
|
GLuint currentTexture_u;
|
||||||
GLuint currentTexture_v;
|
GLuint currentTexture_v;
|
||||||
GstVideoFormat currentVideo_format;
|
|
||||||
GLuint currentTextureWidth;
|
GLuint currentTextureWidth;
|
||||||
GLuint currentTextureHeight;
|
GLuint currentTextureHeight;
|
||||||
|
GstVideoFormat currentVideo_format;
|
||||||
|
gpointer currentData;
|
||||||
|
|
||||||
GLuint textureTrash;
|
GLuint textureTrash;
|
||||||
GLuint textureTrash_u;
|
|
||||||
GLuint textureTrash_v;
|
|
||||||
|
|
||||||
//output frame buffer object (GL -> video)
|
//output frame buffer object (GL -> video)
|
||||||
GLuint videoFBO;
|
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_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_textureRequested (GstGLDisplay* display, GstVideoFormat format,
|
void gst_gl_display_prepare_texture (GstGLDisplay* display, guint* pTexture);
|
||||||
gint width, gint height, guint* texture,
|
void gst_gl_display_do_upload (GstGLDisplay* display, GstVideoFormat video_format,
|
||||||
guint* texture_u, guint* texture_v);
|
gint video_width, gint video_height, gpointer data,
|
||||||
void gst_gl_display_textureChanged (GstGLDisplay* display, GstVideoFormat video_format,
|
guint gl_width, guint gl_height, guint pTexture);
|
||||||
GLuint texture, GLuint texture_u, GLuint texture_v,
|
void gst_gl_display_clearTexture (GstGLDisplay* display, guint texture);
|
||||||
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_videoChanged (GstGLDisplay* display, GstVideoFormat video_format,
|
void gst_gl_display_videoChanged (GstGLDisplay* display, GstVideoFormat video_format,
|
||||||
gint width, gint height, GLuint recordedTexture, gpointer data);
|
gint width, gint height, GLuint recordedTexture, gpointer data);
|
||||||
gboolean gst_gl_display_postRedisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
|
gboolean gst_gl_display_postRedisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
|
||||||
void gst_gl_display_requestFBO (GstGLDisplay* display, 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,
|
void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
|
||||||
guint fbo, guint depthbuffer, guint textureFBO, GLCB cb,
|
guint fbo, guint depthbuffer, guint textureFBO, GLCB cb,
|
||||||
guint inputTextureWidth, guint inputTextureHeight, guint inputTexture,
|
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,
|
guint fbo, guint depthbuffer, guint textureFBO, GLCB2 cb,
|
||||||
gpointer* p1, gpointer* p2);
|
gpointer* p1, gpointer* p2);
|
||||||
void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
|
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_initDonwloadFBO (GstGLDisplay* display, gint width, gint height);
|
||||||
void gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader);
|
void gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader);
|
||||||
void gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader);
|
void gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader);
|
||||||
|
|
|
@ -157,16 +157,14 @@ gst_gl_filter_reset (GstGLFilter* filter)
|
||||||
{
|
{
|
||||||
//blocking call, delete the FBO
|
//blocking call, delete the FBO
|
||||||
gst_gl_display_rejectFBO (filter->display, filter->fbo,
|
gst_gl_display_rejectFBO (filter->display, filter->fbo,
|
||||||
filter->depthbuffer, filter->texture);
|
filter->depthbuffer);
|
||||||
g_object_unref (filter->display);
|
g_object_unref (filter->display);
|
||||||
filter->display = NULL;
|
filter->display = NULL;
|
||||||
}
|
}
|
||||||
filter->video_format = GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
filter->width = 0;
|
filter->width = 0;
|
||||||
filter->height = 0;
|
filter->height = 0;
|
||||||
filter->fbo = 0;
|
filter->fbo = 0;
|
||||||
filter->depthbuffer = 0;
|
filter->depthbuffer = 0;
|
||||||
filter->texture = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -221,14 +219,13 @@ static gboolean
|
||||||
gst_gl_filter_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
gst_gl_filter_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
||||||
guint* size)
|
guint* size)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret = FALSE;
|
||||||
GstVideoFormat video_format;
|
gint width = 0;
|
||||||
gint width;
|
gint height = 0;
|
||||||
gint height;
|
|
||||||
|
|
||||||
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
|
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
|
||||||
if (ret)
|
if (ret)
|
||||||
*size = gst_gl_buffer_format_get_size (video_format, width, height);
|
*size = gst_gl_buffer_get_size (width, height);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -251,17 +248,14 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans,
|
||||||
|
|
||||||
//blocking call, generate a FBO
|
//blocking call, generate a FBO
|
||||||
gst_gl_display_requestFBO (filter->display, filter->width, filter->height,
|
gst_gl_display_requestFBO (filter->display, filter->width, filter->height,
|
||||||
&filter->fbo, &filter->depthbuffer, &filter->texture);
|
&filter->fbo, &filter->depthbuffer);
|
||||||
|
|
||||||
if (filter_class->onInitFBO)
|
if (filter_class->onInitFBO)
|
||||||
filter_class->onInitFBO (filter);
|
filter_class->onInitFBO (filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_outbuf = gst_gl_buffer_new_from_video_format (filter->display,
|
gl_outbuf = gst_gl_buffer_new (filter->display,
|
||||||
filter->video_format,
|
filter->width, filter->height);
|
||||||
filter->width, filter->height,
|
|
||||||
filter->width, filter->height,
|
|
||||||
gl_inbuf->width, gl_inbuf->height);
|
|
||||||
|
|
||||||
*buf = GST_BUFFER (gl_outbuf);
|
*buf = GST_BUFFER (gl_outbuf);
|
||||||
gst_buffer_set_caps (*buf, caps);
|
gst_buffer_set_caps (*buf, caps);
|
||||||
|
@ -277,8 +271,7 @@ gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps,
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||||
|
|
||||||
ret = gst_gl_buffer_format_parse_caps (outcaps, &filter->video_format,
|
ret = gst_gl_buffer_parse_caps (outcaps, &filter->width, &filter->height);
|
||||||
&filter->width, &filter->height);
|
|
||||||
|
|
||||||
if (filter_class->set_caps)
|
if (filter_class->set_caps)
|
||||||
filter_class->set_caps (filter, incaps, outcaps);
|
filter_class->set_caps (filter, incaps, outcaps);
|
||||||
|
|
|
@ -54,12 +54,11 @@ struct _GstGLFilter
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
GstVideoFormat video_format;
|
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
guint fbo;
|
guint fbo;
|
||||||
guint depthbuffer;
|
guint depthbuffer;
|
||||||
guint texture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLFilterClass
|
struct _GstGLFilterClass
|
||||||
|
|
|
@ -104,9 +104,9 @@ gst_gl_colorscale_base_init (gpointer klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 = (GObjectClass *) klass;
|
||||||
gobject_class->set_property = gst_gl_colorscale_set_property;
|
gobject_class->set_property = gst_gl_colorscale_set_property;
|
||||||
|
@ -123,7 +123,7 @@ gst_gl_colorscale_class_init (GstGLColorscaleClass * klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_colorscale_init (GstGLColorscale* colorscale, GstGLColorscaleClass * klass)
|
gst_gl_colorscale_init (GstGLColorscale* colorscale, GstGLColorscaleClass* klass)
|
||||||
{
|
{
|
||||||
gst_gl_colorscale_reset (colorscale);
|
gst_gl_colorscale_reset (colorscale);
|
||||||
}
|
}
|
||||||
|
@ -370,15 +370,15 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
|
||||||
{
|
{
|
||||||
GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt);
|
GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt);
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
static gint glcontext_y = 0;
|
static gint y_pos = 0;
|
||||||
|
|
||||||
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
|
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
|
||||||
|
|
||||||
ret = gst_video_format_parse_caps (outcaps, &colorscale->outVideo_format,
|
ret = gst_video_format_parse_caps (outcaps, &colorscale->output_video_format,
|
||||||
&colorscale->outWidth, &colorscale->outHeight);
|
&colorscale->output_video_width, &colorscale->output_video_height);
|
||||||
|
|
||||||
ret |= gst_video_format_parse_caps (incaps, &colorscale->inVideo_format,
|
ret |= gst_video_format_parse_caps (incaps, &colorscale->input_video_format,
|
||||||
&colorscale->inWidth, &colorscale->inHeight);
|
&colorscale->input_video_width, &colorscale->input_video_height);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
@ -390,12 +390,13 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
|
||||||
|
|
||||||
//init unvisible opengl context
|
//init unvisible opengl context
|
||||||
gst_gl_display_initGLContext (colorscale->display,
|
gst_gl_display_initGLContext (colorscale->display,
|
||||||
50, glcontext_y++ * (colorscale->inHeight+50) + 50,
|
50, y_pos++ * (colorscale->output_video_height+50) + 50,
|
||||||
colorscale->inWidth, colorscale->inHeight,
|
colorscale->output_video_width, colorscale->output_video_height,
|
||||||
colorscale->inWidth, colorscale->inHeight, 0, FALSE);
|
colorscale->output_video_width, colorscale->output_video_height, 0, FALSE);
|
||||||
|
|
||||||
//blocking call
|
//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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -412,11 +413,9 @@ gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
||||||
{
|
{
|
||||||
GstVideoFormat video_format;
|
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
|
||||||
|
|
||||||
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*size = gst_gl_buffer_format_get_size (video_format, width, height);
|
*size = gst_gl_buffer_get_size (width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -437,26 +436,26 @@ gst_gl_colorscale_transform (GstBaseTransform* trans, GstBuffer* inbuf,
|
||||||
GstGLColorscale* colorscale = GST_GL_COLORSCALE (trans);
|
GstGLColorscale* colorscale = GST_GL_COLORSCALE (trans);
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
GstGLBuffer* gl_tembuf = gst_gl_buffer_new_from_video_format (colorscale->display,
|
GstGLBuffer* gl_temp_buffer = gst_gl_buffer_new (colorscale->display,
|
||||||
colorscale->inVideo_format,
|
colorscale->output_video_width, colorscale->output_video_height);
|
||||||
colorscale->outWidth, colorscale->outHeight,
|
|
||||||
colorscale->inWidth, colorscale->inHeight,
|
|
||||||
colorscale->inWidth, colorscale->inHeight);
|
|
||||||
|
|
||||||
GST_DEBUG ("input size %p size %d",
|
GST_DEBUG ("input size %p size %d",
|
||||||
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
|
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
gst_gl_display_textureChanged(colorscale->display, colorscale->inVideo_format,
|
gst_gl_display_do_upload (colorscale->display, colorscale->input_video_format,
|
||||||
gl_tembuf->texture, gl_tembuf->texture_u, gl_tembuf->texture_v,
|
colorscale->input_video_width, colorscale->input_video_height, GST_BUFFER_DATA (inbuf),
|
||||||
gl_tembuf->width, gl_tembuf->height, GST_BUFFER_DATA (inbuf), &gl_tembuf->textureGL);
|
gl_temp_buffer->width, gl_temp_buffer->height, gl_temp_buffer->texture);
|
||||||
|
|
||||||
GST_DEBUG ("output size %p size %d",
|
GST_DEBUG ("output size %p size %d",
|
||||||
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
|
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
gst_gl_display_videoChanged(colorscale->display, colorscale->outVideo_format,
|
gst_gl_display_videoChanged(colorscale->display, colorscale->output_video_format,
|
||||||
gl_tembuf->width, gl_tembuf->height, gl_tembuf->textureGL, GST_BUFFER_DATA (outbuf));
|
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;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,12 +48,14 @@ struct _GstGLColorscale
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
GstVideoFormat inVideo_format;
|
|
||||||
gint inWidth;
|
GstVideoFormat input_video_format;
|
||||||
gint inHeight;
|
gint input_video_width;
|
||||||
GstVideoFormat outVideo_format;
|
gint input_video_height;
|
||||||
gint outWidth;
|
|
||||||
gint outHeight;
|
GstVideoFormat output_video_format;
|
||||||
|
gint output_video_width;
|
||||||
|
gint output_video_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLColorscaleClass
|
struct _GstGLColorscaleClass
|
||||||
|
|
|
@ -270,11 +270,9 @@ gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
||||||
{
|
{
|
||||||
GstVideoFormat video_format;
|
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
|
||||||
|
|
||||||
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*size = gst_gl_buffer_format_get_size (video_format, width, height);
|
*size = gst_gl_buffer_get_size (width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -309,7 +307,7 @@ gst_gl_download_transform (GstBaseTransform* trans, GstBuffer* inbuf,
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
gst_gl_display_videoChanged(download->display, download->video_format,
|
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;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter,
|
||||||
static void gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter);
|
static void gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter);
|
||||||
static gboolean gst_gl_filter_app_filter (GstGLFilter* filter,
|
static gboolean gst_gl_filter_app_filter (GstGLFilter* filter,
|
||||||
GstGLBuffer* inbuf, GstGLBuffer* outbuf);
|
GstGLBuffer* inbuf, GstGLBuffer* outbuf);
|
||||||
|
static void gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -164,14 +165,39 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
|
||||||
{
|
{
|
||||||
//GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter);
|
//GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter);
|
||||||
|
|
||||||
outbuf->width = inbuf->width;
|
//blocking call, use a FBO
|
||||||
outbuf->height = inbuf->height;
|
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
|
||||||
outbuf->texture = inbuf->texture;
|
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback,
|
||||||
outbuf->texture_u = inbuf->texture_u;
|
inbuf->width, inbuf->height, inbuf->texture, 0);
|
||||||
outbuf->texture_v = inbuf->texture_v;
|
|
||||||
outbuf->widthGL = inbuf->widthGL;
|
|
||||||
outbuf->heightGL = inbuf->heightGL;
|
|
||||||
outbuf->textureGL = inbuf->textureGL;
|
|
||||||
|
|
||||||
return TRUE;
|
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 ();
|
||||||
|
}
|
||||||
|
|
|
@ -114,17 +114,10 @@ gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
|
||||||
{
|
{
|
||||||
//GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE(filter);
|
//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,
|
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
|
||||||
filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_cube_callback,
|
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_cube_callback,
|
||||||
inbuf->width, inbuf->height, inbuf->textureGL, 0);
|
inbuf->width, inbuf->height, inbuf->texture, 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;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,15 +170,8 @@ gst_gl_filter_edge_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
|
||||||
|
|
||||||
//blocking call, generate a FBO
|
//blocking call, generate a FBO
|
||||||
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
|
gst_gl_display_useFBO (filter->display, filter->width, filter->height,
|
||||||
filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_edge_callback,
|
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_edge_callback,
|
||||||
inbuf->width, inbuf->height, inbuf->textureGL, edge_filter->handleShader);
|
inbuf->width, inbuf->height, inbuf->texture, 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;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +207,6 @@ gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleA
|
||||||
glTexCoord2i (width, height);
|
glTexCoord2i (width, height);
|
||||||
glVertex2f (1.0f, 1.0f);
|
glVertex2f (1.0f, 1.0f);
|
||||||
glTexCoord2i (0, height);
|
glTexCoord2i (0, height);
|
||||||
glVertex2f (-1.0f, 1.0f);
|
glVertex2f (-1.0f, 1.0f);
|
||||||
|
|
||||||
glEnd ();
|
glEnd ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,15 +444,13 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
gl_buffer = gst_gl_buffer_new_from_video_format (glimage_sink->display,
|
gl_buffer = gst_gl_buffer_new (glimage_sink->display,
|
||||||
glimage_sink->format, glimage_sink->width, glimage_sink->height,
|
|
||||||
glimage_sink->width, glimage_sink->height,
|
|
||||||
glimage_sink->width, glimage_sink->height);
|
glimage_sink->width, glimage_sink->height);
|
||||||
|
|
||||||
//blocking call
|
//blocking call
|
||||||
gst_gl_display_textureChanged(glimage_sink->display, glimage_sink->format,
|
gst_gl_display_do_upload(glimage_sink->display, glimage_sink->format,
|
||||||
gl_buffer->texture, gl_buffer->texture_u, gl_buffer->texture_v,
|
glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf),
|
||||||
gl_buffer->width, gl_buffer->height, GST_BUFFER_DATA (buf), &gl_buffer->textureGL);
|
gl_buffer->width, gl_buffer->height, gl_buffer->texture);
|
||||||
|
|
||||||
//gl_buffer is created in this block, so the gl buffer is already referenced
|
//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
|
//redisplay opengl scene
|
||||||
isAlive = gst_gl_display_postRedisplay (glimage_sink->display,
|
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)
|
if (isAlive)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
|
@ -369,7 +369,7 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps)
|
||||||
gltestsrc->width, gltestsrc->height, 0, FALSE);
|
gltestsrc->width, gltestsrc->height, 0, FALSE);
|
||||||
|
|
||||||
gst_gl_display_requestFBO (gltestsrc->display, gltestsrc->width, gltestsrc->height,
|
gst_gl_display_requestFBO (gltestsrc->display, gltestsrc->width, gltestsrc->height,
|
||||||
&gltestsrc->fbo, &gltestsrc->depthbuffer, &gltestsrc->texture);
|
&gltestsrc->fbo, &gltestsrc->depthbuffer);
|
||||||
}
|
}
|
||||||
return res;
|
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",
|
GST_LOG_OBJECT (src, "creating buffer %dx%d image for frame %d",
|
||||||
src->width, src->height, (gint) src->n_frames);
|
src->width, src->height, (gint) src->n_frames);
|
||||||
|
|
||||||
outbuf = gst_gl_buffer_new_from_video_format (src->display,
|
outbuf = gst_gl_buffer_new (src->display,
|
||||||
GST_VIDEO_FORMAT_UNKNOWN,
|
|
||||||
src->width, src->height,
|
|
||||||
src->width, src->height,
|
|
||||||
src->width, src->height);
|
src->width, src->height);
|
||||||
|
|
||||||
gst_buffer_set_caps (GST_BUFFER (outbuf),
|
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
|
//blocking call, generate a FBO
|
||||||
gst_gl_display_useFBO2 (src->display, src->width, src->height,
|
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);
|
(gpointer*)src, (gpointer*)outbuf);
|
||||||
outbuf->textureGL = src->texture;
|
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (GST_BUFFER (outbuf)) =
|
GST_BUFFER_TIMESTAMP (GST_BUFFER (outbuf)) =
|
||||||
src->timestamp_offset + src->running_time;
|
src->timestamp_offset + src->running_time;
|
||||||
|
@ -631,7 +627,7 @@ gst_gl_test_src_stop (GstBaseSrc* basesrc)
|
||||||
{
|
{
|
||||||
//blocking call, delete the FBO
|
//blocking call, delete the FBO
|
||||||
gst_gl_display_rejectFBO (src->display, src->fbo,
|
gst_gl_display_rejectFBO (src->display, src->fbo,
|
||||||
src->depthbuffer, src->texture);
|
src->depthbuffer);
|
||||||
g_object_unref (src->display);
|
g_object_unref (src->display);
|
||||||
src->display = NULL;
|
src->display = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,6 @@ struct _GstGLTestSrc {
|
||||||
|
|
||||||
guint fbo;
|
guint fbo;
|
||||||
guint depthbuffer;
|
guint depthbuffer;
|
||||||
guint texture;
|
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
|
|
|
@ -377,54 +377,53 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
|
||||||
GstGLUpload* upload = GST_GL_UPLOAD (bt);
|
GstGLUpload* upload = GST_GL_UPLOAD (bt);
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GstVideoFormat video_format = GST_VIDEO_FORMAT_UNKNOWN;
|
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);
|
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
|
||||||
|
|
||||||
ret = gst_video_format_parse_caps (outcaps, &video_format,
|
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,
|
ret |= gst_video_format_parse_caps (incaps, &upload->video_format,
|
||||||
&upload->inWidth, &upload->inHeight);
|
&upload->video_width, &upload->video_height);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("bad caps");
|
GST_DEBUG ("caps connot be parsed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//we have video and gl size, we can now init OpenGL stuffs
|
||||||
upload->display = gst_gl_display_new ();
|
upload->display = gst_gl_display_new ();
|
||||||
|
|
||||||
//init unvisible opengl context
|
//init unvisible opengl context
|
||||||
gst_gl_display_initGLContext (upload->display,
|
gst_gl_display_initGLContext (upload->display,
|
||||||
50, glcontext_y++ * (upload->inHeight+50) + 50,
|
50, y_pos++ * (upload->gl_height+50) + 50,
|
||||||
upload->inWidth, upload->inHeight,
|
upload->gl_width, upload->gl_height,
|
||||||
upload->inWidth, upload->inHeight, 0, FALSE);
|
upload->gl_width, upload->gl_height, 0, FALSE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_upload_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
gst_gl_upload_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
|
||||||
guint* size)
|
guint* size)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret = FALSE;
|
||||||
GstStructure *structure;
|
GstStructure* structure = NULL;
|
||||||
gint width;
|
gint width = 0;
|
||||||
gint height;
|
gint height = 0;
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
if (gst_structure_has_name (structure, "video/x-raw-gl"))
|
||||||
{
|
{
|
||||||
GstVideoFormat video_format;
|
ret = gst_gl_buffer_parse_caps (caps, &width, &height);
|
||||||
|
|
||||||
ret = gst_gl_buffer_format_parse_caps (caps, &video_format, &width, &height);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*size = gst_gl_buffer_format_get_size (video_format, width, height);
|
*size = gst_gl_buffer_get_size (width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GstVideoFormat video_format;
|
GstVideoFormat video_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
|
ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -438,17 +437,12 @@ static GstFlowReturn
|
||||||
gst_gl_upload_prepare_output_buffer (GstBaseTransform* trans,
|
gst_gl_upload_prepare_output_buffer (GstBaseTransform* trans,
|
||||||
GstBuffer* input, gint size, GstCaps* caps, GstBuffer** buf)
|
GstBuffer* input, gint size, GstCaps* caps, GstBuffer** buf)
|
||||||
{
|
{
|
||||||
GstGLUpload* upload;
|
GstGLUpload* upload = GST_GL_UPLOAD (trans);
|
||||||
GstGLBuffer* gl_outbuf;
|
|
||||||
|
|
||||||
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);
|
*buf = GST_BUFFER (gl_outbuf);
|
||||||
gst_buffer_set_caps (*buf, caps);
|
gst_buffer_set_caps (*buf, caps);
|
||||||
|
|
||||||
|
@ -460,18 +454,19 @@ static GstFlowReturn
|
||||||
gst_gl_upload_transform (GstBaseTransform* trans, GstBuffer* inbuf,
|
gst_gl_upload_transform (GstBaseTransform* trans, GstBuffer* inbuf,
|
||||||
GstBuffer* outbuf)
|
GstBuffer* outbuf)
|
||||||
{
|
{
|
||||||
GstGLUpload* upload;
|
GstGLUpload* upload = GST_GL_UPLOAD (trans);
|
||||||
GstGLBuffer* gl_outbuf = GST_GL_BUFFER (outbuf);
|
GstGLBuffer* gl_outbuf = GST_GL_BUFFER (outbuf);
|
||||||
|
|
||||||
upload = GST_GL_UPLOAD (trans);
|
GST_DEBUG ("Upload %p size %d",
|
||||||
|
|
||||||
GST_DEBUG ("making graphic %p size %d",
|
|
||||||
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
|
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
|
||||||
|
|
||||||
//blocking call
|
//blocking call.
|
||||||
gst_gl_display_textureChanged(upload->display, upload->video_format,
|
//Depending on the colorspace, video is upload into several textures.
|
||||||
gl_outbuf->texture, gl_outbuf->texture_u, gl_outbuf->texture_v,
|
//However, there is only one output texture. The one attached
|
||||||
gl_outbuf->width, gl_outbuf->height, GST_BUFFER_DATA (inbuf), &gl_outbuf->textureGL);
|
//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;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,12 @@ struct _GstGLUpload
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
|
|
||||||
GstVideoFormat video_format;
|
GstVideoFormat video_format;
|
||||||
gint inWidth;
|
gint video_width;
|
||||||
gint inHeight;
|
gint video_height;
|
||||||
gint outWidth;
|
gint gl_width;
|
||||||
gint outHeight;
|
gint gl_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLUploadClass
|
struct _GstGLUploadClass
|
||||||
|
|
Loading…
Reference in a new issue