[310/906] Global reindent

Indent parameters:
INDENT_PARAMETERS="--braces-on-if-line \
        --case-brace-indentation0 \
        --case-indentation2 \
        --braces-after-struct-decl-line \
        --line-length80 \
        --no-tabs \
        --cuddle-else \
        --dont-line-up-parentheses \
        --honour-newlines \
        --continuation-indentation4 \
        --tab-size8 \
        --indent-level2"
This commit is contained in:
David Schleef 2009-02-10 22:39:14 -08:00 committed by Matthew Waters
parent 3fbd8bbd24
commit d015d5862d
42 changed files with 5376 additions and 5424 deletions

View file

@ -25,10 +25,10 @@
#include "gstglbuffer.h" #include "gstglbuffer.h"
static GObjectClass* gst_gl_buffer_parent_class; static GObjectClass *gst_gl_buffer_parent_class;
static void static void
gst_gl_buffer_finalize (GstGLBuffer* buffer) gst_gl_buffer_finalize (GstGLBuffer * buffer)
{ {
//blocking call, put the texture in the pool //blocking call, put the texture in the pool
gst_gl_display_del_texture (buffer->display, buffer->texture, gst_gl_display_del_texture (buffer->display, buffer->texture,
@ -36,12 +36,12 @@ gst_gl_buffer_finalize (GstGLBuffer* buffer)
g_object_unref (buffer->display); g_object_unref (buffer->display);
GST_MINI_OBJECT_CLASS (gst_gl_buffer_parent_class)-> GST_MINI_OBJECT_CLASS (gst_gl_buffer_parent_class)->finalize (GST_MINI_OBJECT
finalize (GST_MINI_OBJECT (buffer)); (buffer));
} }
static void 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;
@ -53,7 +53,7 @@ gst_gl_buffer_init (GstGLBuffer* buffer, gpointer g_class)
static void static void
gst_gl_buffer_class_init (gpointer g_class, gpointer class_data) gst_gl_buffer_class_init (gpointer g_class, gpointer class_data)
{ {
GstMiniObjectClass* mini_object_class = GST_MINI_OBJECT_CLASS (g_class); GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
gst_gl_buffer_parent_class = g_type_class_peek_parent (g_class); gst_gl_buffer_parent_class = g_type_class_peek_parent (g_class);
@ -87,11 +87,11 @@ gst_gl_buffer_get_type (void)
} }
GstGLBuffer* GstGLBuffer *
gst_gl_buffer_new (GstGLDisplay* display, gst_gl_buffer_new (GstGLDisplay * display, gint gl_width, gint gl_height)
gint gl_width, gint gl_height)
{ {
GstGLBuffer* gl_buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER); GstGLBuffer *gl_buffer =
(GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
gl_buffer->display = g_object_ref (display); gl_buffer->display = g_object_ref (display);
gl_buffer->width = gl_width; gl_buffer->width = gl_width;
@ -102,7 +102,8 @@ gst_gl_buffer_new (GstGLDisplay* display,
GST_BUFFER_SIZE (gl_buffer) = gst_gl_buffer_get_size (gl_width, gl_height); GST_BUFFER_SIZE (gl_buffer) = gst_gl_buffer_get_size (gl_width, gl_height);
//blocking call, generate a texture using the pool //blocking call, generate a texture using the pool
gst_gl_display_gen_texture (gl_buffer->display, &gl_buffer->texture, gl_width, gl_height) ; gst_gl_display_gen_texture (gl_buffer->display, &gl_buffer->texture, gl_width,
gl_height);
return gl_buffer; return gl_buffer;
} }
@ -118,9 +119,9 @@ gst_gl_buffer_get_size (gint width, gint height)
gboolean gboolean
gst_gl_buffer_parse_caps (GstCaps* caps, gint* width, gint* height) gst_gl_buffer_parse_caps (GstCaps * caps, gint * width, gint * height)
{ {
GstStructure* structure = gst_caps_get_structure (caps, 0); GstStructure *structure = gst_caps_get_structure (caps, 0);
gboolean ret = gst_structure_has_name (structure, "video/x-raw-gl"); gboolean ret = gst_structure_has_name (structure, "video/x-raw-gl");
if (!ret) if (!ret)

File diff suppressed because it is too large Load diff

View file

@ -31,14 +31,14 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static GstStaticPadTemplate gst_gl_filter_src_pad_template = static GstStaticPadTemplate gst_gl_filter_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
); );
static GstStaticPadTemplate gst_gl_filter_sink_pad_template = static GstStaticPadTemplate gst_gl_filter_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
@ -55,8 +55,8 @@ static void gst_gl_filter_set_property (GObject * object, guint prop_id,
static void gst_gl_filter_get_property (GObject * object, guint prop_id, static void gst_gl_filter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static GstCaps* gst_gl_filter_transform_caps (GstBaseTransform* bt, static GstCaps *gst_gl_filter_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps); GstPadDirection direction, GstCaps * caps);
static void gst_gl_filter_reset (GstGLFilter * filter); static void gst_gl_filter_reset (GstGLFilter * filter);
static gboolean gst_gl_filter_start (GstBaseTransform * bt); static gboolean gst_gl_filter_start (GstBaseTransform * bt);
static gboolean gst_gl_filter_stop (GstBaseTransform * bt); static gboolean gst_gl_filter_stop (GstBaseTransform * bt);
@ -71,8 +71,8 @@ static gboolean gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
static gboolean gst_gl_filter_do_transform (GstGLFilter * filter, static gboolean gst_gl_filter_do_transform (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
/* GstGLDisplayThreadFunc */ /* GstGLDisplayThreadFunc */
static void gst_gl_filter_start_gl (GstGLDisplay *display, gpointer data); static void gst_gl_filter_start_gl (GstGLDisplay * display, gpointer data);
static void gst_gl_filter_stop_gl (GstGLDisplay *display, gpointer data); static void gst_gl_filter_stop_gl (GstGLDisplay * display, gpointer data);
static void static void
@ -132,8 +132,7 @@ gst_gl_filter_set_property (GObject * object, guint prop_id,
{ {
//GstGLFilter *filter = GST_GL_FILTER (object); //GstGLFilter *filter = GST_GL_FILTER (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -146,8 +145,7 @@ gst_gl_filter_get_property (GObject * object, guint prop_id,
{ {
//GstGLFilter *filter = GST_GL_FILTER (object); //GstGLFilter *filter = GST_GL_FILTER (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -155,21 +153,20 @@ gst_gl_filter_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_filter_reset (GstGLFilter* filter) gst_gl_filter_reset (GstGLFilter * filter)
{ {
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
if (filter->display) if (filter->display) {
{
if (filter_class->onReset) if (filter_class->onReset)
filter_class->onReset (filter); filter_class->onReset (filter);
if (filter_class->display_reset_cb != NULL) { if (filter_class->display_reset_cb != NULL) {
gst_gl_display_thread_add (filter->display, gst_gl_filter_stop_gl, filter); gst_gl_display_thread_add (filter->display, gst_gl_filter_stop_gl,
filter);
} }
//blocking call, delete the FBO //blocking call, delete the FBO
gst_gl_display_del_fbo (filter->display, filter->fbo, gst_gl_display_del_fbo (filter->display, filter->fbo, filter->depthbuffer);
filter->depthbuffer);
g_object_unref (filter->display); g_object_unref (filter->display);
filter->display = NULL; filter->display = NULL;
} }
@ -180,7 +177,7 @@ gst_gl_filter_reset (GstGLFilter* filter)
} }
static gboolean static gboolean
gst_gl_filter_start (GstBaseTransform* bt) gst_gl_filter_start (GstBaseTransform * bt)
{ {
GstGLFilter *filter = GST_GL_FILTER (bt); GstGLFilter *filter = GST_GL_FILTER (bt);
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
@ -192,7 +189,7 @@ gst_gl_filter_start (GstBaseTransform* bt)
} }
static gboolean static gboolean
gst_gl_filter_stop (GstBaseTransform* bt) gst_gl_filter_stop (GstBaseTransform * bt)
{ {
GstGLFilter *filter = GST_GL_FILTER (bt); GstGLFilter *filter = GST_GL_FILTER (bt);
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
@ -206,7 +203,7 @@ gst_gl_filter_stop (GstBaseTransform* bt)
} }
static void static void
gst_gl_filter_start_gl (GstGLDisplay *display, gpointer data) gst_gl_filter_start_gl (GstGLDisplay * display, gpointer data)
{ {
GstGLFilter *filter = GST_GL_FILTER (data); GstGLFilter *filter = GST_GL_FILTER (data);
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
@ -215,7 +212,7 @@ gst_gl_filter_start_gl (GstGLDisplay *display, gpointer data)
} }
static void static void
gst_gl_filter_stop_gl (GstGLDisplay *display, gpointer data) gst_gl_filter_stop_gl (GstGLDisplay * display, gpointer data)
{ {
GstGLFilter *filter = GST_GL_FILTER (data); GstGLFilter *filter = GST_GL_FILTER (data);
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
@ -223,14 +220,14 @@ gst_gl_filter_stop_gl (GstGLDisplay *display, gpointer data)
filter_class->display_reset_cb (filter); filter_class->display_reset_cb (filter);
} }
static GstCaps* static GstCaps *
gst_gl_filter_transform_caps (GstBaseTransform* bt, gst_gl_filter_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps) GstPadDirection direction, GstCaps * caps)
{ {
//GstGLFilter* filter = GST_GL_FILTER (bt); //GstGLFilter* filter = GST_GL_FILTER (bt);
GstStructure* structure = gst_caps_get_structure (caps, 0); GstStructure *structure = gst_caps_get_structure (caps, 0);
GstCaps* ret = gst_caps_copy (caps); GstCaps *ret = gst_caps_copy (caps);
const GValue* par = NULL; const GValue *par = NULL;
structure = gst_structure_copy (gst_caps_get_structure (ret, 0)); structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
@ -240,13 +237,11 @@ gst_gl_filter_transform_caps (GstBaseTransform* bt,
gst_caps_merge_structure (ret, gst_structure_copy (structure)); gst_caps_merge_structure (ret, gst_structure_copy (structure));
if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
{
gst_structure_set (structure, gst_structure_set (structure,
"pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
gst_caps_merge_structure (ret, structure); gst_caps_merge_structure (ret, structure);
} } else
else
gst_structure_free (structure); gst_structure_free (structure);
GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, ret); GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, ret);
@ -256,8 +251,8 @@ gst_gl_filter_transform_caps (GstBaseTransform* bt,
static gboolean 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 = FALSE; gboolean ret = FALSE;
gint width = 0; gint width = 0;
@ -271,18 +266,17 @@ gst_gl_filter_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
} }
static GstFlowReturn static GstFlowReturn
gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, gst_gl_filter_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer* inbuf, gint size, GstCaps* caps, GstBuffer** buf) GstBuffer * inbuf, gint size, GstCaps * caps, GstBuffer ** buf)
{ {
GstGLFilter* filter = NULL; GstGLFilter *filter = NULL;
GstGLBuffer* gl_inbuf = GST_GL_BUFFER (inbuf); GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
GstGLBuffer* gl_outbuf = NULL; GstGLBuffer *gl_outbuf = NULL;
filter = GST_GL_FILTER (trans); filter = GST_GL_FILTER (trans);
if (filter->display == NULL) if (filter->display == NULL) {
{ GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter);
filter->display = g_object_ref (gl_inbuf->display); filter->display = g_object_ref (gl_inbuf->display);
@ -291,7 +285,8 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans,
&filter->fbo, &filter->depthbuffer); &filter->fbo, &filter->depthbuffer);
if (filter_class->display_init_cb != NULL) { if (filter_class->display_init_cb != NULL) {
gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl, filter); gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl,
filter);
} }
if (filter_class->onInitFBO) if (filter_class->onInitFBO)
@ -311,20 +306,19 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans,
} }
static gboolean static gboolean
gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps, gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
GstGLFilter* filter = GST_GL_FILTER (bt); GstGLFilter *filter = GST_GL_FILTER (bt);
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_parse_caps (outcaps, &filter->width, &filter->height); ret = gst_gl_buffer_parse_caps (outcaps, &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);
if (!ret) if (!ret) {
{
GST_DEBUG ("bad caps"); GST_DEBUG ("bad caps");
return FALSE; return FALSE;
} }
@ -335,12 +329,12 @@ gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps,
} }
static GstFlowReturn static GstFlowReturn
gst_gl_filter_transform (GstBaseTransform* bt, GstBuffer* inbuf, gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
GstBuffer* outbuf) GstBuffer * outbuf)
{ {
GstGLFilter* filter; GstGLFilter *filter;
GstGLBuffer* gl_inbuf = GST_GL_BUFFER (inbuf); GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
GstGLBuffer* gl_outbuf = GST_GL_BUFFER (outbuf); GstGLBuffer *gl_outbuf = GST_GL_BUFFER (outbuf);
filter = GST_GL_FILTER (bt); filter = GST_GL_FILTER (bt);
@ -350,10 +344,10 @@ gst_gl_filter_transform (GstBaseTransform* bt, GstBuffer* inbuf,
} }
static gboolean static gboolean
gst_gl_filter_do_transform (GstGLFilter* filter, gst_gl_filter_do_transform (GstGLFilter * filter,
GstGLBuffer* inbuf, GstGLBuffer* outbuf) GstGLBuffer * inbuf, GstGLBuffer * outbuf)
{ {
GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
filter_class->filter (filter, inbuf, outbuf); filter_class->filter (filter, inbuf, outbuf);
@ -363,15 +357,13 @@ gst_gl_filter_do_transform (GstGLFilter* filter,
/* convenience functions to simplify filter development */ /* convenience functions to simplify filter development */
void void
gst_gl_filter_render_to_target (GstGLFilter *filter, gst_gl_filter_render_to_target (GstGLFilter * filter,
GLuint input, GLuint target, GLuint input, GLuint target, GLCB func, gpointer data)
GLCB func, gpointer data)
{ {
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, target, filter->fbo, filter->depthbuffer, target,
func, func,
filter->width, filter->height, input, filter->width, filter->height, input,
0, filter->width, 0, filter->height, 0, filter->width, 0, filter->height,
GST_GL_DISPLAY_PROJECTION_ORTHO2D, GST_GL_DISPLAY_PROJECTION_ORTHO2D, data);
data);
} }

View file

@ -132,8 +132,8 @@ gst_gl_shader_get_property (GObject * object,
} }
static void static void
gst_gl_shader_log_handler (const gchar *domain, GLogLevelFlags flags, gst_gl_shader_log_handler (const gchar * domain, GLogLevelFlags flags,
const gchar *message, gpointer user_data) const gchar * message, gpointer user_data)
{ {
if (_gst_gl_shader_debug) { if (_gst_gl_shader_debug) {
g_log_default_handler (domain, flags, message, user_data); g_log_default_handler (domain, flags, message, user_data);
@ -511,7 +511,7 @@ gst_gl_shader_set_uniform_1i (GstGLShader * shader, const gchar * name,
} }
GLint GLint
gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar *name) gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar * name)
{ {
GstGLShaderPrivate *priv; GstGLShaderPrivate *priv;

View file

@ -32,9 +32,11 @@
#define WM_GST_GL_WINDOW_CUSTOM (WM_APP+1) #define WM_GST_GL_WINDOW_CUSTOM (WM_APP+1)
#define WM_GST_GL_WINDOW_QUIT (WM_APP+2) #define WM_GST_GL_WINDOW_QUIT (WM_APP+2)
void gst_gl_window_set_pixel_format (GstGLWindow *window); void gst_gl_window_set_pixel_format (GstGLWindow * window);
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LPARAM lParam);
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
#define GST_GL_WINDOW_GET_PRIVATE(o) \ #define GST_GL_WINDOW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate))
@ -79,8 +81,8 @@ gst_gl_window_finalize (GObject * object)
} }
static void static void
gst_gl_window_log_handler (const gchar *domain, GLogLevelFlags flags, gst_gl_window_log_handler (const gchar * domain, GLogLevelFlags flags,
const gchar *message, gpointer user_data) const gchar * message, gpointer user_data)
{ {
if (_gst_gl_window_debug) { if (_gst_gl_window_debug) {
g_log_default_handler (domain, flags, message, user_data); g_log_default_handler (domain, flags, message, user_data);
@ -106,9 +108,8 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
atom = GetClassInfo (hinstance, "GSTGL", &wc); atom = GetClassInfo (hinstance, "GSTGL", &wc);
if (atom == 0) if (atom == 0) {
{ ZeroMemory (&wc, sizeof (WNDCLASS));
ZeroMemory (&wc, sizeof(WNDCLASS));
wc.lpfnWndProc = window_proc; wc.lpfnWndProc = window_proc;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
@ -124,12 +125,12 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
atom = RegisterClass (&wc); atom = RegisterClass (&wc);
if (atom == 0) if (atom == 0)
g_error ("Failed to register window class %x\r\n", GetLastError()); g_error ("Failed to register window class %x\r\n", GetLastError ());
} }
} }
static void static void
gst_gl_window_init (GstGLWindow *window) gst_gl_window_init (GstGLWindow * window)
{ {
window->priv = GST_GL_WINDOW_GET_PRIVATE (window); window->priv = GST_GL_WINDOW_GET_PRIVATE (window);
@ -146,7 +147,7 @@ gst_gl_window_new (gint width, gint height)
{ {
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL); GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window); GstGLWindowClass *klass = GST_GL_WINDOW_GET_CLASS (window);
HINSTANCE hinstance = GetModuleHandle (NULL); HINSTANCE hinstance = GetModuleHandle (NULL);
@ -169,22 +170,16 @@ gst_gl_window_new (gint width, gint height)
priv->visible = FALSE; priv->visible = FALSE;
width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); width += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION); height +=
2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
priv->internal_win_id = CreateWindowEx ( priv->internal_win_id = CreateWindowEx (0,
0,
"GSTGL", "GSTGL",
"OpenGL renderer", "OpenGL renderer",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
x, y, width, height, x, y, width, height, (HWND) NULL, (HMENU) NULL, hinstance, window);
(HWND) NULL,
(HMENU) NULL,
hinstance,
window
);
if (!priv->internal_win_id) if (!priv->internal_win_id) {
{
g_debug ("failed to create gl window: %d\n", priv->internal_win_id); g_debug ("failed to create gl window: %d\n", priv->internal_win_id);
return NULL; return NULL;
} }
@ -206,36 +201,41 @@ gst_gl_window_error_quark (void)
} }
void void
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id) gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
WNDPROC window_parent_proc = (WNDPROC) (guint64) GetWindowLongPtr((HWND)id, GWL_WNDPROC); WNDPROC window_parent_proc =
(WNDPROC) (guint64) GetWindowLongPtr ((HWND) id, GWL_WNDPROC);
RECT rect; RECT rect;
SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND)id); SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND) id);
SetProp ((HWND)id, "gl_window_id", priv->internal_win_id); SetProp ((HWND) id, "gl_window_id", priv->internal_win_id);
SetProp ((HWND)id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc);
SetWindowLongPtr ((HWND)id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc); SetWindowLongPtr ((HWND) id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc);
SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE);
SetParent (priv->internal_win_id, (HWND)id); SetParent (priv->internal_win_id, (HWND) id);
//take changes into account: SWP_FRAMECHANGED //take changes into account: SWP_FRAMECHANGED
GetClientRect ((HWND)id, &rect); GetClientRect ((HWND) id, &rect);
SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top,
SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); rect.right, rect.bottom,
MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, rect.bottom, FALSE); SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_FRAMECHANGED | SWP_NOACTIVATE);
MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right,
rect.bottom, FALSE);
} }
void void
gst_gl_window_set_external_gl_context (GstGLWindow *window, guint64 context) gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{ {
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n"); g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
} }
/* Must be called in the gl thread */ /* Must be called in the gl thread */
void void
gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -245,7 +245,8 @@ gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gp
/* Must be called in the gl thread */ /* Must be called in the gl thread */
void void
gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback , gpointer data) gst_gl_window_set_resize_callback (GstGLWindow * window,
GstGLWindowCB2 callback, gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -255,7 +256,8 @@ gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback
/* Must be called in the gl thread */ /* Must be called in the gl thread */
void void
gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_set_close_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -264,19 +266,18 @@ gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, g
} }
void void
gst_gl_window_draw_unlocked (GstGLWindow *window) gst_gl_window_draw_unlocked (GstGLWindow * window)
{ {
gst_gl_window_draw (window); gst_gl_window_draw (window);
} }
/* Thread safe */ /* Thread safe */
void void
gst_gl_window_draw (GstGLWindow *window) gst_gl_window_draw (GstGLWindow * window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
if (!priv->visible) if (!priv->visible) {
{
ShowWindowAsync (priv->internal_win_id, SW_SHOW); ShowWindowAsync (priv->internal_win_id, SW_SHOW);
priv->visible = TRUE; priv->visible = TRUE;
} }
@ -286,7 +287,7 @@ gst_gl_window_draw (GstGLWindow *window)
} }
void void
gst_gl_window_run_loop (GstGLWindow *window) gst_gl_window_run_loop (GstGLWindow * window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
gboolean running = TRUE; gboolean running = TRUE;
@ -295,15 +296,11 @@ gst_gl_window_run_loop (GstGLWindow *window)
g_debug ("begin loop\n"); g_debug ("begin loop\n");
while (running && (bRet = GetMessage (&msg, NULL, 0, 0)) != 0) while (running && (bRet = GetMessage (&msg, NULL, 0, 0)) != 0) {
{ if (bRet == -1) {
if (bRet == -1) g_error ("Failed to get message %x\r\n", GetLastError ());
{
g_error ("Failed to get message %x\r\n", GetLastError());
running = FALSE; running = FALSE;
} } else {
else
{
TranslateMessage (&msg); TranslateMessage (&msg);
DispatchMessage (&msg); DispatchMessage (&msg);
} }
@ -314,12 +311,13 @@ gst_gl_window_run_loop (GstGLWindow *window)
/* Thread safe */ /* Thread safe */
void void
gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_quit_loop (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
LRESULT res = PostMessage(priv->internal_win_id, WM_GST_GL_WINDOW_QUIT, (WPARAM) data, (LPARAM) callback); LRESULT res = PostMessage (priv->internal_win_id, WM_GST_GL_WINDOW_QUIT,
(WPARAM) data, (LPARAM) callback);
g_assert (SUCCEEDED (res)); g_assert (SUCCEEDED (res));
g_debug ("end loop requested\n"); g_debug ("end loop requested\n");
} }
@ -327,12 +325,13 @@ gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer d
/* Thread safe */ /* Thread safe */
void void
gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
LRESULT res = SendMessage (priv->internal_win_id, WM_GST_GL_WINDOW_CUSTOM, (WPARAM) data, (LPARAM) callback); LRESULT res = SendMessage (priv->internal_win_id, WM_GST_GL_WINDOW_CUSTOM,
(WPARAM) data, (LPARAM) callback);
g_assert (SUCCEEDED (res)); g_assert (SUCCEEDED (res));
} }
} }
@ -340,14 +339,14 @@ gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointe
/* PRIVATE */ /* PRIVATE */
void void
gst_gl_window_set_pixel_format (GstGLWindow *window) gst_gl_window_set_pixel_format (GstGLWindow * window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
gint pixelformat = 0; gint pixelformat = 0;
gboolean res = FALSE; gboolean res = FALSE;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1; pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA; pfd.iPixelType = PFD_TYPE_RGBA;
@ -376,7 +375,7 @@ gst_gl_window_set_pixel_format (GstGLWindow *window)
pfd.cColorBits = (BYTE) GetDeviceCaps (priv->device, BITSPIXEL); pfd.cColorBits = (BYTE) GetDeviceCaps (priv->device, BITSPIXEL);
pixelformat = ChoosePixelFormat (priv->device, &pfd ); pixelformat = ChoosePixelFormat (priv->device, &pfd);
g_assert (pixelformat); g_assert (pixelformat);
@ -385,11 +384,13 @@ gst_gl_window_set_pixel_format (GstGLWindow *window)
g_assert (res); g_assert (res);
} }
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK
window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
if (uMsg == WM_CREATE) { if (uMsg == WM_CREATE) {
GstGLWindow *window = (GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams); GstGLWindow *window =
(GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
g_debug ("WM_CREATE\n"); g_debug ("WM_CREATE\n");
@ -403,20 +404,21 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
if (priv->gl_context) if (priv->gl_context)
g_debug ("gl context created: %d\n", priv->gl_context); g_debug ("gl context created: %d\n", priv->gl_context);
else else
g_debug ("failed to create glcontext %d, %x\r\n", hWnd, GetLastError()); g_debug ("failed to create glcontext %d, %x\r\n", hWnd,
GetLastError ());
g_assert (priv->gl_context); g_assert (priv->gl_context);
ReleaseDC (hWnd, priv->device); ReleaseDC (hWnd, priv->device);
if (!wglMakeCurrent (priv->device, priv->gl_context)) if (!wglMakeCurrent (priv->device, priv->gl_context))
g_debug ("failed to make opengl context current %d, %x\r\n", hWnd, GetLastError()); g_debug ("failed to make opengl context current %d, %x\r\n", hWnd,
GetLastError ());
} }
SetProp (hWnd, "gl_window", window); SetProp (hWnd, "gl_window", window);
return 0; return 0;
} } else if (GetProp (hWnd, "gl_window")) {
else if (GetProp(hWnd, "gl_window")) {
GstGLWindow *window = GetProp(hWnd, "gl_window"); GstGLWindow *window = GetProp (hWnd, "gl_window");
GstGLWindowPrivate *priv = NULL; GstGLWindowPrivate *priv = NULL;
g_assert (window); g_assert (window);
@ -427,21 +429,20 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
g_assert (priv->internal_win_id == hWnd); g_assert (priv->internal_win_id == hWnd);
g_assert (priv->gl_context == wglGetCurrentContext()); g_assert (priv->gl_context == wglGetCurrentContext ());
switch ( uMsg ) { switch (uMsg) {
case WM_SIZE: case WM_SIZE:
{ {
if (priv->resize_cb) if (priv->resize_cb)
priv->resize_cb (priv->resize_data, LOWORD(lParam), HIWORD(lParam)); priv->resize_cb (priv->resize_data, LOWORD (lParam), HIWORD (lParam));
break; break;
} }
case WM_PAINT: case WM_PAINT:
{ {
if (priv->draw_cb) if (priv->draw_cb) {
{
PAINTSTRUCT ps; PAINTSTRUCT ps;
BeginPaint (hWnd, &ps); BeginPaint (hWnd, &ps);
priv->draw_cb (priv->draw_data); priv->draw_cb (priv->draw_data);
@ -477,13 +478,13 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
destroy_cb ((gpointer) wParam); destroy_cb ((gpointer) wParam);
parent_id = GetProp (hWnd, "gl_window_parent_id"); parent_id = GetProp (hWnd, "gl_window_parent_id");
if (parent_id) if (parent_id) {
{
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc"); WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
g_assert (parent_proc); g_assert (parent_proc);
SetWindowLongPtr (parent_id, GWL_WNDPROC, (LONG) (guint64) parent_proc); SetWindowLongPtr (parent_id, GWL_WNDPROC,
(LONG) (guint64) parent_proc);
SetParent (hWnd, NULL); SetParent (hWnd, NULL);
RemoveProp (parent_id, "gl_window_parent_proc"); RemoveProp (parent_id, "gl_window_parent_proc");
@ -494,19 +495,19 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
RemoveProp (hWnd, "gl_window"); RemoveProp (hWnd, "gl_window");
if (!wglMakeCurrent (NULL, NULL)) if (!wglMakeCurrent (NULL, NULL))
g_debug ("failed to make current %d, %x\r\n", hWnd, GetLastError()); g_debug ("failed to make current %d, %x\r\n", hWnd, GetLastError ());
if (priv->gl_context) if (priv->gl_context) {
{
if (!wglDeleteContext (priv->gl_context)) if (!wglDeleteContext (priv->gl_context))
g_debug ("failed to destroy context %d, %x\r\n", priv->gl_context, GetLastError()); g_debug ("failed to destroy context %d, %x\r\n", priv->gl_context,
GetLastError ());
} }
if (priv->internal_win_id) if (priv->internal_win_id) {
{
g_debug ("BEFORE\n"); g_debug ("BEFORE\n");
if (!DestroyWindow(priv->internal_win_id)) if (!DestroyWindow (priv->internal_win_id))
g_debug ("failed to destroy window %d, %x\r\n", hWnd, GetLastError()); g_debug ("failed to destroy window %d, %x\r\n", hWnd,
GetLastError ());
g_debug ("AFTER\n"); g_debug ("AFTER\n");
} }
@ -524,8 +525,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_GST_GL_WINDOW_CUSTOM: case WM_GST_GL_WINDOW_CUSTOM:
{ {
if (!priv->is_closed) if (!priv->is_closed) {
{
GstGLWindowCB custom_cb = (GstGLWindowCB) lParam; GstGLWindowCB custom_cb = (GstGLWindowCB) lParam;
custom_cb ((gpointer) wParam); custom_cb ((gpointer) wParam);
} }
@ -536,25 +536,23 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
return TRUE; return TRUE;
default: default:
return DefWindowProc( hWnd, uMsg, wParam, lParam ); return DefWindowProc (hWnd, uMsg, wParam, lParam);
} }
return 0; return 0;
} } else
else return DefWindowProc (hWnd, uMsg, wParam, lParam);
return DefWindowProc( hWnd, uMsg, wParam, lParam );
} }
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT FAR PASCAL
sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
WNDPROC window_parent_proc = GetProp (hWnd, "gl_window_parent_proc"); WNDPROC window_parent_proc = GetProp (hWnd, "gl_window_parent_proc");
if (uMsg == WM_SIZE) if (uMsg == WM_SIZE) {
{
HWND gl_window_id = GetProp (hWnd, "gl_window_id"); HWND gl_window_id = GetProp (hWnd, "gl_window_id");
MoveWindow (gl_window_id, 0, 0, LOWORD(lParam), HIWORD(lParam), FALSE); MoveWindow (gl_window_id, 0, 0, LOWORD (lParam), HIWORD (lParam), FALSE);
} }
return CallWindowProc (window_parent_proc, hWnd, uMsg, wParam, lParam); return CallWindowProc (window_parent_proc, hWnd, uMsg, wParam, lParam);
} }

View file

@ -119,14 +119,14 @@ gst_gl_window_finalize (GObject * object)
XSync (priv->device, FALSE); XSync (priv->device, FALSE);
while(XPending (priv->device)) while (XPending (priv->device))
XNextEvent (priv->device, &event); XNextEvent (priv->device, &event);
XSetCloseDownMode (priv->device, DestroyAll); XSetCloseDownMode (priv->device, DestroyAll);
/*XAddToSaveSet (display, w) /*XAddToSaveSet (display, w)
Display *display; Display *display;
Window w;*/ Window w; */
//FIXME: it seems it causes destroy all created windows, even by other display connection: //FIXME: it seems it causes destroy all created windows, even by other display connection:
//This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink //This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink
@ -142,16 +142,14 @@ gst_gl_window_finalize (GObject * object)
g_debug ("display sender closed\n"); g_debug ("display sender closed\n");
if (priv->cond_send_message) if (priv->cond_send_message) {
{
g_cond_free (priv->cond_send_message); g_cond_free (priv->cond_send_message);
priv->cond_send_message = NULL; priv->cond_send_message = NULL;
} }
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);
if (priv->x_lock) if (priv->x_lock) {
{
g_mutex_free (priv->x_lock); g_mutex_free (priv->x_lock);
priv->x_lock = NULL; priv->x_lock = NULL;
} }
@ -206,8 +204,8 @@ gst_gl_window_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_window_log_handler (const gchar *domain, GLogLevelFlags flags, gst_gl_window_log_handler (const gchar * domain, GLogLevelFlags flags,
const gchar *message, gpointer user_data) const gchar * message, gpointer user_data)
{ {
if (_gst_gl_window_debug) { if (_gst_gl_window_debug) {
g_log_default_handler (domain, flags, message, user_data); g_log_default_handler (domain, flags, message, user_data);
@ -231,7 +229,7 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
} }
static void static void
gst_gl_window_init (GstGLWindow *window) gst_gl_window_init (GstGLWindow * window)
{ {
window->priv = GST_GL_WINDOW_GET_PRIVATE (window); window->priv = GST_GL_WINDOW_GET_PRIVATE (window);
@ -270,7 +268,7 @@ gst_gl_window_new (gint width, gint height)
static gint x = 0; static gint x = 0;
static gint y = 0; static gint y = 0;
setlocale(LC_NUMERIC, "C"); setlocale (LC_NUMERIC, "C");
priv->x_lock = g_mutex_new (); priv->x_lock = g_mutex_new ();
priv->cond_send_message = g_cond_new (); priv->cond_send_message = g_cond_new ();
@ -314,8 +312,7 @@ gst_gl_window_new (gint width, gint height)
priv->visual_info = glXChooseVisual (priv->device, priv->screen_num, attrib); priv->visual_info = glXChooseVisual (priv->device, priv->screen_num, attrib);
if (!priv->visual_info) if (!priv->visual_info) {
{
g_warning ("glx visual is null (bad attributes)\n"); g_warning ("glx visual is null (bad attributes)\n");
return NULL; return NULL;
} }
@ -326,7 +323,8 @@ gst_gl_window_new (gint width, gint height)
if (priv->visual_info->class == TrueColor) if (priv->visual_info->class == TrueColor)
g_debug ("visual is using TrueColor\n"); g_debug ("visual is using TrueColor\n");
g_debug ("visual ID: %d\n", (gint)XVisualIDFromVisual(priv->visual_info->visual)); g_debug ("visual ID: %d\n",
(gint) XVisualIDFromVisual (priv->visual_info->visual));
g_debug ("visual info screen: %d\n", priv->visual_info->screen); g_debug ("visual info screen: %d\n", priv->visual_info->screen);
g_debug ("visual info visualid: %d\n", (gint) priv->visual_info->visualid); g_debug ("visual info visualid: %d\n", (gint) priv->visual_info->visualid);
g_debug ("visual info depth: %d\n", priv->visual_info->depth); g_debug ("visual info depth: %d\n", priv->visual_info->depth);
@ -336,14 +334,17 @@ gst_gl_window_new (gint width, gint height)
g_debug ("visual info blue_mask: %ld\n", priv->visual_info->blue_mask); g_debug ("visual info blue_mask: %ld\n", priv->visual_info->blue_mask);
g_debug ("visual info bits_per_rgb: %d\n", priv->visual_info->bits_per_rgb); g_debug ("visual info bits_per_rgb: %d\n", priv->visual_info->bits_per_rgb);
win_attr.event_mask = StructureNotifyMask | ExposureMask | VisibilityChangeMask; win_attr.event_mask =
StructureNotifyMask | ExposureMask | VisibilityChangeMask;
win_attr.do_not_propagate_mask = NoEventMask; win_attr.do_not_propagate_mask = NoEventMask;
win_attr.background_pixmap = None; win_attr.background_pixmap = None;
win_attr.background_pixel = 0; win_attr.background_pixel = 0;
win_attr.border_pixel = 0; win_attr.border_pixel = 0;
win_attr.colormap = XCreateColormap(priv->device, priv->root, priv->visual_info->visual, AllocNone); win_attr.colormap =
XCreateColormap (priv->device, priv->root, priv->visual_info->visual,
AllocNone);
mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
@ -358,7 +359,8 @@ gst_gl_window_new (gint width, gint height)
XSetWindowBackgroundPixmap (priv->device, priv->internal_win_id, None); XSetWindowBackgroundPixmap (priv->device, priv->internal_win_id, None);
g_debug ("gl window id: %" G_GUINT64_FORMAT "\n", (guint64) priv->internal_win_id); g_debug ("gl window id: %" G_GUINT64_FORMAT "\n",
(guint64) priv->internal_win_id);
g_debug ("gl window props: x:%d y:%d w:%d h:%d\n", x, y, width, height); g_debug ("gl window props: x:%d y:%d w:%d h:%d\n", x, y, width, height);
@ -376,21 +378,22 @@ gst_gl_window_new (gint width, gint height)
XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2); XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2);
priv->gl_context = glXCreateContext (priv->device, priv->visual_info, NULL, TRUE); priv->gl_context =
glXCreateContext (priv->device, priv->visual_info, NULL, TRUE);
g_debug ("gl context id: %ld\n", (gulong) priv->gl_context); g_debug ("gl context id: %ld\n", (gulong) priv->gl_context);
if (!glXIsDirect(priv->device, priv->gl_context)) if (!glXIsDirect (priv->device, priv->gl_context))
g_debug ("direct rendering failed\n"); g_debug ("direct rendering failed\n");
wm_hints.flags = StateHint; wm_hints.flags = StateHint;
wm_hints.initial_state = NormalState; wm_hints.initial_state = NormalState;
wm_hints.input = False; wm_hints.input = False;
XStringListToTextProperty ((char**)&title, 1, &text_property); XStringListToTextProperty ((char **) &title, 1, &text_property);
XSetWMProperties (priv->device, priv->internal_win_id, &text_property, &text_property, 0, 0, XSetWMProperties (priv->device, priv->internal_win_id, &text_property,
NULL, &wm_hints, NULL); &text_property, 0, 0, NULL, &wm_hints, NULL);
XFree (text_property.value); XFree (text_property.value);
@ -417,10 +420,9 @@ gst_gl_window_error_quark (void)
/* Not called by the gl thread */ /* Not called by the gl thread */
void void
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id) gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
XWindowAttributes attr; XWindowAttributes attr;
@ -432,9 +434,11 @@ gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
XGetWindowAttributes (priv->disp_send, priv->parent, &attr); XGetWindowAttributes (priv->disp_send, priv->parent, &attr);
XResizeWindow (priv->disp_send, priv->internal_win_id, attr.width, attr.height); XResizeWindow (priv->disp_send, priv->internal_win_id, attr.width,
attr.height);
XReparentWindow (priv->disp_send, priv->internal_win_id, priv->parent, attr.x, attr.y); XReparentWindow (priv->disp_send, priv->internal_win_id, priv->parent,
attr.x, attr.y);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
@ -443,13 +447,14 @@ gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
} }
void void
gst_gl_window_set_external_gl_context (GstGLWindow *window, guint64 context) gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{ {
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n"); g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
} }
void void
gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -462,7 +467,8 @@ gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gp
} }
void void
gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback , gpointer data) gst_gl_window_set_resize_callback (GstGLWindow * window,
GstGLWindowCB2 callback, gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -475,7 +481,8 @@ gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback
} }
void void
gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_set_close_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -489,12 +496,11 @@ gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, g
/* Called in the gl thread */ /* Called in the gl thread */
void void
gst_gl_window_draw_unlocked (GstGLWindow *window) gst_gl_window_draw_unlocked (GstGLWindow * window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
if (priv->running && priv->allow_extra_expose_events) if (priv->running && priv->allow_extra_expose_events) {
{
XEvent event; XEvent event;
XWindowAttributes attr; XWindowAttributes attr;
@ -510,44 +516,42 @@ gst_gl_window_draw_unlocked (GstGLWindow *window)
event.xexpose.height = attr.height; event.xexpose.height = attr.height;
event.xexpose.count = 0; event.xexpose.count = 0;
XSendEvent (priv->device, priv->internal_win_id, FALSE, ExposureMask, &event); XSendEvent (priv->device, priv->internal_win_id, FALSE, ExposureMask,
&event);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
} }
} }
/* Not called by the gl thread */ /* Not called by the gl thread */
void void
gst_gl_window_draw (GstGLWindow *window) gst_gl_window_draw (GstGLWindow * window)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
if (priv->running) if (priv->running) {
{
XEvent event; XEvent event;
XWindowAttributes attr; XWindowAttributes attr;
if (!priv->visible) if (!priv->visible) {
{
XMapWindow (priv->disp_send, priv->internal_win_id); XMapWindow (priv->disp_send, priv->internal_win_id);
priv->visible = TRUE; priv->visible = TRUE;
} }
XGetWindowAttributes (priv->disp_send, priv->internal_win_id, &attr); XGetWindowAttributes (priv->disp_send, priv->internal_win_id, &attr);
if (priv->parent) if (priv->parent) {
{
XWindowAttributes attr_parent; XWindowAttributes attr_parent;
XGetWindowAttributes (priv->disp_send, priv->parent, &attr_parent); XGetWindowAttributes (priv->disp_send, priv->parent, &attr_parent);
if (attr.x != attr_parent.x || attr.y != attr_parent.y || if (attr.x != attr_parent.x || attr.y != attr_parent.y ||
attr.width != attr_parent.width || attr.height != attr_parent.height) attr.width != attr_parent.width
{ || attr.height != attr_parent.height) {
XMoveResizeWindow (priv->disp_send, priv->internal_win_id, attr_parent.x, attr_parent.y, XMoveResizeWindow (priv->disp_send, priv->internal_win_id,
attr_parent.width, attr_parent.height); attr_parent.x, attr_parent.y, attr_parent.width,
attr_parent.height);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
attr.x = attr_parent.x; attr.x = attr_parent.x;
@ -556,8 +560,8 @@ gst_gl_window_draw (GstGLWindow *window)
attr.width = attr_parent.width; attr.width = attr_parent.width;
attr.height = attr_parent.height; attr.height = attr_parent.height;
g_debug ("parent resize: %d, %d, %d, %d\n", attr_parent.x, attr_parent.y, g_debug ("parent resize: %d, %d, %d, %d\n", attr_parent.x,
attr_parent.width, attr_parent.height); attr_parent.y, attr_parent.width, attr_parent.height);
} }
} }
@ -571,7 +575,8 @@ gst_gl_window_draw (GstGLWindow *window)
event.xexpose.height = attr.height; event.xexpose.height = attr.height;
event.xexpose.count = 0; event.xexpose.count = 0;
XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, ExposureMask, &event); XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, ExposureMask,
&event);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
} }
@ -581,7 +586,7 @@ gst_gl_window_draw (GstGLWindow *window)
/* Called in the gl thread */ /* Called in the gl thread */
void void
gst_gl_window_run_loop (GstGLWindow *window) gst_gl_window_run_loop (GstGLWindow * window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
@ -589,23 +594,21 @@ gst_gl_window_run_loop (GstGLWindow *window)
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
while (priv->running) while (priv->running) {
{
XEvent event; XEvent event;
XEvent pending_event; XEvent pending_event;
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);
/* XSendEvent (which are called in other threads) are done from another display structure */ /* XSendEvent (which are called in other threads) are done from another display structure */
XNextEvent(priv->device, &event); XNextEvent (priv->device, &event);
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
// use in generic/cube and other related uses // use in generic/cube and other related uses
priv->allow_extra_expose_events = XPending (priv->device) <= 2; priv->allow_extra_expose_events = XPending (priv->device) <= 2;
switch (event.type) switch (event.type) {
{
case ClientMessage: case ClientMessage:
{ {
@ -647,9 +650,10 @@ gst_gl_window_run_loop (GstGLWindow *window)
} }
/* User clicked on the cross */ /* User clicked on the cross */
else if (wm_delete != None && (Atom) event.xclient.data.l[0] == wm_delete) else if (wm_delete != None
{ && (Atom) event.xclient.data.l[0] == wm_delete) {
g_debug ("Close %" G_GUINT64_FORMAT "\n", (guint64) priv->internal_win_id); g_debug ("Close %" G_GUINT64_FORMAT "\n",
(guint64) priv->internal_win_id);
if (priv->close_cb) if (priv->close_cb)
priv->close_cb (priv->close_data); priv->close_cb (priv->close_data);
@ -679,7 +683,8 @@ gst_gl_window_run_loop (GstGLWindow *window)
gpointer destroy_data = (gpointer) event.xclient.data.l[1]; gpointer destroy_data = (gpointer) event.xclient.data.l[1];
#endif #endif
g_debug ("Quit loop message %" G_GUINT64_FORMAT "\n", (guint64) priv->internal_win_id); g_debug ("Quit loop message %" G_GUINT64_FORMAT "\n",
(guint64) priv->internal_win_id);
/* exit loop */ /* exit loop */
priv->running = FALSE; priv->running = FALSE;
@ -716,9 +721,8 @@ gst_gl_window_run_loop (GstGLWindow *window)
destroy_cb (destroy_data); destroy_cb (destroy_data);
} } else
else g_debug ("client message not reconized \n");
g_debug("client message not reconized \n");
break; break;
} }
@ -726,7 +730,8 @@ gst_gl_window_run_loop (GstGLWindow *window)
case ConfigureNotify: case ConfigureNotify:
{ {
if (priv->resize_cb) if (priv->resize_cb)
priv->resize_cb (priv->resize_data, event.xconfigure.width, event.xconfigure.height); priv->resize_cb (priv->resize_data, event.xconfigure.width,
event.xconfigure.height);
break; break;
} }
@ -735,18 +740,16 @@ gst_gl_window_run_loop (GstGLWindow *window)
break; break;
case Expose: case Expose:
if (priv->draw_cb) if (priv->draw_cb) {
{
priv->draw_cb (priv->draw_data); priv->draw_cb (priv->draw_data);
glFlush(); glFlush ();
glXSwapBuffers (priv->device, priv->internal_win_id); glXSwapBuffers (priv->device, priv->internal_win_id);
} }
break; break;
case VisibilityNotify: case VisibilityNotify:
{ {
switch (event.xvisibility.state) switch (event.xvisibility.state) {
{
case VisibilityUnobscured: case VisibilityUnobscured:
if (priv->draw_cb) if (priv->draw_cb)
priv->draw_cb (priv->draw_data); priv->draw_cb (priv->draw_data);
@ -761,7 +764,8 @@ gst_gl_window_run_loop (GstGLWindow *window)
break; break;
default: default:
g_debug("unknown xvisibility event: %d\n", event.xvisibility.state); g_debug ("unknown xvisibility event: %d\n",
event.xvisibility.state);
break; break;
} }
break; break;
@ -771,9 +775,9 @@ gst_gl_window_run_loop (GstGLWindow *window)
g_debug ("unknow\n"); g_debug ("unknow\n");
break; break;
}// switch } // switch
}// while running } // while running
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);
@ -782,23 +786,23 @@ gst_gl_window_run_loop (GstGLWindow *window)
/* Not called by the gl thread */ /* Not called by the gl thread */
void void
gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_quit_loop (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
if (priv->running) if (priv->running) {
{
XEvent event; XEvent event;
event.xclient.type = ClientMessage; event.xclient.type = ClientMessage;
event.xclient.send_event = TRUE; event.xclient.send_event = TRUE;
event.xclient.display = priv->disp_send; event.xclient.display = priv->disp_send;
event.xclient.window = priv->internal_win_id; event.xclient.window = priv->internal_win_id;
event.xclient.message_type = XInternAtom (priv->disp_send, "WM_QUIT_LOOP", True);; event.xclient.message_type =
XInternAtom (priv->disp_send, "WM_QUIT_LOOP", True);;
event.xclient.format = 32; event.xclient.format = 32;
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff; event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
@ -810,7 +814,8 @@ gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer d
event.xclient.data.l[1] = (long) data; event.xclient.data.l[1] = (long) data;
#endif #endif
XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask, &event); XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask,
&event);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
} }
@ -820,23 +825,23 @@ gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer d
/* Not called by the gl thread */ /* Not called by the gl thread */
void void
gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data) gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{ {
if (window) if (window) {
{
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
if (priv->running) if (priv->running) {
{
XEvent event; XEvent event;
event.xclient.type = ClientMessage; event.xclient.type = ClientMessage;
event.xclient.send_event = TRUE; event.xclient.send_event = TRUE;
event.xclient.display = priv->disp_send; event.xclient.display = priv->disp_send;
event.xclient.window = priv->internal_win_id; event.xclient.window = priv->internal_win_id;
event.xclient.message_type = XInternAtom (priv->disp_send, "WM_GL_WINDOW", True); event.xclient.message_type =
XInternAtom (priv->disp_send, "WM_GL_WINDOW", True);
event.xclient.format = 32; event.xclient.format = 32;
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff; event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
@ -848,7 +853,8 @@ gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointe
event.xclient.data.l[1] = (long) data; event.xclient.data.l[1] = (long) data;
#endif #endif
XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask, &event); XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask,
&event);
XSync (priv->disp_send, FALSE); XSync (priv->disp_send, FALSE);
/* block until opengl calls have been executed in the gl thread */ /* block until opengl calls have been executed in the gl thread */

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_bulge_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_bulge_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "bulge0", shader); g_hash_table_insert (effects->shaderstable, "bulge0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, bulge_fragment_source, bulge_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_bulge (GstGLEffects *effects) { gst_gl_effects_bulge (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_bulge_callback, effects); effects->outtexture, gst_gl_effects_bulge_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_fisheye_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_fisheye_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture, gpointe
g_hash_table_insert (effects->shaderstable, "fisheye0", shader); g_hash_table_insert (effects->shaderstable, "fisheye0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, fisheye_fragment_source, fisheye_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture, gpointe
} }
void void
gst_gl_effects_fisheye (GstGLEffects *effects) { gst_gl_effects_fisheye (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_fisheye_callback, effects); effects->outtexture, gst_gl_effects_fisheye_callback, effects);
} }

View file

@ -22,12 +22,14 @@
static gfloat gauss_kernel[9] = { 0.060493f, 0.075284f, 0.088016f, static gfloat gauss_kernel[9] = { 0.060493f, 0.075284f, 0.088016f,
0.096667f, 0.099736f, 0.096667f, 0.096667f, 0.099736f, 0.096667f,
0.088016f, 0.075284f, 0.060493f }; 0.088016f, 0.075284f, 0.060493f
};
static void static void
gst_gl_effects_glow_step_one (gint width, gint height, guint texture, gpointer data) gst_gl_effects_glow_step_one (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -38,9 +40,8 @@ gst_gl_effects_glow_step_one (gint width, gint height, guint texture, gpointer d
g_hash_table_insert (effects->shaderstable, "glow0", shader); g_hash_table_insert (effects->shaderstable, "glow0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, luma_threshold_fragment_source, luma_threshold_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -57,9 +58,10 @@ gst_gl_effects_glow_step_one (gint width, gint height, guint texture, gpointer d
} }
static void static void
gst_gl_effects_glow_step_two (gint width, gint height, guint texture, gpointer stuff) gst_gl_effects_glow_step_two (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (stuff); GstGLEffects *effects = GST_GL_EFFECTS (stuff);
GstGLShader *shader; GstGLShader *shader;
/* hard coded kernel, it could be easily generated at runtime with a /* hard coded kernel, it could be easily generated at runtime with a
@ -72,9 +74,8 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, gpointer s
g_hash_table_insert (effects->shaderstable, "glow1", shader); g_hash_table_insert (effects->shaderstable, "glow1", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, hconv9_fragment_source, hconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -96,9 +97,10 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, gpointer s
} }
void void
gst_gl_effects_glow_step_three (gint width, gint height, guint texture, gpointer stuff) gst_gl_effects_glow_step_three (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (stuff); GstGLEffects *effects = GST_GL_EFFECTS (stuff);
GstGLShader *shader; GstGLShader *shader;
shader = g_hash_table_lookup (effects->shaderstable, "glow2"); shader = g_hash_table_lookup (effects->shaderstable, "glow2");
@ -108,9 +110,8 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "glow2", shader); g_hash_table_insert (effects->shaderstable, "glow2", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, vconv9_fragment_source, vconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -132,9 +133,10 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_glow_step_four (gint width, gint height, guint texture, gpointer stuff) gst_gl_effects_glow_step_four (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (stuff); GstGLEffects *effects = GST_GL_EFFECTS (stuff);
GstGLShader *shader; GstGLShader *shader;
shader = g_hash_table_lookup (effects->shaderstable, "glow3"); shader = g_hash_table_lookup (effects->shaderstable, "glow3");
@ -144,9 +146,8 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "glow3", shader); g_hash_table_insert (effects->shaderstable, "glow3", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, sum_fragment_source, sum_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -156,7 +157,7 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture, gpointer
glActiveTexture (GL_TEXTURE2); glActiveTexture (GL_TEXTURE2);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->intexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->intexture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0); gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0);
gst_gl_shader_set_uniform_1i (shader, "base", 2); gst_gl_shader_set_uniform_1i (shader, "base", 2);
@ -164,27 +165,28 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture, gpointer
glActiveTexture (GL_TEXTURE1); glActiveTexture (GL_TEXTURE1);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1f (shader, "beta", (gfloat) 1/3.5f); gst_gl_shader_set_uniform_1f (shader, "beta", (gfloat) 1 / 3.5f);
gst_gl_shader_set_uniform_1i (shader, "blend", 1); gst_gl_shader_set_uniform_1i (shader, "blend", 1);
gst_gl_effects_draw_texture (effects, texture); gst_gl_effects_draw_texture (effects, texture);
} }
void void
gst_gl_effects_glow (GstGLEffects *effects) { gst_gl_effects_glow (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
/* threshold */ /* threshold */
gst_gl_filter_render_to_target (filter, effects->intexture, effects->midtexture[0], gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_glow_step_one, effects); effects->midtexture[0], gst_gl_effects_glow_step_one, effects);
/* blur */ /* blur */
gst_gl_filter_render_to_target (filter, effects->midtexture[0], effects->midtexture[1], gst_gl_filter_render_to_target (filter, effects->midtexture[0],
gst_gl_effects_glow_step_two, effects); effects->midtexture[1], gst_gl_effects_glow_step_two, effects);
gst_gl_filter_render_to_target (filter, effects->midtexture[1], effects->midtexture[2], gst_gl_filter_render_to_target (filter, effects->midtexture[1],
gst_gl_effects_glow_step_three, effects); effects->midtexture[2], gst_gl_effects_glow_step_three, effects);
/* add blurred luma to intexture */ /* add blurred luma to intexture */
gst_gl_filter_render_to_target (filter, effects->midtexture[2], effects->outtexture, gst_gl_filter_render_to_target (filter, effects->midtexture[2],
gst_gl_effects_glow_step_four, effects); effects->outtexture, gst_gl_effects_glow_step_four, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_identity_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_identity_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -32,9 +33,10 @@ gst_gl_effects_identity_callback (gint width, gint height, guint texture, gpoint
} }
void void
gst_gl_effects_identity (GstGLEffects *effects) { gst_gl_effects_identity (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_identity_callback, effects); effects->outtexture, gst_gl_effects_identity_callback, effects);
} }

