mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
[104/906] start to add a glfilteredge that proceeds edge detection using GLSL
git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@517 93df14bb-0f41-7a43-8087-d3e2a2f0e464
This commit is contained in:
parent
459cde2eaa
commit
f0a68351b3
9 changed files with 369 additions and 13 deletions
|
@ -28,11 +28,13 @@
|
|||
static void gst_gl_display_finalize (GObject * object);
|
||||
static gpointer gst_gl_display_glutThreadFunc (GstGLDisplay* display);
|
||||
static void gst_gl_display_glutCreateWindow (GstGLDisplay* display);
|
||||
static void gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutUseFBO (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutUseFBO2 (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutDestroyFBO (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutInitShader (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutDestroyShader (GstGLDisplay *display);
|
||||
static void gst_gl_display_glutDestroyWindow (GstGLDisplay* display);
|
||||
static void gst_gl_display_glutSetVisibleWindow (GstGLDisplay* display);
|
||||
static void gst_gl_display_glutReshapeWindow (GstGLDisplay* display);
|
||||
|
@ -106,6 +108,8 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
|||
display->cond_create = g_cond_new ();
|
||||
display->cond_destroy = g_cond_new ();
|
||||
display->cond_download = g_cond_new ();
|
||||
display->cond_initShader = g_cond_new ();
|
||||
display->cond_destroyShader = g_cond_new ();
|
||||
|
||||
display->fbo = 0;
|
||||
display->depthBuffer = 0;
|
||||
|
@ -204,6 +208,11 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
|||
display->GLSLProgram_to_I420_YV12 = 0;
|
||||
display->GLSLProgram_to_AYUV = 0;
|
||||
|
||||
display->requestedTextShader = NULL;
|
||||
display->requestedHandleShader = 0;
|
||||
display->usedHandleShader = 0;
|
||||
display->rejectedHandleShader = 0;
|
||||
|
||||
//YUY2:r,g,a
|
||||
//UYVY:a,b,r
|
||||
display->textFProgram_YUY2_UYVY =
|
||||
|
@ -370,6 +379,14 @@ gst_gl_display_finalize (GObject *object)
|
|||
g_cond_free (display->cond_download);
|
||||
display->cond_download = NULL;
|
||||
}
|
||||
if (display->cond_initShader) {
|
||||
g_cond_free (display->cond_initShader);
|
||||
display->cond_initShader = NULL;
|
||||
}
|
||||
if (display->cond_destroyShader) {
|
||||
g_cond_free (display->cond_destroyShader);
|
||||
display->cond_destroyShader = NULL;
|
||||
}
|
||||
if (display->cond_generateFBO) {
|
||||
g_cond_free (display->cond_generateFBO);
|
||||
display->cond_generateFBO = NULL;
|
||||
|
@ -595,7 +612,7 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
|
|||
|
||||
/* Called by the idle funtion */
|
||||
static void
|
||||
gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display)
|
||||
gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display)
|
||||
{
|
||||
glutSetWindow (display->glutWinId);
|
||||
|
||||
|
@ -821,7 +838,8 @@ gst_gl_display_glutUseFBO (GstGLDisplay *display)
|
|||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//the opengl scene
|
||||
display->glsceneFBO_cb (display->inputTextureWidth, display->inputTextureHeight, display->inputTexture);
|
||||
display->glsceneFBO_cb (display->inputTextureWidth, display->inputTextureHeight, display->inputTexture,
|
||||
display->usedHandleShader);
|
||||
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
||||
|
@ -890,9 +908,8 @@ gst_gl_display_glutUseFBO2 (GstGLDisplay *display)
|
|||
|
||||
/* Called by the idle funtion */
|
||||
static void
|
||||
gst_gl_display_glutDestroyFBO (GstGLDisplay *display)
|
||||
gst_gl_display_glutDestroyFBO (GstGLDisplay* display)
|
||||
{
|
||||
|
||||
glutSetWindow (display->glutWinId);
|
||||
|
||||
glDeleteFramebuffersEXT (1, &display->rejectedFBO);
|
||||
|
@ -906,6 +923,27 @@ gst_gl_display_glutDestroyFBO (GstGLDisplay *display)
|
|||
}
|
||||
|
||||
|
||||
/* Called by the idle funtion */
|
||||
static void
|
||||
gst_gl_display_glutInitShader (GstGLDisplay* display)
|
||||
{
|
||||
glutSetWindow (display->glutWinId);
|
||||
display->requestedHandleShader = gst_gl_display_loadGLSLprogram (display->requestedTextShader);
|
||||
g_cond_signal (display->cond_initShader);
|
||||
}
|
||||
|
||||
|
||||
/* Called by the idle funtion */
|
||||
static void
|
||||
gst_gl_display_glutDestroyShader (GstGLDisplay* display)
|
||||
{
|
||||
glutSetWindow (display->glutWinId);
|
||||
glDeleteObjectARB (display->rejectedHandleShader);
|
||||
g_cond_signal (display->cond_destroyShader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by the idle function */
|
||||
static void
|
||||
gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
|
||||
|
@ -1127,7 +1165,13 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg)
|
|||
gst_gl_display_glutUseFBO2 (msg->display);
|
||||
break;
|
||||
case GST_GL_DISPLAY_ACTION_OVFBO:
|
||||
gst_gldisplay_glutGenerateOutputVideoFBO (msg->display);
|
||||
gst_gl_display_glutGenerateOutputVideoFBO (msg->display);
|
||||
break;
|
||||
case GST_GL_DISPLAY_ACTION_GENSHADER:
|
||||
gst_gl_display_glutInitShader (msg->display);
|
||||
break;
|
||||
case GST_GL_DISPLAY_ACTION_DELSHADER:
|
||||
gst_gl_display_glutDestroyShader (msg->display);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
|
@ -1161,6 +1205,8 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg)
|
|||
case GST_GL_DISPLAY_ACTION_USEFBO:
|
||||
case GST_GL_DISPLAY_ACTION_USEFBO2:
|
||||
case GST_GL_DISPLAY_ACTION_OVFBO:
|
||||
case GST_GL_DISPLAY_ACTION_GENSHADER:
|
||||
case GST_GL_DISPLAY_ACTION_DELSHADER:
|
||||
//msg is out of date if the associated display is not in the map
|
||||
if (!g_hash_table_lookup (gst_gl_display_map, GINT_TO_POINTER (msg->glutWinId)))
|
||||
valid = FALSE;
|
||||
|
@ -1413,7 +1459,8 @@ gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
|
|||
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)
|
||||
guint inputTextureWidth, guint inputTextureHeight, guint inputTexture,
|
||||
GLhandleARB handleShader)
|
||||
{
|
||||
gst_gl_display_lock (display);
|
||||
display->usedFBO = fbo;
|
||||
|
@ -1425,6 +1472,7 @@ gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint texture
|
|||
display->inputTextureWidth = inputTextureWidth;
|
||||
display->inputTextureHeight = inputTextureHeight;
|
||||
display->inputTexture = inputTexture;
|
||||
display->usedHandleShader = handleShader;
|
||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO, display);
|
||||
g_cond_wait (display->cond_useFBO, display->mutex);
|
||||
gst_gl_display_unlock (display);
|
||||
|
@ -1478,6 +1526,31 @@ gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height)
|
|||
}
|
||||
|
||||
|
||||
/* Called by gst_gl elements */
|
||||
void
|
||||
gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader)
|
||||
{
|
||||
gst_gl_display_lock (display);
|
||||
display->requestedTextShader = textShader;
|
||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_GENSHADER, display);
|
||||
g_cond_wait (display->cond_initShader, display->mutex);
|
||||
*handleShader = display->requestedHandleShader;
|
||||
gst_gl_display_unlock (display);
|
||||
}
|
||||
|
||||
|
||||
/* Called by gst_gl elements */
|
||||
void
|
||||
gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader)
|
||||
{
|
||||
gst_gl_display_lock (display);
|
||||
display->rejectedHandleShader = shader;
|
||||
gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELSHADER, display);
|
||||
g_cond_wait (display->cond_destroyShader, display->mutex);
|
||||
gst_gl_display_unlock (display);
|
||||
}
|
||||
|
||||
|
||||
/* Called by gst_gl elements */
|
||||
void
|
||||
gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId)
|
||||
|
|
|
@ -56,7 +56,9 @@ typedef enum {
|
|||
GST_GL_DISPLAY_ACTION_DELFBO,
|
||||
GST_GL_DISPLAY_ACTION_USEFBO,
|
||||
GST_GL_DISPLAY_ACTION_USEFBO2,
|
||||
GST_GL_DISPLAY_ACTION_OVFBO
|
||||
GST_GL_DISPLAY_ACTION_OVFBO,
|
||||
GST_GL_DISPLAY_ACTION_GENSHADER,
|
||||
GST_GL_DISPLAY_ACTION_DELSHADER
|
||||
|
||||
} GstGLDisplayAction;
|
||||
|
||||
|
@ -82,7 +84,7 @@ typedef void (* CRCB) ( GLuint, GLuint );
|
|||
typedef gboolean (* CDCB) ( GLuint, GLuint, GLuint);
|
||||
|
||||
//opengl scene callback
|
||||
typedef void (* GLCB) ( GLuint, GLuint, GLuint);
|
||||
typedef void (* GLCB) ( GLuint, GLuint, GLuint, GLhandleARB);
|
||||
typedef void (* GLCB2) ( gpointer* p1, gpointer* p2, gint w, gint h);
|
||||
|
||||
struct _GstGLDisplay {
|
||||
|
@ -101,6 +103,8 @@ struct _GstGLDisplay {
|
|||
GCond* cond_useFBO2;
|
||||
GCond* cond_destroyFBO;
|
||||
GCond* cond_download;
|
||||
GCond* cond_initShader;
|
||||
GCond* cond_destroyShader;
|
||||
|
||||
GCond* cond_create;
|
||||
GCond* cond_destroy;
|
||||
|
@ -219,6 +223,12 @@ struct _GstGLDisplay {
|
|||
|
||||
gchar* textFProgram_to_AYUV;
|
||||
GLhandleARB GLSLProgram_to_AYUV;
|
||||
|
||||
//requested shader
|
||||
gchar* requestedTextShader;
|
||||
GLhandleARB requestedHandleShader;
|
||||
GLhandleARB usedHandleShader;
|
||||
GLhandleARB rejectedHandleShader;
|
||||
|
||||
//client callbacks
|
||||
CRCB clientReshapeCallback;
|
||||
|
@ -263,13 +273,16 @@ void gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height,
|
|||
guint* fbo, guint* depthbuffer, guint* texture);
|
||||
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);
|
||||
guint inputTextureWidth, guint inputTextureHeight, guint inputTexture,
|
||||
GLhandleARB handleShader);
|
||||
void gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
|
||||
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);
|
||||
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);
|
||||
void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,7 @@ gst_gl_filter_class_init (GstGLFilterClass * klass)
|
|||
klass->set_caps = NULL;
|
||||
klass->filter = NULL;
|
||||
klass->onInitFBO = NULL;
|
||||
klass->onReset = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -147,6 +148,11 @@ gst_gl_filter_get_property (GObject * object, guint prop_id,
|
|||
static void
|
||||
gst_gl_filter_reset (GstGLFilter* filter)
|
||||
{
|
||||
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||
|
||||
if (filter_class->onReset)
|
||||
filter_class->onReset (filter);
|
||||
|
||||
if (filter->display)
|
||||
{
|
||||
//blocking call, delete the FBO
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef gboolean (*GstGLFilterSetCaps) (GstGLFilter* filter,
|
|||
typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter,
|
||||
GstGLBuffer *inbuf, GstGLBuffer *outbuf);
|
||||
typedef void (*GstGLFilterOnInitFBO) (GstGLFilter *filter);
|
||||
typedef void (*GstGLFilterOnReset) (GstGLFilter *filter);
|
||||
|
||||
struct _GstGLFilter
|
||||
{
|
||||
|
@ -67,6 +68,7 @@ struct _GstGLFilterClass
|
|||
GstGLFilterSetCaps set_caps;
|
||||
GstGLFilterProcessFunc filter;
|
||||
GstGLFilterOnInitFBO onInitFBO;
|
||||
GstGLFilterOnReset onReset;
|
||||
};
|
||||
|
||||
GType gst_gl_filter_get_type(void);
|
||||
|
|
|
@ -14,6 +14,8 @@ libgstopengl_la_SOURCES = \
|
|||
gstgldownload.h \
|
||||
gstglfiltercube.c \
|
||||
gstglfiltercube.h \
|
||||
gstglfilteredge.c \
|
||||
gstglfilteredge.h \
|
||||
gstglfilterapp.c \
|
||||
gstglfilterapp.h \
|
||||
gstglcolorscale.c \
|
||||
|
|
|
@ -51,7 +51,7 @@ static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id,
|
|||
|
||||
static gboolean gst_gl_filter_cube_filter (GstGLFilter * filter,
|
||||
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
|
||||
static void gst_gl_filter_cube_callback (guint width, guint height, guint texture);
|
||||
static void gst_gl_filter_cube_callback (guint width, guint height, guint texture, GLhandleARB shader);
|
||||
|
||||
|
||||
static void
|
||||
|
@ -117,7 +117,7 @@ gst_gl_filter_cube_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_cube_callback,
|
||||
inbuf->width, inbuf->height, inbuf->textureGL);
|
||||
inbuf->width, inbuf->height, inbuf->textureGL, 0);
|
||||
|
||||
outbuf->width = inbuf->width;
|
||||
outbuf->height = inbuf->height;
|
||||
|
@ -131,7 +131,7 @@ gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
|
|||
|
||||
//opengl scene, params: input texture (not the output filter->texture)
|
||||
static void
|
||||
gst_gl_filter_cube_callback (guint width, guint height, guint texture)
|
||||
gst_gl_filter_cube_callback (guint width, guint height, guint texture, GLhandleARB shader)
|
||||
{
|
||||
static GLfloat xrot = 0;
|
||||
static GLfloat yrot = 0;
|
||||
|
|
198
gst/gl/gstglfilteredge.c
Normal file
198
gst/gl/gstglfilteredge.c
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstglfilteredge.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_filter_edge_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static const GstElementDetails element_details =
|
||||
GST_ELEMENT_DETAILS ("OpenGL edge filter",
|
||||
"Filter/Effect",
|
||||
"Edge detection",
|
||||
"Julien Isorce <julien.isorce@gmail.com>");
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0
|
||||
};
|
||||
|
||||
#define DEBUG_INIT(bla) \
|
||||
GST_DEBUG_CATEGORY_INIT (gst_gl_filter_edge_debug, "glfilteredge", 0, "glfilteredge element");
|
||||
|
||||
GST_BOILERPLATE_FULL (GstGLFilterEdge, gst_gl_filter_edge, GstGLFilter,
|
||||
GST_TYPE_GL_FILTER, DEBUG_INIT);
|
||||
|
||||
static void gst_gl_filter_edge_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gl_filter_edge_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_gl_filter_edge_reset (GstGLFilter* filter);
|
||||
static void gst_gl_filter_edge_init_shader (GstGLFilter* filter);
|
||||
static gboolean gst_gl_filter_edge_filter (GstGLFilter * filter,
|
||||
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
|
||||
static void gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleARB shader);
|
||||
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_set_details (element_class, &element_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_class_init (GstGLFilterEdgeClass* klass)
|
||||
{
|
||||
GObjectClass* gobject_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gobject_class->set_property = gst_gl_filter_edge_set_property;
|
||||
gobject_class->get_property = gst_gl_filter_edge_get_property;
|
||||
|
||||
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_edge_filter;
|
||||
GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_edge_init_shader;
|
||||
GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_edge_reset;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_init (GstGLFilterEdge* filter,
|
||||
GstGLFilterEdgeClass* klass)
|
||||
{
|
||||
filter->handleShader = 0;
|
||||
filter->textShader =
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main(void) {\n"
|
||||
" float r,g,b,y;\n"
|
||||
" vec2 nxy=gl_TexCoord[0].xy;\n"
|
||||
" r=texture2DRect(tex,nxy).r;\n"
|
||||
" g=texture2DRect(tex,nxy).g;\n"
|
||||
" b=texture2DRect(tex,nxy).b;\n"
|
||||
" gl_FragColor=vec4(b,g,r,1.0);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_reset (GstGLFilter* filter)
|
||||
{
|
||||
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter);
|
||||
|
||||
//blocking call, wait the opengl thread has destroyed the shader program
|
||||
gst_gl_display_destroyShader (filter->display, edge_filter->handleShader);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_set_property (GObject* object, guint prop_id,
|
||||
const GValue* value, GParamSpec* pspec)
|
||||
{
|
||||
//GstGLFilterEdge *filter = GST_GL_FILTER_EDGE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_get_property (GObject* object, guint prop_id,
|
||||
GValue* value, GParamSpec* pspec)
|
||||
{
|
||||
//GstGLFilterEdge *filter = GST_GL_FILTER_EDGE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_edge_init_shader (GstGLFilter* filter)
|
||||
{
|
||||
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter);
|
||||
|
||||
//blocking call, wait the opengl thread has compiled the shader program
|
||||
gst_gl_display_initShader (filter->display, edge_filter->textShader, &edge_filter->handleShader);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_filter_edge_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
|
||||
GstGLBuffer* outbuf)
|
||||
{
|
||||
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter);
|
||||
|
||||
//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;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//opengl scene, params: input texture (not the output filter->texture)
|
||||
static void
|
||||
gst_gl_filter_edge_callback (guint width, guint height, guint texture, GLhandleARB shader)
|
||||
{
|
||||
gint i=0;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgramObjectARB (shader);
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
i = glGetUniformLocationARB (shader, "tex");
|
||||
glUniform1iARB (i, 0);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2i (width, 0);
|
||||
glVertex2f (1.0f, 1.0f);
|
||||
glTexCoord2i (0, 0);
|
||||
glVertex2f (-1.0f, 1.0f);
|
||||
glTexCoord2i (0, height);
|
||||
glVertex2f (-1.0f, -1.0f);
|
||||
glTexCoord2i (width, height);
|
||||
glVertex2f (1.0f, -1.0f);
|
||||
glEnd ();
|
||||
}
|
55
gst/gl/gstglfilteredge.h
Normal file
55
gst/gl/gstglfilteredge.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GST_GL_FILTEREDGE_H_
|
||||
#define _GST_GL_FILTEREDGE_H_
|
||||
|
||||
#include "gstglfilter.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_GL_FILTER_EDGE (gst_gl_filter_edge_get_type())
|
||||
#define GST_GL_FILTER_EDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER_EDGE,GstGLFilterEdge))
|
||||
#define GST_IS_GL_FILTER_EDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER_EDGE))
|
||||
#define GST_GL_FILTER_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER_EDGE,GstGLFilterEdgeClass))
|
||||
#define GST_IS_GL_FILTER_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER_EDGE))
|
||||
#define GST_GL_FILTER_EDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER_EDGE,GstGLFilterEdgeClass))
|
||||
|
||||
typedef struct _GstGLFilterEdge GstGLFilterEdge;
|
||||
typedef struct _GstGLFilterEdgeClass GstGLFilterEdgeClass;
|
||||
|
||||
struct _GstGLFilterEdge
|
||||
{
|
||||
GstGLFilter filter;
|
||||
|
||||
gchar* textShader;
|
||||
GLhandleARB handleShader;
|
||||
};
|
||||
|
||||
struct _GstGLFilterEdgeClass
|
||||
{
|
||||
GstGLFilterClass filter_class;
|
||||
};
|
||||
|
||||
GType gst_gl_glfilteredge_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _GST_GLFILTEREDGE_H_ */
|
|
@ -25,6 +25,7 @@
|
|||
#include "gstgltestsrc.h"
|
||||
#include "gstglupload.h"
|
||||
#include "gstglfiltercube.h"
|
||||
#include "gstglfilteredge.h"
|
||||
#include "gstglfilterapp.h"
|
||||
#include "gstgldownload.h"
|
||||
#include "gstglimagesink.h"
|
||||
|
@ -32,6 +33,7 @@
|
|||
|
||||
GType gst_gl_filter_app_get_type (void);
|
||||
GType gst_gl_filter_cube_get_type (void);
|
||||
GType gst_gl_filter_edge_get_type (void);
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_gstgl_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
@ -57,6 +59,11 @@ plugin_init (GstPlugin * plugin)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_element_register (plugin, "glfilteredge",
|
||||
GST_RANK_NONE, GST_TYPE_GL_FILTER_EDGE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_element_register (plugin, "glfilterapp",
|
||||
GST_RANK_NONE, GST_TYPE_GL_FILTER_APP)) {
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in a new issue