View file

@ -21,11 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
#include <gstgleffectlumatocurve.h> #include <gstgleffectlumatocurve.h>
void gst_gl_effects_luma_to_curve (GstGLEffects *effects, void
gst_gl_effects_luma_to_curve (GstGLEffects * effects,
GstGLEffectsCurve curve, GstGLEffectsCurve curve,
gint curve_index, gint curve_index, gint width, gint height, GLuint texture)
gint width, gint height,
GLuint texture)
{ {
GstGLShader *shader; GstGLShader *shader;
@ -36,9 +35,8 @@ void gst_gl_effects_luma_to_curve (GstGLEffects *effects,
g_hash_table_insert (effects->shaderstable, "lumamap0", shader); g_hash_table_insert (effects->shaderstable, "lumamap0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, luma_to_curve_fragment_source, luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -47,20 +45,18 @@ void gst_gl_effects_luma_to_curve (GstGLEffects *effects,
if (effects->curve[curve_index] == 0) { if (effects->curve[curve_index] == 0) {
/* this parameters are needed to have a right, predictable, mapping */ /* this parameters are needed to have a right, predictable, mapping */
glGenTextures(1, &effects->curve[curve_index]); glGenTextures (1, &effects->curve[curve_index]);
glEnable(GL_TEXTURE_1D); glEnable (GL_TEXTURE_1D);
glBindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); glBindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage1D(GL_TEXTURE_1D, 0, curve.bytes_per_pixel, glTexImage1D (GL_TEXTURE_1D, 0, curve.bytes_per_pixel,
curve.width, 0, curve.width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve.pixel_data);
GL_RGB, GL_UNSIGNED_BYTE,
curve.pixel_data);
glDisable(GL_TEXTURE_1D); glDisable (GL_TEXTURE_1D);
} }
glActiveTexture (GL_TEXTURE2); glActiveTexture (GL_TEXTURE2);
@ -82,51 +78,59 @@ void gst_gl_effects_luma_to_curve (GstGLEffects *effects,
gst_gl_effects_draw_texture (effects, texture); gst_gl_effects_draw_texture (effects, texture);
} }
static void gst_gl_effects_heat_callback (gint width, gint height, guint texture, gpointer data) static void
gst_gl_effects_heat_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
gst_gl_effects_luma_to_curve (effects, heat_curve, GST_GL_EFFECTS_CURVE_HEAT, gst_gl_effects_luma_to_curve (effects, heat_curve, GST_GL_EFFECTS_CURVE_HEAT,
width, height, texture); width, height, texture);
} }
void void
gst_gl_effects_heat (GstGLEffects *effects) { gst_gl_effects_heat (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_heat_callback, effects); effects->outtexture, gst_gl_effects_heat_callback, effects);
} }
static void gst_gl_effects_sepia_callback (gint width, gint height, guint texture, gpointer data) static void
gst_gl_effects_sepia_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
gst_gl_effects_luma_to_curve (effects, sepia_curve, GST_GL_EFFECTS_CURVE_SEPIA, gst_gl_effects_luma_to_curve (effects, sepia_curve,
width, height, texture); GST_GL_EFFECTS_CURVE_SEPIA, width, height, texture);
} }
void void
gst_gl_effects_sepia (GstGLEffects *effects) { gst_gl_effects_sepia (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_sepia_callback, effects); effects->outtexture, gst_gl_effects_sepia_callback, effects);
} }
static void gst_gl_effects_luma_xpro_callback (gint width, gint height, guint texture, gpointer data) static void
gst_gl_effects_luma_xpro_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
gst_gl_effects_luma_to_curve (effects, luma_xpro_curve, GST_GL_EFFECTS_CURVE_LUMA_XPRO, gst_gl_effects_luma_to_curve (effects, luma_xpro_curve,
width, height, texture); GST_GL_EFFECTS_CURVE_LUMA_XPRO, width, height, texture);
} }
void void
gst_gl_effects_luma_xpro (GstGLEffects *effects) { gst_gl_effects_luma_xpro (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_luma_xpro_callback, effects); effects->outtexture, gst_gl_effects_luma_xpro_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "mirror0", shader); g_hash_table_insert (effects->shaderstable, "mirror0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, mirror_fragment_source, mirror_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_mirror (GstGLEffects *effects) { gst_gl_effects_mirror (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_mirror_callback, effects); effects->outtexture, gst_gl_effects_mirror_callback, effects);
} }

View file

@ -21,11 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
#include <gstgleffectscurves.h> #include <gstgleffectscurves.h>
static void gst_gl_effects_rgb_to_curve (GstGLEffects *effects, static void
gst_gl_effects_rgb_to_curve (GstGLEffects * effects,
GstGLEffectsCurve curve, GstGLEffectsCurve curve,
gint curve_index, gint curve_index, gint width, gint height, GLuint texture)
gint width, gint height,
GLuint texture)
{ {
GstGLShader *shader; GstGLShader *shader;
@ -36,9 +35,8 @@ static void gst_gl_effects_rgb_to_curve (GstGLEffects *effects,
g_hash_table_insert (effects->shaderstable, "rgbmap0", shader); g_hash_table_insert (effects->shaderstable, "rgbmap0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, rgb_to_curve_fragment_source, rgb_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -47,20 +45,18 @@ static void gst_gl_effects_rgb_to_curve (GstGLEffects *effects,
if (effects->curve[curve_index] == 0) { if (effects->curve[curve_index] == 0) {
/* this parameters are needed to have a right, predictable, mapping */ /* this parameters are needed to have a right, predictable, mapping */
glGenTextures(1, &effects->curve[curve_index]); glGenTextures (1, &effects->curve[curve_index]);
glEnable(GL_TEXTURE_1D); glEnable (GL_TEXTURE_1D);
glBindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); glBindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage1D(GL_TEXTURE_1D, 0, curve.bytes_per_pixel, glTexImage1D (GL_TEXTURE_1D, 0, curve.bytes_per_pixel,
curve.width, 0, curve.width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve.pixel_data);
GL_RGB, GL_UNSIGNED_BYTE,
curve.pixel_data);
glDisable(GL_TEXTURE_1D); glDisable (GL_TEXTURE_1D);
} }
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
@ -82,18 +78,21 @@ static void gst_gl_effects_rgb_to_curve (GstGLEffects *effects,
gst_gl_effects_draw_texture (effects, texture); gst_gl_effects_draw_texture (effects, texture);
} }
static void gst_gl_effects_xpro_callback (gint width, gint height, guint texture, gpointer data) static void
gst_gl_effects_xpro_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
gst_gl_effects_rgb_to_curve (effects, xpro_curve, GST_GL_EFFECTS_CURVE_XPRO, gst_gl_effects_rgb_to_curve (effects, xpro_curve, GST_GL_EFFECTS_CURVE_XPRO,
width, height, texture); width, height, texture);
} }
void void
gst_gl_effects_xpro (GstGLEffects *effects) { gst_gl_effects_xpro (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_xpro_callback, effects); effects->outtexture, gst_gl_effects_xpro_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_sin_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_sin_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_sin_callback (gint width, gint height, guint texture, gpointer da
g_hash_table_insert (effects->shaderstable, "sin0", shader); g_hash_table_insert (effects->shaderstable, "sin0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, sin_fragment_source, sin_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -53,9 +53,10 @@ gst_gl_effects_sin_callback (gint width, gint height, guint texture, gpointer da
} }
void void
gst_gl_effects_sin (GstGLEffects *effects) { gst_gl_effects_sin (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_sin_callback, effects); effects->outtexture, gst_gl_effects_sin_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_square_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_square_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "square0", shader); g_hash_table_insert (effects->shaderstable, "square0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, square_fragment_source, square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_square (GstGLEffects *effects) { gst_gl_effects_square (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_square_callback, effects); effects->outtexture, gst_gl_effects_square_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointe
g_hash_table_insert (effects->shaderstable, "squeeze0", shader); g_hash_table_insert (effects->shaderstable, "squeeze0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, squeeze_fragment_source, squeeze_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointe
} }
void void
gst_gl_effects_squeeze (GstGLEffects *effects) { gst_gl_effects_squeeze (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_squeeze_callback, effects); effects->outtexture, gst_gl_effects_squeeze_callback, effects);
} }

View file

@ -38,8 +38,7 @@ const gchar *mirror_fragment_source =
" normcoord.x *= sign (normcoord.x);" " normcoord.x *= sign (normcoord.x);"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord); " " vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color * gl_Color;" " gl_FragColor = color * gl_Color;" "}";
"}";
/* Squeeze effect */ /* Squeeze effect */
@ -57,8 +56,7 @@ const gchar *squeeze_fragment_source =
" normcoord = normcoord / r;" " normcoord = normcoord / r;"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord); " " vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color * gl_Color;" " gl_FragColor = color * gl_Color;" "}";
"}";
/* Stretch Effect */ /* Stretch Effect */
@ -75,8 +73,7 @@ const gchar *stretch_fragment_source =
" normcoord *= 2.0 - smoothstep(0.0, 0.7, r);" " normcoord *= 2.0 - smoothstep(0.0, 0.7, r);"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord);" " vec4 color = texture2DRect (tex, texturecoord);"
" gl_FragColor = color * gl_Color;" " gl_FragColor = color * gl_Color;" "}";
"}";
/* Light Tunnel effect */ /* Light Tunnel effect */
const gchar *tunnel_fragment_source = const gchar *tunnel_fragment_source =
@ -85,19 +82,14 @@ const gchar *tunnel_fragment_source =
"uniform float width, height;" "uniform float width, height;"
"void main () {" "void main () {"
" vec2 tex_size = vec2 (width, height);" " vec2 tex_size = vec2 (width, height);"
" vec2 texturecoord = gl_TexCoord[0].xy;" " vec2 texturecoord = gl_TexCoord[0].xy;" " vec2 normcoord;"
" vec2 normcoord;"
/* little trick with normalized coords to obtain a circle */ /* little trick with normalized coords to obtain a circle */
" normcoord = texturecoord / tex_size.x - tex_size / tex_size.x;" " normcoord = texturecoord / tex_size.x - tex_size / tex_size.x;" " float r = length(normcoord);" " float phi = atan(normcoord.y, normcoord.x);" " r = clamp (r, 0.0, 0.5);" /* is there a way to do this without polars? */
" float r = length(normcoord);"
" float phi = atan(normcoord.y, normcoord.x);"
" r = clamp (r, 0.0, 0.5);" /* is there a way to do this without polars? */
" normcoord.x = r * cos(phi);" " normcoord.x = r * cos(phi);"
" normcoord.y = r * sin(phi); " " normcoord.y = r * sin(phi); "
" texturecoord = (normcoord + tex_size/tex_size.x) * tex_size.x;" " texturecoord = (normcoord + tex_size/tex_size.x) * tex_size.x;"
" vec4 color = texture2DRect (tex, texturecoord); " " vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color;" " gl_FragColor = color;" "}";
"}";
/* FishEye effect */ /* FishEye effect */
const gchar *fisheye_fragment_source = const gchar *fisheye_fragment_source =
@ -113,8 +105,7 @@ const gchar *fisheye_fragment_source =
" normcoord *= r/sqrt(2.0);" " normcoord *= r/sqrt(2.0);"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord);" " vec4 color = texture2DRect (tex, texturecoord);"
" gl_FragColor = color;" " gl_FragColor = color;" "}";
"}";
/* Twirl effect */ /* Twirl effect */
@ -134,8 +125,7 @@ const gchar *twirl_fragment_source =
" normcoord.y = r * sin(phi);" " normcoord.y = r * sin(phi);"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord); " " vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color;" " gl_FragColor = color;" "}";
"}";
/* Bulge effect */ /* Bulge effect */
@ -152,8 +142,7 @@ const gchar *bulge_fragment_source =
" normcoord *= smoothstep (-0.1, 0.5, r);" " normcoord *= smoothstep (-0.1, 0.5, r);"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord);" " vec4 color = texture2DRect (tex, texturecoord);"
" gl_FragColor = color;" " gl_FragColor = color;" "}";
"}";
/* Square Effect */ /* Square Effect */
@ -172,18 +161,10 @@ const gchar *square_fragment_source =
" normcoord /= 2.0; /* zoom amount */" " normcoord /= 2.0; /* zoom amount */"
" texturecoord = (normcoord + 1.0) * tex_size;" " texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord);" " vec4 color = texture2DRect (tex, texturecoord);"
" gl_FragColor = color * gl_Color;" " gl_FragColor = color * gl_Color;" "}";
"}";
const gchar *luma_threshold_fragment_source = const gchar *luma_threshold_fragment_source = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" "void main () {" " vec2 texturecoord = gl_TexCoord[0].st;" " int i;" " vec4 color = texture2DRect(tex, texturecoord);" " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));" /* BT.709 (from orange book) */
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].st;"
" int i;"
" vec4 color = texture2DRect(tex, texturecoord);"
" float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));" /* BT.709 (from orange book) */
" gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);" " gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);"
"}"; "}";
@ -211,9 +192,7 @@ const gchar *sobel_fragment_source =
" }" " }"
" }" " }"
" float g = sqrt(gx*gx + gy*gy);" " float g = sqrt(gx*gx + gy*gy);"
" if (invert) g = 1.0 - g;" " if (invert) g = 1.0 - g;" " gl_FragColor = vec4(vec3(g), 1.0);" "}";
" gl_FragColor = vec4(vec3(g), 1.0);"
"}";
/* horizontal convolution */ /* horizontal convolution */
@ -221,9 +200,7 @@ const gchar *hconv9_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;" "uniform sampler2DRect tex;"
"uniform float norm_const;" "uniform float norm_const;"
"uniform float norm_offset;" "uniform float norm_offset;" "uniform float kernel[9];" "void main () {"
"uniform float kernel[9];"
"void main () {"
/* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */ /* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */
/* don't use array constructor so we don't have to depend on #version 120 */ /* don't use array constructor so we don't have to depend on #version 120 */
" float offset[9];" " float offset[9];"
@ -243,19 +220,14 @@ const gchar *hconv9_fragment_source =
" if (kernel[i] != 0.0) {" " if (kernel[i] != 0.0) {"
" vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s+offset[i], texturecoord.t)); " " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s+offset[i], texturecoord.t)); "
" sum += neighbor * kernel[i]/norm_const; " " sum += neighbor * kernel[i]/norm_const; "
" }" " }" " }" " gl_FragColor = sum + norm_offset;" "}";
" }"
" gl_FragColor = sum + norm_offset;"
"}";
/* vertical convolution */ /* vertical convolution */
const gchar *vconv9_fragment_source = const gchar *vconv9_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;" "uniform sampler2DRect tex;"
"uniform float norm_const;" "uniform float norm_const;"
"uniform float norm_offset;" "uniform float norm_offset;" "uniform float kernel[9];" "void main () {"
"uniform float kernel[9];"
"void main () {"
/* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */ /* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */
/* don't use array constructor so we don't have to depend on #version 120 */ /* don't use array constructor so we don't have to depend on #version 120 */
" float offset[9];" " float offset[9];"
@ -275,10 +247,7 @@ const gchar *vconv9_fragment_source =
" if (kernel[i] != 0.0) {" " if (kernel[i] != 0.0) {"
" vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s, texturecoord.t+offset[i])); " " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s, texturecoord.t+offset[i])); "
" sum += neighbor * kernel[i]/norm_const; " " sum += neighbor * kernel[i]/norm_const; "
" }" " }" " }" " gl_FragColor = sum + norm_offset;" "}";
" }"
" gl_FragColor = sum + norm_offset;"
"}";
/* TODO: support several blend modes */ /* TODO: support several blend modes */
@ -291,8 +260,7 @@ const gchar *sum_fragment_source =
"void main () {" "void main () {"
" vec4 basecolor = texture2DRect (base, gl_TexCoord[0].st);" " vec4 basecolor = texture2DRect (base, gl_TexCoord[0].st);"
" vec4 blendcolor = texture2DRect (blend, gl_TexCoord[0].st);" " vec4 blendcolor = texture2DRect (blend, gl_TexCoord[0].st);"
" gl_FragColor = alpha * basecolor + beta * blendcolor;" " gl_FragColor = alpha * basecolor + beta * blendcolor;" "}";
"}";
const gchar *multiply_fragment_source = const gchar *multiply_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
@ -314,9 +282,7 @@ const gchar *luma_to_curve_fragment_source =
" vec2 texturecoord = gl_TexCoord[0].st;" " vec2 texturecoord = gl_TexCoord[0].st;"
" vec4 color = texture2DRect (tex, texturecoord);" " vec4 color = texture2DRect (tex, texturecoord);"
" float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));" " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
" color = texture1D(curve, luma);" " color = texture1D(curve, luma);" " gl_FragColor = color;" "}";
" gl_FragColor = color;"
"}";
/* lut operations, map rgb to tex1d, see orange book (chapter 19) */ /* lut operations, map rgb to tex1d, see orange book (chapter 19) */
@ -331,15 +297,11 @@ const gchar *rgb_to_curve_fragment_source =
" outcolor.r = texture1D(curve, color.r).r;" " outcolor.r = texture1D(curve, color.r).r;"
" outcolor.g = texture1D(curve, color.g).g;" " outcolor.g = texture1D(curve, color.g).g;"
" outcolor.b = texture1D(curve, color.b).b;" " outcolor.b = texture1D(curve, color.b).b;"
" outcolor.a = color.a;" " outcolor.a = color.a;" " gl_FragColor = outcolor;" "}";
" gl_FragColor = outcolor;"
"}";
const gchar *sin_fragment_source = const gchar *sin_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;" "uniform sampler2DRect tex;" "vec3 rgb2hsl (vec3 v) " "{"
"vec3 rgb2hsl (vec3 v) "
"{"
/* TODO: check this algorythm */ /* TODO: check this algorythm */
" float MIN, MAX;" " float MIN, MAX;"
" float r, g, b;" " float r, g, b;"
@ -371,16 +333,14 @@ const gchar *sin_fragment_source =
/* move hls discontinuity away from the desired red zone so we can use /* move hls discontinuity away from the desired red zone so we can use
* smoothstep.. to try: convert degrees in radiants, divide by 2 and * smoothstep.. to try: convert degrees in radiants, divide by 2 and
* smoothstep cosine */ * smoothstep cosine */
" HSL.x += 180.0;" " HSL.x += 180.0;" " if ((HSL.x) > 360.0) HSL.x -= 360.0;"
" if ((HSL.x) > 360.0) HSL.x -= 360.0;"
/* damn, it is extremely hard to get rid of human face reds! */ /* damn, it is extremely hard to get rid of human face reds! */
/* picked hue is slightly shifted towards violet to prevent this but /* picked hue is slightly shifted towards violet to prevent this but
* still fails.. maybe hsl is not well suited for this */ * still fails.. maybe hsl is not well suited for this */
" float a = smoothstep (110.0, 150.0, HSL.x);" " float a = smoothstep (110.0, 150.0, HSL.x);"
" float b = smoothstep (170.0, 210.0, HSL.x);" " float b = smoothstep (170.0, 210.0, HSL.x);"
" float alpha = a - b;" " float alpha = a - b;"
" gl_FragColor = color * alpha + luma * (1.0 - alpha);" " gl_FragColor = color * alpha + luma * (1.0 - alpha);" "}";
"}";
const gchar *interpolate_fragment_source = const gchar *interpolate_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
@ -390,8 +350,7 @@ const gchar *interpolate_fragment_source =
"vec4 basecolor = texture2DRect (base, gl_TexCoord[0].st);" "vec4 basecolor = texture2DRect (base, gl_TexCoord[0].st);"
"vec4 blendcolor = texture2DRect (blend, gl_TexCoord[0].st);" "vec4 blendcolor = texture2DRect (blend, gl_TexCoord[0].st);"
"vec4 white = vec4(1.0);" "vec4 white = vec4(1.0);"
"gl_FragColor = blendcolor + (1.0 - blendcolor.a) * basecolor;" "gl_FragColor = blendcolor + (1.0 - blendcolor.a) * basecolor;" "}";
"}";
const gchar *texture_interp_fragment_source = const gchar *texture_interp_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_stretch_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_stretch_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture, gpointe
g_hash_table_insert (effects->shaderstable, "stretch0", shader); g_hash_table_insert (effects->shaderstable, "stretch0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, stretch_fragment_source, stretch_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture, gpointe
} }
void void
gst_gl_effects_stretch (GstGLEffects *effects) { gst_gl_effects_stretch (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_stretch_callback, effects); effects->outtexture, gst_gl_effects_stretch_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_tunnel_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_tunnel_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "tunnel0", shader); g_hash_table_insert (effects->shaderstable, "tunnel0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, tunnel_fragment_source, tunnel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_tunnel (GstGLEffects *effects) { gst_gl_effects_tunnel (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_tunnel_callback, effects); effects->outtexture, gst_gl_effects_tunnel_callback, effects);
} }

View file

@ -21,9 +21,10 @@
#include <gstgleffects.h> #include <gstgleffects.h>
static void static void
gst_gl_effects_twirl_callback (gint width, gint height, guint texture, gpointer data) gst_gl_effects_twirl_callback (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
@ -34,9 +35,8 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "twirl0", shader); g_hash_table_insert (effects->shaderstable, "twirl0", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, twirl_fragment_source, twirl_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -56,9 +56,10 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_twirl (GstGLEffects *effects) { gst_gl_effects_twirl (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_twirl_callback, effects); effects->outtexture, gst_gl_effects_twirl_callback, effects);
} }

View file

@ -25,21 +25,26 @@
/* Gaussian Kernel: std = 1.200000, size = 9x1 */ /* Gaussian Kernel: std = 1.200000, size = 9x1 */
static gfloat gauss_kernel[9] = { 0.001285f, 0.014607f, 0.082898f, static gfloat gauss_kernel[9] = { 0.001285f, 0.014607f, 0.082898f,
0.234927f, 0.332452f, 0.234927f, 0.234927f, 0.332452f, 0.234927f,
0.082898f, 0.014607f, 0.001285f }; 0.082898f, 0.014607f, 0.001285f
};
/* Normalization Constant = 0.999885 */ /* Normalization Constant = 0.999885 */
static void gst_gl_effects_xray_step_one (gint width, gint height, guint texture, gpointer data) static void
gst_gl_effects_xray_step_one (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
gst_gl_effects_luma_to_curve (effects, xray_curve, GST_GL_EFFECTS_CURVE_XRAY, gst_gl_effects_luma_to_curve (effects, xray_curve, GST_GL_EFFECTS_CURVE_XRAY,
width, height, texture); width, height, texture);
} }
static void static void
gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer data) gst_gl_effects_xray_step_two (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
shader = g_hash_table_lookup (effects->shaderstable, "xray1"); shader = g_hash_table_lookup (effects->shaderstable, "xray1");
@ -49,9 +54,8 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer d
g_hash_table_insert (effects->shaderstable, "xray1", shader); g_hash_table_insert (effects->shaderstable, "xray1", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, hconv9_fragment_source, hconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -73,9 +77,10 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer d
} }
static void static void
gst_gl_effects_xray_step_three (gint width, gint height, guint texture, gpointer data) gst_gl_effects_xray_step_three (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
shader = g_hash_table_lookup (effects->shaderstable, "xray2"); shader = g_hash_table_lookup (effects->shaderstable, "xray2");
@ -85,9 +90,8 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "xray2", shader); g_hash_table_insert (effects->shaderstable, "xray2", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, vconv9_fragment_source, vconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -109,9 +113,10 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, gpointer
} }
static void static void
gst_gl_effects_xray_step_four (gint width, gint height, guint texture, gpointer data) gst_gl_effects_xray_step_four (gint width, gint height, guint texture,
gpointer data)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (data); GstGLEffects *effects = GST_GL_EFFECTS (data);
GstGLShader *shader; GstGLShader *shader;
gfloat hkern[9] = { gfloat hkern[9] = {
@ -133,9 +138,8 @@ gst_gl_effects_xray_step_four (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "xray3", shader); g_hash_table_insert (effects->shaderstable, "xray3", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, sobel_fragment_source, sobel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -158,9 +162,10 @@ gst_gl_effects_xray_step_four (gint width, gint height, guint texture, gpointer
} }
void void
gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer stuff) gst_gl_effects_xray_step_five (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLEffects* effects = GST_GL_EFFECTS (stuff); GstGLEffects *effects = GST_GL_EFFECTS (stuff);
GstGLShader *shader; GstGLShader *shader;
shader = g_hash_table_lookup (effects->shaderstable, "xray4"); shader = g_hash_table_lookup (effects->shaderstable, "xray4");
@ -170,9 +175,8 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer
g_hash_table_insert (effects->shaderstable, "xray4", shader); g_hash_table_insert (effects->shaderstable, "xray4", shader);
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (shader,
gst_gl_shader_compile_and_check (shader, multiply_fragment_source, multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -182,14 +186,14 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer
glActiveTexture (GL_TEXTURE2); glActiveTexture (GL_TEXTURE2);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->midtexture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->midtexture[2]);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (shader, "base", 2); gst_gl_shader_set_uniform_1i (shader, "base", 2);
glActiveTexture (GL_TEXTURE1); glActiveTexture (GL_TEXTURE1);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.28f); gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.28f);
gst_gl_shader_set_uniform_1i (shader, "blend", 1); gst_gl_shader_set_uniform_1i (shader, "blend", 1);
@ -197,22 +201,24 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer
gst_gl_effects_draw_texture (effects, texture); gst_gl_effects_draw_texture (effects, texture);
} }
void gst_gl_effects_xray (GstGLEffects *effects) { void
gst_gl_effects_xray (GstGLEffects * effects)
{
GstGLFilter *filter = GST_GL_FILTER (effects); GstGLFilter *filter = GST_GL_FILTER (effects);
/* map luma to xray curve */ /* map luma to xray curve */
gst_gl_filter_render_to_target (filter, effects->intexture, effects->midtexture[0], gst_gl_filter_render_to_target (filter, effects->intexture,
gst_gl_effects_xray_step_one, effects); effects->midtexture[0], gst_gl_effects_xray_step_one, effects);
/* horizontal blur */ /* horizontal blur */
gst_gl_filter_render_to_target (filter, effects->midtexture[0], effects->midtexture[1], gst_gl_filter_render_to_target (filter, effects->midtexture[0],
gst_gl_effects_xray_step_two, effects); effects->midtexture[1], gst_gl_effects_xray_step_two, effects);
/* vertical blur */ /* vertical blur */
gst_gl_filter_render_to_target (filter, effects->midtexture[1], effects->midtexture[2], gst_gl_filter_render_to_target (filter, effects->midtexture[1],
gst_gl_effects_xray_step_three, effects); effects->midtexture[2], gst_gl_effects_xray_step_three, effects);
/* detect edges with Sobel */ /* detect edges with Sobel */
gst_gl_filter_render_to_target (filter, effects->midtexture[2], effects->midtexture[3], gst_gl_filter_render_to_target (filter, effects->midtexture[2],
gst_gl_effects_xray_step_four, effects); effects->midtexture[3], gst_gl_effects_xray_step_four, effects);
/* multiply edges with the blurred image */ /* multiply edges with the blurred image */
gst_gl_filter_render_to_target (filter, effects->midtexture[3], effects->outtexture, gst_gl_filter_render_to_target (filter, effects->midtexture[3],
gst_gl_effects_xray_step_five, effects); effects->outtexture, gst_gl_effects_xray_step_five, effects);
} }

View file

@ -101,7 +101,8 @@ gst_gl_test_src_smpte (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
vts_colors[i].B * (1 / 255.0f), 1.0f); vts_colors[i].B * (1 / 255.0f), 1.0f);
glBegin (GL_QUADS); glBegin (GL_QUADS);
glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0 * (2.0f / 3.0f), 0); glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0 * (2.0f / 3.0f), 0);
glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0); glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f),
-1.0f + 2.0f * (2.0f / 3.0f), 0);
glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), -1.0f, 0); glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), -1.0f, 0);
glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f, 0); glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f, 0);
glEnd (); glEnd ();
@ -120,8 +121,10 @@ gst_gl_test_src_smpte (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
vts_colors[k].B * (1 / 255.0f), 1.0f); vts_colors[k].B * (1 / 255.0f), 1.0f);
glBegin (GL_QUADS); glBegin (GL_QUADS);
glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0);
glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f),
glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0); 0);
glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f),
0);
glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0); glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0);
glEnd (); glEnd ();
} }
@ -142,7 +145,8 @@ gst_gl_test_src_smpte (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
glBegin (GL_QUADS); glBegin (GL_QUADS);
glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0);
glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0);
glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f),
0);
glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0);
glEnd (); glEnd ();
} }
@ -162,11 +166,12 @@ gst_gl_test_src_smpte (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
vts_colors[k].B * (1 / 255.0f), 1.0f); vts_colors[k].B * (1 / 255.0f), 1.0f);
glBegin (GL_QUADS); glBegin (GL_QUADS);
glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), -1.0 + 2.0f * 1, 0); glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), -1.0 + 2.0f * 1, 0);
glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), -1.0f + 2.0f * 1, 0); glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)),
-1.0f + 2.0f * 1, 0);
glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)),
-1.0f + 2.0f * (3.0f / 4.0f), 0); -1.0f + 2.0f * (3.0f / 4.0f), 0);
glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), -1.0f + 2.0f * (3.0f / 4.0f), glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)),
0); -1.0f + 2.0f * (3.0f / 4.0f), 0);
glEnd (); glEnd ();
} }

View file

@ -44,7 +44,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL bumper filter", GST_ELEMENT_DETAILS ("OpenGL bumper filter",
"Filter/Effect", "Filter/Effect",
"Bump mapping filter", "Bump mapping filter",
"Cyril Comparon <cyril.comparon@gmail.com>, Julien Isorce <julien.isorce@gmail.com>"); "Cyril Comparon <cyril.comparon@gmail.com>, Julien Isorce <julien.isorce@gmail.com>");
@ -66,11 +66,12 @@ static void gst_gl_bumper_set_property (GObject * object, guint prop_id,
static void gst_gl_bumper_get_property (GObject * object, guint prop_id, static void gst_gl_bumper_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_bumper_reset (GstGLFilter* filter); static void gst_gl_bumper_reset (GstGLFilter * filter);
static void gst_gl_bumper_init_shader (GstGLFilter* filter); static void gst_gl_bumper_init_shader (GstGLFilter * filter);
static gboolean gst_gl_bumper_filter (GstGLFilter * filter, static gboolean gst_gl_bumper_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_bumper_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_bumper_callback (gint width, gint height, guint texture,
gpointer stuff);
//vertex source //vertex source
static const gchar *bumper_v_src = static const gchar *bumper_v_src =
@ -102,8 +103,7 @@ static const gchar *bumper_v_src =
"\n" "\n"
" // use the two first sets of texture coordinates in the fragment shader\n" " // use the two first sets of texture coordinates in the fragment shader\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n" " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
" gl_TexCoord[1] = gl_MultiTexCoord1;\n" " gl_TexCoord[1] = gl_MultiTexCoord1;\n" "}\n";
"}\n";
//fragment source //fragment source
static const gchar *bumper_f_src = static const gchar *bumper_f_src =
@ -143,14 +143,14 @@ static const gchar *bumper_f_src =
//png reading error handler //png reading error handler
static void static void
user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
{ {
g_warning("%s\n", warning_msg); g_warning ("%s\n", warning_msg);
} }
//Called in the gl thread //Called in the gl thread
static void static void
gst_gl_bumper_init_resources (GstGLFilter *filter) gst_gl_bumper_init_resources (GstGLFilter * filter)
{ {
GstGLBumper *bumper = GST_GL_BUMPER (filter); GstGLBumper *bumper = GST_GL_BUMPER (filter);
GstGLDisplay *display = filter->display; GstGLDisplay *display = filter->display;
@ -173,57 +173,54 @@ gst_gl_bumper_init_resources (GstGLFilter *filter)
/* BEGIN load png image file */ /* BEGIN load png image file */
if ((fp = fopen(bumper->location, "rb")) == NULL) if ((fp = fopen (bumper->location, "rb")) == NULL)
LOAD_ERROR ("file not found"); LOAD_ERROR ("file not found");
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) if (png_ptr == NULL) {
{ fclose (fp);
fclose(fp);
LOAD_ERROR ("failed to initialize the png_struct"); LOAD_ERROR ("failed to initialize the png_struct");
} }
png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn); png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) if (info_ptr == NULL) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("failed to initialize the memory for image information"); LOAD_ERROR ("failed to initialize the memory for image information");
} }
png_init_io(png_ptr, fp); png_init_io (png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read); png_set_sig_bytes (png_ptr, sig_read);
png_read_info(png_ptr, info_ptr); png_read_info (png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, int_p_NULL, int_p_NULL); &interlace_type, int_p_NULL, int_p_NULL);
if (color_type != PNG_COLOR_TYPE_RGB) if (color_type != PNG_COLOR_TYPE_RGB) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("color type is not rgb"); LOAD_ERROR ("color type is not rgb");
} }
raw_data = (guchar*) malloc ( sizeof(guchar) * width * height * 3 ); raw_data = (guchar *) malloc (sizeof (guchar) * width * height * 3);
rows = (guchar**)malloc(sizeof(guchar*) * height); rows = (guchar **) malloc (sizeof (guchar *) * height);
for (y = 0; y < height; ++y) for (y = 0; y < height; ++y)
rows[y] = (guchar*) (raw_data + y * width * 3); rows[y] = (guchar *) (raw_data + y * width * 3);
png_read_image(png_ptr, rows); png_read_image (png_ptr, rows);
free(rows); free (rows);
png_read_end(png_ptr, info_ptr); png_read_end (png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp); fclose (fp);
/* END load png image file */ /* END load png image file */
@ -231,7 +228,7 @@ gst_gl_bumper_init_resources (GstGLFilter *filter)
bumper->bumpmap_height = height; bumper->bumpmap_height = height;
glGenTextures (1, &bumper->bumpmap); glGenTextures (1, &bumper->bumpmap);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, bumper->bumpmap); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, bumper->bumpmap);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
bumper->bumpmap_width, bumper->bumpmap_height, 0, bumper->bumpmap_width, bumper->bumpmap_height, 0,
GL_RGB, GL_UNSIGNED_BYTE, raw_data); GL_RGB, GL_UNSIGNED_BYTE, raw_data);
@ -241,12 +238,11 @@ gst_gl_bumper_init_resources (GstGLFilter *filter)
//Called in the gl thread //Called in the gl thread
static void static void
gst_gl_bumper_reset_resources (GstGLFilter *filter) gst_gl_bumper_reset_resources (GstGLFilter * filter)
{ {
GstGLBumper *bumper = GST_GL_BUMPER (filter); GstGLBumper *bumper = GST_GL_BUMPER (filter);
if (bumper->bumpmap) if (bumper->bumpmap) {
{
glDeleteTextures (1, &bumper->bumpmap); glDeleteTextures (1, &bumper->bumpmap);
bumper->bumpmap = 0; bumper->bumpmap = 0;
} }
@ -261,9 +257,9 @@ gst_gl_bumper_base_init (gpointer klass)
} }
static void static void
gst_gl_bumper_class_init (GstGLBumperClass* klass) gst_gl_bumper_class_init (GstGLBumperClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_bumper_set_property; gobject_class->set_property = gst_gl_bumper_set_property;
@ -278,13 +274,11 @@ gst_gl_bumper_class_init (GstGLBumperClass* klass)
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_LOCATION, g_param_spec_string ("location", PROP_LOCATION, g_param_spec_string ("location",
"Normal map location", "Normal map location",
"Normal map location", "Normal map location", NULL, G_PARAM_READWRITE));
NULL, G_PARAM_READWRITE));
} }
static void static void
gst_gl_bumper_init (GstGLBumper* bumper, gst_gl_bumper_init (GstGLBumper * bumper, GstGLBumperClass * klass)
GstGLBumperClass* klass)
{ {
bumper->shader = NULL; bumper->shader = NULL;
bumper->bumpmap = 0; bumper->bumpmap = 0;
@ -294,22 +288,21 @@ gst_gl_bumper_init (GstGLBumper* bumper,
} }
static void static void
gst_gl_bumper_reset (GstGLFilter* filter) gst_gl_bumper_reset (GstGLFilter * filter)
{ {
GstGLBumper* bumper_filter = GST_GL_BUMPER(filter); GstGLBumper *bumper_filter = GST_GL_BUMPER (filter);
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, bumper_filter->shader); gst_gl_display_del_shader (filter->display, bumper_filter->shader);
} }
static void static void
gst_gl_bumper_set_property (GObject* object, guint prop_id, gst_gl_bumper_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
GstGLBumper *bumper = GST_GL_BUMPER (object); GstGLBumper *bumper = GST_GL_BUMPER (object);
switch (prop_id) switch (prop_id) {
{
case PROP_LOCATION: case PROP_LOCATION:
if (bumper->location != NULL) if (bumper->location != NULL)
g_free (bumper->location); g_free (bumper->location);
@ -322,13 +315,12 @@ gst_gl_bumper_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_bumper_get_property (GObject* object, guint prop_id, gst_gl_bumper_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
GstGLBumper *bumper = GST_GL_BUMPER (object); GstGLBumper *bumper = GST_GL_BUMPER (object);
switch (prop_id) switch (prop_id) {
{
case PROP_LOCATION: case PROP_LOCATION:
g_value_set_string (value, bumper->location); g_value_set_string (value, bumper->location);
break; break;
@ -339,17 +331,18 @@ gst_gl_bumper_get_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_bumper_init_shader (GstGLFilter* filter) gst_gl_bumper_init_shader (GstGLFilter * filter)
{ {
GstGLBumper *bumper = GST_GL_BUMPER (filter); GstGLBumper *bumper = GST_GL_BUMPER (filter);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, bumper_v_src, bumper_f_src, &bumper->shader); gst_gl_display_gen_shader (filter->display, bumper_v_src, bumper_f_src,
&bumper->shader);
} }
static gboolean static gboolean
gst_gl_bumper_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_bumper_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
gpointer bumper_filter = GST_GL_BUMPER (filter); gpointer bumper_filter = GST_GL_BUMPER (filter);
@ -358,7 +351,7 @@ gst_gl_bumper_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_bumper_callback, filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_bumper_callback,
inbuf->width, inbuf->height, inbuf->texture, inbuf->width, inbuf->height, inbuf->texture,
//bumper_filter->fovy, bumper_filter->aspect, bumper_filter->znear, bumper_filter->zfar, //bumper_filter->fovy, bumper_filter->aspect, bumper_filter->znear, bumper_filter->zfar,
45, (gdouble)filter->width/(gdouble)filter->height, 0.1, 50, 45, (gdouble) filter->width / (gdouble) filter->height, 0.1, 50,
GST_GL_DISPLAY_PROJECTION_PERSPECIVE, bumper_filter); GST_GL_DISPLAY_PROJECTION_PERSPECIVE, bumper_filter);
return TRUE; return TRUE;
@ -372,7 +365,7 @@ gst_gl_bumper_callback (gint width, gint height, guint texture, gpointer stuff)
static GLfloat yrot = 0; static GLfloat yrot = 0;
static GLfloat zrot = 0; static GLfloat zrot = 0;
GstGLBumper* bumper = GST_GL_BUMPER (stuff); GstGLBumper *bumper = GST_GL_BUMPER (stuff);
GLint locTangent = 0; GLint locTangent = 0;
//choose the lights //choose the lights
@ -383,33 +376,32 @@ gst_gl_bumper_callback (gint width, gint height, guint texture, gpointer stuff)
GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
//eye point //eye point
glMatrixMode(GL_PROJECTION); glMatrixMode (GL_PROJECTION);
gluLookAt(0.0, 0.0, -6.0, gluLookAt (0.0, 0.0, -6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
0.0, 0.0, 0.0, glMatrixMode (GL_MODELVIEW);
0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
//scene conf //scene conf
glEnable(GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc (GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH); glShadeModel (GL_SMOOTH);
//set the lights //set the lights
glLightfv(GL_LIGHT0, GL_POSITION, light_direction0); glLightfv (GL_LIGHT0, GL_POSITION, light_direction0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
glLightfv(GL_LIGHT1, GL_POSITION, light_direction1); glLightfv (GL_LIGHT1, GL_POSITION, light_direction1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1); glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL); glEnable (GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING); glEnable (GL_LIGHTING);
glEnable(GL_LIGHT0); glEnable (GL_LIGHT0);
glEnable(GL_LIGHT1); glEnable (GL_LIGHT1);
//configure shader //configure shader
gst_gl_shader_use (bumper->shader); gst_gl_shader_use (bumper->shader);
locTangent = gst_gl_shader_get_attribute_location (bumper->shader, "aTangent"); locTangent =
gst_gl_shader_get_attribute_location (bumper->shader, "aTangent");
//set the normal map //set the normal map
glActiveTextureARB (GL_TEXTURE1_ARB); glActiveTextureARB (GL_TEXTURE1_ARB);
@ -423,117 +415,123 @@ gst_gl_bumper_callback (gint width, gint height, guint texture, gpointer stuff)
//glTranslatef(2.0f, 2.0f, 5.0f); //glTranslatef(2.0f, 2.0f, 5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef (xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f); glRotatef (yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f); glRotatef (zrot, 0.0f, 0.0f, 1.0f);
//Cube //Cube
glBegin(GL_QUADS); glBegin (GL_QUADS);
// front face // front face
glNormal3d(0.0, 0.0, -1.0); glNormal3d (0.0, 0.0, -1.0);
glVertexAttrib3dARB(locTangent, 0.0, 1.0, 0.0); glVertexAttrib3dARB (locTangent, 0.0, 1.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d( 1.0, 1.0, -1.0); // B glVertex3d (1.0, 1.0, -1.0); // B
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d( 1.0, -1.0, -1.0); // A glVertex3d (1.0, -1.0, -1.0); // A
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d(-1.0, -1.0, -1.0); // D bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (-1.0, -1.0, -1.0); // D
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d(-1.0, 1.0, -1.0); // C glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glVertex3d (-1.0, 1.0, -1.0); // C
// right face // right face
glNormal3d(-1.0, 0.0, 0.0); glNormal3d (-1.0, 0.0, 0.0);
glVertexAttrib3dARB(locTangent, 0.0, 1.0, 0.0); glVertexAttrib3dARB (locTangent, 0.0, 1.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d(-1.0, 1.0, -1.0); // C glVertex3d (-1.0, 1.0, -1.0); // C
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d(-1.0, -1.0, -1.0); // D glVertex3d (-1.0, -1.0, -1.0); // D
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d(-1.0, -1.0, 1.0); // H bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (-1.0, -1.0, 1.0); // H
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d(-1.0, 1.0, 1.0); // G glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glVertex3d (-1.0, 1.0, 1.0); // G
// back face // back face
glNormal3d(0.0, 0.0, 1.0); glNormal3d (0.0, 0.0, 1.0);
glVertexAttrib3dARB(locTangent, 0.0, 1.0, 0.0); glVertexAttrib3dARB (locTangent, 0.0, 1.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d(-1.0, 1.0, 1.0); // G glVertex3d (-1.0, 1.0, 1.0); // G
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d(-1.0, -1.0, 1.0); // H glVertex3d (-1.0, -1.0, 1.0); // H
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d( 1.0, -1.0, 1.0); // E bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (1.0, -1.0, 1.0); // E
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d( 1.0, 1.0, 1.0); // F glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glVertex3d (1.0, 1.0, 1.0); // F
// left face // left face
glNormal3d(1.0, 0.0, 0.0); glNormal3d (1.0, 0.0, 0.0);
glVertexAttrib3dARB(locTangent, 0.0, 1.0, 0.0); glVertexAttrib3dARB (locTangent, 0.0, 1.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d( 1.0, 1.0, 1.0); // F glVertex3d (1.0, 1.0, 1.0); // F
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d( 1.0, -1.0, 1.0); // E glVertex3d (1.0, -1.0, 1.0); // E
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d( 1.0, -1.0, -1.0); // A bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (1.0, -1.0, -1.0); // A
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d( 1.0, 1.0, -1.0); // B glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glVertex3d (1.0, 1.0, -1.0); // B
// top face // top face
glNormal3d(0.0, 1.0, 0.0); glNormal3d (0.0, 1.0, 0.0);
glVertexAttrib3dARB(locTangent, 0.0, 0.0, 1.0); glVertexAttrib3dARB (locTangent, 0.0, 0.0, 1.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d( 1.0, 1.0, 1.0); // F glVertex3d (1.0, 1.0, 1.0); // F
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d( 1.0, 1.0, -1.0); // B glVertex3d (1.0, 1.0, -1.0); // B
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d(-1.0, 1.0, -1.0); // C bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (-1.0, 1.0, -1.0); // C
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d(-1.0, 1.0, 1.0); // G glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glVertex3d (-1.0, 1.0, 1.0); // G
// bottom face // bottom face
glNormal3d(0.0, -1.0, 0.0); glNormal3d (0.0, -1.0, 0.0);
glVertexAttrib3dARB(locTangent, 0.0, 0.0, -1.0); glVertexAttrib3dARB (locTangent, 0.0, 0.0, -1.0);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, 0.0);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, 0.0); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, 0.0);
glVertex3d( 1.0, -1.0, -1.0); // A glVertex3d (1.0, -1.0, -1.0); // A
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0.0, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, 0.0, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, 0.0, bumper->bumpmap_height);
glVertex3d( 1.0, -1.0, 1.0); // E glVertex3d (1.0, -1.0, 1.0); // E
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, height); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, height);
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, bumper->bumpmap_height); glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width,
glVertex3d(-1.0, -1.0, 1.0); // H bumper->bumpmap_height);
glMultiTexCoord2dARB(GL_TEXTURE0_ARB, width, 0.0); glVertex3d (-1.0, -1.0, 1.0); // H
glMultiTexCoord2dARB(GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0); glMultiTexCoord2dARB (GL_TEXTURE0_ARB, width, 0.0);
glVertex3d(-1.0, -1.0, -1.0); // D glMultiTexCoord2dARB (GL_TEXTURE1_ARB, bumper->bumpmap_width, 0.0);
glEnd(); glVertex3d (-1.0, -1.0, -1.0); // D
glEnd ();
glUseProgram(0); glUseProgram (0);
glDisable(GL_LIGHT0); glDisable (GL_LIGHT0);
glDisable(GL_LIGHT1); glDisable (GL_LIGHT1);
glDisable(GL_LIGHTING); glDisable (GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL); glDisable (GL_COLOR_MATERIAL);
xrot+=1.0f; xrot += 1.0f;
yrot+=0.9f; yrot += 0.9f;
zrot+=1.1f; zrot += 1.1f;
} }

View file

@ -51,17 +51,17 @@
#define GST_CAT_DEFAULT gst_gl_colorscale_debug #define GST_CAT_DEFAULT gst_gl_colorscale_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL color scale", GST_ELEMENT_DETAILS ("OpenGL color scale",
"Filter/Effect", "Filter/Effect",
"Colorspace converter and video scaler", "Colorspace converter and video scaler",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
/* Source pad definition */ /* Source pad definition */
static GstStaticPadTemplate gst_gl_colorscale_src_pad_template = static GstStaticPadTemplate gst_gl_colorscale_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";" GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";"
@ -95,24 +95,24 @@ enum
GST_BOILERPLATE_FULL (GstGLColorscale, gst_gl_colorscale, GstBaseTransform, GST_BOILERPLATE_FULL (GstGLColorscale, gst_gl_colorscale, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT); GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_colorscale_set_property (GObject* object, guint prop_id, static void gst_gl_colorscale_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_colorscale_get_property (GObject* object, guint prop_id, static void gst_gl_colorscale_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_colorscale_reset (GstGLColorscale* colorscale); static void gst_gl_colorscale_reset (GstGLColorscale * colorscale);
static gboolean gst_gl_colorscale_set_caps (GstBaseTransform* bt, static gboolean gst_gl_colorscale_set_caps (GstBaseTransform * bt,
GstCaps* incaps, GstCaps* outcaps); GstCaps * incaps, GstCaps * outcaps);
static GstCaps *gst_gl_colorscale_transform_caps (GstBaseTransform* bt, static GstCaps *gst_gl_colorscale_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps); GstPadDirection direction, GstCaps * caps);
static void gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction, static void gst_gl_colorscale_fixate_caps (GstBaseTransform * base,
GstCaps* caps, GstCaps* othercaps); GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static gboolean gst_gl_colorscale_start (GstBaseTransform* bt); static gboolean gst_gl_colorscale_start (GstBaseTransform * bt);
static gboolean gst_gl_colorscale_stop (GstBaseTransform* bt); static gboolean gst_gl_colorscale_stop (GstBaseTransform * bt);
static GstFlowReturn gst_gl_colorscale_transform (GstBaseTransform* trans, static GstFlowReturn gst_gl_colorscale_transform (GstBaseTransform * trans,
GstBuffer* inbuf, GstBuffer * outbuf); GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, static gboolean gst_gl_colorscale_get_unit_size (GstBaseTransform * trans,
GstCaps* caps, guint* size); GstCaps * caps, guint * size);
static void static void
@ -129,9 +129,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;
@ -144,23 +144,24 @@ gst_gl_colorscale_class_init (GstGLColorscaleClass* klass)
GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_colorscale_start; GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_colorscale_start;
GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_colorscale_stop; GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_colorscale_stop;
GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_colorscale_set_caps; GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_colorscale_set_caps;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_colorscale_get_unit_size; GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
gst_gl_colorscale_get_unit_size;
} }
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);
} }
static void static void
gst_gl_colorscale_set_property (GObject* object, guint prop_id, gst_gl_colorscale_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
//GstGLColorscale* colorscale = GST_GL_COLORSCALE (object); //GstGLColorscale* colorscale = GST_GL_COLORSCALE (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -168,13 +169,12 @@ gst_gl_colorscale_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_colorscale_get_property (GObject* object, guint prop_id, gst_gl_colorscale_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLColorscale *colorscale = GST_GL_COLORSCALE (object); //GstGLColorscale *colorscale = GST_GL_COLORSCALE (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -182,17 +182,16 @@ gst_gl_colorscale_get_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_colorscale_reset (GstGLColorscale* colorscale) gst_gl_colorscale_reset (GstGLColorscale * colorscale)
{ {
if (colorscale->display) if (colorscale->display) {
{
g_object_unref (colorscale->display); g_object_unref (colorscale->display);
colorscale->display = NULL; colorscale->display = NULL;
} }
} }
static gboolean static gboolean
gst_gl_colorscale_start (GstBaseTransform* bt) gst_gl_colorscale_start (GstBaseTransform * bt)
{ {
//GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt); //GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt);
@ -200,32 +199,32 @@ gst_gl_colorscale_start (GstBaseTransform* bt)
} }
static gboolean static gboolean
gst_gl_colorscale_stop (GstBaseTransform* bt) gst_gl_colorscale_stop (GstBaseTransform * bt)
{ {
GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt); GstGLColorscale *colorscale = GST_GL_COLORSCALE (bt);
gst_gl_colorscale_reset (colorscale); gst_gl_colorscale_reset (colorscale);
return TRUE; return TRUE;
} }
static GstCaps* static GstCaps *
gst_gl_colorscale_transform_caps (GstBaseTransform* bt, gst_gl_colorscale_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps) GstPadDirection direction, GstCaps * caps)
{ {
//GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt); //GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt);
GstStructure* structure = gst_caps_get_structure (caps, 0); GstStructure *structure = gst_caps_get_structure (caps, 0);
GstCaps* newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL); GstCaps *newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL);
GstCaps* newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL); GstCaps *newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
const GValue* framerate_value = NULL; const GValue *framerate_value = NULL;
const GValue* par_value = NULL; const GValue *par_value = NULL;
GST_DEBUG ("transform caps %" GST_PTR_FORMAT, caps); GST_DEBUG ("transform caps %" GST_PTR_FORMAT, caps);
framerate_value = gst_structure_get_value (structure, "framerate"); framerate_value = gst_structure_get_value (structure, "framerate");
par_value = gst_structure_get_value (structure, "pixel-aspect-ratio"); par_value = gst_structure_get_value (structure, "pixel-aspect-ratio");
gst_caps_append(newcaps, newothercaps); gst_caps_append (newcaps, newothercaps);
structure = gst_structure_copy (gst_caps_get_structure (newcaps, 0)); structure = gst_structure_copy (gst_caps_get_structure (newcaps, 0));
@ -250,8 +249,8 @@ gst_gl_colorscale_transform_caps (GstBaseTransform* bt,
/* from gst-plugins-base "videoscale" code */ /* from gst-plugins-base "videoscale" code */
static void static void
gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction, gst_gl_colorscale_fixate_caps (GstBaseTransform * base,
GstCaps* caps, GstCaps* othercaps) GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{ {
GstStructure *ins, *outs; GstStructure *ins, *outs;
@ -269,8 +268,7 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");
//we have both PAR but they might not be fixated //we have both PAR but they might not be fixated
if (from_par && to_par) if (from_par && to_par) {
{
gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
gint count = 0, w = 0, h = 0; gint count = 0, w = 0, h = 0;
@ -284,8 +282,7 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
from_par_d = gst_value_get_fraction_denominator (from_par); from_par_d = gst_value_get_fraction_denominator (from_par);
//fixate the out PAR //fixate the out PAR
if (!gst_value_is_fixed (to_par)) if (!gst_value_is_fixed (to_par)) {
{
GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n, GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n,
from_par_d); from_par_d);
gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio", gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio",
@ -301,8 +298,7 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
++count; ++count;
if (gst_structure_get_int (outs, "height", &h)) if (gst_structure_get_int (outs, "height", &h))
++count; ++count;
if (count == 2) if (count == 2) {
{
GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating", GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating",
w, h); w, h);
return; return;
@ -312,8 +308,7 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
gst_structure_get_int (ins, "height", &from_h); gst_structure_get_int (ins, "height", &from_h);
if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h, if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h,
from_par_n, from_par_d, to_par_n, to_par_d)) from_par_n, from_par_d, to_par_n, to_par_d)) {
{
GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
("Error calculating the output scaled size - integer overflow")); ("Error calculating the output scaled size - integer overflow"));
return; return;
@ -330,35 +325,25 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
//using wd / hd = num / den //using wd / hd = num / den
//if one of the output width or height is fixed, we work from there //if one of the output width or height is fixed, we work from there
if (h) if (h) {
{
GST_DEBUG_OBJECT (base, "height is fixed,scaling width"); GST_DEBUG_OBJECT (base, "height is fixed,scaling width");
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
} } else if (w) {
else if (w)
{
GST_DEBUG_OBJECT (base, "width is fixed, scaling height"); GST_DEBUG_OBJECT (base, "width is fixed, scaling height");
h = (guint) gst_util_uint64_scale_int (w, den, num); h = (guint) gst_util_uint64_scale_int (w, den, num);
} } else {
else
{
//none of width or height is fixed, figure out both of them based only on //none of width or height is fixed, figure out both of them based only on
//the input width and height //the input width and height
//check hd / den is an integer scale factor, and scale wd with the PAR //check hd / den is an integer scale factor, and scale wd with the PAR
if (from_h % den == 0) if (from_h % den == 0) {
{
GST_DEBUG_OBJECT (base, "keeping video height"); GST_DEBUG_OBJECT (base, "keeping video height");
h = from_h; h = from_h;
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
} } else if (from_w % num == 0) {
else if (from_w % num == 0)
{
GST_DEBUG_OBJECT (base, "keeping video width"); GST_DEBUG_OBJECT (base, "keeping video width");
w = from_w; w = from_w;
h = (guint) gst_util_uint64_scale_int (w, den, num); h = (guint) gst_util_uint64_scale_int (w, den, num);
} } else {
else
{
GST_DEBUG_OBJECT (base, "approximating but keeping video height"); GST_DEBUG_OBJECT (base, "approximating but keeping video height");
h = from_h; h = from_h;
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
@ -369,13 +354,10 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
//now fixate //now fixate
gst_structure_fixate_field_nearest_int (outs, "width", w); gst_structure_fixate_field_nearest_int (outs, "width", w);
gst_structure_fixate_field_nearest_int (outs, "height", h); gst_structure_fixate_field_nearest_int (outs, "height", h);
} } else {
else
{
gint width, height; gint width, height;
if (gst_structure_get_int (ins, "width", &width)) if (gst_structure_get_int (ins, "width", &width)) {
{
if (gst_structure_has_field (outs, "width")) if (gst_structure_has_field (outs, "width"))
gst_structure_fixate_field_nearest_int (outs, "width", width); gst_structure_fixate_field_nearest_int (outs, "width", width);
} }
@ -390,10 +372,10 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform* base, GstPadDirection direction
} }
static gboolean static gboolean
gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps, gst_gl_colorscale_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt); GstGLColorscale *colorscale = GST_GL_COLORSCALE (bt);
gboolean ret = FALSE; gboolean ret = FALSE;
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps); GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
@ -404,8 +386,7 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
ret |= gst_video_format_parse_caps (incaps, &colorscale->input_video_format, ret |= gst_video_format_parse_caps (incaps, &colorscale->input_video_format,
&colorscale->input_video_width, &colorscale->input_video_height); &colorscale->input_video_width, &colorscale->input_video_height);
if (!ret) if (!ret) {
{
GST_DEBUG ("bad caps"); GST_DEBUG ("bad caps");
return FALSE; return FALSE;
} }
@ -417,20 +398,22 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
colorscale->output_video_width, colorscale->output_video_height); colorscale->output_video_width, colorscale->output_video_height);
//blocking call, init colorspace conversion if needed //blocking call, init colorspace conversion if needed
gst_gl_display_init_upload (colorscale->display, colorscale->input_video_format, gst_gl_display_init_upload (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height, colorscale->input_video_format, colorscale->output_video_width,
colorscale->input_video_width, colorscale->input_video_height); colorscale->output_video_height, colorscale->input_video_width,
colorscale->input_video_height);
//blocking call, init colorspace conversion if needed //blocking call, init colorspace conversion if needed
gst_gl_display_init_download (colorscale->display, colorscale->output_video_format, gst_gl_display_init_download (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height); colorscale->output_video_format, colorscale->output_video_width,
colorscale->output_video_height);
return ret; return ret;
} }
static gboolean static gboolean
gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, GstCaps* caps, gst_gl_colorscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint* size) guint * size)
{ {
gboolean ret; gboolean ret;
GstStructure *structure; GstStructure *structure;
@ -438,14 +421,11 @@ gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
gint height; gint height;
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")) {
{
ret = gst_gl_buffer_parse_caps (caps, &width, &height); ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret) if (ret)
*size = gst_gl_buffer_get_size (width, height); *size = gst_gl_buffer_get_size (width, height);
} } else {
else
{
GstVideoFormat video_format; GstVideoFormat video_format;
ret = gst_video_format_parse_caps (caps, &video_format, &width, &height); ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
@ -457,21 +437,22 @@ gst_gl_colorscale_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
} }
static GstFlowReturn static GstFlowReturn
gst_gl_colorscale_transform (GstBaseTransform* trans, GstBuffer* inbuf, gst_gl_colorscale_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer* outbuf) GstBuffer * outbuf)
{ {
GstGLColorscale* colorscale = GST_GL_COLORSCALE (trans); GstGLColorscale *colorscale = GST_GL_COLORSCALE (trans);
gboolean isAlive = TRUE; gboolean isAlive = TRUE;
//blocking call //blocking call
GstGLBuffer* gl_temp_buffer = gst_gl_buffer_new (colorscale->display, GstGLBuffer *gl_temp_buffer = gst_gl_buffer_new (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height); colorscale->output_video_width, colorscale->output_video_height);
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
isAlive = gst_gl_display_do_upload (colorscale->display, gl_temp_buffer->texture, isAlive =
gst_gl_display_do_upload (colorscale->display, gl_temp_buffer->texture,
colorscale->input_video_width, colorscale->input_video_height, colorscale->input_video_width, colorscale->input_video_height,
GST_BUFFER_DATA (inbuf)); GST_BUFFER_DATA (inbuf));
@ -479,9 +460,9 @@ gst_gl_colorscale_transform (GstBaseTransform* trans, GstBuffer* inbuf,
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf)); GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
//blocking call //blocking call
isAlive &= gst_gl_display_do_download(colorscale->display, gl_temp_buffer->texture, isAlive &=
gl_temp_buffer->width, gl_temp_buffer->height, gst_gl_display_do_download (colorscale->display, gl_temp_buffer->texture,
GST_BUFFER_DATA (outbuf)); gl_temp_buffer->width, gl_temp_buffer->height, GST_BUFFER_DATA (outbuf));
gst_buffer_unref (gl_temp_buffer); gst_buffer_unref (gl_temp_buffer);

View file

@ -80,21 +80,21 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
GST_BOILERPLATE_FULL (GstGLDifferenceMatte, gst_gl_differencematte, GstGLFilter, GST_BOILERPLATE_FULL (GstGLDifferenceMatte, gst_gl_differencematte, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT); GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_differencematte_set_property (GObject * object, guint prop_id, static void gst_gl_differencematte_set_property (GObject * object,
const GValue * value, GParamSpec * pspec); guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_gl_differencematte_get_property (GObject * object, guint prop_id, static void gst_gl_differencematte_get_property (GObject * object,
GValue * value, GParamSpec * pspec); guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_gl_differencematte_init_resources (GstGLFilter* filter); static void gst_gl_differencematte_init_resources (GstGLFilter * filter);
static void gst_gl_differencematte_reset_resources (GstGLFilter* filter); static void gst_gl_differencematte_reset_resources (GstGLFilter * filter);
static gboolean gst_gl_differencematte_filter (GstGLFilter * filter, static gboolean gst_gl_differencematte_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static gboolean gst_gl_differencematte_loader (GstGLFilter* filter); static gboolean gst_gl_differencematte_loader (GstGLFilter * filter);
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ( static const GstElementDetails element_details =
"Gstreamer OpenGL DifferenceMatte", GST_ELEMENT_DETAILS ("Gstreamer OpenGL DifferenceMatte",
"Filter/Effect", "Filter/Effect",
"Saves a background frame and replace it with a pixbuf", "Saves a background frame and replace it with a pixbuf",
"Filippo Argiolas <filippo.argiolas@gmail.com>"); "Filippo Argiolas <filippo.argiolas@gmail.com>");
@ -108,53 +108,49 @@ enum
/* init resources that need a gl context */ /* init resources that need a gl context */
static void static void
gst_gl_differencematte_init_gl_resources (GstGLFilter *filter) gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
{ {
GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
gint i; gint i;
for (i=0; i<4; i++) { for (i = 0; i < 4; i++) {
glGenTextures (1, &differencematte->midtexture[i]); glGenTextures (1, &differencematte->midtexture[i]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, differencematte->midtexture[i]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->midtexture[i]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); filter->width, filter->height, 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_MAG_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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);
differencematte->shader[i] = gst_gl_shader_new (); differencematte->shader[i] = gst_gl_shader_new ();
} }
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[0],
gst_gl_shader_compile_and_check (differencematte->shader[0], difference_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
difference_fragment_source, g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[1],
GST_GL_SHADER_FRAGMENT_SOURCE)); hconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
g_return_if_fail (
gst_gl_shader_compile_and_check (differencematte->shader[1],
hconv9_fragment_source,
GST_GL_SHADER_FRAGMENT_SOURCE));
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[2],
gst_gl_shader_compile_and_check (differencematte->shader[2], vconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
vconv9_fragment_source,
GST_GL_SHADER_FRAGMENT_SOURCE));
g_return_if_fail ( g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[3],
gst_gl_shader_compile_and_check (differencematte->shader[3], texture_interp_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
texture_interp_fragment_source,
GST_GL_SHADER_FRAGMENT_SOURCE));
} }
/* free resources that need a gl context */ /* free resources that need a gl context */
static void static void
gst_gl_differencematte_reset_gl_resources (GstGLFilter *filter) gst_gl_differencematte_reset_gl_resources (GstGLFilter * filter)
{ {
GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
gint i; gint i;
glDeleteTextures (1, &differencematte->savedbgtexture); glDeleteTextures (1, &differencematte->savedbgtexture);
glDeleteTextures (1, &differencematte->newbgtexture); glDeleteTextures (1, &differencematte->newbgtexture);
for (i=0; i<4; i++) { for (i = 0; i < 4; i++) {
g_object_unref (differencematte->shader[i]); g_object_unref (differencematte->shader[i]);
differencematte->shader[i] = NULL; differencematte->shader[i] = NULL;
glDeleteTextures (1, &differencematte->midtexture[i]); glDeleteTextures (1, &differencematte->midtexture[i]);
@ -184,8 +180,10 @@ gst_gl_differencematte_class_init (GstGLDifferenceMatteClass * klass)
gobject_class->get_property = gst_gl_differencematte_get_property; gobject_class->get_property = gst_gl_differencematte_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_differencematte_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_differencematte_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb = gst_gl_differencematte_init_gl_resources; GST_GL_FILTER_CLASS (klass)->display_init_cb =
GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_differencematte_reset_gl_resources; gst_gl_differencematte_init_gl_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_differencematte_reset_gl_resources;
GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_differencematte_init_resources; GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_differencematte_init_resources;
GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_differencematte_reset_resources; GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_differencematte_reset_resources;
@ -193,12 +191,12 @@ gst_gl_differencematte_class_init (GstGLDifferenceMatteClass * klass)
PROP_LOCATION, PROP_LOCATION,
g_param_spec_string ("location", g_param_spec_string ("location",
"Background image location", "Background image location",
"Background image location", "Background image location", NULL, G_PARAM_READWRITE));
NULL, G_PARAM_READWRITE));
} }
void void
gst_gl_differencematte_draw_texture (GstGLDifferenceMatte * differencematte, GLuint tex) gst_gl_differencematte_draw_texture (GstGLDifferenceMatte * differencematte,
GLuint tex)
{ {
GstGLFilter *filter = GST_GL_FILTER (differencematte); GstGLFilter *filter = GST_GL_FILTER (differencematte);
@ -210,11 +208,11 @@ gst_gl_differencematte_draw_texture (GstGLDifferenceMatte * differencematte, GLu
glTexCoord2f (0.0, 0.0); glTexCoord2f (0.0, 0.0);
glVertex2f (-1.0, -1.0); glVertex2f (-1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, 0.0); glTexCoord2f ((gfloat) filter->width, 0.0);
glVertex2f (1.0, -1.0); glVertex2f (1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, (gfloat)filter->height); glTexCoord2f ((gfloat) filter->width, (gfloat) filter->height);
glVertex2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, (gfloat)filter->height); glTexCoord2f (0.0, (gfloat) filter->height);
glVertex2f (-1.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd (); glEnd ();
@ -236,7 +234,7 @@ gst_gl_differencematte_init (GstGLDifferenceMatte * differencematte,
} }
static void static void
gst_gl_differencematte_reset_resources (GstGLFilter* filter) gst_gl_differencematte_reset_resources (GstGLFilter * filter)
{ {
// GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter); // GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter);
} }
@ -249,7 +247,8 @@ gst_gl_differencematte_set_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_LOCATION: case PROP_LOCATION:
if (differencematte->location != NULL) g_free (differencematte->location); if (differencematte->location != NULL)
g_free (differencematte->location);
differencematte->bg_has_changed = TRUE; differencematte->bg_has_changed = TRUE;
differencematte->location = g_value_dup_string (value); differencematte->location = g_value_dup_string (value);
break; break;
@ -276,15 +275,16 @@ gst_gl_differencematte_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_differencematte_init_resources (GstGLFilter* filter) gst_gl_differencematte_init_resources (GstGLFilter * filter)
{ {
// GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); // GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
} }
static void static void
gst_gl_differencematte_save_texture (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_save_texture (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -292,7 +292,8 @@ gst_gl_differencematte_save_texture (gint width, gint height, guint texture, gpo
gst_gl_differencematte_draw_texture (differencematte, texture); gst_gl_differencematte_draw_texture (differencematte, texture);
} }
static void init_pixbuf_texture (GstGLDisplay *display, gpointer data) static void
init_pixbuf_texture (GstGLDisplay * display, gpointer data)
{ {
GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data);
GstGLFilter *filter = GST_GL_FILTER (data); GstGLFilter *filter = GST_GL_FILTER (data);
@ -306,20 +307,25 @@ static void init_pixbuf_texture (GstGLDisplay *display, gpointer data)
if (differencematte->savedbgtexture == 0) { if (differencematte->savedbgtexture == 0) {
glGenTextures (1, &differencematte->savedbgtexture); glGenTextures (1, &differencematte->savedbgtexture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, differencematte->savedbgtexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->savedbgtexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); filter->width, filter->height, 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_MAG_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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);
} }
} }
static void static void
gst_gl_differencematte_diff (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_diff (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -329,7 +335,7 @@ gst_gl_differencematte_diff (gint width, gint height, guint texture, gpointer st
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (differencematte->shader[0], "current", 0); gst_gl_shader_set_uniform_1i (differencematte->shader[0], "current", 0);
@ -344,9 +350,10 @@ gst_gl_differencematte_diff (gint width, gint height, guint texture, gpointer st
} }
static void static void
gst_gl_differencematte_hblur (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_hblur (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
gfloat gauss_kernel[9] = { gfloat gauss_kernel[9] = {
0.026995f, 0.064759f, 0.120985f, 0.026995f, 0.064759f, 0.120985f,
0.176033f, 0.199471f, 0.176033f, 0.176033f, 0.199471f, 0.176033f,
@ -361,21 +368,25 @@ gst_gl_differencematte_hblur (gint width, gint height, guint texture, gpointer s
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (differencematte->shader[1], "tex", 0); gst_gl_shader_set_uniform_1i (differencematte->shader[1], "tex", 0);
gst_gl_shader_set_uniform_1fv (differencematte->shader[1], "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1fv (differencematte->shader[1], "kernel", 9,
gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_const", 0.977016f); gauss_kernel);
gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_offset", 0.0f); gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_const",
0.977016f);
gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_offset",
0.0f);
gst_gl_differencematte_draw_texture (differencematte, texture); gst_gl_differencematte_draw_texture (differencematte, texture);
} }
static void static void
gst_gl_differencematte_vblur (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_vblur (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
gfloat gauss_kernel[9] = { gfloat gauss_kernel[9] = {
0.026995f, 0.064759f, 0.120985f, 0.026995f, 0.064759f, 0.120985f,
0.176033f, 0.199471f, 0.176033f, 0.176033f, 0.199471f, 0.176033f,
@ -390,21 +401,25 @@ gst_gl_differencematte_vblur (gint width, gint height, guint texture, gpointer s
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (differencematte->shader[2], "tex", 0); gst_gl_shader_set_uniform_1i (differencematte->shader[2], "tex", 0);
gst_gl_shader_set_uniform_1fv (differencematte->shader[2], "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1fv (differencematte->shader[2], "kernel", 9,
gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_const", 0.977016f); gauss_kernel);
gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_offset", 0.0f); gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_const",
0.977016f);
gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_offset",
0.0f);
gst_gl_differencematte_draw_texture (differencematte, texture); gst_gl_differencematte_draw_texture (differencematte, texture);
} }
static void static void
gst_gl_differencematte_interp (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_interp (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -414,7 +429,7 @@ gst_gl_differencematte_interp (gint width, gint height, guint texture, gpointer
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (differencematte->shader[3], "blend", 0); gst_gl_shader_set_uniform_1i (differencematte->shader[3], "blend", 0);
@ -436,9 +451,10 @@ gst_gl_differencematte_interp (gint width, gint height, guint texture, gpointer
} }
static void static void
gst_gl_differencematte_identity (gint width, gint height, guint texture, gpointer stuff) gst_gl_differencematte_identity (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -447,10 +463,10 @@ gst_gl_differencematte_identity (gint width, gint height, guint texture, gpointe
} }
static gboolean static gboolean
gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_differencematte_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
differencematte->intexture = inbuf->texture; differencematte->intexture = inbuf->texture;
@ -460,14 +476,14 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
differencematte->pixbuf = NULL; differencematte->pixbuf = NULL;
/* if loader failed then display is turned off */ /* if loader failed then display is turned off */
gst_gl_display_thread_add (filter->display, init_pixbuf_texture, differencematte); gst_gl_display_thread_add (filter->display, init_pixbuf_texture,
differencematte);
/* save current frame, needed to calculate difference between /* save current frame, needed to calculate difference between
* this frame and next ones */ * this frame and next ones */
gst_gl_filter_render_to_target (filter, inbuf->texture, gst_gl_filter_render_to_target (filter, inbuf->texture,
differencematte->savedbgtexture, differencematte->savedbgtexture,
gst_gl_differencematte_save_texture, gst_gl_differencematte_save_texture, differencematte);
differencematte);
if (differencematte->pixbuf) { if (differencematte->pixbuf) {
free (differencematte->pixbuf); free (differencematte->pixbuf);
@ -492,30 +508,28 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
gst_gl_differencematte_vblur, differencematte); gst_gl_differencematte_vblur, differencematte);
gst_gl_filter_render_to_target (filter, gst_gl_filter_render_to_target (filter,
inbuf->texture, inbuf->texture,
outbuf->texture, outbuf->texture, gst_gl_differencematte_interp, differencematte);
gst_gl_differencematte_interp, differencematte);
} else { } else {
gst_gl_filter_render_to_target (filter, gst_gl_filter_render_to_target (filter,
inbuf->texture, inbuf->texture,
outbuf->texture, outbuf->texture, gst_gl_differencematte_identity, differencematte);
gst_gl_differencematte_identity, differencematte);
} }
return TRUE; return TRUE;
} }
static void static void
user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
{ {
g_warning("%s\n", warning_msg); g_warning ("%s\n", warning_msg);
} }
#define LOAD_ERROR(msg) { GST_WARNING ("unable to load %s: %s", differencematte->location, msg); return FALSE; } #define LOAD_ERROR(msg) { GST_WARNING ("unable to load %s: %s", differencematte->location, msg); return FALSE; }
static gboolean static gboolean
gst_gl_differencematte_loader (GstGLFilter* filter) gst_gl_differencematte_loader (GstGLFilter * filter)
{ {
GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
@ -532,60 +546,58 @@ gst_gl_differencematte_loader (GstGLFilter* filter)
if (!filter->display) if (!filter->display)
return TRUE; return TRUE;
if ((fp = fopen(differencematte->location, "rb")) == NULL) if ((fp = fopen (differencematte->location, "rb")) == NULL)
LOAD_ERROR ("file not found"); LOAD_ERROR ("file not found");
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) if (png_ptr == NULL) {
{ fclose (fp);
fclose(fp);
LOAD_ERROR ("failed to initialize the png_struct"); LOAD_ERROR ("failed to initialize the png_struct");
} }
png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn); png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) if (info_ptr == NULL) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("failed to initialize the memory for image information"); LOAD_ERROR ("failed to initialize the memory for image information");
} }
png_init_io(png_ptr, fp); png_init_io (png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read); png_set_sig_bytes (png_ptr, sig_read);
png_read_info(png_ptr, info_ptr); png_read_info (png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, int_p_NULL, int_p_NULL); &interlace_type, int_p_NULL, int_p_NULL);
if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("color type is not rgb"); LOAD_ERROR ("color type is not rgb");
} }
filter->width = width; filter->width = width;
filter->height = height; filter->height = height;
differencematte->pixbuf = (guchar*) malloc ( sizeof(guchar) * width * height * 4 ); differencematte->pixbuf =
(guchar *) malloc (sizeof (guchar) * width * height * 4);
rows = (guchar**)malloc(sizeof(guchar*) * height); rows = (guchar **) malloc (sizeof (guchar *) * height);
for (y = 0; y < height; ++y) for (y = 0; y < height; ++y)
rows[y] = (guchar*) (differencematte->pixbuf + y * width * 4); rows[y] = (guchar *) (differencematte->pixbuf + y * width * 4);
png_read_image(png_ptr, rows); png_read_image (png_ptr, rows);
free(rows); free (rows);
png_read_end(png_ptr, info_ptr); png_read_end (png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp); fclose (fp);
return TRUE; return TRUE;
} }

View file

@ -66,10 +66,10 @@
#include "gstgldownload.h" #include "gstgldownload.h"
#define GST_CAT_DEFAULT gst_gl_download_debug #define GST_CAT_DEFAULT gst_gl_download_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL video maker", GST_ELEMENT_DETAILS ("OpenGL video maker",
"Filter/Effect", "Filter/Effect",
"A from GL to video flow filter", "A from GL to video flow filter",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -78,8 +78,7 @@ static GstStaticPadTemplate gst_gl_download_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ( GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";"
@ -105,28 +104,28 @@ enum
GST_BOILERPLATE_FULL (GstGLDownload, gst_gl_download, GstBaseTransform, GST_BOILERPLATE_FULL (GstGLDownload, gst_gl_download, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT); GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_download_set_property (GObject* object, guint prop_id, static void gst_gl_download_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_download_get_property (GObject* object, guint prop_id, static void gst_gl_download_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_download_reset (GstGLDownload* download); static void gst_gl_download_reset (GstGLDownload * download);
static gboolean gst_gl_download_set_caps (GstBaseTransform* bt, static gboolean gst_gl_download_set_caps (GstBaseTransform * bt,
GstCaps* incaps, GstCaps* outcaps); GstCaps * incaps, GstCaps * outcaps);
static GstCaps* gst_gl_download_transform_caps (GstBaseTransform* bt, static GstCaps *gst_gl_download_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps); GstPadDirection direction, GstCaps * caps);
static gboolean gst_gl_download_start (GstBaseTransform* bt); static gboolean gst_gl_download_start (GstBaseTransform * bt);
static gboolean gst_gl_download_stop (GstBaseTransform* bt); static gboolean gst_gl_download_stop (GstBaseTransform * bt);
static GstFlowReturn gst_gl_download_transform (GstBaseTransform* trans, static GstFlowReturn gst_gl_download_transform (GstBaseTransform * trans,
GstBuffer* inbuf, GstBuffer* outbuf); GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps, static gboolean gst_gl_download_get_unit_size (GstBaseTransform * trans,
guint* size); GstCaps * caps, guint * size);
static void static void
gst_gl_download_base_init (gpointer klass) gst_gl_download_base_init (gpointer klass)
{ {
GstElementClass* element_class = GST_ELEMENT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &element_details); gst_element_class_set_details (element_class, &element_details);
@ -138,9 +137,9 @@ gst_gl_download_base_init (gpointer klass)
static void static void
gst_gl_download_class_init (GstGLDownloadClass* klass) gst_gl_download_class_init (GstGLDownloadClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_download_set_property; gobject_class->set_property = gst_gl_download_set_property;
@ -158,30 +157,15 @@ gst_gl_download_class_init (GstGLDownloadClass* klass)
static void static void
gst_gl_download_init (GstGLDownload* download, GstGLDownloadClass* klass) gst_gl_download_init (GstGLDownload * download, GstGLDownloadClass * klass)
{ {
gst_gl_download_reset (download); gst_gl_download_reset (download);
} }
static void static void
gst_gl_download_set_property (GObject* object, guint prop_id, gst_gl_download_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{
//GstGLDownload *download = GST_GL_DOWNLOAD (object);
switch (prop_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_download_get_property (GObject* object, guint prop_id,
GValue* value, GParamSpec* pspec)
{ {
//GstGLDownload *download = GST_GL_DOWNLOAD (object); //GstGLDownload *download = GST_GL_DOWNLOAD (object);
@ -194,10 +178,23 @@ gst_gl_download_get_property (GObject* object, guint prop_id,
static void static void
gst_gl_download_reset (GstGLDownload* download) gst_gl_download_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{ {
if (download->display) //GstGLDownload *download = GST_GL_DOWNLOAD (object);
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_download_reset (GstGLDownload * download)
{
if (download->display) {
g_object_unref (download->display); g_object_unref (download->display);
download->display = NULL; download->display = NULL;
} }
@ -205,7 +202,7 @@ gst_gl_download_reset (GstGLDownload* download)
static gboolean static gboolean
gst_gl_download_start (GstBaseTransform* bt) gst_gl_download_start (GstBaseTransform * bt)
{ {
//GstGLDownload* download = GST_GL_DOWNLOAD (bt); //GstGLDownload* download = GST_GL_DOWNLOAD (bt);
@ -213,27 +210,27 @@ gst_gl_download_start (GstBaseTransform* bt)
} }
static gboolean static gboolean
gst_gl_download_stop (GstBaseTransform* bt) gst_gl_download_stop (GstBaseTransform * bt)
{ {
GstGLDownload* download = GST_GL_DOWNLOAD (bt); GstGLDownload *download = GST_GL_DOWNLOAD (bt);
gst_gl_download_reset (download); gst_gl_download_reset (download);
return TRUE; return TRUE;
} }
static GstCaps* static GstCaps *
gst_gl_download_transform_caps (GstBaseTransform * bt, gst_gl_download_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps) GstPadDirection direction, GstCaps * caps)
{ {
GstGLDownload* download; GstGLDownload *download;
GstStructure* structure; GstStructure *structure;
GstCaps *newcaps, *newothercaps; GstCaps *newcaps, *newothercaps;
GstStructure* newstruct; GstStructure *newstruct;
const GValue* width_value; const GValue *width_value;
const GValue* height_value; const GValue *height_value;
const GValue* framerate_value; const GValue *framerate_value;
const GValue* par_value; const GValue *par_value;
download = GST_GL_DOWNLOAD (bt); download = GST_GL_DOWNLOAD (bt);
@ -246,8 +243,7 @@ gst_gl_download_transform_caps (GstBaseTransform * bt,
framerate_value = gst_structure_get_value (structure, "framerate"); framerate_value = gst_structure_get_value (structure, "framerate");
par_value = gst_structure_get_value (structure, "pixel-aspect-ratio"); par_value = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (direction == GST_PAD_SINK) if (direction == GST_PAD_SINK) {
{
newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL); newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
newstruct = gst_caps_get_structure (newothercaps, 0); newstruct = gst_caps_get_structure (newothercaps, 0);
gst_structure_set_value (newstruct, "width", width_value); gst_structure_set_value (newstruct, "width", width_value);
@ -259,9 +255,9 @@ gst_gl_download_transform_caps (GstBaseTransform * bt,
gst_structure_set (newstruct, "pixel-aspect-ratio", GST_TYPE_FRACTION, gst_structure_set (newstruct, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1, 1, NULL); 1, 1, NULL);
newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL); newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL);
gst_caps_append(newcaps, newothercaps); gst_caps_append (newcaps, newothercaps);
} } else
else newcaps = gst_caps_new_simple ("video/x-raw-gl", NULL); newcaps = gst_caps_new_simple ("video/x-raw-gl", NULL);
newstruct = gst_caps_get_structure (newcaps, 0); newstruct = gst_caps_get_structure (newcaps, 0);
gst_structure_set_value (newstruct, "width", width_value); gst_structure_set_value (newstruct, "width", width_value);
@ -279,10 +275,10 @@ gst_gl_download_transform_caps (GstBaseTransform * bt,
} }
static gboolean static gboolean
gst_gl_download_set_caps (GstBaseTransform* bt, GstCaps* incaps, gst_gl_download_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
GstGLDownload* download; GstGLDownload *download;
gboolean ret; gboolean ret;
download = GST_GL_DOWNLOAD (bt); download = GST_GL_DOWNLOAD (bt);
@ -292,8 +288,7 @@ gst_gl_download_set_caps (GstBaseTransform* bt, GstCaps* incaps,
ret = gst_video_format_parse_caps (outcaps, &download->video_format, ret = gst_video_format_parse_caps (outcaps, &download->video_format,
&download->width, &download->height); &download->width, &download->height);
if (!ret) if (!ret) {
{
GST_ERROR ("bad caps"); GST_ERROR ("bad caps");
return FALSE; return FALSE;
} }
@ -302,8 +297,8 @@ gst_gl_download_set_caps (GstBaseTransform* bt, GstCaps* incaps,
} }
static gboolean static gboolean
gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps, gst_gl_download_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint* size) guint * size)
{ {
gboolean ret; gboolean ret;
GstStructure *structure; GstStructure *structure;
@ -311,14 +306,11 @@ gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
gint height; gint height;
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")) {
{
ret = gst_gl_buffer_parse_caps (caps, &width, &height); ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret) if (ret)
*size = gst_gl_buffer_get_size (width, height); *size = gst_gl_buffer_get_size (width, height);
} } else {
else
{
GstVideoFormat video_format; GstVideoFormat video_format;
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)
@ -329,28 +321,26 @@ gst_gl_download_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
} }
static GstFlowReturn static GstFlowReturn
gst_gl_download_transform (GstBaseTransform* trans, GstBuffer* inbuf, gst_gl_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer* outbuf) GstBuffer * outbuf)
{ {
GstGLDownload* download = GST_GL_DOWNLOAD (trans); GstGLDownload *download = GST_GL_DOWNLOAD (trans);
GstGLBuffer* gl_inbuf = GST_GL_BUFFER (inbuf); GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
if (download->display == NULL) if (download->display == NULL) {
{
download->display = g_object_ref (gl_inbuf->display); download->display = g_object_ref (gl_inbuf->display);
//blocking call, init color space conversion if needed //blocking call, init color space conversion if needed
gst_gl_display_init_download (download->display, download->video_format, gst_gl_display_init_download (download->display, download->video_format,
download->width, download->height); download->width, download->height);
} } else
else
g_assert (download->display == gl_inbuf->display); g_assert (download->display == gl_inbuf->display);
GST_DEBUG ("making video %p size %d", GST_DEBUG ("making video %p size %d",
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf)); GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
//blocking call //blocking call
if (gst_gl_display_do_download(download->display, gl_inbuf->texture, if (gst_gl_display_do_download (download->display, gl_inbuf->texture,
gl_inbuf->width, gl_inbuf->height, GST_BUFFER_DATA (outbuf))) gl_inbuf->width, gl_inbuf->height, GST_BUFFER_DATA (outbuf)))
return GST_FLOW_OK; return GST_FLOW_OK;
else else

View file

@ -55,24 +55,26 @@ static void gst_gl_effects_set_property (GObject * object, guint prop_id,
static void gst_gl_effects_get_property (GObject * object, guint prop_id, static void gst_gl_effects_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_effects_init_resources (GstGLFilter* filter); static void gst_gl_effects_init_resources (GstGLFilter * filter);
static void gst_gl_effects_reset_resources (GstGLFilter* filter); static void gst_gl_effects_reset_resources (GstGLFilter * filter);
static void gst_gl_effects_on_init_gl_context (GstGLFilter* filter); static void gst_gl_effects_on_init_gl_context (GstGLFilter * filter);
static void gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data); static void gst_gl_effects_ghash_func_clean (gpointer key, gpointer value,
gpointer data);
static gboolean gst_gl_effects_filter (GstGLFilter * filter, static gboolean gst_gl_effects_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ( static const GstElementDetails element_details =
"Gstreamer OpenGL Effects", GST_ELEMENT_DETAILS ("Gstreamer OpenGL Effects",
"Filter/Effect", "Filter/Effect",
"GL Shading Language effects", "GL Shading Language effects",
"Filippo Argiolas <filippo.argiolas@gmail.com>"); "Filippo Argiolas <filippo.argiolas@gmail.com>");
/* dont' forget to edit the following when a new effect is added */ /* dont' forget to edit the following when a new effect is added */
typedef enum { typedef enum
{
GST_GL_EFFECT_IDENTITY, GST_GL_EFFECT_IDENTITY,
GST_GL_EFFECT_MIRROR, GST_GL_EFFECT_MIRROR,
GST_GL_EFFECT_SQUEEZE, GST_GL_EFFECT_SQUEEZE,
@ -97,24 +99,24 @@ static GType
gst_gl_effects_effect_get_type (void) gst_gl_effects_effect_get_type (void)
{ {
static GType gl_effects_effect_type = 0; static GType gl_effects_effect_type = 0;
static const GEnumValue effect_types [] = { static const GEnumValue effect_types[] = {
{ GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity" }, {GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"},
{ GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror" }, {GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"},
{ GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze" }, {GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"},
{ GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch" }, {GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
{ GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye" }, {GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
{ GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl" }, {GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
{ GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge" }, {GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge"},
{ GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel" }, {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
{ GST_GL_EFFECT_SQUARE, "Square Effect", "square" }, {GST_GL_EFFECT_SQUARE, "Square Effect", "square"},
{ GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat" }, {GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat"},
{ GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia" }, {GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia"},
{ GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro" }, {GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro"},
{ GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro" }, {GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro"},
{ GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray" }, {GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray"},
{ GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin" }, {GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin"},
{ GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow" }, {GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow"},
{ 0, NULL, NULL } {0, NULL, NULL}
}; };
if (!gl_effects_effect_type) { if (!gl_effects_effect_type) {
@ -125,7 +127,8 @@ gst_gl_effects_effect_get_type (void)
} }
static void static void
gst_gl_effects_set_effect (GstGLEffects *effects, gint effect_type) { gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
{
switch (effect_type) { switch (effect_type) {
case GST_GL_EFFECT_IDENTITY: case GST_GL_EFFECT_IDENTITY:
@ -184,35 +187,39 @@ gst_gl_effects_set_effect (GstGLEffects *effects, gint effect_type) {
/* init resources that need a gl context */ /* init resources that need a gl context */
static void static void
gst_gl_effects_init_gl_resources (GstGLFilter *filter) gst_gl_effects_init_gl_resources (GstGLFilter * filter)
{ {
GstGLEffects *effects = GST_GL_EFFECTS (filter); GstGLEffects *effects = GST_GL_EFFECTS (filter);
gint i; gint i;
for (i=0; i<NEEDED_TEXTURES; i++) { for (i = 0; i < NEEDED_TEXTURES; i++) {
glGenTextures (1, &effects->midtexture[i]); glGenTextures (1, &effects->midtexture[i]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, effects->midtexture[i]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->midtexture[i]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); filter->width, filter->height, 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_MAG_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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);
} }
} }
/* free resources that need a gl context */ /* free resources that need a gl context */
static void static void
gst_gl_effects_reset_gl_resources (GstGLFilter *filter) gst_gl_effects_reset_gl_resources (GstGLFilter * filter)
{ {
GstGLEffects *effects = GST_GL_EFFECTS (filter); GstGLEffects *effects = GST_GL_EFFECTS (filter);
gint i; gint i;
for (i=0; i<10; i++) { for (i = 0; i < 10; i++) {
glDeleteTextures (1, &effects->midtexture[i]); glDeleteTextures (1, &effects->midtexture[i]);
effects->midtexture[i] = 0; effects->midtexture[i] = 0;
} }
for (i=0; i<GST_GL_EFFECTS_N_CURVES; i++) { for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
glDeleteTextures (1, &effects->curve[i]); glDeleteTextures (1, &effects->curve[i]);
effects->curve[i] = 0; effects->curve[i] = 0;
} }
@ -236,29 +243,27 @@ gst_gl_effects_class_init (GstGLEffectsClass * klass)
gobject_class->get_property = gst_gl_effects_get_property; gobject_class->get_property = gst_gl_effects_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_effects_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_effects_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb = gst_gl_effects_init_gl_resources; GST_GL_FILTER_CLASS (klass)->display_init_cb =
GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_effects_reset_gl_resources; gst_gl_effects_init_gl_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_effects_reset_gl_resources;
GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_effects_init_resources; GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_effects_init_resources;
GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_effects_reset_resources; GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_effects_reset_resources;
GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_effects_on_init_gl_context; GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_effects_on_init_gl_context;
g_object_class_install_property ( g_object_class_install_property (gobject_class,
gobject_class,
PROP_EFFECT, PROP_EFFECT,
g_param_spec_enum ("effect", g_param_spec_enum ("effect",
"Effect", "Effect",
"Select which effect apply to GL video texture", "Select which effect apply to GL video texture",
GST_TYPE_GL_EFFECTS_EFFECT, GST_TYPE_GL_EFFECTS_EFFECT,
GST_GL_EFFECT_IDENTITY, GST_GL_EFFECT_IDENTITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class,
g_object_class_install_property (
gobject_class,
PROP_HSWAP, PROP_HSWAP,
g_param_spec_boolean ("hswap", g_param_spec_boolean ("hswap",
"Horizontal Swap", "Horizontal Swap",
"Switch video texture left to right, useful with webcams", "Switch video texture left to right, useful with webcams",
FALSE, FALSE, G_PARAM_READWRITE));
G_PARAM_READWRITE));
} }
void void
@ -274,18 +279,18 @@ gst_gl_effects_draw_texture (GstGLEffects * effects, GLuint tex)
glTexCoord2f (0.0, 0.0); glTexCoord2f (0.0, 0.0);
glVertex2f (-1.0, -1.0); glVertex2f (-1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, 0.0); glTexCoord2f ((gfloat) filter->width, 0.0);
glVertex2f (1.0, -1.0); glVertex2f (1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, (gfloat)filter->height); glTexCoord2f ((gfloat) filter->width, (gfloat) filter->height);
glVertex2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, (gfloat)filter->height); glTexCoord2f (0.0, (gfloat) filter->height);
glVertex2f (-1.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd (); glEnd ();
} }
static void static void
set_horizontal_swap (GstGLDisplay *display, gpointer data) set_horizontal_swap (GstGLDisplay * display, gpointer data)
{ {
// GstGLEffects *effects = GST_GL_EFFECTS (data); // GstGLEffects *effects = GST_GL_EFFECTS (data);
@ -310,8 +315,8 @@ gst_gl_effects_init (GstGLEffects * effects, GstGLEffectsClass * klass)
static void static void
gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data) gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data)
{ {
GstGLShader* shader = (GstGLShader*) value; GstGLShader *shader = (GstGLShader *) value;
GstGLFilter* filter = (GstGLFilter*) data; GstGLFilter *filter = (GstGLFilter *) data;
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, shader); gst_gl_display_del_shader (filter->display, shader);
@ -320,9 +325,9 @@ gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data)
} }
static void static void
gst_gl_effects_reset_resources (GstGLFilter* filter) gst_gl_effects_reset_resources (GstGLFilter * filter)
{ {
GstGLEffects* effects = GST_GL_EFFECTS(filter); GstGLEffects *effects = GST_GL_EFFECTS (filter);
// g_message ("reset resources"); // g_message ("reset resources");
@ -376,25 +381,24 @@ gst_gl_effects_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_effects_init_resources (GstGLFilter* filter) gst_gl_effects_init_resources (GstGLFilter * filter)
{ {
GstGLEffects *effects = GST_GL_EFFECTS (filter); GstGLEffects *effects = GST_GL_EFFECTS (filter);
gint i; gint i;
// g_message ("init resources"); // g_message ("init resources");
// g_message ("init hashtable"); // g_message ("init hashtable");
effects->shaderstable = g_hash_table_new (g_str_hash, effects->shaderstable = g_hash_table_new (g_str_hash, g_str_equal);
g_str_equal);
// g_message ("zero textures and curves"); // g_message ("zero textures and curves");
for (i=0; i<NEEDED_TEXTURES; i++) { for (i = 0; i < NEEDED_TEXTURES; i++) {
effects->midtexture[i] = 0; effects->midtexture[i] = 0;
} }
for (i=0; i<GST_GL_EFFECTS_N_CURVES; i++) { for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
effects->curve[i] = 0; effects->curve[i] = 0;
} }
} }
static void static void
gst_gl_effects_on_init_gl_context (GstGLFilter* filter) gst_gl_effects_on_init_gl_context (GstGLFilter * filter)
{ {
//check that your hardware supports shader //check that your hardware supports shader
//if not the pipeline correctly shut down //if not the pipeline correctly shut down
@ -402,10 +406,10 @@ gst_gl_effects_on_init_gl_context (GstGLFilter* filter)
} }
static gboolean static gboolean
gst_gl_effects_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_effects_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLEffects* effects = GST_GL_EFFECTS(filter); GstGLEffects *effects = GST_GL_EFFECTS (filter);
effects->intexture = inbuf->texture; effects->intexture = inbuf->texture;
effects->outtexture = outbuf->texture; effects->outtexture = outbuf->texture;

View file

@ -46,7 +46,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL application filter", GST_ELEMENT_DETAILS ("OpenGL application filter",
"Filter/Effect", "Filter/Effect",
"Use client callbacks to define the scene", "Use client callbacks to define the scene",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -64,16 +64,17 @@ enum
GST_BOILERPLATE_FULL (GstGLFilterApp, gst_gl_filter_app, GstGLFilter, GST_BOILERPLATE_FULL (GstGLFilterApp, gst_gl_filter_app, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT); GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_filter_app_set_property (GObject* object, guint prop_id, static void gst_gl_filter_app_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_app_get_property (GObject* object, guint prop_id, static void gst_gl_filter_app_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter, static gboolean gst_gl_filter_app_set_caps (GstGLFilter * filter,
GstCaps* incaps, GstCaps* outcaps); GstCaps * incaps, GstCaps * outcaps);
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 (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filter_app_callback (gint width, gint height, guint texture,
gpointer stuff);
static void static void
@ -85,9 +86,9 @@ gst_gl_filter_app_base_init (gpointer klass)
} }
static void static void
gst_gl_filter_app_class_init (GstGLFilterAppClass* klass) gst_gl_filter_app_class_init (GstGLFilterAppClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_app_set_property; gobject_class->set_property = gst_gl_filter_app_set_property;
@ -97,29 +98,28 @@ gst_gl_filter_app_class_init (GstGLFilterAppClass* klass)
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_app_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_app_filter;
g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK,
g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", g_param_spec_pointer ("client_reshape_callback",
"Client reshape callback",
"Define a custom reshape callback in a client code", "Define a custom reshape callback in a client code",
G_PARAM_WRITABLE)); G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK,
g_param_spec_pointer ("client_draw_callback", "Client draw callback", g_param_spec_pointer ("client_draw_callback", "Client draw callback",
"Define a custom draw callback in a client code", "Define a custom draw callback in a client code", G_PARAM_WRITABLE));
G_PARAM_WRITABLE));
} }
static void static void
gst_gl_filter_app_init (GstGLFilterApp* filter, gst_gl_filter_app_init (GstGLFilterApp * filter, GstGLFilterAppClass * klass)
GstGLFilterAppClass* klass)
{ {
filter->clientReshapeCallback = NULL; filter->clientReshapeCallback = NULL;
filter->clientDrawCallback = NULL; filter->clientDrawCallback = NULL;
} }
static void static void
gst_gl_filter_app_set_property (GObject* object, guint prop_id, gst_gl_filter_app_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
GstGLFilterApp* filter = GST_GL_FILTER_APP (object); GstGLFilterApp *filter = GST_GL_FILTER_APP (object);
switch (prop_id) { switch (prop_id) {
case PROP_CLIENT_RESHAPE_CALLBACK: case PROP_CLIENT_RESHAPE_CALLBACK:
@ -139,13 +139,12 @@ gst_gl_filter_app_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_app_get_property (GObject* object, guint prop_id, gst_gl_filter_app_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterApp* filter = GST_GL_FILTER_APP (object); //GstGLFilterApp* filter = GST_GL_FILTER_APP (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -153,8 +152,8 @@ gst_gl_filter_app_get_property (GObject* object, guint prop_id,
} }
static gboolean static gboolean
gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, gst_gl_filter_app_set_caps (GstGLFilter * filter, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
//GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); //GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter);
@ -162,29 +161,27 @@ gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps,
} }
static gboolean static gboolean
gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filter_app_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); GstGLFilterApp *app_filter = GST_GL_FILTER_APP (filter);
if (app_filter->clientDrawCallback) if (app_filter->clientDrawCallback) {
{
//blocking call, use a FBO //blocking call, use a FBO
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, app_filter->clientDrawCallback, filter->fbo, filter->depthbuffer, outbuf->texture,
inbuf->width, inbuf->height, inbuf->texture, app_filter->clientDrawCallback, inbuf->width, inbuf->height,
45, (gfloat)filter->width / (gfloat)filter->height, 0.1, 100, inbuf->texture, 45, (gfloat) filter->width / (gfloat) filter->height,
GST_GL_DISPLAY_PROJECTION_PERSPECIVE, NULL); 0.1, 100, GST_GL_DISPLAY_PROJECTION_PERSPECIVE, NULL);
} }
//default //default
else else {
{
//blocking call, use a FBO //blocking call, use a FBO
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback, filter->fbo, filter->depthbuffer, outbuf->texture,
inbuf->width, inbuf->height, inbuf->texture, gst_gl_filter_app_callback, inbuf->width, inbuf->height, inbuf->texture,
0, filter->width, 0, filter->height, 0, filter->width, 0, filter->height, GST_GL_DISPLAY_PROJECTION_ORTHO2D,
GST_GL_DISPLAY_PROJECTION_ORTHO2D, NULL); NULL);
} }
return TRUE; return TRUE;
@ -192,17 +189,20 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
//opengl scene, params: input texture (not the output filter->texture) //opengl scene, params: input texture (not the output filter->texture)
static void static void
gst_gl_filter_app_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filter_app_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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_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_S,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();

View file

@ -66,45 +66,39 @@ GType gst_gl_glfilterblur_get_type (void);
/* horizontal convolution */ /* horizontal convolution */
static const gchar *hconv9_fragment_source = static const gchar *hconv9_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;" "uniform sampler2DRect tex;"
"uniform float norm_const;" "uniform float norm_const;"
"uniform float norm_offset;" "uniform float norm_offset;"
"uniform float kernel[9];" "uniform float kernel[9];"
"void main () {" "void main () {"
" float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" " float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);"
" vec2 texturecoord = gl_TexCoord[0].st;" " vec2 texturecoord = gl_TexCoord[0].st;"
" int i;" " int i;"
" vec4 sum = vec4 (0.0);" " vec4 sum = vec4 (0.0);"
" for (i = 0; i < 9; i++) { " " for (i = 0; i < 9; i++) { "
" if (kernel[i] != 0.0) {" " if (kernel[i] != 0.0) {"
" vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s+offset[i], texturecoord.t)); " " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s+offset[i], texturecoord.t)); "
" sum += neighbor * kernel[i]/norm_const; " " sum += neighbor * kernel[i]/norm_const; "
" }" " }" " }" " gl_FragColor = sum + norm_offset;" "}";
" }"
" gl_FragColor = sum + norm_offset;"
"}";
/* vertical convolution */ /* vertical convolution */
static const gchar *vconv9_fragment_source = static const gchar *vconv9_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;" "uniform sampler2DRect tex;"
"uniform float norm_const;" "uniform float norm_const;"
"uniform float norm_offset;" "uniform float norm_offset;"
"uniform float kernel[9];" "uniform float kernel[9];"
"void main () {" "void main () {"
" float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" " float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);"
" vec2 texturecoord = gl_TexCoord[0].st;" " vec2 texturecoord = gl_TexCoord[0].st;"
" int i;" " int i;"
" vec4 sum = vec4 (0.0);" " vec4 sum = vec4 (0.0);"
" for (i = 0; i < 9; i++) { " " for (i = 0; i < 9; i++) { "
" if (kernel[i] != 0.0) {" " if (kernel[i] != 0.0) {"
" vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s, texturecoord.t+offset[i])); " " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s, texturecoord.t+offset[i])); "
" sum += neighbor * kernel[i]/norm_const; " " sum += neighbor * kernel[i]/norm_const; "
" }" " }" " }" " gl_FragColor = sum + norm_offset;" "}";
" }"
" gl_FragColor = sum + norm_offset;"
"}";
#define GST_CAT_DEFAULT gst_gl_filterblur_debug #define GST_CAT_DEFAULT gst_gl_filterblur_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@ -125,33 +119,38 @@ static void gst_gl_filterblur_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_filterblur_get_property (GObject * object, guint prop_id, static void gst_gl_filterblur_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_filter_filterblur_reset (GstGLFilter* filter); static void gst_gl_filter_filterblur_reset (GstGLFilter * filter);
static void gst_gl_filterblur_draw_texture (GstGLFilterBlur * filterblur, GLuint tex); static void gst_gl_filterblur_draw_texture (GstGLFilterBlur * filterblur,
GLuint tex);
static void gst_gl_filterblur_init_shader (GstGLFilter* filter); static void gst_gl_filterblur_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filterblur_filter (GstGLFilter * filter, static gboolean gst_gl_filterblur_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filterblur_hcallback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filterblur_hcallback (gint width, gint height, guint texture,
static void gst_gl_filterblur_vcallback (gint width, gint height, guint texture, gpointer stuff); gpointer stuff);
static void gst_gl_filterblur_vcallback (gint width, gint height, guint texture,
gpointer stuff);
static void static void
gst_gl_filterblur_init_resources (GstGLFilter *filter) gst_gl_filterblur_init_resources (GstGLFilter * filter)
{ {
GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
glGenTextures (1, &filterblur->midtexture); glGenTextures (1, &filterblur->midtexture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, filterblur->midtexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, filterblur->midtexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); filter->width, filter->height, 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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_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_S,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
} }
static void static void
gst_gl_filterblur_reset_resources (GstGLFilter *filter) gst_gl_filterblur_reset_resources (GstGLFilter * filter)
{ {
GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
@ -176,14 +175,17 @@ gst_gl_filterblur_class_init (GstGLFilterBlurClass * klass)
gobject_class->get_property = gst_gl_filterblur_get_property; gobject_class->get_property = gst_gl_filterblur_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filterblur_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filterblur_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb = gst_gl_filterblur_init_resources; GST_GL_FILTER_CLASS (klass)->display_init_cb =
GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_filterblur_reset_resources; gst_gl_filterblur_init_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_filterblur_reset_resources;
GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filterblur_init_shader; GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filterblur_init_shader;
GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filterblur_reset; GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filterblur_reset;
} }
static void static void
gst_gl_filterblur_init (GstGLFilterBlur * filterblur, GstGLFilterBlurClass * klass) gst_gl_filterblur_init (GstGLFilterBlur * filterblur,
GstGLFilterBlurClass * klass)
{ {
filterblur->shader0 = NULL; filterblur->shader0 = NULL;
filterblur->shader1 = NULL; filterblur->shader1 = NULL;
@ -191,9 +193,9 @@ gst_gl_filterblur_init (GstGLFilterBlur * filterblur, GstGLFilterBlurClass * kla
} }
static void static void
gst_gl_filter_filterblur_reset (GstGLFilter* filter) gst_gl_filter_filterblur_reset (GstGLFilter * filter)
{ {
GstGLFilterBlur* filterblur = GST_GL_FILTERBLUR(filter); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, filterblur->shader0); gst_gl_display_del_shader (filter->display, filterblur->shader0);
@ -229,15 +231,17 @@ gst_gl_filterblur_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_filterblur_init_shader (GstGLFilter* filter) gst_gl_filterblur_init_shader (GstGLFilter * filter)
{ {
GstGLFilterBlur* blur_filter = GST_GL_FILTERBLUR (filter); GstGLFilterBlur *blur_filter = GST_GL_FILTERBLUR (filter);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, hconv9_fragment_source, &blur_filter->shader0); gst_gl_display_gen_shader (filter->display, 0, hconv9_fragment_source,
&blur_filter->shader0);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, vconv9_fragment_source, &blur_filter->shader1); gst_gl_display_gen_shader (filter->display, 0, vconv9_fragment_source,
&blur_filter->shader1);
} }
static void static void
@ -253,18 +257,18 @@ gst_gl_filterblur_draw_texture (GstGLFilterBlur * filterblur, GLuint tex)
glTexCoord2f (0.0, 0.0); glTexCoord2f (0.0, 0.0);
glVertex2f (-1.0, -1.0); glVertex2f (-1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, 0.0); glTexCoord2f ((gfloat) filter->width, 0.0);
glVertex2f (1.0, -1.0); glVertex2f (1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, (gfloat)filter->height); glTexCoord2f ((gfloat) filter->width, (gfloat) filter->height);
glVertex2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, (gfloat)filter->height); glTexCoord2f (0.0, (gfloat) filter->height);
glVertex2f (-1.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd (); glEnd ();
} }
static void static void
change_view (GstGLDisplay *display, gpointer data) change_view (GstGLDisplay * display, gpointer data)
{ {
// GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (data); // GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (data);
@ -280,33 +284,35 @@ change_view (GstGLDisplay *display, gpointer data)
} }
static gboolean static gboolean
gst_gl_filterblur_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filterblur_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLFilterBlur* filterblur = GST_GL_FILTERBLUR(filter); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
gst_gl_filter_render_to_target (filter, inbuf->texture, filterblur->midtexture, gst_gl_filter_render_to_target (filter, inbuf->texture,
gst_gl_filterblur_hcallback, filterblur); filterblur->midtexture, gst_gl_filterblur_hcallback, filterblur);
gst_gl_display_thread_add (filter->display, change_view, filterblur); gst_gl_display_thread_add (filter->display, change_view, filterblur);
gst_gl_filter_render_to_target (filter, filterblur->midtexture, outbuf->texture, gst_gl_filter_render_to_target (filter, filterblur->midtexture,
gst_gl_filterblur_vcallback, filterblur); outbuf->texture, gst_gl_filterblur_vcallback, filterblur);
return TRUE; return TRUE;
} }
static void static void
gst_gl_filterblur_hcallback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filterblur_hcallback (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLFilterBlur* filterblur = GST_GL_FILTERBLUR (stuff); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (stuff);
/* hard coded kernel, it could be easily generated at runtime with a /* hard coded kernel, it could be easily generated at runtime with a
* property to change standard deviation */ * property to change standard deviation */
gfloat gauss_kernel[9] = { gfloat gauss_kernel[9] = {
0.026995f, 0.064759f, 0.120985f, 0.026995f, 0.064759f, 0.120985f,
0.176033f, 0.199471f, 0.176033f, 0.176033f, 0.199471f, 0.176033f,
0.120985f, 0.064759f, 0.026995f }; 0.120985f, 0.064759f, 0.026995f
};
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -320,7 +326,8 @@ gst_gl_filterblur_hcallback (gint width, gint height, guint texture, gpointer st
gst_gl_shader_set_uniform_1i (filterblur->shader0, "tex", 1); gst_gl_shader_set_uniform_1i (filterblur->shader0, "tex", 1);
gst_gl_shader_set_uniform_1fv (filterblur->shader0, "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1fv (filterblur->shader0, "kernel", 9,
gauss_kernel);
gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_const", 0.977016f); gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_const", 0.977016f);
gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_offset", 0.0f); gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_offset", 0.0f);
@ -329,16 +336,18 @@ gst_gl_filterblur_hcallback (gint width, gint height, guint texture, gpointer st
static void static void
gst_gl_filterblur_vcallback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filterblur_vcallback (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLFilterBlur* filterblur = GST_GL_FILTERBLUR (stuff); GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (stuff);
/* hard coded kernel, it could be easily generated at runtime with a /* hard coded kernel, it could be easily generated at runtime with a
* property to change standard deviation */ * property to change standard deviation */
gfloat gauss_kernel[9] = { gfloat gauss_kernel[9] = {
0.026995f, 0.064759f, 0.120985f, 0.026995f, 0.064759f, 0.120985f,
0.176033f, 0.199471f, 0.176033f, 0.176033f, 0.199471f, 0.176033f,
0.120985f, 0.064759f, 0.026995f }; 0.120985f, 0.064759f, 0.026995f
};
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -352,7 +361,8 @@ gst_gl_filterblur_vcallback (gint width, gint height, guint texture, gpointer st
gst_gl_shader_set_uniform_1i (filterblur->shader1, "tex", 1); gst_gl_shader_set_uniform_1i (filterblur->shader1, "tex", 1);
gst_gl_shader_set_uniform_1fv (filterblur->shader1, "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1fv (filterblur->shader1, "kernel", 9,
gauss_kernel);
gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_const", 0.977016f); gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_const", 0.977016f);
gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_offset", 0.0f); gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_offset", 0.0f);

View file

@ -50,7 +50,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL cube filter", GST_ELEMENT_DETAILS ("OpenGL cube filter",
"Filter/Effect", "Filter/Effect",
"Map input texture on the 6 cube faces", "Map input texture on the 6 cube faces",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -73,16 +73,17 @@ enum
GST_BOILERPLATE_FULL (GstGLFilterCube, gst_gl_filter_cube, GstGLFilter, GST_BOILERPLATE_FULL (GstGLFilterCube, gst_gl_filter_cube, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT); GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_filter_cube_set_property (GObject* object, guint prop_id, static void gst_gl_filter_cube_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_cube_get_property (GObject* object, guint prop_id, static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_gl_filter_cube_set_caps (GstGLFilter* filter, static gboolean gst_gl_filter_cube_set_caps (GstGLFilter * filter,
GstCaps* incaps, GstCaps* outcaps); GstCaps * incaps, GstCaps * outcaps);
static gboolean gst_gl_filter_cube_filter (GstGLFilter* filter, static gboolean gst_gl_filter_cube_filter (GstGLFilter * filter,
GstGLBuffer* inbuf, GstGLBuffer* outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filter_cube_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filter_cube_callback (gint width, gint height, guint texture,
gpointer stuff);
static void static void
@ -96,7 +97,7 @@ gst_gl_filter_cube_base_init (gpointer klass)
static void static void
gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_cube_set_property; gobject_class->set_property = gst_gl_filter_cube_set_property;
@ -122,8 +123,8 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass)
0.0, 180.0, 45.0, G_PARAM_WRITABLE)); 0.0, 180.0, 45.0, G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_ASPECT, g_object_class_install_property (gobject_class, PROP_ASPECT,
g_param_spec_double ("aspect", "Aspect", "Field of view in the x direction", g_param_spec_double ("aspect", "Aspect",
0.0, 100, 0.0, G_PARAM_WRITABLE)); "Field of view in the x direction", 0.0, 100, 0.0, G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_ZNEAR, g_object_class_install_property (gobject_class, PROP_ZNEAR,
g_param_spec_double ("znear", "Znear", g_param_spec_double ("znear", "Znear",
@ -137,8 +138,7 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass)
} }
static void static void
gst_gl_filter_cube_init (GstGLFilterCube* filter, gst_gl_filter_cube_init (GstGLFilterCube * filter, GstGLFilterCubeClass * klass)
GstGLFilterCubeClass* klass)
{ {
filter->fovy = 45; filter->fovy = 45;
filter->aspect = 0; filter->aspect = 0;
@ -147,13 +147,12 @@ gst_gl_filter_cube_init (GstGLFilterCube* filter,
} }
static void static void
gst_gl_filter_cube_set_property (GObject* object, guint prop_id, gst_gl_filter_cube_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object); GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object);
switch (prop_id) switch (prop_id) {
{
case PROP_RED: case PROP_RED:
filter->red = g_value_get_float (value); filter->red = g_value_get_float (value);
break; break;
@ -182,13 +181,12 @@ gst_gl_filter_cube_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_cube_get_property (GObject* object, guint prop_id, gst_gl_filter_cube_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object); //GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -196,100 +194,128 @@ gst_gl_filter_cube_get_property (GObject* object, guint prop_id,
} }
static gboolean static gboolean
gst_gl_filter_cube_set_caps (GstGLFilter* filter, GstCaps* incaps, gst_gl_filter_cube_set_caps (GstGLFilter * filter, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (filter); GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
if (cube_filter->aspect == 0) if (cube_filter->aspect == 0)
cube_filter->aspect = (gdouble)filter->width / (gdouble)filter->height; cube_filter->aspect = (gdouble) filter->width / (gdouble) filter->height;
return TRUE; return TRUE;
} }
static gboolean static gboolean
gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filter_cube_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (filter); GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
//blocking call, use a FBO //blocking call, use a FBO
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_cube_callback, filter->fbo, filter->depthbuffer, outbuf->texture,
inbuf->width, inbuf->height, inbuf->texture, gst_gl_filter_cube_callback, inbuf->width, inbuf->height, inbuf->texture,
cube_filter->fovy, cube_filter->aspect, cube_filter->znear, cube_filter->zfar, cube_filter->fovy, cube_filter->aspect, cube_filter->znear,
GST_GL_DISPLAY_PROJECTION_PERSPECIVE, (gpointer)cube_filter); cube_filter->zfar, GST_GL_DISPLAY_PROJECTION_PERSPECIVE,
(gpointer) cube_filter);
return TRUE; return TRUE;
} }
//opengl scene, params: input texture (not the output filter->texture) //opengl scene, params: input texture (not the output filter->texture)
static void static void
gst_gl_filter_cube_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filter_cube_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
static GLfloat xrot = 0; static GLfloat xrot = 0;
static GLfloat yrot = 0; static GLfloat yrot = 0;
static GLfloat zrot = 0; static GLfloat zrot = 0;
GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE (stuff); GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (stuff);
glEnable(GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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_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_S,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClearColor(cube_filter->red, cube_filter->green, cube_filter->blue, 0.0); glClearColor (cube_filter->red, cube_filter->green, cube_filter->blue, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity ();
glTranslatef(0.0f,0.0f,-5.0f); glTranslatef (0.0f, 0.0f, -5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef (xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f); glRotatef (yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f); glRotatef (zrot, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); glBegin (GL_QUADS);
// Front Face // Front Face
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f ((gfloat) width, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f (-1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f (0.0f, 0.0f);
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f (1.0f, -1.0f, 1.0f);
glTexCoord2f (0.0f, (gfloat) height);
glVertex3f (1.0f, 1.0f, 1.0f);
glTexCoord2f ((gfloat) width, (gfloat) height);
glVertex3f (-1.0f, 1.0f, 1.0f);
// Back Face // Back Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, 0.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f (-1.0f, -1.0f, -1.0f);
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f (0.0f, (gfloat) height);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f (-1.0f, 1.0f, -1.0f);
glTexCoord2f ((gfloat) width, (gfloat) height);
glVertex3f (1.0f, 1.0f, -1.0f);
glTexCoord2f ((gfloat) width, 0.0f);
glVertex3f (1.0f, -1.0f, -1.0f);
// Top Face // Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f ((gfloat) width, (gfloat) height);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f (-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f ((gfloat) width, 0.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f (-1.0f, 1.0f, 1.0f);
glTexCoord2f (0.0f, 0.0f);
glVertex3f (1.0f, 1.0f, 1.0f);
glTexCoord2f (0.0f, (gfloat) height);
glVertex3f (1.0f, 1.0f, -1.0f);
// Bottom Face // Bottom Face
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f ((gfloat) width, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f (-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f (0.0f, 0.0f);
glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f (1.0f, -1.0f, -1.0f);
glTexCoord2f (0.0f, (gfloat) height);
glVertex3f (1.0f, -1.0f, 1.0f);
glTexCoord2f ((gfloat) width, (gfloat) height);
glVertex3f (-1.0f, -1.0f, 1.0f);
// Right face // Right face
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, 0.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f (1.0f, -1.0f, -1.0f);
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f (0.0f, (gfloat) height);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f (1.0f, 1.0f, -1.0f);
glTexCoord2f ((gfloat) width, (gfloat) height);
glVertex3f (1.0f, 1.0f, 1.0f);
glTexCoord2f ((gfloat) width, 0.0f);
glVertex3f (1.0f, -1.0f, 1.0f);
// Left Face // Left Face
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f ((gfloat) width, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f (-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f (0.0f, 0.0f);
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f (-1.0f, -1.0f, 1.0f);
glEnd(); glTexCoord2f (0.0f, (gfloat) height);
glVertex3f (-1.0f, 1.0f, 1.0f);
glTexCoord2f ((gfloat) width, (gfloat) height);
glVertex3f (-1.0f, 1.0f, -1.0f);
glEnd ();
xrot+=0.3f; xrot += 0.3f;
yrot+=0.2f; yrot += 0.2f;
zrot+=0.4f; zrot += 0.4f;
glDisable(GL_DEPTH_TEST); glDisable (GL_DEPTH_TEST);
} }

View file

@ -47,7 +47,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL glass filter", GST_ELEMENT_DETAILS ("OpenGL glass filter",
"Filter/Effect", "Filter/Effect",
"Glass Filter", "Glass Filter",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -68,17 +68,18 @@ static void gst_gl_filter_glass_set_property (GObject * object, guint prop_id,
static void gst_gl_filter_glass_get_property (GObject * object, guint prop_id, static void gst_gl_filter_glass_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_filter_glass_reset (GstGLFilter* filter); static void gst_gl_filter_glass_reset (GstGLFilter * filter);
static void gst_gl_filter_glass_init_shader (GstGLFilter* filter); static void gst_gl_filter_glass_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filter_glass_filter (GstGLFilter * filter, static gboolean gst_gl_filter_glass_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filter_glass_draw_background_gradient (); static void gst_gl_filter_glass_draw_background_gradient ();
static void gst_gl_filter_glass_draw_video_plane (GstGLFilter* filter, static void gst_gl_filter_glass_draw_video_plane (GstGLFilter * filter,
gint width, gint height, guint texture, gfloat center_x, gfloat center_y, gint width, gint height, guint texture, gfloat center_x, gfloat center_y,
gfloat start_alpha, gfloat stop_alpha, gboolean reversed); gfloat start_alpha, gfloat stop_alpha, gboolean reversed);
static void gst_gl_filter_glass_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filter_glass_callback (gint width, gint height,
guint texture, gpointer stuff);
static const gchar *glass_fragment_source = static const gchar *glass_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
@ -93,20 +94,16 @@ static const gchar *glass_fragment_source =
" float r = L1;" " float r = L1;"
" if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y < L1)" " if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y < L1)"
" r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );" " r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );"
" else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y < L1)" " else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y < L1)"
" r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );" " r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );"
" else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y > L3)" " else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y > L3)"
" r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );" " r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );"
" else if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y > L3)" " else if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y > L3)"
" r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );" " r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );"
" if (r > L1)" " if (r > L1)"
" w = 0.0;" " w = 0.0;"
" vec4 color = texture2DRect (tex, gl_TexCoord[0].st);" " vec4 color = texture2DRect (tex, gl_TexCoord[0].st);"
" gl_FragColor = vec4(color.rgb, gl_Color.a * w);" " gl_FragColor = vec4(color.rgb, gl_Color.a * w);" "}";
"}";
static void static void
gst_gl_filter_glass_base_init (gpointer klass) gst_gl_filter_glass_base_init (gpointer klass)
@ -117,9 +114,9 @@ gst_gl_filter_glass_base_init (gpointer klass)
} }
static void static void
gst_gl_filter_glass_class_init (GstGLFilterGlassClass* klass) gst_gl_filter_glass_class_init (GstGLFilterGlassClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_glass_set_property; gobject_class->set_property = gst_gl_filter_glass_set_property;
@ -131,30 +128,29 @@ gst_gl_filter_glass_class_init (GstGLFilterGlassClass* klass)
} }
static void static void
gst_gl_filter_glass_init (GstGLFilterGlass* filter, gst_gl_filter_glass_init (GstGLFilterGlass * filter,
GstGLFilterGlassClass* klass) GstGLFilterGlassClass * klass)
{ {
filter->shader = NULL; filter->shader = NULL;
filter->timestamp = 0; filter->timestamp = 0;
} }
static void static void
gst_gl_filter_glass_reset (GstGLFilter* filter) gst_gl_filter_glass_reset (GstGLFilter * filter)
{ {
GstGLFilterGlass* glass_filter = GST_GL_FILTER_GLASS(filter); GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, glass_filter->shader); gst_gl_display_del_shader (filter->display, glass_filter->shader);
} }
static void static void
gst_gl_filter_glass_set_property (GObject* object, guint prop_id, gst_gl_filter_glass_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object); //GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -162,13 +158,12 @@ gst_gl_filter_glass_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_glass_get_property (GObject* object, guint prop_id, gst_gl_filter_glass_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object); //GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -176,27 +171,28 @@ gst_gl_filter_glass_get_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_glass_init_shader (GstGLFilter* filter) gst_gl_filter_glass_init_shader (GstGLFilter * filter)
{ {
GstGLFilterGlass* glass_filter = GST_GL_FILTER_GLASS (filter); GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, glass_fragment_source, &glass_filter->shader); gst_gl_display_gen_shader (filter->display, 0, glass_fragment_source,
&glass_filter->shader);
} }
static gboolean static gboolean
gst_gl_filter_glass_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filter_glass_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
gpointer glass_filter = GST_GL_FILTER_GLASS (filter); gpointer glass_filter = GST_GL_FILTER_GLASS (filter);
GST_GL_FILTER_GLASS(glass_filter)->timestamp = GST_BUFFER_TIMESTAMP (inbuf); GST_GL_FILTER_GLASS (glass_filter)->timestamp = GST_BUFFER_TIMESTAMP (inbuf);
//blocking call, use a FBO //blocking call, use a FBO
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_glass_callback, filter->fbo, filter->depthbuffer, outbuf->texture,
inbuf->width, inbuf->height, inbuf->texture, gst_gl_filter_glass_callback, inbuf->width, inbuf->height, inbuf->texture,
80, (gdouble)filter->width/(gdouble)filter->height, 1.0, 5000.0, 80, (gdouble) filter->width / (gdouble) filter->height, 1.0, 5000.0,
GST_GL_DISPLAY_PROJECTION_PERSPECIVE, (gpointer)glass_filter); GST_GL_DISPLAY_PROJECTION_PERSPECIVE, (gpointer) glass_filter);
return TRUE; return TRUE;
} }
@ -242,13 +238,12 @@ gst_gl_filter_glass_draw_background_gradient ()
} }
static void static void
gst_gl_filter_glass_draw_video_plane (GstGLFilter* filter, gst_gl_filter_glass_draw_video_plane (GstGLFilter * filter,
gint width, gint height, guint texture, gint width, gint height, guint texture,
gfloat center_x, gfloat center_y, gfloat center_x, gfloat center_y,
gfloat start_alpha, gfloat stop_alpha, gfloat start_alpha, gfloat stop_alpha, gboolean reversed)
gboolean reversed)
{ {
GstGLFilterGlass* glass_filter = GST_GL_FILTER_GLASS (filter); GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
gfloat topy; gfloat topy;
gfloat bottomy; gfloat bottomy;
@ -268,8 +263,9 @@ gst_gl_filter_glass_draw_video_plane (GstGLFilter* filter,
glDisable (GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
gst_gl_shader_set_uniform_1i (glass_filter->shader, "tex", 0); gst_gl_shader_set_uniform_1i (glass_filter->shader, "tex", 0);
gst_gl_shader_set_uniform_1f (glass_filter->shader, "width", (gfloat)width); gst_gl_shader_set_uniform_1f (glass_filter->shader, "width", (gfloat) width);
gst_gl_shader_set_uniform_1f (glass_filter->shader, "height", (gfloat)height); gst_gl_shader_set_uniform_1f (glass_filter->shader, "height",
(gfloat) height);
glBegin (GL_QUADS); glBegin (GL_QUADS);
glColor4f (1.0f, 1.0f, 1.0f, start_alpha); glColor4f (1.0f, 1.0f, 1.0f, start_alpha);
@ -290,27 +286,27 @@ gst_gl_filter_glass_draw_video_plane (GstGLFilter* filter,
//opengl scene, params: input texture (not the output filter->texture) //opengl scene, params: input texture (not the output filter->texture)
static void static void
gst_gl_filter_glass_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filter_glass_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
static gint64 start_time = 0; static gint64 start_time = 0;
GstGLFilter* filter = GST_GL_FILTER (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff);
GstGLFilterGlass* glass_filter = GST_GL_FILTER_GLASS (stuff); GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (stuff);
if (start_time == 0) if (start_time == 0)
start_time = get_time (); start_time = get_time ();
else else {
{ gint64 time_left =
gint64 time_left = (glass_filter->timestamp / 1000) - (get_time () - start_time); (glass_filter->timestamp / 1000) - (get_time () - start_time);
time_left -= 1000000 / 25; time_left -= 1000000 / 25;
if (time_left > 2000) if (time_left > 2000) {
{
GST_LOG ("escape"); GST_LOG ("escape");
return; return;
} }
} }
glTranslatef(0.0f, 2.0f, -3.0f); glTranslatef (0.0f, 2.0f, -3.0f);
gst_gl_filter_glass_draw_background_gradient (); gst_gl_filter_glass_draw_background_gradient ();

View file

@ -42,7 +42,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL laplacian filter", GST_ELEMENT_DETAILS ("OpenGL laplacian filter",
"Filter/Effect", "Filter/Effect",
"Laplacian Convolution Demo Filter", "Laplacian Convolution Demo Filter",
"Filippo Argiolas <filippo.argiolas@gmail.com>"); "Filippo Argiolas <filippo.argiolas@gmail.com>");
@ -55,19 +55,20 @@ enum
#define DEBUG_INIT(bla) \ #define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_filter_laplacian_debug, "glfilterlaplacian", 0, "glfilterlaplacian element"); GST_DEBUG_CATEGORY_INIT (gst_gl_filter_laplacian_debug, "glfilterlaplacian", 0, "glfilterlaplacian element");
GST_BOILERPLATE_FULL (GstGLFilterLaplacian, gst_gl_filter_laplacian, GstGLFilter, GST_BOILERPLATE_FULL (GstGLFilterLaplacian, gst_gl_filter_laplacian,
GST_TYPE_GL_FILTER, DEBUG_INIT); GstGLFilter, GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_filter_laplacian_set_property (GObject * object, guint prop_id, static void gst_gl_filter_laplacian_set_property (GObject * object,
const GValue * value, GParamSpec * pspec); guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id, static void gst_gl_filter_laplacian_get_property (GObject * object,
GValue * value, GParamSpec * pspec); guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_gl_filter_laplacian_reset (GstGLFilter* filter); static void gst_gl_filter_laplacian_reset (GstGLFilter * filter);
static void gst_gl_filter_laplacian_init_shader (GstGLFilter* filter); static void gst_gl_filter_laplacian_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filter_laplacian_filter (GstGLFilter * filter, static gboolean gst_gl_filter_laplacian_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filter_laplacian_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filter_laplacian_callback (gint width, gint height,
guint texture, gpointer stuff);
static const gchar *convolution_fragment_source = static const gchar *convolution_fragment_source =
"#extension GL_ARB_texture_rectangle : enable\n" "#extension GL_ARB_texture_rectangle : enable\n"
@ -87,10 +88,7 @@ static const gchar *convolution_fragment_source =
" if (kernel[i] != 0.0) {" " if (kernel[i] != 0.0) {"
" vec4 neighbor = texture2DRect(tex, texturecoord + vec2(offset[i])); " " vec4 neighbor = texture2DRect(tex, texturecoord + vec2(offset[i])); "
" sum += neighbor * kernel[i]/norm_const; " " sum += neighbor * kernel[i]/norm_const; "
" }" " }" " }" " gl_FragColor = sum + norm_offset;" "}";
" }"
" gl_FragColor = sum + norm_offset;"
"}";
static void static void
gst_gl_filter_laplacian_base_init (gpointer klass) gst_gl_filter_laplacian_base_init (gpointer klass)
@ -101,9 +99,9 @@ gst_gl_filter_laplacian_base_init (gpointer klass)
} }
static void static void
gst_gl_filter_laplacian_class_init (GstGLFilterLaplacianClass* klass) gst_gl_filter_laplacian_class_init (GstGLFilterLaplacianClass * klass)
{ {
GObjectClass* gobject_class; GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_laplacian_set_property; gobject_class->set_property = gst_gl_filter_laplacian_set_property;
@ -115,29 +113,28 @@ gst_gl_filter_laplacian_class_init (GstGLFilterLaplacianClass* klass)
} }
static void static void
gst_gl_filter_laplacian_init (GstGLFilterLaplacian* filter, gst_gl_filter_laplacian_init (GstGLFilterLaplacian * filter,
GstGLFilterLaplacianClass* klass) GstGLFilterLaplacianClass * klass)
{ {
filter->shader = NULL; filter->shader = NULL;
} }
static void static void
gst_gl_filter_laplacian_reset (GstGLFilter* filter) gst_gl_filter_laplacian_reset (GstGLFilter * filter)
{ {
GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN(filter); GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, laplacian_filter->shader); gst_gl_display_del_shader (filter->display, laplacian_filter->shader);
} }
static void static void
gst_gl_filter_laplacian_set_property (GObject* object, guint prop_id, gst_gl_filter_laplacian_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object); //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -145,13 +142,12 @@ gst_gl_filter_laplacian_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_laplacian_get_property (GObject* object, guint prop_id, gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object); //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -159,25 +155,26 @@ gst_gl_filter_laplacian_get_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_filter_laplacian_init_shader (GstGLFilter* filter) gst_gl_filter_laplacian_init_shader (GstGLFilter * filter)
{ {
GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter); GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, convolution_fragment_source, &laplacian_filter->shader); gst_gl_display_gen_shader (filter->display, 0, convolution_fragment_source,
&laplacian_filter->shader);
} }
static gboolean static gboolean
gst_gl_filter_laplacian_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filter_laplacian_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
gpointer laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter); gpointer laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
//blocking call, use a FBO //blocking call, use a FBO
gst_gl_display_use_fbo (filter->display, filter->width, filter->height, gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_laplacian_callback, filter->fbo, filter->depthbuffer, outbuf->texture,
inbuf->width, inbuf->height, inbuf->texture, gst_gl_filter_laplacian_callback, inbuf->width, inbuf->height,
0, filter->width, 0, filter->height, inbuf->texture, 0, filter->width, 0, filter->height,
GST_GL_DISPLAY_PROJECTION_ORTHO2D, laplacian_filter); GST_GL_DISPLAY_PROJECTION_ORTHO2D, laplacian_filter);
return TRUE; return TRUE;
@ -185,13 +182,15 @@ gst_gl_filter_laplacian_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
//opengl scene, params: input texture (not the output filter->texture) //opengl scene, params: input texture (not the output filter->texture)
static void static void
gst_gl_filter_laplacian_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filter_laplacian_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (stuff); GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (stuff);
gfloat kernel[9] = { 0.0, -1.0, 0.0, gfloat kernel[9] = { 0.0, -1.0, 0.0,
-1.0, 4.0, -1.0, -1.0, 4.0, -1.0,
0.0, -1.0, 0.0 }; 0.0, -1.0, 0.0
};
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();

View file

@ -91,31 +91,35 @@ static void gst_gl_filtersobel_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_filtersobel_get_property (GObject * object, guint prop_id, static void gst_gl_filtersobel_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_filter_filtersobel_reset (GstGLFilter* filter); static void gst_gl_filter_filtersobel_reset (GstGLFilter * filter);
static void gst_gl_filtersobel_draw_texture (GstGLFilterSobel * filtersobel, GLuint tex); static void gst_gl_filtersobel_draw_texture (GstGLFilterSobel * filtersobel,
GLuint tex);
static void gst_gl_filtersobel_init_shader (GstGLFilter* filter); static void gst_gl_filtersobel_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filtersobel_filter (GstGLFilter * filter, static gboolean gst_gl_filtersobel_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filtersobel_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_filtersobel_callback (gint width, gint height, guint texture,
gpointer stuff);
static void static void
gst_gl_filtersobel_init_resources (GstGLFilter *filter) gst_gl_filtersobel_init_resources (GstGLFilter * filter)
{ {
GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
glGenTextures (1, &filtersobel->midtexture); glGenTextures (1, &filtersobel->midtexture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, filtersobel->midtexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, filtersobel->midtexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); filter->width, filter->height, 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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_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_S,
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
} }
static void static void
gst_gl_filtersobel_reset_resources (GstGLFilter *filter) gst_gl_filtersobel_reset_resources (GstGLFilter * filter)
{ {
GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
@ -140,23 +144,24 @@ gst_gl_filtersobel_class_init (GstGLFilterSobelClass * klass)
gobject_class->get_property = gst_gl_filtersobel_get_property; gobject_class->get_property = gst_gl_filtersobel_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filtersobel_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filtersobel_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb = gst_gl_filtersobel_init_resources; GST_GL_FILTER_CLASS (klass)->display_init_cb =
GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_filtersobel_reset_resources; gst_gl_filtersobel_init_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_filtersobel_reset_resources;
GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filtersobel_init_shader; GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filtersobel_init_shader;
GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filtersobel_reset; GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filtersobel_reset;
g_object_class_install_property ( g_object_class_install_property (gobject_class,
gobject_class,
PROP_INVERT, PROP_INVERT,
g_param_spec_boolean ("invert", g_param_spec_boolean ("invert",
"Invert the colors", "Invert the colors",
"Invert colors to get dark edges on bright background", "Invert colors to get dark edges on bright background",
FALSE, FALSE, G_PARAM_READWRITE));
G_PARAM_READWRITE));
} }
static void static void
gst_gl_filtersobel_init (GstGLFilterSobel * filtersobel, GstGLFilterSobelClass * klass) gst_gl_filtersobel_init (GstGLFilterSobel * filtersobel,
GstGLFilterSobelClass * klass)
{ {
filtersobel->shader0 = NULL; filtersobel->shader0 = NULL;
filtersobel->midtexture = 0; filtersobel->midtexture = 0;
@ -164,9 +169,9 @@ gst_gl_filtersobel_init (GstGLFilterSobel * filtersobel, GstGLFilterSobelClass *
} }
static void static void
gst_gl_filter_filtersobel_reset (GstGLFilter* filter) gst_gl_filter_filtersobel_reset (GstGLFilter * filter)
{ {
GstGLFilterSobel* filtersobel = GST_GL_FILTERSOBEL(filter); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
//blocking call, wait the opengl thread has destroyed the shader //blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, filtersobel->shader0); gst_gl_display_del_shader (filter->display, filtersobel->shader0);
@ -205,12 +210,13 @@ gst_gl_filtersobel_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_filtersobel_init_shader (GstGLFilter* filter) gst_gl_filtersobel_init_shader (GstGLFilter * filter)
{ {
GstGLFilterSobel* filtersobel = GST_GL_FILTERSOBEL (filter); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
//blocking call, wait the opengl thread has compiled the shader //blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, sobel_fragment_source, &filtersobel->shader0); gst_gl_display_gen_shader (filter->display, 0, sobel_fragment_source,
&filtersobel->shader0);
} }
static void static void
@ -226,11 +232,11 @@ gst_gl_filtersobel_draw_texture (GstGLFilterSobel * filtersobel, GLuint tex)
glTexCoord2f (0.0, 0.0); glTexCoord2f (0.0, 0.0);
glVertex2f (-1.0, -1.0); glVertex2f (-1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, 0.0); glTexCoord2f ((gfloat) filter->width, 0.0);
glVertex2f (1.0, -1.0); glVertex2f (1.0, -1.0);
glTexCoord2f ((gfloat)filter->width, (gfloat)filter->height); glTexCoord2f ((gfloat) filter->width, (gfloat) filter->height);
glVertex2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, (gfloat)filter->height); glTexCoord2f (0.0, (gfloat) filter->height);
glVertex2f (-1.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd (); glEnd ();
@ -253,10 +259,10 @@ change_view (GstGLDisplay *display, gpointer data)
}*/ }*/
static gboolean static gboolean
gst_gl_filtersobel_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_filtersobel_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLFilterSobel* filtersobel = GST_GL_FILTERSOBEL(filter); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
// gst_gl_display_thread_add (filter->display, change_view, filtersobel); // gst_gl_display_thread_add (filter->display, change_view, filtersobel);
@ -267,9 +273,10 @@ gst_gl_filtersobel_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
} }
static void static void
gst_gl_filtersobel_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_filtersobel_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLFilterSobel* filtersobel = GST_GL_FILTERSOBEL (stuff); GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (stuff);
gfloat hkern[9] = { gfloat hkern[9] = {
1.0, 0.0, -1.0, 1.0, 0.0, -1.0,
@ -298,7 +305,8 @@ gst_gl_filtersobel_callback (gint width, gint height, guint texture, gpointer st
gst_gl_shader_set_uniform_1fv (filtersobel->shader0, "hkern", 9, hkern); gst_gl_shader_set_uniform_1fv (filtersobel->shader0, "hkern", 9, hkern);
gst_gl_shader_set_uniform_1fv (filtersobel->shader0, "vkern", 9, vkern); gst_gl_shader_set_uniform_1fv (filtersobel->shader0, "vkern", 9, vkern);
gst_gl_shader_set_uniform_1i (filtersobel->shader0, "invert", filtersobel->invert); gst_gl_shader_set_uniform_1i (filtersobel->shader0, "invert",
filtersobel->invert);
gst_gl_filtersobel_draw_texture (filtersobel, texture); gst_gl_filtersobel_draw_texture (filtersobel, texture);
} }

View file

@ -119,7 +119,7 @@ static void gst_glimage_sink_implements_init (GstImplementsInterfaceClass *
klass); klass);
static const GstElementDetails gst_glimage_sink_details = static const GstElementDetails gst_glimage_sink_details =
GST_ELEMENT_DETAILS ("OpenGL video sink", GST_ELEMENT_DETAILS ("OpenGL video sink",
"Sink/Video", "Sink/Video",
"A videosink based on OpenGL", "A videosink based on OpenGL",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -185,7 +185,7 @@ gst_glimage_sink_base_init (gpointer g_class)
} }
static void static void
gst_glimage_sink_class_init (GstGLImageSinkClass* klass) gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *gstelement_class; GstElementClass *gstelement_class;
@ -203,14 +203,14 @@ gst_glimage_sink_class_init (GstGLImageSinkClass* klass)
NULL, G_PARAM_READWRITE)); NULL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK,
g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", g_param_spec_pointer ("client_reshape_callback",
"Client reshape callback",
"Define a custom reshape callback in a client code", "Define a custom reshape callback in a client code",
G_PARAM_WRITABLE)); G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK,
g_param_spec_pointer ("client_draw_callback", "Client draw callback", g_param_spec_pointer ("client_draw_callback", "Client draw callback",
"Define a custom draw callback in a client code", "Define a custom draw callback in a client code", G_PARAM_WRITABLE));
G_PARAM_WRITABLE));
gobject_class->finalize = gst_glimage_sink_finalize; gobject_class->finalize = gst_glimage_sink_finalize;
@ -225,8 +225,8 @@ gst_glimage_sink_class_init (GstGLImageSinkClass* klass)
} }
static void static void
gst_glimage_sink_init (GstGLImageSink* glimage_sink, gst_glimage_sink_init (GstGLImageSink * glimage_sink,
GstGLImageSinkClass* glimage_sink_class) GstGLImageSinkClass * glimage_sink_class)
{ {
glimage_sink->display_name = NULL; glimage_sink->display_name = NULL;
glimage_sink->window_id = 0; glimage_sink->window_id = 0;
@ -237,8 +237,8 @@ gst_glimage_sink_init (GstGLImageSink* glimage_sink,
} }
static void static void
gst_glimage_sink_set_property (GObject* object, guint prop_id, gst_glimage_sink_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
GstGLImageSink *glimage_sink; GstGLImageSink *glimage_sink;
@ -246,8 +246,7 @@ gst_glimage_sink_set_property (GObject* object, guint prop_id,
glimage_sink = GST_GLIMAGE_SINK (object); glimage_sink = GST_GLIMAGE_SINK (object);
switch (prop_id) switch (prop_id) {
{
case ARG_DISPLAY: case ARG_DISPLAY:
{ {
g_free (glimage_sink->display_name); g_free (glimage_sink->display_name);
@ -271,9 +270,9 @@ gst_glimage_sink_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_glimage_sink_finalize (GObject* object) gst_glimage_sink_finalize (GObject * object)
{ {
GstGLImageSink* glimage_sink; GstGLImageSink *glimage_sink;
g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); g_return_if_fail (GST_IS_GLIMAGE_SINK (object));
@ -288,8 +287,8 @@ gst_glimage_sink_finalize (GObject* object)
} }
static void static void
gst_glimage_sink_get_property (GObject* object, guint prop_id, gst_glimage_sink_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
GstGLImageSink *glimage_sink; GstGLImageSink *glimage_sink;
@ -297,8 +296,7 @@ gst_glimage_sink_get_property (GObject* object, guint prop_id,
glimage_sink = GST_GLIMAGE_SINK (object); glimage_sink = GST_GLIMAGE_SINK (object);
switch (prop_id) switch (prop_id) {
{
case ARG_DISPLAY: case ARG_DISPLAY:
g_value_set_string (value, glimage_sink->display_name); g_value_set_string (value, glimage_sink->display_name);
break; break;
@ -313,17 +311,16 @@ gst_glimage_sink_get_property (GObject* object, guint prop_id,
*/ */
static GstStateChangeReturn static GstStateChangeReturn
gst_glimage_sink_change_state (GstElement* element, GstStateChange transition) gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
{ {
GstGLImageSink* glimage_sink; GstGLImageSink *glimage_sink;
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GST_DEBUG ("change state"); GST_DEBUG ("change state");
glimage_sink = GST_GLIMAGE_SINK (element); glimage_sink = GST_GLIMAGE_SINK (element);
switch (transition) switch (transition) {
{
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
@ -338,8 +335,7 @@ gst_glimage_sink_change_state (GstElement* element, GstStateChange transition)
if (ret == GST_STATE_CHANGE_FAILURE) if (ret == GST_STATE_CHANGE_FAILURE)
return ret; return ret;
switch (transition) switch (transition) {
{
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
@ -363,7 +359,7 @@ gst_glimage_sink_change_state (GstElement* element, GstStateChange transition)
*/ */
static gboolean static gboolean
gst_glimage_sink_start (GstBaseSink* bsink) gst_glimage_sink_start (GstBaseSink * bsink)
{ {
//GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink); //GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink);
@ -373,21 +369,19 @@ gst_glimage_sink_start (GstBaseSink* bsink)
} }
static gboolean static gboolean
gst_glimage_sink_stop (GstBaseSink* bsink) gst_glimage_sink_stop (GstBaseSink * bsink)
{ {
GstGLImageSink* glimage_sink; GstGLImageSink *glimage_sink;
GST_DEBUG ("stop"); GST_DEBUG ("stop");
glimage_sink = GST_GLIMAGE_SINK (bsink); glimage_sink = GST_GLIMAGE_SINK (bsink);
if (glimage_sink->stored_buffer) if (glimage_sink->stored_buffer) {
{
gst_buffer_unref (glimage_sink->stored_buffer); gst_buffer_unref (glimage_sink->stored_buffer);
glimage_sink->stored_buffer = NULL; glimage_sink->stored_buffer = NULL;
} }
if (glimage_sink->display) if (glimage_sink->display) {
{
g_object_unref (glimage_sink->display); g_object_unref (glimage_sink->display);
glimage_sink->display = NULL; glimage_sink->display = NULL;
} }
@ -396,20 +390,18 @@ gst_glimage_sink_stop (GstBaseSink* bsink)
} }
static void static void
gst_glimage_sink_get_times (GstBaseSink* bsink, GstBuffer* buf, gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
GstClockTime* start, GstClockTime* end) GstClockTime * start, GstClockTime * end)
{ {
GstGLImageSink* glimagesink; GstGLImageSink *glimagesink;
glimagesink = GST_GLIMAGE_SINK (bsink); glimagesink = GST_GLIMAGE_SINK (bsink);
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
{
*start = GST_BUFFER_TIMESTAMP (buf); *start = GST_BUFFER_TIMESTAMP (buf);
if (GST_BUFFER_DURATION_IS_VALID (buf)) if (GST_BUFFER_DURATION_IS_VALID (buf))
*end = *start + GST_BUFFER_DURATION (buf); *end = *start + GST_BUFFER_DURATION (buf);
else else {
{
if (glimagesink->fps_n > 0) { if (glimagesink->fps_n > 0) {
*end = *start + *end = *start +
gst_util_uint64_scale_int (GST_SECOND, glimagesink->fps_d, gst_util_uint64_scale_int (GST_SECOND, glimagesink->fps_d,
@ -420,9 +412,9 @@ gst_glimage_sink_get_times (GstBaseSink* bsink, GstBuffer* buf,
} }
static gboolean static gboolean
gst_glimage_sink_set_caps (GstBaseSink* bsink, GstCaps* caps) gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{ {
GstGLImageSink* glimage_sink; GstGLImageSink *glimage_sink;
gint width; gint width;
gint height; gint height;
gboolean ok; gboolean ok;
@ -470,28 +462,27 @@ gst_glimage_sink_set_caps (GstBaseSink* bsink, GstCaps* caps)
} }
static GstFlowReturn static GstFlowReturn
gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{ {
GstGLImageSink* glimage_sink = NULL; GstGLImageSink *glimage_sink = NULL;
GstGLBuffer* gl_buffer = NULL; GstGLBuffer *gl_buffer = NULL;
glimage_sink = GST_GLIMAGE_SINK (bsink); glimage_sink = GST_GLIMAGE_SINK (bsink);
GST_INFO ("buffer size: %d", GST_BUFFER_SIZE (buf)); GST_INFO ("buffer size: %d", GST_BUFFER_SIZE (buf));
//is gl //is gl
if (glimage_sink->is_gl) if (glimage_sink->is_gl) {
{
//increment gl buffer ref before storage //increment gl buffer ref before storage
gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
//if glimagesink has not the display yet //if glimagesink has not the display yet
if (glimage_sink->display == NULL) if (glimage_sink->display == NULL) {
{
glimage_sink->display = g_object_ref (gl_buffer->display); glimage_sink->display = g_object_ref (gl_buffer->display);
if (glimage_sink->window_id) if (glimage_sink->window_id)
gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id); gst_gl_display_set_window_id (glimage_sink->display,
glimage_sink->window_id);
gst_gl_display_set_client_reshape_callback (glimage_sink->display, gst_gl_display_set_client_reshape_callback (glimage_sink->display,
glimage_sink->clientReshapeCallback); glimage_sink->clientReshapeCallback);
@ -501,11 +492,9 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
} }
} }
//is not gl //is not gl
else else {
{
//if glimagesink has not the display yet //if glimagesink has not the display yet
if (glimage_sink->display == NULL) if (glimage_sink->display == NULL) {
{
//create a display //create a display
glimage_sink->display = gst_gl_display_new (); glimage_sink->display = gst_gl_display_new ();
@ -514,7 +503,8 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
glimage_sink->width, glimage_sink->height); glimage_sink->width, glimage_sink->height);
if (glimage_sink->window_id) if (glimage_sink->window_id)
gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id); gst_gl_display_set_window_id (glimage_sink->display,
glimage_sink->window_id);
//init colorspace conversion if needed //init colorspace conversion if needed
gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format,
@ -527,25 +517,22 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
gst_gl_display_set_client_draw_callback (glimage_sink->display, gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback); glimage_sink->clientDrawCallback);
} }
//blocking call //blocking call
gl_buffer = gst_gl_buffer_new (glimage_sink->display, gl_buffer = gst_gl_buffer_new (glimage_sink->display,
glimage_sink->width, glimage_sink->height); glimage_sink->width, glimage_sink->height);
//blocking call //blocking call
gst_gl_display_do_upload(glimage_sink->display, gl_buffer->texture, gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture,
glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf)); glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf));
//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
} }
//the buffer is cleared when an other comes in //the buffer is cleared when an other comes in
if (glimage_sink->stored_buffer) if (glimage_sink->stored_buffer) {
{
gst_buffer_unref (glimage_sink->stored_buffer); gst_buffer_unref (glimage_sink->stored_buffer);
glimage_sink->stored_buffer = NULL; glimage_sink->stored_buffer = NULL;
} }
//store current buffer //store current buffer
glimage_sink->stored_buffer = gl_buffer; glimage_sink->stored_buffer = gl_buffer;
@ -560,7 +547,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
static void static void
gst_glimage_sink_xoverlay_init (GstXOverlayClass* iface) gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface)
{ {
iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id; iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id;
iface->expose = gst_glimage_sink_expose; iface->expose = gst_glimage_sink_expose;
@ -568,9 +555,9 @@ gst_glimage_sink_xoverlay_init (GstXOverlayClass* iface)
static void static void
gst_glimage_sink_set_xwindow_id (GstXOverlay* overlay, gulong window_id) gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay, gulong window_id)
{ {
GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (overlay); GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay);
g_return_if_fail (GST_IS_GLIMAGE_SINK (overlay)); g_return_if_fail (GST_IS_GLIMAGE_SINK (overlay));
@ -585,9 +572,9 @@ gst_glimage_sink_set_xwindow_id (GstXOverlay* overlay, gulong window_id)
static void static void
gst_glimage_sink_expose (GstXOverlay* overlay) gst_glimage_sink_expose (GstXOverlay * overlay)
{ {
GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (overlay); GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay);
//redisplay opengl scene //redisplay opengl scene
if (glimage_sink->display && glimage_sink->window_id) if (glimage_sink->display && glimage_sink->window_id)
@ -596,7 +583,7 @@ gst_glimage_sink_expose (GstXOverlay* overlay)
static gboolean static gboolean
gst_glimage_sink_interface_supported (GstImplementsInterface* iface, gst_glimage_sink_interface_supported (GstImplementsInterface * iface,
GType type) GType type)
{ {
return TRUE; return TRUE;
@ -604,7 +591,7 @@ gst_glimage_sink_interface_supported (GstImplementsInterface* iface,
static void static void
gst_glimage_sink_implements_init (GstImplementsInterfaceClass* klass) gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass)
{ {
klass->supported = gst_glimage_sink_interface_supported; klass->supported = gst_glimage_sink_interface_supported;
} }

View file

@ -83,16 +83,16 @@ static void gst_gl_overlay_set_property (GObject * object, guint prop_id,
static void gst_gl_overlay_get_property (GObject * object, guint prop_id, static void gst_gl_overlay_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_overlay_init_resources (GstGLFilter* filter); static void gst_gl_overlay_init_resources (GstGLFilter * filter);
static void gst_gl_overlay_reset_resources (GstGLFilter* filter); static void gst_gl_overlay_reset_resources (GstGLFilter * filter);
static gboolean gst_gl_overlay_filter (GstGLFilter * filter, static gboolean gst_gl_overlay_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf); GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static gboolean gst_gl_overlay_loader (GstGLFilter* filter); static gboolean gst_gl_overlay_loader (GstGLFilter * filter);
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ( static const GstElementDetails element_details =
"Gstreamer OpenGL Overlay", GST_ELEMENT_DETAILS ("Gstreamer OpenGL Overlay",
"Filter/Effect", "Filter/Effect",
"Overlay GL video texture with a PNG image", "Overlay GL video texture with a PNG image",
"Filippo Argiolas <filippo.argiolas@gmail.com>"); "Filippo Argiolas <filippo.argiolas@gmail.com>");
@ -112,14 +112,14 @@ enum
/* init resources that need a gl context */ /* init resources that need a gl context */
static void static void
gst_gl_overlay_init_gl_resources (GstGLFilter *filter) gst_gl_overlay_init_gl_resources (GstGLFilter * filter)
{ {
// GstGLOverlay *overlay = GST_GL_OVERLAY (filter); // GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
} }
/* free resources that need a gl context */ /* free resources that need a gl context */
static void static void
gst_gl_overlay_reset_gl_resources (GstGLFilter *filter) gst_gl_overlay_reset_gl_resources (GstGLFilter * filter)
{ {
GstGLOverlay *overlay = GST_GL_OVERLAY (filter); GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
@ -144,8 +144,10 @@ gst_gl_overlay_class_init (GstGLOverlayClass * klass)
gobject_class->get_property = gst_gl_overlay_get_property; gobject_class->get_property = gst_gl_overlay_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_overlay_filter; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_overlay_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb = gst_gl_overlay_init_gl_resources; GST_GL_FILTER_CLASS (klass)->display_init_cb =
GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_overlay_reset_gl_resources; gst_gl_overlay_init_gl_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_overlay_reset_gl_resources;
GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_overlay_init_resources; GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_overlay_init_resources;
GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_overlay_reset_resources; GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_overlay_reset_resources;
@ -153,8 +155,7 @@ gst_gl_overlay_class_init (GstGLOverlayClass * klass)
PROP_LOCATION, PROP_LOCATION,
g_param_spec_string ("location", g_param_spec_string ("location",
"Location of the image", "Location of the image",
"Location of the image", "Location of the image", NULL, G_PARAM_READWRITE));
NULL, G_PARAM_READWRITE));
/* /*
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_STRETCH, PROP_STRETCH,
@ -190,15 +191,16 @@ gst_gl_overlay_draw_texture (GstGLOverlay * overlay, GLuint tex)
glEnd (); glEnd ();
if (overlay->pbuftexture == 0) return; if (overlay->pbuftexture == 0)
return;
// if (overlay->stretch) { // if (overlay->stretch) {
width = (gfloat) overlay->width; width = (gfloat) overlay->width;
height = (gfloat) overlay->height; height = (gfloat) overlay->height;
// } // }
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); glEnable (GL_BLEND);
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, overlay->pbuftexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, overlay->pbuftexture);
@ -221,8 +223,7 @@ gst_gl_overlay_draw_texture (GstGLOverlay * overlay, GLuint tex)
} }
static void static void
gst_gl_overlay_init (GstGLOverlay * overlay, gst_gl_overlay_init (GstGLOverlay * overlay, GstGLOverlayClass * klass)
GstGLOverlayClass * klass)
{ {
overlay->location = NULL; overlay->location = NULL;
overlay->pixbuf = NULL; overlay->pixbuf = NULL;
@ -235,7 +236,7 @@ gst_gl_overlay_init (GstGLOverlay * overlay,
} }
static void static void
gst_gl_overlay_reset_resources (GstGLFilter* filter) gst_gl_overlay_reset_resources (GstGLFilter * filter)
{ {
// GstGLOverlay* overlay = GST_GL_OVERLAY(filter); // GstGLOverlay* overlay = GST_GL_OVERLAY(filter);
} }
@ -248,7 +249,8 @@ gst_gl_overlay_set_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_LOCATION: case PROP_LOCATION:
if (overlay->location != NULL) g_free (overlay->location); if (overlay->location != NULL)
g_free (overlay->location);
overlay->pbuf_has_changed = TRUE; overlay->pbuf_has_changed = TRUE;
overlay->location = g_value_dup_string (value); overlay->location = g_value_dup_string (value);
break; break;
@ -283,7 +285,7 @@ gst_gl_overlay_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_gl_overlay_init_resources (GstGLFilter* filter) gst_gl_overlay_init_resources (GstGLFilter * filter)
{ {
// GstGLOverlay *overlay = GST_GL_OVERLAY (filter); // GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
} }
@ -291,7 +293,7 @@ gst_gl_overlay_init_resources (GstGLFilter* filter)
static void static void
gst_gl_overlay_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_overlay_callback (gint width, gint height, guint texture, gpointer stuff)
{ {
GstGLOverlay* overlay = GST_GL_OVERLAY (stuff); GstGLOverlay *overlay = GST_GL_OVERLAY (stuff);
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
@ -299,7 +301,8 @@ gst_gl_overlay_callback (gint width, gint height, guint texture, gpointer stuff)
gst_gl_overlay_draw_texture (overlay, texture); gst_gl_overlay_draw_texture (overlay, texture);
} }
static void init_pixbuf_texture (GstGLDisplay *display, gpointer data) static void
init_pixbuf_texture (GstGLDisplay * display, gpointer data)
{ {
GstGLOverlay *overlay = GST_GL_OVERLAY (data); GstGLOverlay *overlay = GST_GL_OVERLAY (data);
@ -309,18 +312,17 @@ static void init_pixbuf_texture (GstGLDisplay *display, gpointer data)
glGenTextures (1, &overlay->pbuftexture); glGenTextures (1, &overlay->pbuftexture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, overlay->pbuftexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, overlay->pbuftexture);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
(gint)overlay->width, (gint)overlay->height, 0, (gint) overlay->width, (gint) overlay->height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, overlay->pixbuf); GL_RGBA, GL_UNSIGNED_BYTE, overlay->pixbuf);
} } else
else
display->isAlive = FALSE; display->isAlive = FALSE;
} }
static gboolean static gboolean
gst_gl_overlay_filter (GstGLFilter* filter, GstGLBuffer* inbuf, gst_gl_overlay_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer* outbuf) GstGLBuffer * outbuf)
{ {
GstGLOverlay* overlay = GST_GL_OVERLAY(filter); GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
if (overlay->pbuf_has_changed && (overlay->location != NULL)) { if (overlay->pbuf_has_changed && (overlay->location != NULL)) {
@ -345,17 +347,17 @@ gst_gl_overlay_filter (GstGLFilter* filter, GstGLBuffer* inbuf,
} }
static void static void
user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
{ {
g_warning("%s\n", warning_msg); g_warning ("%s\n", warning_msg);
} }
#define LOAD_ERROR(msg) { GST_WARNING ("unable to load %s: %s", overlay->location, msg); return FALSE; } #define LOAD_ERROR(msg) { GST_WARNING ("unable to load %s: %s", overlay->location, msg); return FALSE; }
static gboolean static gboolean
gst_gl_overlay_loader (GstGLFilter* filter) gst_gl_overlay_loader (GstGLFilter * filter)
{ {
GstGLOverlay* overlay = GST_GL_OVERLAY(filter); GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
@ -372,60 +374,57 @@ gst_gl_overlay_loader (GstGLFilter* filter)
if (!filter->display) if (!filter->display)
return TRUE; return TRUE;
if ((fp = fopen(overlay->location, "rb")) == NULL) if ((fp = fopen (overlay->location, "rb")) == NULL)
LOAD_ERROR ("file not found"); LOAD_ERROR ("file not found");
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) if (png_ptr == NULL) {
{ fclose (fp);
fclose(fp);
LOAD_ERROR ("failed to initialize the png_struct"); LOAD_ERROR ("failed to initialize the png_struct");
} }
png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn); png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) if (info_ptr == NULL) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("failed to initialize the memory for image information"); LOAD_ERROR ("failed to initialize the memory for image information");
} }
png_init_io(png_ptr, fp); png_init_io (png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read); png_set_sig_bytes (png_ptr, sig_read);
png_read_info(png_ptr, info_ptr); png_read_info (png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, int_p_NULL, int_p_NULL); &interlace_type, int_p_NULL, int_p_NULL);
if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
{ fclose (fp);
fclose(fp); png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
LOAD_ERROR ("color type is not rgb"); LOAD_ERROR ("color type is not rgb");
} }
overlay->width = width; overlay->width = width;
overlay->height = height; overlay->height = height;
overlay->pixbuf = (guchar*) malloc ( sizeof(guchar) * width * height * 4 ); overlay->pixbuf = (guchar *) malloc (sizeof (guchar) * width * height * 4);
rows = (guchar**)malloc(sizeof(guchar*) * height); rows = (guchar **) malloc (sizeof (guchar *) * height);
for (y = 0; y < height; ++y) for (y = 0; y < height; ++y)
rows[y] = (guchar*) (overlay->pixbuf + y * width * 4); rows[y] = (guchar *) (overlay->pixbuf + y * width * 4);
png_read_image(png_ptr, rows); png_read_image (png_ptr, rows);
free(rows); free (rows);
png_read_end(png_ptr, info_ptr); png_read_end (png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp); fclose (fp);
return TRUE; return TRUE;
} }

View file

@ -69,29 +69,30 @@ enum
GST_BOILERPLATE (GstGLTestSrc, gst_gl_test_src, GstPushSrc, GST_TYPE_PUSH_SRC); GST_BOILERPLATE (GstGLTestSrc, gst_gl_test_src, GstPushSrc, GST_TYPE_PUSH_SRC);
static void gst_gl_test_src_set_pattern (GstGLTestSrc* gltestsrc, static void gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc,
int pattern_type); int pattern_type);
static void gst_gl_test_src_set_property (GObject* object, guint prop_id, static void gst_gl_test_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_test_src_get_property (GObject* object, guint prop_id, static void gst_gl_test_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps); static gboolean gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
static void gst_gl_test_src_src_fixate (GstPad* pad, GstCaps* caps); static void gst_gl_test_src_src_fixate (GstPad * pad, GstCaps * caps);
static gboolean gst_gl_test_src_is_seekable (GstBaseSrc* psrc); static gboolean gst_gl_test_src_is_seekable (GstBaseSrc * psrc);
static gboolean gst_gl_test_src_do_seek (GstBaseSrc* bsrc, static gboolean gst_gl_test_src_do_seek (GstBaseSrc * bsrc,
GstSegment * segment); GstSegment * segment);
static gboolean gst_gl_test_src_query (GstBaseSrc* bsrc, GstQuery * query); static gboolean gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query);
static void gst_gl_test_src_get_times (GstBaseSrc* basesrc, static void gst_gl_test_src_get_times (GstBaseSrc * basesrc,
GstBuffer * buffer, GstClockTime* start, GstClockTime* end); GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static GstFlowReturn gst_gl_test_src_create (GstPushSrc* psrc, static GstFlowReturn gst_gl_test_src_create (GstPushSrc * psrc,
GstBuffer** buffer); GstBuffer ** buffer);
static gboolean gst_gl_test_src_start (GstBaseSrc* basesrc); static gboolean gst_gl_test_src_start (GstBaseSrc * basesrc);
static gboolean gst_gl_test_src_stop (GstBaseSrc* basesrc); static gboolean gst_gl_test_src_stop (GstBaseSrc * basesrc);
static void gst_gl_test_src_callback (gint width, gint height, guint texture, gpointer stuff); static void gst_gl_test_src_callback (gint width, gint height, guint texture,
gpointer stuff);
#define GST_TYPE_GL_TEST_SRC_PATTERN (gst_gl_test_src_pattern_get_type ()) #define GST_TYPE_GL_TEST_SRC_PATTERN (gst_gl_test_src_pattern_get_type ())
static GType static GType
@ -115,8 +116,7 @@ gst_gl_test_src_pattern_get_type (void)
{0, NULL, NULL} {0, NULL, NULL}
}; };
if (!gl_test_src_pattern_type) if (!gl_test_src_pattern_type) {
{
gl_test_src_pattern_type = gl_test_src_pattern_type =
g_enum_register_static ("GstGLTestSrcPattern", pattern_types); g_enum_register_static ("GstGLTestSrcPattern", pattern_types);
} }
@ -136,7 +136,7 @@ gst_gl_test_src_base_init (gpointer g_class)
} }
static void static void
gst_gl_test_src_class_init (GstGLTestSrcClass* klass) gst_gl_test_src_class_init (GstGLTestSrcClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstBaseSrcClass *gstbasesrc_class; GstBaseSrcClass *gstbasesrc_class;
@ -177,7 +177,7 @@ gst_gl_test_src_class_init (GstGLTestSrcClass* klass)
} }
static void static void
gst_gl_test_src_init (GstGLTestSrc* src, GstGLTestSrcClass* g_class) gst_gl_test_src_init (GstGLTestSrc * src, GstGLTestSrcClass * g_class)
{ {
GstPad *pad = GST_BASE_SRC_PAD (src); GstPad *pad = GST_BASE_SRC_PAD (src);
@ -193,7 +193,7 @@ gst_gl_test_src_init (GstGLTestSrc* src, GstGLTestSrcClass* g_class)
} }
static void static void
gst_gl_test_src_src_fixate (GstPad* pad, GstCaps* caps) gst_gl_test_src_src_fixate (GstPad * pad, GstCaps * caps)
{ {
GstStructure *structure; GstStructure *structure;
@ -207,7 +207,7 @@ gst_gl_test_src_src_fixate (GstPad* pad, GstCaps* caps)
} }
static void static void
gst_gl_test_src_set_pattern (GstGLTestSrc* gltestsrc, gint pattern_type) gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc, gint pattern_type)
{ {
gltestsrc->pattern_type = pattern_type; gltestsrc->pattern_type = pattern_type;
@ -259,13 +259,12 @@ gst_gl_test_src_set_pattern (GstGLTestSrc* gltestsrc, gint pattern_type)
} }
static void static void
gst_gl_test_src_set_property (GObject* object, guint prop_id, gst_gl_test_src_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
GstGLTestSrc* src = GST_GL_TEST_SRC (object); GstGLTestSrc *src = GST_GL_TEST_SRC (object);
switch (prop_id) switch (prop_id) {
{
case PROP_PATTERN: case PROP_PATTERN:
gst_gl_test_src_set_pattern (src, g_value_get_enum (value)); gst_gl_test_src_set_pattern (src, g_value_get_enum (value));
break; break;
@ -281,10 +280,10 @@ gst_gl_test_src_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_test_src_get_property (GObject* object, guint prop_id, gst_gl_test_src_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
GstGLTestSrc* src = GST_GL_TEST_SRC (object); GstGLTestSrc *src = GST_GL_TEST_SRC (object);
switch (prop_id) { switch (prop_id) {
case PROP_PATTERN: case PROP_PATTERN:
@ -303,8 +302,8 @@ gst_gl_test_src_get_property (GObject* object, guint prop_id,
} }
static gboolean static gboolean
gst_gl_test_src_parse_caps (const GstCaps* caps, gst_gl_test_src_parse_caps (const GstCaps * caps,
gint* width, gint* height, gint* rate_numerator, gint* rate_denominator) gint * width, gint * height, gint * rate_numerator, gint * rate_denominator)
{ {
const GstStructure *structure; const GstStructure *structure;
GstPadLinkReturn ret; GstPadLinkReturn ret;
@ -321,18 +320,16 @@ gst_gl_test_src_parse_caps (const GstCaps* caps,
ret &= gst_structure_get_int (structure, "height", height); ret &= gst_structure_get_int (structure, "height", height);
framerate = gst_structure_get_value (structure, "framerate"); framerate = gst_structure_get_value (structure, "framerate");
if (framerate) if (framerate) {
{
*rate_numerator = gst_value_get_fraction_numerator (framerate); *rate_numerator = gst_value_get_fraction_numerator (framerate);
*rate_denominator = gst_value_get_fraction_denominator (framerate); *rate_denominator = gst_value_get_fraction_denominator (framerate);
} } else
else
goto no_framerate; goto no_framerate;
return ret; return ret;
/* ERRORS */ /* ERRORS */
no_framerate: no_framerate:
{ {
GST_DEBUG ("gltestsrc no framerate given"); GST_DEBUG ("gltestsrc no framerate given");
return FALSE; return FALSE;
@ -340,11 +337,11 @@ gst_gl_test_src_parse_caps (const GstCaps* caps,
} }
static gboolean static gboolean
gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps) gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
{ {
gboolean res; gboolean res;
gint width, height, rate_denominator, rate_numerator; gint width, height, rate_denominator, rate_numerator;
GstGLTestSrc* gltestsrc; GstGLTestSrc *gltestsrc;
gltestsrc = GST_GL_TEST_SRC (bsrc); gltestsrc = GST_GL_TEST_SRC (bsrc);
@ -352,8 +349,7 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps)
res = gst_gl_test_src_parse_caps (caps, &width, &height, res = gst_gl_test_src_parse_caps (caps, &width, &height,
&rate_numerator, &rate_denominator); &rate_numerator, &rate_denominator);
if (res) if (res) {
{
/* looks ok here */ /* looks ok here */
gltestsrc->width = width; gltestsrc->width = width;
gltestsrc->height = height; gltestsrc->height = height;
@ -370,47 +366,41 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps)
gst_gl_display_create_context (gltestsrc->display, gst_gl_display_create_context (gltestsrc->display,
gltestsrc->width, gltestsrc->height); gltestsrc->width, gltestsrc->height);
gst_gl_display_gen_fbo (gltestsrc->display, gltestsrc->width, gltestsrc->height, gst_gl_display_gen_fbo (gltestsrc->display, gltestsrc->width,
&gltestsrc->fbo, &gltestsrc->depthbuffer); gltestsrc->height, &gltestsrc->fbo, &gltestsrc->depthbuffer);
} }
return res; return res;
} }
static gboolean static gboolean
gst_gl_test_src_query (GstBaseSrc* bsrc, GstQuery* query) gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query)
{ {
gboolean res; gboolean res;
GstGLTestSrc *src; GstGLTestSrc *src;
src = GST_GL_TEST_SRC (bsrc); src = GST_GL_TEST_SRC (bsrc);
switch (GST_QUERY_TYPE (query)) switch (GST_QUERY_TYPE (query)) {
{
case GST_QUERY_CONVERT: case GST_QUERY_CONVERT:
{ {
GstFormat src_fmt, dest_fmt; GstFormat src_fmt, dest_fmt;
gint64 src_val, dest_val; gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
if (src_fmt == dest_fmt) if (src_fmt == dest_fmt) {
{
dest_val = src_val; dest_val = src_val;
goto done; goto done;
} }
switch (src_fmt) switch (src_fmt) {
{
case GST_FORMAT_DEFAULT: case GST_FORMAT_DEFAULT:
switch (dest_fmt) switch (dest_fmt) {
{
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
/* frames to time */ /* frames to time */
if (src->rate_numerator) if (src->rate_numerator) {
{
dest_val = gst_util_uint64_scale (src_val, dest_val = gst_util_uint64_scale (src_val,
src->rate_denominator * GST_SECOND, src->rate_numerator); src->rate_denominator * GST_SECOND, src->rate_numerator);
} } else
else
dest_val = 0; dest_val = 0;
break; break;
default: default:
@ -418,16 +408,13 @@ gst_gl_test_src_query (GstBaseSrc* bsrc, GstQuery* query)
} }
break; break;
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
switch (dest_fmt) switch (dest_fmt) {
{
case GST_FORMAT_DEFAULT: case GST_FORMAT_DEFAULT:
/* time to frames */ /* time to frames */
if (src->rate_numerator) if (src->rate_numerator) {
{
dest_val = gst_util_uint64_scale (src_val, dest_val = gst_util_uint64_scale (src_val,
src->rate_numerator, src->rate_denominator * GST_SECOND); src->rate_numerator, src->rate_denominator * GST_SECOND);
} } else
else
dest_val = 0; dest_val = 0;
break; break;
default: default:
@ -448,7 +435,7 @@ gst_gl_test_src_query (GstBaseSrc* bsrc, GstQuery* query)
return res; return res;
/* ERROR */ /* ERROR */
error: error:
{ {
GST_DEBUG_OBJECT (src, "query failed"); GST_DEBUG_OBJECT (src, "query failed");
return FALSE; return FALSE;
@ -460,12 +447,10 @@ gst_gl_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end) GstClockTime * start, GstClockTime * end)
{ {
/* for live sources, sync on the timestamp of the buffer */ /* for live sources, sync on the timestamp of the buffer */
if (gst_base_src_is_live (basesrc)) if (gst_base_src_is_live (basesrc)) {
{
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer); GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
if (GST_CLOCK_TIME_IS_VALID (timestamp)) if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
{
/* get duration to calculate end time */ /* get duration to calculate end time */
GstClockTime duration = GST_BUFFER_DURATION (buffer); GstClockTime duration = GST_BUFFER_DURATION (buffer);
@ -473,19 +458,17 @@ gst_gl_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
*end = timestamp + duration; *end = timestamp + duration;
*start = timestamp; *start = timestamp;
} }
} } else {
else
{
*start = -1; *start = -1;
*end = -1; *end = -1;
} }
} }
static gboolean static gboolean
gst_gl_test_src_do_seek (GstBaseSrc* bsrc, GstSegment* segment) gst_gl_test_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
{ {
GstClockTime time; GstClockTime time;
GstGLTestSrc* src; GstGLTestSrc *src;
src = GST_GL_TEST_SRC (bsrc); src = GST_GL_TEST_SRC (bsrc);
@ -493,21 +476,16 @@ gst_gl_test_src_do_seek (GstBaseSrc* bsrc, GstSegment* segment)
time = segment->last_stop; time = segment->last_stop;
/* now move to the time indicated */ /* now move to the time indicated */
if (src->rate_numerator) if (src->rate_numerator) {
{
src->n_frames = gst_util_uint64_scale (time, src->n_frames = gst_util_uint64_scale (time,
src->rate_numerator, src->rate_denominator * GST_SECOND); src->rate_numerator, src->rate_denominator * GST_SECOND);
} } else
else
src->n_frames = 0; src->n_frames = 0;
if (src->rate_numerator) if (src->rate_numerator) {
{
src->running_time = gst_util_uint64_scale (src->n_frames, src->running_time = gst_util_uint64_scale (src->n_frames,
src->rate_denominator * GST_SECOND, src->rate_numerator); src->rate_denominator * GST_SECOND, src->rate_numerator);
} } else {
else
{
/* FIXME : Not sure what to set here */ /* FIXME : Not sure what to set here */
src->running_time = 0; src->running_time = 0;
} }
@ -518,17 +496,17 @@ gst_gl_test_src_do_seek (GstBaseSrc* bsrc, GstSegment* segment)
} }
static gboolean static gboolean
gst_gl_test_src_is_seekable (GstBaseSrc* psrc) gst_gl_test_src_is_seekable (GstBaseSrc * psrc)
{ {
/* we're seekable... */ /* we're seekable... */
return TRUE; return TRUE;
} }
static GstFlowReturn static GstFlowReturn
gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer) gst_gl_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
{ {
GstGLTestSrc* src; GstGLTestSrc *src;
GstGLBuffer* outbuf; GstGLBuffer *outbuf;
//GstFlowReturn res; //GstFlowReturn res;
GstClockTime next_time; GstClockTime next_time;
@ -545,11 +523,9 @@ 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 (src->display, outbuf = gst_gl_buffer_new (src->display, src->width, src->height);
src->width, src->height);
if (!outbuf->texture) if (!outbuf->texture) {
{
gst_buffer_unref (outbuf); gst_buffer_unref (outbuf);
goto eos; goto eos;
} }
@ -557,8 +533,7 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer)
gst_buffer_set_caps (GST_BUFFER (outbuf), gst_buffer_set_caps (GST_BUFFER (outbuf),
GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc))); GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
if (src->pattern_type == GST_GL_TEST_SRC_BLINK) if (src->pattern_type == GST_GL_TEST_SRC_BLINK) {
{
if (src->n_frames & 0x1) if (src->n_frames & 0x1)
src->make_image = gst_gl_test_src_white; src->make_image = gst_gl_test_src_white;
else else
@ -568,14 +543,9 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer)
src->buffer = outbuf; src->buffer = outbuf;
//blocking call, generate a FBO //blocking call, generate a FBO
if(!gst_gl_display_use_fbo (src->display, src->width, src->height, if (!gst_gl_display_use_fbo (src->display, src->width, src->height, src->fbo, src->depthbuffer, outbuf->texture, gst_gl_test_src_callback, 0, 0, 0, //no input texture
src->fbo, src->depthbuffer, outbuf->texture,
gst_gl_test_src_callback,
0, 0, 0, //no input texture
0, src->width, 0, src->height, 0, src->width, 0, src->height,
GST_GL_DISPLAY_PROJECTION_ORTHO2D, GST_GL_DISPLAY_PROJECTION_ORTHO2D, (gpointer) src)) {
(gpointer)src))
{
gst_buffer_unref (outbuf); gst_buffer_unref (outbuf);
goto eos; goto eos;
} }
@ -585,13 +555,11 @@ gst_gl_test_src_create (GstPushSrc* psrc, GstBuffer** buffer)
GST_BUFFER_OFFSET (GST_BUFFER (outbuf)) = src->n_frames; GST_BUFFER_OFFSET (GST_BUFFER (outbuf)) = src->n_frames;
src->n_frames++; src->n_frames++;
GST_BUFFER_OFFSET_END (GST_BUFFER (outbuf)) = src->n_frames; GST_BUFFER_OFFSET_END (GST_BUFFER (outbuf)) = src->n_frames;
if (src->rate_numerator) if (src->rate_numerator) {
{
next_time = gst_util_uint64_scale_int (src->n_frames * GST_SECOND, next_time = gst_util_uint64_scale_int (src->n_frames * GST_SECOND,
src->rate_denominator, src->rate_numerator); src->rate_denominator, src->rate_numerator);
GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = next_time - src->running_time; GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = next_time - src->running_time;
} } else {
else {
next_time = src->timestamp_offset; next_time = src->timestamp_offset;
/* NONE means forever */ /* NONE means forever */
GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = GST_CLOCK_TIME_NONE;
@ -625,9 +593,9 @@ no_buffer:
} }
static gboolean static gboolean
gst_gl_test_src_start (GstBaseSrc* basesrc) gst_gl_test_src_start (GstBaseSrc * basesrc)
{ {
GstGLTestSrc* src = GST_GL_TEST_SRC (basesrc); GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
src->running_time = 0; src->running_time = 0;
src->n_frames = 0; src->n_frames = 0;
@ -637,15 +605,13 @@ gst_gl_test_src_start (GstBaseSrc* basesrc)
} }
static gboolean static gboolean
gst_gl_test_src_stop (GstBaseSrc* basesrc) gst_gl_test_src_stop (GstBaseSrc * basesrc)
{ {
GstGLTestSrc* src = GST_GL_TEST_SRC (basesrc); GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
if (src->display) if (src->display) {
{
//blocking call, delete the FBO //blocking call, delete the FBO
gst_gl_display_del_fbo (src->display, src->fbo, gst_gl_display_del_fbo (src->display, src->fbo, src->depthbuffer);
src->depthbuffer);
g_object_unref (src->display); g_object_unref (src->display);
src->display = NULL; src->display = NULL;
} }
@ -655,9 +621,10 @@ gst_gl_test_src_stop (GstBaseSrc* basesrc)
//opengl scene //opengl scene
static void static void
gst_gl_test_src_callback (gint width, gint height, guint texture, gpointer stuff) gst_gl_test_src_callback (gint width, gint height, guint texture,
gpointer stuff)
{ {
GstGLTestSrc* src = GST_GL_TEST_SRC (stuff); GstGLTestSrc *src = GST_GL_TEST_SRC (stuff);
src->make_image (src, src->buffer, src->width, src->height); src->make_image (src, src->buffer, src->width, src->height);
} }

View file

@ -75,7 +75,7 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static const GstElementDetails element_details = static const GstElementDetails element_details =
GST_ELEMENT_DETAILS ("OpenGL upload", GST_ELEMENT_DETAILS ("OpenGL upload",
"Filter/Effect", "Filter/Effect",
"A from video to GL flow filter", "A from video to GL flow filter",
"Julien Isorce <julien.isorce@gmail.com>"); "Julien Isorce <julien.isorce@gmail.com>");
@ -93,8 +93,7 @@ static GstStaticPadTemplate gst_gl_upload_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ( GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";"
@ -114,26 +113,26 @@ enum
GST_BOILERPLATE_FULL (GstGLUpload, gst_gl_upload, GstBaseTransform, GST_BOILERPLATE_FULL (GstGLUpload, gst_gl_upload, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT); GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_upload_set_property (GObject* object, guint prop_id, static void gst_gl_upload_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec); const GValue * value, GParamSpec * pspec);
static void gst_gl_upload_get_property (GObject* object, guint prop_id, static void gst_gl_upload_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec); GValue * value, GParamSpec * pspec);
static void gst_gl_upload_reset (GstGLUpload* upload); static void gst_gl_upload_reset (GstGLUpload * upload);
static gboolean gst_gl_upload_set_caps (GstBaseTransform* bt, static gboolean gst_gl_upload_set_caps (GstBaseTransform * bt,
GstCaps* incaps, GstCaps* outcaps); GstCaps * incaps, GstCaps * outcaps);
static GstCaps *gst_gl_upload_transform_caps (GstBaseTransform* bt, static GstCaps *gst_gl_upload_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps); GstPadDirection direction, GstCaps * caps);
static void gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction, static void gst_gl_upload_fixate_caps (GstBaseTransform * base,
GstCaps* caps, GstCaps* othercaps); GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static gboolean gst_gl_upload_start (GstBaseTransform* bt); static gboolean gst_gl_upload_start (GstBaseTransform * bt);
static gboolean gst_gl_upload_stop (GstBaseTransform* bt); static gboolean gst_gl_upload_stop (GstBaseTransform * bt);
static GstFlowReturn gst_gl_upload_prepare_output_buffer (GstBaseTransform* trans, static GstFlowReturn gst_gl_upload_prepare_output_buffer (GstBaseTransform *
GstBuffer* input, gint size, GstCaps* caps, GstBuffer** buf); trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
static GstFlowReturn gst_gl_upload_transform (GstBaseTransform* trans, static GstFlowReturn gst_gl_upload_transform (GstBaseTransform * trans,
GstBuffer* inbuf, GstBuffer * outbuf); GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_upload_get_unit_size (GstBaseTransform* trans, static gboolean gst_gl_upload_get_unit_size (GstBaseTransform * trans,
GstCaps* caps, guint* size); GstCaps * caps, guint * size);
static void static void
@ -171,19 +170,18 @@ gst_gl_upload_class_init (GstGLUploadClass * klass)
} }
static void static void
gst_gl_upload_init (GstGLUpload* upload, GstGLUploadClass * klass) gst_gl_upload_init (GstGLUpload * upload, GstGLUploadClass * klass)
{ {
gst_gl_upload_reset (upload); gst_gl_upload_reset (upload);
} }
static void static void
gst_gl_upload_set_property (GObject* object, guint prop_id, gst_gl_upload_set_property (GObject * object, guint prop_id,
const GValue* value, GParamSpec* pspec) const GValue * value, GParamSpec * pspec)
{ {
//GstGLUpload* upload = GST_GL_UPLOAD (object); //GstGLUpload* upload = GST_GL_UPLOAD (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -191,13 +189,12 @@ gst_gl_upload_set_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_upload_get_property (GObject* object, guint prop_id, gst_gl_upload_get_property (GObject * object, guint prop_id,
GValue* value, GParamSpec* pspec) GValue * value, GParamSpec * pspec)
{ {
//GstGLUpload *upload = GST_GL_UPLOAD (object); //GstGLUpload *upload = GST_GL_UPLOAD (object);
switch (prop_id) switch (prop_id) {
{
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -205,17 +202,16 @@ gst_gl_upload_get_property (GObject* object, guint prop_id,
} }
static void static void
gst_gl_upload_reset (GstGLUpload* upload) gst_gl_upload_reset (GstGLUpload * upload)
{ {
if (upload->display) if (upload->display) {
{
g_object_unref (upload->display); g_object_unref (upload->display);
upload->display = NULL; upload->display = NULL;
} }
} }
static gboolean static gboolean
gst_gl_upload_start (GstBaseTransform* bt) gst_gl_upload_start (GstBaseTransform * bt)
{ {
//GstGLUpload* upload = GST_GL_UPLOAD (bt); //GstGLUpload* upload = GST_GL_UPLOAD (bt);
@ -223,37 +219,35 @@ gst_gl_upload_start (GstBaseTransform* bt)
} }
static gboolean static gboolean
gst_gl_upload_stop (GstBaseTransform* bt) gst_gl_upload_stop (GstBaseTransform * bt)
{ {
GstGLUpload* upload = GST_GL_UPLOAD (bt); GstGLUpload *upload = GST_GL_UPLOAD (bt);
gst_gl_upload_reset (upload); gst_gl_upload_reset (upload);
return TRUE; return TRUE;
} }
static GstCaps* static GstCaps *
gst_gl_upload_transform_caps (GstBaseTransform* bt, gst_gl_upload_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps* caps) GstPadDirection direction, GstCaps * caps)
{ {
//GstGLUpload* upload = GST_GL_UPLOAD (bt); //GstGLUpload* upload = GST_GL_UPLOAD (bt);
GstStructure* structure = gst_caps_get_structure (caps, 0); GstStructure *structure = gst_caps_get_structure (caps, 0);
GstCaps* newcaps = NULL; GstCaps *newcaps = NULL;
const GValue* framerate_value = NULL; const GValue *framerate_value = NULL;
const GValue* par_value = NULL; const GValue *par_value = NULL;
GST_DEBUG ("transform caps %" GST_PTR_FORMAT, caps); GST_DEBUG ("transform caps %" GST_PTR_FORMAT, caps);
framerate_value = gst_structure_get_value (structure, "framerate"); framerate_value = gst_structure_get_value (structure, "framerate");
par_value = gst_structure_get_value (structure, "pixel-aspect-ratio"); par_value = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (direction == GST_PAD_SRC) if (direction == GST_PAD_SRC) {
{ GstCaps *newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
GstCaps* newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL); newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL);
gst_caps_append(newcaps, newothercaps); gst_caps_append (newcaps, newothercaps);
} } else
else
newcaps = gst_caps_new_simple ("video/x-raw-gl", NULL); newcaps = gst_caps_new_simple ("video/x-raw-gl", NULL);
structure = gst_caps_get_structure (newcaps, 0); structure = gst_caps_get_structure (newcaps, 0);
@ -278,8 +272,8 @@ gst_gl_upload_transform_caps (GstBaseTransform* bt,
/* from gst-plugins-base "videoscale" code */ /* from gst-plugins-base "videoscale" code */
static void static void
gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction, gst_gl_upload_fixate_caps (GstBaseTransform * base, GstPadDirection direction,
GstCaps* caps, GstCaps* othercaps) GstCaps * caps, GstCaps * othercaps)
{ {
GstStructure *ins, *outs; GstStructure *ins, *outs;
@ -297,8 +291,7 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");
//we have both PAR but they might not be fixated //we have both PAR but they might not be fixated
if (from_par && to_par) if (from_par && to_par) {
{
gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
gint count = 0, w = 0, h = 0; gint count = 0, w = 0, h = 0;
@ -312,8 +305,7 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
from_par_d = gst_value_get_fraction_denominator (from_par); from_par_d = gst_value_get_fraction_denominator (from_par);
//fixate the out PAR //fixate the out PAR
if (!gst_value_is_fixed (to_par)) if (!gst_value_is_fixed (to_par)) {
{
GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n, GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n,
from_par_d); from_par_d);
gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio", gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio",
@ -329,8 +321,7 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
++count; ++count;
if (gst_structure_get_int (outs, "height", &h)) if (gst_structure_get_int (outs, "height", &h))
++count; ++count;
if (count == 2) if (count == 2) {
{
GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating", GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating",
w, h); w, h);
return; return;
@ -340,8 +331,7 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
gst_structure_get_int (ins, "height", &from_h); gst_structure_get_int (ins, "height", &from_h);
if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h, if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h,
from_par_n, from_par_d, to_par_n, to_par_d)) from_par_n, from_par_d, to_par_n, to_par_d)) {
{
GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
("Error calculating the output scaled size - integer overflow")); ("Error calculating the output scaled size - integer overflow"));
return; return;
@ -358,35 +348,25 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
//using wd / hd = num / den //using wd / hd = num / den
//if one of the output width or height is fixed, we work from there //if one of the output width or height is fixed, we work from there
if (h) if (h) {
{
GST_DEBUG_OBJECT (base, "height is fixed,scaling width"); GST_DEBUG_OBJECT (base, "height is fixed,scaling width");
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
} } else if (w) {
else if (w)
{
GST_DEBUG_OBJECT (base, "width is fixed, scaling height"); GST_DEBUG_OBJECT (base, "width is fixed, scaling height");
h = (guint) gst_util_uint64_scale_int (w, den, num); h = (guint) gst_util_uint64_scale_int (w, den, num);
} } else {
else
{
//none of width or height is fixed, figure out both of them based only on //none of width or height is fixed, figure out both of them based only on
//the input width and height //the input width and height
//check hd / den is an integer scale factor, and scale wd with the PAR //check hd / den is an integer scale factor, and scale wd with the PAR
if (from_h % den == 0) if (from_h % den == 0) {
{
GST_DEBUG_OBJECT (base, "keeping video height"); GST_DEBUG_OBJECT (base, "keeping video height");
h = from_h; h = from_h;
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
} } else if (from_w % num == 0) {
else if (from_w % num == 0)
{
GST_DEBUG_OBJECT (base, "keeping video width"); GST_DEBUG_OBJECT (base, "keeping video width");
w = from_w; w = from_w;
h = (guint) gst_util_uint64_scale_int (w, den, num); h = (guint) gst_util_uint64_scale_int (w, den, num);
} } else {
else
{
GST_DEBUG_OBJECT (base, "approximating but keeping video height"); GST_DEBUG_OBJECT (base, "approximating but keeping video height");
h = from_h; h = from_h;
w = (guint) gst_util_uint64_scale_int (h, num, den); w = (guint) gst_util_uint64_scale_int (h, num, den);
@ -397,13 +377,10 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
//now fixate //now fixate
gst_structure_fixate_field_nearest_int (outs, "width", w); gst_structure_fixate_field_nearest_int (outs, "width", w);
gst_structure_fixate_field_nearest_int (outs, "height", h); gst_structure_fixate_field_nearest_int (outs, "height", h);
} } else {
else
{
gint width, height; gint width, height;
if (gst_structure_get_int (ins, "width", &width)) if (gst_structure_get_int (ins, "width", &width)) {
{
if (gst_structure_has_field (outs, "width")) if (gst_structure_has_field (outs, "width"))
gst_structure_fixate_field_nearest_int (outs, "width", width); gst_structure_fixate_field_nearest_int (outs, "width", width);
} }
@ -418,10 +395,10 @@ gst_gl_upload_fixate_caps (GstBaseTransform* base, GstPadDirection direction,
} }
static gboolean static gboolean
gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps, gst_gl_upload_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps* outcaps) GstCaps * outcaps)
{ {
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;
@ -433,12 +410,10 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
ret |= gst_video_format_parse_caps (incaps, &upload->video_format, ret |= gst_video_format_parse_caps (incaps, &upload->video_format,
&upload->video_width, &upload->video_height); &upload->video_width, &upload->video_height);
if (!ret) if (!ret) {
{
GST_DEBUG ("caps connot be parsed"); GST_DEBUG ("caps connot be parsed");
return FALSE; return FALSE;
} }
//we have video and gl size, we can now init OpenGL stuffs //we have video and gl size, we can now init OpenGL stuffs
upload->display = gst_gl_display_new (); upload->display = gst_gl_display_new ();
@ -455,23 +430,20 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
} }
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 = FALSE; gboolean ret = FALSE;
GstStructure* structure = NULL; GstStructure *structure = NULL;
gint width = 0; gint width = 0;
gint height = 0; 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")) {
{
ret = gst_gl_buffer_parse_caps (caps, &width, &height); ret = gst_gl_buffer_parse_caps (caps, &width, &height);
if (ret) if (ret)
*size = gst_gl_buffer_get_size (width, height); *size = gst_gl_buffer_get_size (width, height);
} } else {
else
{
GstVideoFormat video_format = GST_VIDEO_FORMAT_UNKNOWN; 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);
@ -483,13 +455,13 @@ gst_gl_upload_get_unit_size (GstBaseTransform* trans, GstCaps* caps,
} }
static GstFlowReturn 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 = GST_GL_UPLOAD (trans); GstGLUpload *upload = GST_GL_UPLOAD (trans);
//blocking call, request a texture and attach it to the upload FBO //blocking call, request a texture and attach it to the upload FBO
GstGLBuffer* gl_outbuf = gst_gl_buffer_new (upload->display, GstGLBuffer *gl_outbuf = gst_gl_buffer_new (upload->display,
upload->gl_width, upload->gl_height); upload->gl_width, upload->gl_height);
*buf = GST_BUFFER (gl_outbuf); *buf = GST_BUFFER (gl_outbuf);
@ -503,11 +475,11 @@ gst_gl_upload_prepare_output_buffer (GstBaseTransform* trans,
static GstFlowReturn static GstFlowReturn
gst_gl_upload_transform (GstBaseTransform* trans, GstBuffer* inbuf, gst_gl_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer* outbuf) GstBuffer * outbuf)
{ {
GstGLUpload* upload = GST_GL_UPLOAD (trans); GstGLUpload *upload = GST_GL_UPLOAD (trans);
GstGLBuffer* gl_outbuf = GST_GL_BUFFER (outbuf); GstGLBuffer *gl_outbuf = GST_GL_BUFFER (outbuf);
GST_DEBUG ("Upload %p size %d", GST_DEBUG ("Upload %p size %d",
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf)); GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));

View file

@ -91,30 +91,30 @@ plugin_init (GstPlugin * plugin)
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "gloverlay", if (!gst_element_register (plugin, "gloverlay",
GST_RANK_NONE, gst_gl_overlay_get_type())) { GST_RANK_NONE, gst_gl_overlay_get_type ())) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "gldifferencematte", if (!gst_element_register (plugin, "gldifferencematte",
GST_RANK_NONE, gst_gl_differencematte_get_type())) { GST_RANK_NONE, gst_gl_differencematte_get_type ())) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "glbumper", if (!gst_element_register (plugin, "glbumper",
GST_RANK_NONE, gst_gl_bumper_get_type())) { GST_RANK_NONE, gst_gl_bumper_get_type ())) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "gleffects", if (!gst_element_register (plugin, "gleffects",
GST_RANK_NONE, gst_gl_effects_get_type())) { GST_RANK_NONE, gst_gl_effects_get_type ())) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "glfilterblur", if (!gst_element_register (plugin, "glfilterblur",
GST_RANK_NONE, gst_gl_filterblur_get_type())) { GST_RANK_NONE, gst_gl_filterblur_get_type ())) {
return FALSE; return FALSE;
} }
if (!gst_element_register (plugin, "glfiltersobel", if (!gst_element_register (plugin, "glfiltersobel",
GST_RANK_NONE, gst_gl_filtersobel_get_type())) { GST_RANK_NONE, gst_gl_filtersobel_get_type ())) {
return FALSE; return FALSE;
} }

View file

@ -31,7 +31,8 @@
#define W 320 #define W 320
#define H 240 #define H 240
struct GstGLClutterActor_ { struct GstGLClutterActor_
{
Window win; Window win;
Window root; Window root;
ClutterActor *texture; ClutterActor *texture;
@ -41,22 +42,24 @@ struct GstGLClutterActor_ {
typedef struct GstGLClutterActor_ GstGLClutterActor; typedef struct GstGLClutterActor_ GstGLClutterActor;
static gboolean static gboolean
create_actor (GstGLClutterActor *actor) { create_actor (GstGLClutterActor * actor)
{
ClutterKnot knot[2]; ClutterKnot knot[2];
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterEffectTemplate *effect_template; ClutterEffectTemplate *effect_template;
actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP,
"window", actor->win, "window", actor->win, "automatic-updates", TRUE, NULL);
"automatic-updates", TRUE, NULL); clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage),
clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage), actor->texture); actor->texture);
clutter_actor_set_scale (actor->texture, 0.2 , 0.2); clutter_actor_set_scale (actor->texture, 0.2, 0.2);
clutter_actor_set_opacity (actor->texture, 0); clutter_actor_set_opacity (actor->texture, 0);
clutter_actor_show (actor->texture); clutter_actor_show (actor->texture);
timeline = clutter_timeline_new(120 /* frames */, 50 /* frames per second. */); timeline =
clutter_timeline_set_loop(timeline, TRUE); clutter_timeline_new (120 /* frames */ , 50 /* frames per second. */ );
clutter_timeline_start(timeline); clutter_timeline_set_loop (timeline, TRUE);
clutter_timeline_start (timeline);
/* Instead of our custom callback, /* Instead of our custom callback,
* we could use a standard callback. For instance, CLUTTER_ALPHA_SINE_INC. * we could use a standard callback. For instance, CLUTTER_ALPHA_SINE_INC.
@ -66,19 +69,18 @@ create_actor (GstGLClutterActor *actor) {
knot[0].x = -10; knot[0].x = -10;
knot[0].y = -10; knot[0].y = -10;
knot[1].x= 160; knot[1].x = 160;
knot[1].y= 120; knot[1].y = 120;
// Move the actor along the path: // Move the actor along the path:
clutter_effect_path (effect_template, actor->texture, knot, clutter_effect_path (effect_template, actor->texture, knot,
sizeof(knot) / sizeof(ClutterKnot), NULL, NULL); sizeof (knot) / sizeof (ClutterKnot), NULL, NULL);
clutter_effect_scale (effect_template, actor->texture, 1.0, 1.0, NULL, NULL); clutter_effect_scale (effect_template, actor->texture, 1.0, 1.0, NULL, NULL);
clutter_effect_rotate (effect_template, actor->texture, clutter_effect_rotate (effect_template, actor->texture,
CLUTTER_Z_AXIS, 360.0, W/2.0, H/2.0, 0.0, CLUTTER_Z_AXIS, 360.0, W / 2.0, H / 2.0, 0.0,
CLUTTER_ROTATE_CW, NULL, NULL); CLUTTER_ROTATE_CW, NULL, NULL);
clutter_effect_rotate (effect_template, actor->texture, clutter_effect_rotate (effect_template, actor->texture,
CLUTTER_X_AXIS, 360.0, 0.0, W/4.0, 0.0, CLUTTER_X_AXIS, 360.0, 0.0, W / 4.0, 0.0, CLUTTER_ROTATE_CW, NULL, NULL);
CLUTTER_ROTATE_CW, NULL, NULL);
// Also change the actor's opacity while moving it along the path: // Also change the actor's opacity while moving it along the path:
// (You would probably want to use a different ClutterEffectTemplate, // (You would probably want to use a different ClutterEffectTemplate,
@ -104,7 +106,8 @@ create_window (GstBus * bus, GstMessage * message, gpointer data)
g_debug ("CREATING WINDOW"); g_debug ("CREATING WINDOW");
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), actor->win); gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)),
actor->win);
clutter_threads_add_idle ((GSourceFunc) create_actor, actor); clutter_threads_add_idle ((GSourceFunc) create_actor, actor);
gst_message_unref (message); gst_message_unref (message);
@ -125,7 +128,7 @@ main (int argc, char *argv[])
gst_init (&argc, &argv); gst_init (&argc, &argv);
disp = clutter_x11_get_default_display (); disp = clutter_x11_get_default_display ();
if(!clutter_x11_has_composite_extension ()) { if (!clutter_x11_has_composite_extension ()) {
g_error ("XComposite extension missing"); g_error ("XComposite extension missing");
} }
@ -142,7 +145,9 @@ main (int argc, char *argv[])
XMapRaised (disp, actor->win); XMapRaised (disp, actor->win);
XSync (disp, FALSE); XSync (disp, FALSE);
pipeline = GST_PIPELINE (gst_parse_launch ("videotestsrc ! video/x-raw-rgb, width=320, height=240, framerate=(fraction)30/1 ! " pipeline =
GST_PIPELINE (gst_parse_launch
("videotestsrc ! video/x-raw-rgb, width=320, height=240, framerate=(fraction)30/1 ! "
"glupload ! gleffects effect=twirl ! glimagesink", NULL)); "glupload ! gleffects effect=twirl ! glimagesink", NULL));
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
@ -153,7 +158,7 @@ main (int argc, char *argv[])
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
clutter_main(); clutter_main ();
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
g_object_unref (pipeline); g_object_unref (pipeline);

View file

@ -32,7 +32,8 @@
#define W 160 #define W 160
#define H 120 #define H 120
struct GstGLClutterActor_ { struct GstGLClutterActor_
{
Window win; Window win;
Window root; Window root;
ClutterActor *texture; ClutterActor *texture;
@ -42,24 +43,25 @@ struct GstGLClutterActor_ {
typedef struct GstGLClutterActor_ GstGLClutterActor; typedef struct GstGLClutterActor_ GstGLClutterActor;
static gboolean static gboolean
create_actor (GstGLClutterActor *actor) { create_actor (GstGLClutterActor * actor)
{
static gint xpos = 0; static gint xpos = 0;
static gint ypos = 0; static gint ypos = 0;
Display *disp; Display *disp;
actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP,
"window", actor->win, "window", actor->win, "automatic-updates", TRUE, NULL);
"automatic-updates", TRUE, NULL); clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage),
clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage), actor->texture); actor->texture);
clutter_actor_set_position (actor->texture, xpos, ypos); clutter_actor_set_position (actor->texture, xpos, ypos);
disp = clutter_x11_get_default_display (); disp = clutter_x11_get_default_display ();
XMoveResizeWindow (disp, actor->win, xpos, ypos, W, H); XMoveResizeWindow (disp, actor->win, xpos, ypos, W, H);
if (xpos > (COLS-1)*W) { if (xpos > (COLS - 1) * W) {
xpos = 0; xpos = 0;
ypos += H+1; ypos += H + 1;
} else } else
xpos += W+1; xpos += W + 1;
clutter_actor_show (actor->texture); clutter_actor_show (actor->texture);
return FALSE; return FALSE;
@ -99,7 +101,7 @@ create_window (GstBus * bus, GstMessage * message, gpointer data)
#if 0 #if 0
void void
apply_fx (GstElement *element, const gchar *fx) apply_fx (GstElement * element, const gchar * fx)
{ {
GEnumClass *p_class; GEnumClass *p_class;
@ -125,7 +127,8 @@ main (int argc, char *argv[])
GstElement *srcbin; GstElement *srcbin;
GstElement *tee; GstElement *tee;
GstElement *queue[N_ACTORS], *upload[N_ACTORS], *effect[N_ACTORS], *sink[N_ACTORS]; GstElement *queue[N_ACTORS], *upload[N_ACTORS], *effect[N_ACTORS],
*sink[N_ACTORS];
ClutterActor *stage; ClutterActor *stage;
GstGLClutterActor *actor[N_ACTORS]; GstGLClutterActor *actor[N_ACTORS];
@ -139,18 +142,17 @@ main (int argc, char *argv[])
gst_init (&argc, &argv); gst_init (&argc, &argv);
disp = clutter_x11_get_default_display (); disp = clutter_x11_get_default_display ();
if(!clutter_x11_has_composite_extension ()) { if (!clutter_x11_has_composite_extension ()) {
g_error ("XComposite extension missing"); g_error ("XComposite extension missing");
} }
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
clutter_actor_set_size (CLUTTER_ACTOR (stage), clutter_actor_set_size (CLUTTER_ACTOR (stage),
W*COLS + (COLS-1), W * COLS + (COLS - 1), H * ROWS + (ROWS - 1));
H*ROWS + (ROWS-1));
stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
for (i=0; i<N_ACTORS; i++) { for (i = 0; i < N_ACTORS; i++) {
actor[i] = g_new0 (GstGLClutterActor, 1); actor[i] = g_new0 (GstGLClutterActor, 1);
actor[i]->stage = stage; actor[i]->stage = stage;
actor[i]->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0); actor[i]->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0);
@ -166,18 +168,18 @@ main (int argc, char *argv[])
"identity", W, H); "identity", W, H);
*/ */
desc = g_strdup_printf ("videotestsrc ! " desc = g_strdup_printf ("videotestsrc ! "
"video/x-raw-rgb, width=%d, height=%d !" "video/x-raw-rgb, width=%d, height=%d !" "identity", W, H);
"identity", W, H);
pipeline = GST_PIPELINE (gst_pipeline_new (NULL)); pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
srcbin = gst_parse_bin_from_description (desc, TRUE, NULL); srcbin = gst_parse_bin_from_description (desc, TRUE, NULL);
if (!srcbin) g_error ("Source bin creation failed"); if (!srcbin)
g_error ("Source bin creation failed");
tee = gst_element_factory_make ("tee", NULL); tee = gst_element_factory_make ("tee", NULL);
gst_bin_add_many (GST_BIN (pipeline), srcbin, tee, NULL); gst_bin_add_many (GST_BIN (pipeline), srcbin, tee, NULL);
for (i=0; i<N_ACTORS; i++) { for (i = 0; i < N_ACTORS; i++) {
queue[i] = gst_element_factory_make ("queue", NULL); queue[i] = gst_element_factory_make ("queue", NULL);
upload[i] = gst_element_factory_make ("glupload", NULL); upload[i] = gst_element_factory_make ("glupload", NULL);
effect[i] = gst_element_factory_make ("gleffects", NULL); effect[i] = gst_element_factory_make ("gleffects", NULL);
@ -188,16 +190,19 @@ main (int argc, char *argv[])
gst_element_link_many (srcbin, tee, NULL); gst_element_link_many (srcbin, tee, NULL);
for (i=0; i<N_ACTORS; i++) { for (i = 0; i < N_ACTORS; i++) {
ok |= gst_element_link_many (tee, queue[i], upload[i], effect[i], sink[i], NULL); ok |=
gst_element_link_many (tee, queue[i], upload[i], effect[i], sink[i],
NULL);
} }
if (!ok) if (!ok)
g_error ("Failed to link one or more elements"); g_error ("Failed to link one or more elements");
for (i=0; i<N_ACTORS; i++) { for (i = 0; i < N_ACTORS; i++) {
g_message ("setting effect %d on %s", i+1, gst_element_get_name (effect[i])); g_message ("setting effect %d on %s", i + 1,
g_object_set (G_OBJECT (effect[i]), "effect", i+1, NULL); gst_element_get_name (effect[i]));
g_object_set (G_OBJECT (effect[i]), "effect", i + 1, NULL);
} }
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
@ -208,7 +213,7 @@ main (int argc, char *argv[])
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
clutter_main(); clutter_main ();
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
g_object_unref (pipeline); g_object_unref (pipeline);

View file

@ -20,7 +20,8 @@ expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer data)
GST_X_OVERLAY (gst_bin_get_by_interface (GST_BIN (data), GST_X_OVERLAY (gst_bin_get_by_interface (GST_BIN (data),
GST_TYPE_X_OVERLAY)); GST_TYPE_X_OVERLAY));
#ifdef WIN32 #ifdef WIN32
gst_x_overlay_set_xwindow_id (overlay, (gulong)GDK_WINDOW_HWND(widget->window)); gst_x_overlay_set_xwindow_id (overlay,
(gulong) GDK_WINDOW_HWND (widget->window));
#else #else
gst_x_overlay_set_xwindow_id (overlay, GDK_WINDOW_XWINDOW (widget->window)); gst_x_overlay_set_xwindow_id (overlay, GDK_WINDOW_XWINDOW (widget->window));
#endif #endif
@ -29,7 +30,7 @@ expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer data)
} }
static void static void
destroy_cb (GtkWidget *widget, GdkEvent *event, GstElement *pipeline) destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
{ {
g_message ("destroy callback"); g_message ("destroy callback");
@ -111,9 +112,10 @@ main (gint argc, gchar * argv[])
GOptionContext *context; GOptionContext *context;
GOptionEntry options[] = { GOptionEntry options[] = {
{ "source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array, {"source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array,
"Use a custom source bin description (gst-launch style)", NULL }, "Use a custom source bin description (gst-launch style)", NULL}
{ NULL } ,
{NULL}
}; };
g_thread_init (NULL); g_thread_init (NULL);
@ -133,10 +135,13 @@ main (gint argc, gchar * argv[])
g_strfreev (source_desc_array); g_strfreev (source_desc_array);
} }
if (source_desc == NULL) { if (source_desc == NULL) {
source_desc = g_strdup ("videotestsrc ! video/x-raw-rgb, width=352, height=288 ! identity"); source_desc =
g_strdup
("videotestsrc ! video/x-raw-rgb, width=352, height=288 ! identity");
} }
sourcebin = gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error); sourcebin =
gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error);
g_free (source_desc); g_free (source_desc);
if (error) { if (error) {
g_print ("Error while parsing source bin description: %s\n", g_print ("Error while parsing source bin description: %s\n",

View file

@ -24,7 +24,7 @@ struct _SourceData
typedef struct _SourceData SourceData; typedef struct _SourceData SourceData;
static GstBusSyncReply static GstBusSyncReply
create_window (GstBus *bus, GstMessage *message, GtkWidget *widget) create_window (GstBus * bus, GstMessage * message, GtkWidget * widget)
{ {
// ignore anything but 'prepare-xwindow-id' element messages // ignore anything but 'prepare-xwindow-id' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
@ -35,10 +35,10 @@ create_window (GstBus *bus, GstMessage *message, GtkWidget *widget)
#ifdef WIN32 #ifdef WIN32
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)),
(gulong)GDK_WINDOW_HWND(widget->window)); (gulong) GDK_WINDOW_HWND (widget->window));
#else #else
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)),
GDK_WINDOW_XWINDOW(widget->window)); GDK_WINDOW_XWINDOW (widget->window));
#endif #endif
gst_message_unref (message); gst_message_unref (message);
@ -47,14 +47,14 @@ create_window (GstBus *bus, GstMessage *message, GtkWidget *widget)
} }
static gboolean static gboolean
expose_cb(GtkWidget *widget, GdkEventExpose *event, GstElement *videosink) expose_cb (GtkWidget * widget, GdkEventExpose * event, GstElement * videosink)
{ {
gst_x_overlay_expose (GST_X_OVERLAY (videosink)); gst_x_overlay_expose (GST_X_OVERLAY (videosink));
return FALSE; return FALSE;
} }
static void static void
destroy_cb (GtkWidget *widget, GdkEvent *event, GstElement *pipeline) destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
{ {
g_message ("destroy callback"); g_message ("destroy callback");
@ -113,8 +113,7 @@ set_location_delayed (gpointer data)
static void static void
on_drag_data_received (GtkWidget * widget, on_drag_data_received (GtkWidget * widget,
GdkDragContext * context, int x, int y, GdkDragContext * context, int x, int y,
GtkSelectionData * seldata, guint inf, guint time, GtkSelectionData * seldata, guint inf, guint time, gpointer data)
gpointer data)
{ {
GdkPixbufFormat *format; GdkPixbufFormat *format;
SourceData *userdata = g_new0 (SourceData, 1); SourceData *userdata = g_new0 (SourceData, 1);
@ -135,9 +134,9 @@ on_drag_data_received (GtkWidget * widget,
if (delay > 0) { if (delay > 0) {
g_print ("%d\n", delay); g_print ("%d\n", delay);
g_timeout_add_seconds (1, set_location_delayed, userdata); g_timeout_add_seconds (1, set_location_delayed, userdata);
} } else
else g_object_set (G_OBJECT (userdata->data), userdata->nick, userdata->value,
g_object_set (G_OBJECT (userdata->data), userdata->nick, userdata->value, NULL); NULL);
g_free (filename); g_free (filename);
} }
@ -163,11 +162,17 @@ main (gint argc, gchar * argv[])
GOptionContext *context; GOptionContext *context;
GOptionEntry options[] = { GOptionEntry options[] = {
{ "source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array, {"source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array,
"Use a custom source bin description (gst-launch style)", NULL }, "Use a custom source bin description (gst-launch style)", NULL}
{ "method", 'm', 0, G_OPTION_ARG_INT, &method, "1 for gstdifferencematte, 2 for gloverlay", "M" }, ,
{ "delay", 'd', 0, G_OPTION_ARG_INT, &delay, "Wait N seconds before to send the image to gstreamer (useful with differencematte)", "N" }, {"method", 'm', 0, G_OPTION_ARG_INT, &method,
{ NULL } "1 for gstdifferencematte, 2 for gloverlay", "M"}
,
{"delay", 'd', 0, G_OPTION_ARG_INT, &delay,
"Wait N seconds before to send the image to gstreamer (useful with differencematte)",
"N"}
,
{NULL}
}; };
g_thread_init (NULL); g_thread_init (NULL);
@ -187,10 +192,13 @@ main (gint argc, gchar * argv[])
g_strfreev (source_desc_array); g_strfreev (source_desc_array);
} }
if (source_desc == NULL) { if (source_desc == NULL) {
source_desc = g_strdup ("videotestsrc ! video/x-raw-rgb, width=352, height=288 ! identity"); source_desc =
g_strdup
("videotestsrc ! video/x-raw-rgb, width=352, height=288 ! identity");
} }
sourcebin = gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error); sourcebin =
gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error);
g_free (source_desc); g_free (source_desc);
if (error) { if (error) {
g_print ("Error while parsing source bin description: %s\n", g_print ("Error while parsing source bin description: %s\n",
@ -265,7 +273,7 @@ main (gint argc, gchar * argv[])
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, screen); gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, screen);
gst_object_unref (bus); gst_object_unref (bus);
g_signal_connect(screen, "expose-event", G_CALLBACK(expose_cb), sink); g_signal_connect (screen, "expose-event", G_CALLBACK (expose_cb), sink);
gtk_drag_dest_set (screen, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY); gtk_drag_dest_set (screen, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
gtk_drag_dest_add_uri_targets (screen); gtk_drag_dest_add_uri_targets (screen);