gl/examples: move to -bad
authorMatthew Waters <ystreet00@gmail.com>
Tue, 29 Apr 2014 06:38:55 +0000 (16:38 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:38 +0000 (19:31 +0000)
- fix all the compiler errors
- give them their own gl directory

112 files changed:
tests/examples/gl/Makefile.am [new file with mode: 0644]
tests/examples/gl/clutter/.gitignore [new file with mode: 0644]
tests/examples/gl/clutter/Makefile.am [new file with mode: 0644]
tests/examples/gl/clutter/clutteractor.c [new file with mode: 0644]
tests/examples/gl/clutter/clutteractortee.c [new file with mode: 0644]
tests/examples/gl/clutter/cluttershare.c [new file with mode: 0644]
tests/examples/gl/clutter/cluttershare.cbp [new file with mode: 0644]
tests/examples/gl/cocoa/Makefile.am [new file with mode: 0755]
tests/examples/gl/cocoa/README [new file with mode: 0644]
tests/examples/gl/cocoa/videooverlay/.gitignore [new file with mode: 0644]
tests/examples/gl/cocoa/videooverlay/Makefile.am [new file with mode: 0755]
tests/examples/gl/cocoa/videooverlay/main.m [new file with mode: 0755]
tests/examples/gl/generic/Makefile.am [new file with mode: 0644]
tests/examples/gl/generic/README [new file with mode: 0644]
tests/examples/gl/generic/cube/.gitignore [new file with mode: 0644]
tests/examples/gl/generic/cube/Makefile.am [new file with mode: 0644]
tests/examples/gl/generic/cube/cube.vcproj [new file with mode: 0644]
tests/examples/gl/generic/cube/main.cpp [new file with mode: 0644]
tests/examples/gl/generic/cubeyuv/.gitignore [new file with mode: 0644]
tests/examples/gl/generic/cubeyuv/Makefile.am [new file with mode: 0644]
tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj [new file with mode: 0644]
tests/examples/gl/generic/cubeyuv/main.cpp [new file with mode: 0644]
tests/examples/gl/generic/doublecube/.gitignore [new file with mode: 0644]
tests/examples/gl/generic/doublecube/Makefile.am [new file with mode: 0644]
tests/examples/gl/generic/doublecube/doublecube.vcproj [new file with mode: 0644]
tests/examples/gl/generic/doublecube/main.cpp [new file with mode: 0644]
tests/examples/gl/generic/generic.sln [new file with mode: 0644]
tests/examples/gl/generic/recordgraphic/.gitignore [new file with mode: 0644]
tests/examples/gl/generic/recordgraphic/Makefile.am [new file with mode: 0644]
tests/examples/gl/generic/recordgraphic/main.cpp [new file with mode: 0644]
tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/README [new file with mode: 0644]
tests/examples/gl/gtk/filternovideooverlay/.gitignore [new file with mode: 0644]
tests/examples/gl/gtk/filternovideooverlay/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/filternovideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/gtk/filtervideooverlay/.gitignore [new file with mode: 0644]
tests/examples/gl/gtk/filtervideooverlay/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/filtervideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/gtk/fxtest/.gitignore [new file with mode: 0644]
tests/examples/gl/gtk/fxtest/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/fxtest/fxtest.c [new file with mode: 0644]
tests/examples/gl/gtk/fxtest/fxtest.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/fxtest/pixbufdrop.c [new file with mode: 0644]
tests/examples/gl/gtk/gstgtk.c [new file with mode: 0644]
tests/examples/gl/gtk/gstgtk.h [new file with mode: 0644]
tests/examples/gl/gtk/gtk.sln [new file with mode: 0644]
tests/examples/gl/gtk/gtkvideooverlay/.gitignore [new file with mode: 0644]
tests/examples/gl/gtk/gtkvideooverlay/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/gtkvideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj [new file with mode: 0644]
tests/examples/gl/gtk/switchvideooverlay/.gitignore [new file with mode: 0644]
tests/examples/gl/gtk/switchvideooverlay/Makefile.am [new file with mode: 0644]
tests/examples/gl/gtk/switchvideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/qt/Makefile.am [new file with mode: 0644]
tests/examples/gl/qt/README [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/gstthread.cpp [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/gstthread.h [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/pipeline.cpp [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/pipeline.h [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp [new file with mode: 0644]
tests/examples/gl/qt/mousevideooverlay/qrenderer.h [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln [new file with mode: 0644]
tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/README [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/glcontextid.h [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/gstthread.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/gstthread.h [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/main.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/pipeline.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/pipeline.h [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/qglrenderer.h [new file with mode: 0644]
tests/examples/gl/qt/qglwtextureshare/qglwtextureshare [new file with mode: 0755]
tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/Debug/videooverlay [new file with mode: 0755]
tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/videooverlay.cpp [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/videooverlay.pri [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/videooverlay.sln [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/videooverlay.vcproj [new file with mode: 0644]
tests/examples/gl/qt/videooverlay/videovideooverlay.pro [new file with mode: 0644]
tests/examples/gl/sdl/.gitignore [new file with mode: 0644]
tests/examples/gl/sdl/Makefile.am [new file with mode: 0644]
tests/examples/gl/sdl/sdl.sln [new file with mode: 0644]
tests/examples/gl/sdl/sdlshare.c [new file with mode: 0644]
tests/examples/gl/sdl/sdlshare.vcproj [new file with mode: 0644]

diff --git a/tests/examples/gl/Makefile.am b/tests/examples/gl/Makefile.am
new file mode 100644 (file)
index 0000000..8d7d9f7
--- /dev/null
@@ -0,0 +1,26 @@
+
+SUBDIRS =
+
+if USE_OPENGL
+
+if HAVE_WINDOW_COCOA
+SUBDIRS += cocoa
+else
+
+SUBDIRS += generic qt
+
+#if HAVE_CLUTTER
+#SUBDIRS += clutter
+#endif
+
+if HAVE_SDL
+SUBDIRS += sdl
+endif
+
+if HAVE_GTK3
+SUBDIRS += gtk
+endif
+
+endif
+
+endif
diff --git a/tests/examples/gl/clutter/.gitignore b/tests/examples/gl/clutter/.gitignore
new file mode 100644 (file)
index 0000000..9b1eb53
--- /dev/null
@@ -0,0 +1,3 @@
+clutteractor
+clutteractortee
+cluttershare
diff --git a/tests/examples/gl/clutter/Makefile.am b/tests/examples/gl/clutter/Makefile.am
new file mode 100644 (file)
index 0000000..0383a6a
--- /dev/null
@@ -0,0 +1,45 @@
+noinst_PROGRAMS = ##
+
+#works on win32 and X
+if HAVE_CLUTTER
+
+noinst_PROGRAMS += cluttershare
+
+cluttershare_SOURCES = cluttershare.c
+
+cluttershare_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
+    $(GST_CFLAGS) $(GL_CFLAGS) $(CLUTTER_CFLAGS)
+cluttershare_LDADD=$(CLUTTER_LIBS) $(GST_PLUGINS_BASE_LIBS) \
+    $(GST_LIBS) $(GL_LIBS) \
+    -lgstvideo-$(GST_API_VERSION) $(top_builddir)/gst-libs/gst/gl/libgstgl-@GST_API_VERSION@.la
+
+endif
+
+
+if HAVE_CLUTTER_GLX
+if HAVE_CLUTTER_X11
+if HAVE_XCOMPOSITE
+
+noinst_PROGRAMS += clutteractor clutteractortee
+
+clutteractor_SOURCES = clutteractor.c
+
+clutteractor_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       $(GL_CFLAGS) $(CLUTTER_CFLAGS) \
+       $(CLUTTER_GLX_CFLAGS) $(CLUTTER_X11_CFLAGS) $(XCOMPOSITE_CFLAGS)
+clutteractor_LDADD=$(CLUTTER_LIBS) $(CLUTTER_GLX_LIBS) $(CLUTTER_X11_LIBS) \
+       $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) $(XCOMPOSITE_LIBS) -lgstvideo-$(GST_API_VERSION)
+
+clutteractortee_SOURCES = clutteractortee.c
+
+clutteractortee_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       $(GL_CFLAGS) $(CLUTTER_CFLAGS) \
+       $(CLUTTER_GLX_CFLAGS) $(CLUTTER_X11_CFLAGS) $(XCOMPOSITE_CFLAGS)
+clutteractortee_LDADD=$(CLUTTER_LIBS) $(CLUTTER_GLX_LIBS) $(CLUTTER_X11_LIBS) \
+       $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) $(XCOMPOSITE_LIBS) -lgstvideo-$(GST_API_VERSION)
+
+endif
+endif
+endif
diff --git a/tests/examples/gl/clutter/clutteractor.c b/tests/examples/gl/clutter/clutteractor.c
new file mode 100644 (file)
index 0000000..44c97ba
--- /dev/null
@@ -0,0 +1,178 @@
+/* 
+ * GStreamer
+ * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define CLUTTER_VERSION_MIN_REQUIRED CLUTTER_VERSION_1_8
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <clutter/clutter.h>
+#include <clutter/x11/clutter-x11.h>
+#include <clutter/glx/clutter-glx.h>
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+
+#define W 320
+#define H 240
+
+struct GstGLClutterActor_
+{
+  Window win;
+  Window root;
+  ClutterActor *texture;
+  ClutterActor *stage;
+};
+
+typedef struct GstGLClutterActor_ GstGLClutterActor;
+
+static gboolean
+create_actor (GstGLClutterActor * actor)
+{
+  //ClutterKnot knot[2];
+  //ClutterTimeline *timeline;
+  ClutterAnimation *animation = NULL;
+
+  actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP,
+      "window", actor->win, "automatic-updates", TRUE, NULL);
+  clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage),
+      actor->texture);
+  clutter_actor_set_scale (actor->texture, 0.2, 0.2);
+  clutter_actor_set_opacity (actor->texture, 0);
+  clutter_actor_show (actor->texture);
+
+  //timeline =
+  //    clutter_timeline_new (120 /* frames */ , 50 /* frames per second. */ );
+  //clutter_timeline_set_loop (timeline, TRUE);
+  //clutter_timeline_start (timeline);
+
+  /* Instead of our custom callback, 
+   * we could use a standard callback. For instance, CLUTTER_ALPHA_SINE_INC. 
+   */
+  /*effect_template =
+     clutter_effect_template_new (timeline, CLUTTER_ALPHA_SINE_INC); */
+  animation =
+      clutter_actor_animate (actor->texture, CLUTTER_LINEAR, 2400,
+      "x", 100.0, "y", 100.0, "opacity", 0, NULL);
+
+  /* knot[0].x = -10;
+     knot[0].y = -10;
+     knot[1].x = 160;
+     knot[1].y = 120; */
+
+  // Move the actor along the path:
+  /* clutter_effect_path (effect_template, actor->texture, knot,
+     sizeof (knot) / sizeof (ClutterKnot), NULL, NULL);
+     clutter_effect_scale (effect_template, actor->texture, 1.0, 1.0, NULL, NULL);
+     clutter_effect_rotate (effect_template, actor->texture,
+     CLUTTER_Z_AXIS, 360.0, W / 2.0, H / 2.0, 0.0,
+     CLUTTER_ROTATE_CW, NULL, NULL);
+     clutter_effect_rotate (effect_template, actor->texture,
+     CLUTTER_X_AXIS, 360.0, 0.0, W / 4.0, 0.0, CLUTTER_ROTATE_CW, NULL, NULL); */
+
+  // Also change the actor's opacity while moving it along the path:
+  // (You would probably want to use a different ClutterEffectTemplate, 
+  // so you could use a different alpha callback for this.)
+  //clutter_effect_fade (effect_template, actor->texture, 255, NULL, NULL);
+
+  g_object_unref (animation);
+  //g_object_unref (timeline);
+
+  return FALSE;
+}
+
+static GstBusSyncReply
+create_window (GstBus * bus, GstMessage * message, gpointer data)
+{
+  GstGLClutterActor *actor = (GstGLClutterActor *) data;
+  // ignore anything but 'prepare-window-handle' element messages
+  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+    return GST_BUS_PASS;
+
+  if (!gst_is_video_overlay_prepare_window_handle_message (message))
+    return GST_BUS_PASS;
+
+  g_debug ("CREATING WINDOW");
+
+  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC
+          (message)), actor->win);
+  clutter_threads_add_idle ((GSourceFunc) create_actor, actor);
+
+  gst_message_unref (message);
+  return GST_BUS_DROP;
+}
+
+int
+main (int argc, char *argv[])
+{
+  GstPipeline *pipeline;
+  GstBus *bus;
+  ClutterActor *stage;
+  GstGLClutterActor *actor;
+  Display *disp;
+  Window stage_win;
+  ClutterInitError clutter_err = CLUTTER_INIT_ERROR_UNKNOWN;
+
+  clutter_err = clutter_init (&argc, &argv);
+  if (clutter_err != CLUTTER_INIT_SUCCESS)
+    g_warning ("Failed to initalize clutter: %d\n", clutter_err);
+
+  gst_init (&argc, &argv);
+
+  disp = clutter_x11_get_default_display ();
+  if (!clutter_x11_has_composite_extension ()) {
+    g_error ("XComposite extension missing");
+  }
+
+
+  stage = clutter_stage_get_default ();
+//  clutter_actor_set_size (CLUTTER_ACTOR (stage), W*3+2, H);
+
+  stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+
+  actor = g_new0 (GstGLClutterActor, 1);
+  actor->stage = stage;
+  actor->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0);
+  XCompositeRedirectWindow (disp, actor->win, CompositeRedirectManual);
+  XMapRaised (disp, actor->win);
+  XSync (disp, FALSE);
+
+  pipeline =
+      GST_PIPELINE (gst_parse_launch
+      ("videotestsrc ! video/x-raw, width=320, height=240, framerate=(fraction)30/1 ! "
+          "gleffects effect=twirl ! glimagesink", NULL));
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, actor,
+      NULL);
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  clutter_actor_show_all (stage);
+
+  clutter_main ();
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  return 0;
+}
diff --git a/tests/examples/gl/clutter/clutteractortee.c b/tests/examples/gl/clutter/clutteractortee.c
new file mode 100644 (file)
index 0000000..a46f323
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+#define CLUTTER_VERSION_MIN_REQUIRED CLUTTER_VERSION_1_8
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <clutter/clutter.h>
+#include <clutter/x11/clutter-x11.h>
+#include <clutter/glx/clutter-glx.h>
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+
+#define ROWS 3
+#define COLS 3
+#define N_ACTORS ROWS*COLS
+#define W 160
+#define H 120
+
+struct GstGLClutterActor_
+{
+  Window win;
+  Window root;
+  ClutterActor *texture;
+  ClutterActor *stage;
+};
+
+typedef struct GstGLClutterActor_ GstGLClutterActor;
+
+static gboolean
+create_actor (GstGLClutterActor * actor)
+{
+  static gint xpos = 0;
+  static gint ypos = 0;
+  actor->texture = g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP,
+      "window", actor->win, "automatic-updates", TRUE, NULL);
+  clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage),
+      actor->texture);
+  clutter_actor_set_position (actor->texture, xpos, ypos);
+
+  if (xpos > (COLS - 1) * W) {
+    xpos = 0;
+    ypos += H + 1;
+  } else
+    xpos += W + 1;
+  clutter_actor_show (actor->texture);
+
+  return FALSE;
+}
+
+static GstBusSyncReply
+create_window (GstBus * bus, GstMessage * message, gpointer data)
+{
+  GstGLClutterActor **actor = (GstGLClutterActor **) data;
+  static gint count = 0;
+  static GMutex mutex;
+  // ignore anything but 'prepare-window-handle' element messages
+  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+    return GST_BUS_PASS;
+
+  if (!gst_is_video_overlay_prepare_window_handle_message (message))
+    return GST_BUS_PASS;
+
+  g_mutex_lock (&mutex);
+
+  if (count < N_ACTORS) {
+    g_message ("adding actor %d", count);
+    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC
+            (message)), actor[count]->win);
+    clutter_threads_add_idle ((GSourceFunc) create_actor, actor[count]);
+    count++;
+  }
+
+  g_mutex_unlock (&mutex);
+
+  gst_message_unref (message);
+  return GST_BUS_DROP;
+}
+
+#if 0
+void
+apply_fx (GstElement * element, const gchar * fx)
+{
+  GEnumClass *p_class;
+
+  /* from fxtest ;) */
+  /* heeeellppppp!! */
+  p_class =
+      G_PARAM_SPEC_ENUM (g_object_class_find_property (G_OBJECT_GET_CLASS
+          (G_OBJECT (data)), "effect")
+      )->enum_class;
+
+  g_print ("setting: %s - %s\n", fx, g_enum_get_value_by_nick (p_class,
+          fx)->value_name);
+  g_object_set (G_OBJECT (element), "effect", g_enum_get_value_by_nick (p_class,
+          fx)->value, NULL);
+}
+#endif
+
+int
+main (int argc, char *argv[])
+{
+  GstPipeline *pipeline;
+  GstBus *bus;
+
+  GstElement *srcbin;
+  GstElement *tee;
+  GstElement *queue[N_ACTORS], *sink[N_ACTORS];
+  GstElement *upload[N_ACTORS];
+/*
+  GstElement *effect[N_ACTORS];
+*/
+  ClutterActor *stage;
+  GstGLClutterActor *actor[N_ACTORS];
+  Display *disp;
+  Window stage_win;
+  const gchar *desc;
+  gint i;
+  gint ok = FALSE;
+  ClutterInitError clutter_err = CLUTTER_INIT_ERROR_UNKNOWN;
+
+  clutter_err = clutter_init (&argc, &argv);
+  if (clutter_err != CLUTTER_INIT_SUCCESS)
+    g_warning ("Failed to initalize clutter: %d\n", clutter_err);
+
+  gst_init (&argc, &argv);
+
+  disp = clutter_x11_get_default_display ();
+  if (!clutter_x11_has_composite_extension ()) {
+    g_error ("XComposite extension missing");
+  }
+
+  stage = clutter_stage_get_default ();
+  clutter_actor_set_size (CLUTTER_ACTOR (stage),
+      W * COLS + (COLS - 1), H * ROWS + (ROWS - 1));
+
+  stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+  XCompositeRedirectSubwindows (disp, stage_win, CompositeRedirectManual);
+
+  for (i = 0; i < N_ACTORS; i++) {
+    actor[i] = g_new0 (GstGLClutterActor, 1);
+    actor[i]->stage = stage;
+    actor[i]->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0);
+    XMapRaised (disp, actor[i]->win);
+    XSync (disp, FALSE);
+  }
+/*
+  desc = g_strdup_printf ("v4l2src ! "
+                          "video/x-raw, width=640, height=480, framerate=30/1 ! "
+                          "videoscale !"
+                          "video/x-raw, width=%d, height=%d ! "
+                          "identity", W, H);
+*/
+  desc = g_strdup_printf ("videotestsrc ! "
+      "video/x-raw, format=RGB, width=%d, height=%d !" "identity", W, H);
+  pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
+
+  srcbin = gst_parse_bin_from_description (desc, TRUE, NULL);
+  if (!srcbin)
+    g_error ("Source bin creation failed");
+
+  tee = gst_element_factory_make ("tee", NULL);
+
+  gst_bin_add_many (GST_BIN (pipeline), srcbin, tee, NULL);
+
+  for (i = 0; i < N_ACTORS; i++) {
+    queue[i] = gst_element_factory_make ("queue", NULL);
+    upload[i] = gst_element_factory_make ("glupload", NULL);
+/*      effect[i] = gst_element_factory_make ("gleffects", NULL); */
+    sink[i] = gst_element_factory_make ("glimagesink", NULL);
+/*    gst_bin_add_many (GST_BIN (pipeline),
+        queue[i], upload[i], effect[i], sink[i], NULL); */
+    gst_bin_add_many (GST_BIN (pipeline), queue[i], upload[i], sink[i], NULL);
+  }
+
+  gst_element_link_many (srcbin, tee, NULL);
+
+  for (i = 0; i < N_ACTORS; i++) {
+    ok |=
+//        gst_element_link_many (tee, queue[i], upload[i], effect[i], sink[i],
+        gst_element_link_many (tee, queue[i], upload[i], sink[i], NULL);
+  }
+
+  if (!ok)
+    g_error ("Failed to link one or more elements");
+
+/*
+  for (i = 0; i < N_ACTORS; i++) {
+    g_message ("setting effect %d on %s", i + 1,
+        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));
+
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, actor,
+      NULL);
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  clutter_actor_show_all (stage);
+
+  clutter_main ();
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  return 0;
+}
diff --git a/tests/examples/gl/clutter/cluttershare.c b/tests/examples/gl/clutter/cluttershare.c
new file mode 100644 (file)
index 0000000..d3f1b1e
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <GL/gl.h>
+
+#define CLUTTER_VERSION_MIN_REQUIRED CLUTTER_VERSION_1_8
+#define CLUTTER_VERSION_MAX_ALLOWED CLUTTER_VERSION_1_10
+#define COGL_VERSION_MIN_REQUIRED COGL_VERSION_1_16
+#define COGL_VERSION_MAX_ALLOWED COGL_VERSION_1_18
+#include <clutter/clutter.h>
+#ifndef WIN32
+#include <clutter/x11/clutter-x11.h>
+#include <GL/glx.h>
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/gl/gstglmemory.h>
+
+/* This example shows how to use textures that come from a
+ * gst-plugins-gl pipeline, into the clutter framework
+ * It requires at least clutter 0.8.6
+ */
+
+/* rotation */
+static void
+on_new_frame (ClutterTimeline * timeline, gint msecs, gpointer data)
+{
+  ClutterActor *rect_actor = CLUTTER_ACTOR (data);
+  ClutterActor *texture_actor =
+      g_object_get_data (G_OBJECT (timeline), "texture_actor");
+
+  clutter_actor_set_rotation (rect_actor, CLUTTER_Z_AXIS,
+      60.0 * (gdouble) msecs / 1000.0, clutter_actor_get_width (rect_actor) / 2,
+      clutter_actor_get_height (rect_actor) / 2, 0);
+
+  clutter_actor_set_rotation (texture_actor, CLUTTER_Z_AXIS,
+      60.0 * (gdouble) msecs / 1000.0,
+      clutter_actor_get_width (texture_actor) / 6,
+      clutter_actor_get_height (texture_actor) / 6, 0);
+}
+
+
+/* clutter scene */
+static ClutterActor *
+setup_stage (ClutterStage * stage)
+{
+  ClutterTimeline *timeline = NULL;
+  ClutterActor *texture_actor = NULL;
+  ClutterColor rect_color = { 125, 50, 200, 255 };
+  ClutterActor *rect_actor = NULL;
+
+  /* texture actor */
+
+  texture_actor = clutter_texture_new ();
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture_actor);
+  clutter_actor_set_position (texture_actor, 300, 170);
+  clutter_actor_set_scale (texture_actor, 0.6, 0.6);
+  clutter_actor_show (texture_actor);
+  g_object_set_data (G_OBJECT (texture_actor), "stage", stage);
+
+  /* rectangle actor */
+
+  rect_actor = clutter_rectangle_new_with_color (&rect_color);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect_actor);
+  clutter_actor_set_size (rect_actor, 50, 50);
+  clutter_actor_set_position (rect_actor, 300, 300);
+  clutter_actor_show (rect_actor);
+
+  /* timeline */
+
+  timeline = clutter_timeline_new (6000);
+  g_object_set_data (G_OBJECT (timeline), "texture_actor", texture_actor);
+  clutter_timeline_set_loop (timeline, TRUE);
+  clutter_timeline_start (timeline);
+  g_signal_connect (timeline, "new-frame", G_CALLBACK (on_new_frame),
+      rect_actor);
+
+  return texture_actor;
+}
+
+/* put a gst gl buffer in the texture actor */
+static gboolean
+update_texture_actor (gpointer data)
+{
+  ClutterTexture *texture_actor = (ClutterTexture *) data;
+  GAsyncQueue *queue_input_buf =
+      g_object_get_data (G_OBJECT (texture_actor), "queue_input_buf");
+  GAsyncQueue *queue_output_buf =
+      g_object_get_data (G_OBJECT (texture_actor), "queue_output_buf");
+  GstBuffer *inbuf = g_async_queue_pop (queue_input_buf);
+  ClutterActor *stage = g_object_get_data (G_OBJECT (texture_actor), "stage");
+  CoglHandle cogl_texture = 0;
+  GstVideoMeta *v_meta;
+  GstVideoInfo info;
+  GstVideoFrame frame;
+  guint tex_id;
+
+  v_meta = gst_buffer_get_video_meta (inbuf);
+  if (!v_meta) {
+    g_warning ("Required Meta was not found on buffers");
+    return FALSE;
+  }
+
+  gst_video_info_set_format (&info, v_meta->format, v_meta->width,
+      v_meta->height);
+
+  if (!gst_video_frame_map (&frame, &info, inbuf, GST_MAP_READ | GST_MAP_GL)) {
+    g_warning ("Failed to map video frame");
+    return FALSE;
+  }
+
+  if (!gst_is_gl_memory (frame.map[0].memory)) {
+    g_warning ("Input buffer does not have GLMemory");
+    gst_video_frame_unmap (&frame);
+    return FALSE;
+  }
+
+  tex_id = *(guint *) frame.data[0];
+
+  /* Create a cogl texture from the gst gl texture */
+  glEnable (GL_TEXTURE_2D);
+  glBindTexture (GL_TEXTURE_2D, tex_id);
+  if (glGetError () != GL_NO_ERROR)
+    g_debug ("failed to bind texture that comes from gst-gl\n");
+  cogl_texture = cogl_texture_new_from_foreign (tex_id,
+      GL_TEXTURE_2D, v_meta->width, v_meta->height, 0, 0,
+      COGL_PIXEL_FORMAT_RGBA_8888);
+  glBindTexture (GL_TEXTURE_2D, 0);
+
+  gst_video_frame_unmap (&frame);
+
+  /* Previous cogl texture is replaced and so its ref counter discreases to 0.
+   * According to the source code, glDeleteTexture is not called when the previous
+   * ref counter of the previous cogl texture is reaching 0 because is_foreign is TRUE */
+  clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (texture_actor),
+      cogl_texture);
+  cogl_handle_unref (cogl_texture);
+
+  /* we can now show the clutter scene if not yet visible */
+  if (!CLUTTER_ACTOR_IS_VISIBLE (stage))
+    clutter_actor_show_all (stage);
+
+  /* push buffer so it can be unref later */
+  g_async_queue_push (queue_output_buf, inbuf);
+
+  return FALSE;
+}
+
+
+/* fakesink handoff callback */
+static void
+on_gst_buffer (GstElement * element, GstBuffer * buf, GstPad * pad,
+    ClutterActor * texture_actor)
+{
+  GAsyncQueue *queue_input_buf = NULL;
+  GAsyncQueue *queue_output_buf = NULL;
+
+  /* ref then push buffer to use it in clutter */
+  gst_buffer_ref (buf);
+  queue_input_buf =
+      g_object_get_data (G_OBJECT (texture_actor), "queue_input_buf");
+  g_async_queue_push (queue_input_buf, buf);
+  if (g_async_queue_length (queue_input_buf) > 2)
+    clutter_threads_add_idle_full (G_PRIORITY_HIGH, update_texture_actor,
+        texture_actor, NULL);
+
+  /* pop then unref buffer we have finished to use in clutter */
+  queue_output_buf =
+      g_object_get_data (G_OBJECT (texture_actor), "queue_output_buf");
+  if (g_async_queue_length (queue_output_buf) > 2) {
+    GstBuffer *buf_old = g_async_queue_pop (queue_output_buf);
+    gst_buffer_unref (buf_old);
+  }
+}
+
+/* gst bus signal watch callback */
+static void
+end_stream_cb (GstBus * bus, GstMessage * msg, gpointer data)
+{
+  switch (GST_MESSAGE_TYPE (msg)) {
+
+    case GST_MESSAGE_EOS:
+      g_print ("End-of-stream\n");
+      g_print
+          ("For more information, try to run: GST_DEBUG=gldisplay:2 ./cluttershare\n");
+      break;
+
+    case GST_MESSAGE_ERROR:
+    {
+      gchar *debug = NULL;
+      GError *err = NULL;
+
+      gst_message_parse_error (msg, &err, &debug);
+
+      g_print ("Error: %s\n", err->message);
+      g_error_free (err);
+
+      if (debug) {
+        g_print ("Debug deails: %s\n", debug);
+        g_free (debug);
+      }
+
+      break;
+    }
+
+    default:
+      break;
+  }
+
+  clutter_main_quit ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  ClutterInitError clutter_err = CLUTTER_INIT_ERROR_UNKNOWN;
+#ifdef WIN32
+  HGLRC clutter_gl_context = 0;
+  HDC clutter_dc = 0;
+#else
+  Display *clutter_display = NULL;
+  Window clutter_win = 0;
+  GLXContext clutter_gl_context = NULL;
+#endif
+  GstPipeline *pipeline = NULL;
+  GstBus *bus = NULL;
+  GstElement *glfilter = NULL;
+  GstState state = 0;
+  ClutterActor *stage = NULL;
+  ClutterActor *clutter_texture = NULL;
+  GAsyncQueue *queue_input_buf = NULL;
+  GAsyncQueue *queue_output_buf = NULL;
+  GstElement *fakesink = NULL;
+
+  /* init gstreamer then clutter */
+
+  gst_init (&argc, &argv);
+  clutter_threads_init ();
+  clutter_err = clutter_init (&argc, &argv);
+  if (clutter_err != CLUTTER_INIT_SUCCESS)
+    g_warning ("Failed to initalize clutter: %d\n", clutter_err);
+  clutter_threads_enter ();
+  g_print ("clutter version: %s\n", CLUTTER_VERSION_S);
+  clutter_set_default_frame_rate (2);
+
+  /* avoid to dispatch unecesary events */
+  clutter_ungrab_keyboard ();
+  clutter_ungrab_pointer ();
+
+  /* retrieve and turn off clutter opengl context */
+  stage = clutter_stage_get_default ();
+
+#ifdef WIN32
+  clutter_gl_context = wglGetCurrentContext ();
+  clutter_dc = wglGetCurrentDC ();
+  wglMakeCurrent (0, 0);
+#else
+  clutter_display = clutter_x11_get_default_display ();
+  clutter_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+  clutter_gl_context = glXGetCurrentContext ();
+  glXMakeCurrent (clutter_display, None, 0);
+#endif
+
+  /* setup gstreamer pipeline */
+
+  pipeline =
+      GST_PIPELINE (gst_parse_launch
+      ("videotestsrc ! video/x-raw, width=320, height=240, framerate=(fraction)30/1 ! "
+          "gleffects effect=5 ! glfiltercube ! fakesink sync=1", NULL));
+
+  /* setup bus */
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  gst_bus_add_signal_watch (bus);
+  g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), NULL);
+  g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), NULL);
+  g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), NULL);
+  gst_object_unref (bus);
+
+  /* clutter_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */
+  glfilter = gst_bin_get_by_name (GST_BIN (pipeline), "glfiltercube0");
+  g_object_set (G_OBJECT (glfilter), "external-opengl-context",
+      clutter_gl_context, NULL);
+  gst_object_unref (glfilter);
+
+  /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and
+   * shared with the clutter one */
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
+  state = GST_STATE_PAUSED;
+  if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
+          GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
+    g_debug ("failed to pause pipeline\n");
+    return -1;
+  }
+
+  /* turn on back clutter opengl context */
+#ifdef WIN32
+  wglMakeCurrent (clutter_dc, clutter_gl_context);
+#else
+  glXMakeCurrent (clutter_display, clutter_win, clutter_gl_context);
+#endif
+
+  /* clutter stage */
+  clutter_actor_set_size (stage, 640, 480);
+  clutter_actor_set_position (stage, 0, 0);
+  clutter_stage_set_title (CLUTTER_STAGE (stage), "clutter and gst-plugins-gl");
+  clutter_texture = setup_stage (CLUTTER_STAGE (stage));
+
+  /* append a gst-gl texture to this queue when you do not need it no more */
+  queue_input_buf = g_async_queue_new ();
+  queue_output_buf = g_async_queue_new ();
+  g_object_set_data (G_OBJECT (clutter_texture), "queue_input_buf",
+      queue_input_buf);
+  g_object_set_data (G_OBJECT (clutter_texture), "queue_output_buf",
+      queue_output_buf);
+
+  /* set a callback to retrieve the gst gl textures */
+  fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
+  g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
+  g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer),
+      clutter_texture);
+  gst_object_unref (fakesink);
+
+  /* play gst */
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  /* main loop */
+  clutter_main ();
+
+  /* before to deinitialize the gst-gl-opengl context,
+   * no shared context (here the clutter one) must be current
+   */
+#ifdef WIN32
+  wglMakeCurrent (0, 0);
+#else
+  glXMakeCurrent (clutter_display, None, 0);
+#endif
+
+  clutter_threads_leave ();
+
+  /* stop and clean up the pipeline */
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  /* make sure there is no pending gst gl buffer in the communication queues
+   * between clutter and gst-gl
+   */
+  while (g_async_queue_length (queue_input_buf) > 0) {
+    GstBuffer *buf = g_async_queue_pop (queue_input_buf);
+    gst_buffer_unref (buf);
+  }
+
+  while (g_async_queue_length (queue_output_buf) > 0) {
+    GstBuffer *buf = g_async_queue_pop (queue_output_buf);
+    gst_buffer_unref (buf);
+  }
+
+  g_print ("END\n");
+
+  return 0;
+}
diff --git a/tests/examples/gl/clutter/cluttershare.cbp b/tests/examples/gl/clutter/cluttershare.cbp
new file mode 100644 (file)
index 0000000..cb4907e
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+       <FileVersion major="1" minor="6" />
+       <Project>
+               <Option title="cluttershare" />
+               <Option pch_mode="2" />
+               <Option compiler="gcc" />
+               <Build>
+                       <Target title="Debug">
+                               <Option output="bin\Debug\cluttershare" prefix_auto="1" extension_auto="1" />
+                               <Option object_output="obj\Debug\" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Compiler>
+                                       <Add option="-g" />
+                               </Compiler>
+                       </Target>
+                       <Target title="Release">
+                               <Option output="bin\Release\cluttershare" prefix_auto="1" extension_auto="1" />
+                               <Option object_output="obj\Release\" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Compiler>
+                                       <Add option="-O2" />
+                               </Compiler>
+                               <Linker>
+                                       <Add option="-s" />
+                               </Linker>
+                       </Target>
+               </Build>
+               <Compiler>
+                       <Add option="-Wall" />
+                       <Add option="-ansi" />
+                       <Add option="-std=c89" />
+                       <Add option="-DWIN32" />
+                       <Add directory="..\..\..\..\clutter\include\clutter-0.8" />
+                       <Add directory="C:\gstreamer\include\glib-2.0" />
+                       <Add directory="C:\gstreamer\lib\glib-2.0\include" />
+                       <Add directory="C:\gstreamer\include\gstreamer-1.0" />
+                       <Add directory="C:\gstreamer\include\pango-1.0" />
+                       <Add directory="C:\gstreamer\include\cairo" />
+                       <Add directory="C:\gstreamer\include\libxml2" />
+                       <Add directory="C:\gstreamer\include" />
+               </Compiler>
+               <Linker>
+                       <Add library="clutter-win32-0.8" />
+                       <Add library="gio-2.0" />
+                       <Add library="gthread-2.0" />
+                       <Add library="gobject-2.0" />
+                       <Add library="gstreamer-1.0" />
+                       <Add library="gmodule-2.0" />
+                       <Add library="gstvideo-1.0" />
+                       <Add library="glib-2.0" />
+                       <Add library="pangocairo-1.0" />
+                       <Add library="pangowin32-1.0" />
+                       <Add library="pango-1.0" />
+                       <Add library="gdk_pixbuf-2.0" />
+                       <Add library="cairo" />
+                       <Add library="glu32" />
+                       <Add library="opengl32" />
+                       <Add library="gdi32" />
+                       <Add library="winmm" />
+                       <Add directory="..\..\..\..\clutter\lib" />
+                       <Add directory="C:\gstreamer\lib" />
+                       <Add directory="C:\gstreamer\bin" />
+                       <Add directory="..\..\..\..\gtk+\lib" />
+               </Linker>
+               <Unit filename="cluttershare.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Extensions>
+                       <code_completion />
+                       <debugger />
+               </Extensions>
+       </Project>
+</CodeBlocks_project_file>
diff --git a/tests/examples/gl/cocoa/Makefile.am b/tests/examples/gl/cocoa/Makefile.am
new file mode 100755 (executable)
index 0000000..716aa30
--- /dev/null
@@ -0,0 +1,4 @@
+
+if HAVE_WINDOW_COCOA
+SUBDIRS = videooverlay
+endif
diff --git a/tests/examples/gl/cocoa/README b/tests/examples/gl/cocoa/README
new file mode 100644 (file)
index 0000000..74fe337
--- /dev/null
@@ -0,0 +1,9 @@
+--- Description of the Cocoa examples ---
+
+- videooverlay:
+Show how to use the videooverlay interface through Cocoa.
+For now, the source is videotestsrc. (not yet a video file)
+
+--- How to build the Cocoa examples on GNUstep environnements ---
+
+make clean all -f GNUmakefile.gnustep
diff --git a/tests/examples/gl/cocoa/videooverlay/.gitignore b/tests/examples/gl/cocoa/videooverlay/.gitignore
new file mode 100644 (file)
index 0000000..c5ee310
--- /dev/null
@@ -0,0 +1 @@
+videooverlay
diff --git a/tests/examples/gl/cocoa/videooverlay/Makefile.am b/tests/examples/gl/cocoa/videooverlay/Makefile.am
new file mode 100755 (executable)
index 0000000..47dac61
--- /dev/null
@@ -0,0 +1,14 @@
+if HAVE_WINDOW_COCOA
+
+noinst_PROGRAMS = videooverlay
+
+videooverlay_SOURCES = main.m
+
+videooverlay_OBJCFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       $(GL_CFLAGS) -I/usr/local/include/gstreamer-${GST_API_VERSION} ${GL_OBJCFLAGS}
+videooverlay_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
+
+videooverlay_LIBTOOLFLAGS = --tag=OBJC
+
+endif
diff --git a/tests/examples/gl/cocoa/videooverlay/main.m b/tests/examples/gl/cocoa/videooverlay/main.m
new file mode 100755 (executable)
index 0000000..8f959fe
--- /dev/null
@@ -0,0 +1,240 @@
+#include <Cocoa/Cocoa.h>
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+
+/* ============================================================= */
+/*                                                               */
+/*                          MainWindow                           */
+/*                                                               */
+/* ============================================================= */
+
+@interface MainWindow: NSWindow {
+  GMainLoop *m_loop;
+  GstElement *m_pipeline;
+  gboolean m_isClosed;
+}
+- (id) initWithContentRect:(NSRect) contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline;
+- (GMainLoop*) loop;
+- (GstElement*) pipeline;
+- (gboolean) isClosed;
+@end
+
+@implementation MainWindow
+
+- (id) initWithContentRect:(NSRect)contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline
+{
+  m_loop = loop;
+  m_pipeline = pipeline;
+  m_isClosed = FALSE;
+
+  self = [super initWithContentRect: contentRect
+               styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask)
+    backing: NSBackingStoreBuffered defer: NO screen: nil];
+
+  [self setReleasedWhenClosed:NO];
+  [NSApp setDelegate:self];
+
+  [self setTitle:@"gst-plugins-gl implements videooverlay interface"];
+
+  return self;
+}
+
+- (GMainLoop*) loop {
+  return m_loop;
+}
+
+- (GstElement*) pipeline {
+  return m_pipeline;
+}
+
+- (gboolean) isClosed {
+  return m_isClosed;
+}
+
+- (void) customClose {
+  m_isClosed = TRUE;
+}
+
+- (BOOL) windowShouldClose:(id)sender {
+  gst_element_send_event (m_pipeline, gst_event_new_eos ());
+  return YES;
+}
+
+- (void) applicationDidFinishLaunching: (NSNotification *) not {
+  [self makeMainWindow];
+  [self center];
+  [self orderFront:self];
+}
+
+- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {
+  return NO;
+}
+
+@end
+
+
+/* ============================================================= */
+/*                                                               */
+/*                   gstreamer callbacks                         */
+/*                                                               */
+/* ============================================================= */
+
+
+static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, MainWindow* window)
+{
+  // ignore anything but 'prepare-window-handle' element messages
+  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+    return GST_BUS_PASS;
+
+  if (!gst_is_video_overlay_prepare_window_handle_message (message))
+    return GST_BUS_PASS;
+
+  g_print ("setting window handle %lud\n", (gulong) window);
+
+  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr) window);
+
+  gst_message_unref (message);
+
+  return GST_BUS_DROP;
+}
+
+
+static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+  g_print ("end of stream\n");
+
+  gst_element_set_state ([window pipeline], GST_STATE_NULL);
+  gst_object_unref ([window pipeline]);
+  g_main_loop_quit ([window loop]);
+
+  [window performSelectorOnMainThread:@selector(customClose) withObject:nil waitUntilDone:YES];
+
+  [pool release];
+}
+
+static gpointer thread_func (MainWindow* window)
+{
+#ifdef GNUSTEP
+  GSRegisterCurrentThread();
+#endif
+
+  g_main_loop_run ([window loop]);
+
+#ifdef GNUSTEP
+  GSUnregisterCurrentThread();
+#endif
+  return NULL;
+}
+
+
+/* ============================================================= */
+/*                                                               */
+/*                         application                           */
+/*                                                               */
+/* ============================================================= */
+
+int main(int argc, char **argv)
+{
+       int width = 640;
+  int height = 480;
+
+  GMainLoop *loop = NULL;
+  GstElement *pipeline = NULL;
+
+  GstElement *videosrc  = NULL;
+  GstElement *videosink = NULL;
+  GstCaps *caps=NULL;
+  gboolean ok=FALSE;
+  GstBus *bus=NULL;
+  GThread *loop_thread=NULL;
+  NSAutoreleasePool *pool=nil;
+  NSRect rect;
+  MainWindow *window=nil;
+  
+#ifdef GNUSTEP
+  GstState state;
+#endif
+
+  g_print("app created\n");
+
+  gst_init (&argc, &argv);
+
+  loop = g_main_loop_new (NULL, FALSE);
+  pipeline = gst_pipeline_new ("pipeline");
+
+  videosrc  = gst_element_factory_make ("videotestsrc", "videotestsrc");
+  videosink = gst_element_factory_make ("glimagesink", "glimagesink");
+
+  g_object_set(G_OBJECT(videosrc), "num-buffers", 500, NULL);
+
+  gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
+
+  caps = gst_caps_new_simple("video/x-raw",
+    "width", G_TYPE_INT, width,
+    "height", G_TYPE_INT, height,
+    "framerate", GST_TYPE_FRACTION, 25, 1,
+    "format", G_TYPE_STRING, "I420",
+    NULL);
+
+  ok = gst_element_link_filtered(videosrc, videosink, caps);
+  gst_caps_unref(caps);
+  if (!ok)
+    g_warning("could not link videosrc to videosink\n");
+
+#ifdef GNUSTEP
+  gst_element_set_state (pipeline, GST_STATE_PAUSED);
+  state = GST_STATE_PAUSED;
+  gst_element_get_state (pipeline, &state, &state, GST_CLOCK_TIME_NONE);
+  g_print("pipeline paused\n");
+  GSRegisterCurrentThread();
+#endif
+
+  pool = [[NSAutoreleasePool alloc] init];
+#ifndef GNUSTEP
+  [NSApplication sharedApplication];
+#endif
+
+  rect.origin.x = 0; rect.origin.y = 0;
+  rect.size.width = width; rect.size.height = height;
+
+  window = [[MainWindow alloc] initWithContentRect:rect Loop:loop Pipeline:pipeline];
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  gst_bus_add_signal_watch (bus);
+  g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), window);
+  g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), window);
+  g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), window);
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, window, NULL);
+  gst_object_unref (bus);
+
+  loop_thread = g_thread_new (NULL,
+      (GThreadFunc) thread_func, window);
+
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  [window orderFront:window];
+
+#ifndef GNUSTEP
+  while (![window isClosed]) {
+    NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
+      untilDate:[NSDate dateWithTimeIntervalSinceNow:1]
+      inMode:NSDefaultRunLoopMode dequeue:YES];
+    if (event)
+      [NSApp sendEvent:event];
+  }
+#endif
+
+  g_thread_join (loop_thread);
+
+  [window release];
+
+  [pool release];
+
+#ifdef GNUSTEP
+  GSUnregisterCurrentThread();
+#endif
+
+  return 0;
+}
diff --git a/tests/examples/gl/generic/Makefile.am b/tests/examples/gl/generic/Makefile.am
new file mode 100644 (file)
index 0000000..a334e12
--- /dev/null
@@ -0,0 +1,2 @@
+
+SUBDIRS = cube cubeyuv doublecube recordgraphic
diff --git a/tests/examples/gl/generic/README b/tests/examples/gl/generic/README
new file mode 100644 (file)
index 0000000..a91d6bf
--- /dev/null
@@ -0,0 +1,21 @@
+--- Description of the generic (no GUI) examples ---
+
+- cube:
+Show how to have a graphic FPS greater than the input video frame rate.
+The source is the videotestsrc rgb.
+
+- cubeyuv:
+Show how to have a graphic FPS greater than the input video frame rate.
+The source is a local video file needed in argument.
+The colorspace conversion is maded by the glupload element.
+
+- doublecube:
+A local video source is displayed into two renderers.
+The first one is a normal 2D screen, the second is a 3D cube.
+We can visually check that the video is displayed at the same speed
+in the two renderers.
+
+- recordgraphic:
+Show how to use the glfilterapp to define the draw callback in a gstreamer client code.
+The scene is recorded into an avi file using mpeg4 encoder.
+The colorspace conversion is made by the gldownload element.
diff --git a/tests/examples/gl/generic/cube/.gitignore b/tests/examples/gl/generic/cube/.gitignore
new file mode 100644 (file)
index 0000000..3c088dd
--- /dev/null
@@ -0,0 +1 @@
+cube
diff --git a/tests/examples/gl/generic/cube/Makefile.am b/tests/examples/gl/generic/cube/Makefile.am
new file mode 100644 (file)
index 0000000..41a5e2c
--- /dev/null
@@ -0,0 +1,8 @@
+
+noinst_PROGRAMS = cube
+
+cube_SOURCES = main.cpp
+
+cube_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
+cube_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)
+
diff --git a/tests/examples/gl/generic/cube/cube.vcproj b/tests/examples/gl/generic/cube/cube.vcproj
new file mode 100644 (file)
index 0000000..aefb6ad
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="cube"
+       ProjectGUID="{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}"
+       RootNamespace="cube"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/generic/cube/main.cpp b/tests/examples/gl/generic/cube/main.cpp
new file mode 100644 (file)
index 0000000..b3b167c
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#if __WIN32__ || _WIN32
+# include <GL/glext.h>
+#endif
+#include <gst/gst.h>
+
+#include <iostream>
+#include <string>
+
+static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+    GMainLoop *loop = (GMainLoop*)data;
+
+    switch (GST_MESSAGE_TYPE (msg))
+    {
+        case GST_MESSAGE_EOS:
+              g_print ("End-of-stream\n");
+              g_main_loop_quit (loop);
+              break;
+        case GST_MESSAGE_ERROR:
+          {
+              gchar *debug = NULL;
+              GError *err = NULL;
+
+              gst_message_parse_error (msg, &err, &debug);
+
+              g_print ("Error: %s\n", err->message);
+              g_error_free (err);
+
+              if (debug)
+              {
+                  g_print ("Debug deails: %s\n", debug);
+                  g_free (debug);
+              }
+
+              g_main_loop_quit (loop);
+              break;
+          }
+        default:
+          break;
+    }
+
+    return TRUE;
+}
+
+//client reshape callback
+static void reshapeCallback (GLuint width, GLuint height, gpointer data)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+//client draw callback
+
+static gboolean drawCallback (GLuint texture, GLuint width, GLuint height, gpointer data)
+{
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;
+    static GLfloat     zrot = 0;
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(xrot,1.0f,0.0f,0.0f);
+    glRotatef(yrot,0.0f,1.0f,0.0f);
+    glRotatef(zrot,0.0f,0.0f,1.0f);
+
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd();
+
+    xrot+=0.3f;
+    yrot+=0.2f;
+    zrot+=0.4f;
+
+    //return TRUE causes a postRedisplay
+    return TRUE;
+}
+
+
+//gst-launch-1.0 videotestsrc num_buffers=400 ! video/x-raw, width=320, height=240 !
+//glgraphicmaker ! glfiltercube ! video/x-raw, width=800, height=600 ! glimagesink
+gint main (gint argc, gchar *argv[])
+{
+    GstStateChangeReturn ret;
+    GstElement *pipeline, *videosrc, *glimagesink;
+
+    GMainLoop *loop;
+    GstBus *bus;
+
+    /* initialization */
+    gst_init (&argc, &argv);
+    loop = g_main_loop_new (NULL, FALSE);
+
+    /* create elements */
+    pipeline = gst_pipeline_new ("pipeline");
+
+    /* watch for messages on the pipeline's bus (note that this will only
+     * work like this when a GLib main loop is running) */
+    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_watch (bus, bus_call, loop);
+    gst_object_unref (bus);
+
+    /* create elements */
+    videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
+    glimagesink  = gst_element_factory_make ("glimagesink", "glimagesink0");
+
+
+    if (!videosrc || !glimagesink)
+    {
+        g_print ("one element could not be found \n");
+        return -1;
+    }
+
+    /* change video source caps */
+    GstCaps *caps = gst_caps_new_simple("video/x-raw",
+                                        "format", G_TYPE_STRING, "RGB",
+                                        "width", G_TYPE_INT, 320,
+                                        "height", G_TYPE_INT, 240,
+                                        "framerate", GST_TYPE_FRACTION, 25, 1,
+                                        NULL) ;
+
+    /* configure elements */
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
+    g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
+    g_object_set(G_OBJECT(glimagesink), "client-data", NULL, NULL);
+
+    /* add elements */
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, glimagesink, NULL);
+
+    /* link elements */
+    gboolean link_ok = gst_element_link_filtered(videosrc, glimagesink, caps) ;
+    gst_caps_unref(caps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link videosrc to glimagesink!\n") ;
+        return -1 ;
+    }
+
+    /* run */
+    ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        g_print ("Failed to start up pipeline!\n");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+        if (msg)
+        {
+          GError *err = NULL;
+
+          gst_message_parse_error (msg, &err, NULL);
+          g_print ("ERROR: %s\n", err->message);
+          g_error_free (err);
+          gst_message_unref (msg);
+        }
+        return -1;
+    }
+
+    g_main_loop_run (loop);
+
+    /* clean up */
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+
+    return 0;
+
+}
diff --git a/tests/examples/gl/generic/cubeyuv/.gitignore b/tests/examples/gl/generic/cubeyuv/.gitignore
new file mode 100644 (file)
index 0000000..bd5c0ce
--- /dev/null
@@ -0,0 +1 @@
+cubeyuv
diff --git a/tests/examples/gl/generic/cubeyuv/Makefile.am b/tests/examples/gl/generic/cubeyuv/Makefile.am
new file mode 100644 (file)
index 0000000..0fe4fcd
--- /dev/null
@@ -0,0 +1,8 @@
+
+noinst_PROGRAMS = cubeyuv
+
+cubeyuv_SOURCES = main.cpp
+
+cubeyuv_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
+cubeyuv_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)
+
diff --git a/tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj b/tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj
new file mode 100644 (file)
index 0000000..1d20859
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="cubeyuv"
+       ProjectGUID="{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}"
+       RootNamespace="cubeyuv"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/generic/cubeyuv/main.cpp b/tests/examples/gl/generic/cubeyuv/main.cpp
new file mode 100644 (file)
index 0000000..6e17b6a
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#if __WIN32__ || _WIN32
+# include <GL/glext.h>
+#endif
+#include <gst/gst.h>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+    GMainLoop *loop = (GMainLoop*)data;
+
+    switch (GST_MESSAGE_TYPE (msg)) 
+    {
+        case GST_MESSAGE_EOS:
+              g_print ("End-of-stream\n");
+              g_main_loop_quit (loop);
+              break;
+        case GST_MESSAGE_ERROR: 
+          {
+              gchar *debug = NULL;
+              GError *err = NULL;
+
+              gst_message_parse_error (msg, &err, &debug);
+
+              g_print ("Error: %s\n", err->message);
+              g_error_free (err);
+
+              if (debug) 
+              {
+                  g_print ("Debug deails: %s\n", debug);
+                  g_free (debug);
+              }
+
+              g_main_loop_quit (loop);
+              break;
+          } 
+        default:
+          break;
+    }
+
+    return TRUE;
+}
+
+
+//display video framerate
+static void identityCallback (GstElement *src, GstBuffer  *buffer, GstElement* textoverlay)
+{
+    static GstClockTime last_timestamp = 0;
+    static gint nbFrames = 0 ;
+
+    //display estimated video FPS 
+    nbFrames++ ;
+    if (GST_BUFFER_TIMESTAMP(buffer) - last_timestamp >= 1000000000)
+    {
+        std::ostringstream oss ;
+        oss << "video framerate = " << nbFrames ;
+        std::string s(oss.str()) ;
+        g_object_set(G_OBJECT(textoverlay), "text", s.c_str(), NULL);
+        last_timestamp = GST_BUFFER_TIMESTAMP(buffer) ;
+        nbFrames = 0 ; 
+    }
+}
+
+
+//client reshape callback
+static void reshapeCallback (GLuint width, GLuint height)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);  
+    glMatrixMode(GL_MODELVIEW);        
+}
+
+
+//client draw callback
+static gboolean drawCallback (GLuint texture, GLuint width, GLuint height)
+{
+    
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;                               
+    static GLfloat     zrot = 0;
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;  
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+    
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+  
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+       
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(xrot,1.0f,0.0f,0.0f);
+    glRotatef(yrot,0.0f,1.0f,0.0f);
+    glRotatef(zrot,0.0f,0.0f,1.0f);
+
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd(); 
+
+       xrot+=0.03f;
+    yrot+=0.02f;
+    zrot+=0.04f;
+
+    //return TRUE causes a postRedisplay
+    //so you have to return FALSE to synchronise to have a graphic FPS
+    //equals to the input video frame rate
+
+    //Usually, we will not always return TRUE (or FALSE)
+    //For example, if you want a fixed graphic FPS equals to 60
+    //then you have to use the timeclock to return TRUE or FALSE
+    //in order to increase or decrease the FPS in real time
+    //to reach the 60.
+
+    return TRUE;
+}
+
+
+static void cb_new_pad (GstElement* decodebin, GstPad* pad, GstElement* identity)
+{
+    GstPad* identity_pad = gst_element_get_static_pad (identity, "sink");
+    
+    //only link once 
+    if (GST_PAD_IS_LINKED (identity_pad)) 
+    {
+        gst_object_unref (identity_pad);
+        return;
+    }
+
+    GstCaps* caps = gst_pad_get_current_caps (pad);
+    GstStructure* str = gst_caps_get_structure (caps, 0);
+    if (!g_strrstr (gst_structure_get_name (str), "video")) 
+    {
+        gst_caps_unref (caps);
+        gst_object_unref (identity_pad);
+        return;
+    }
+    gst_caps_unref (caps);
+
+    GstPadLinkReturn ret = gst_pad_link (pad, identity_pad);
+    if (ret != GST_PAD_LINK_OK) 
+        g_warning ("Failed to link with decodebin!\n");   
+}
+
+
+gint main (gint argc, gchar *argv[])
+{
+    if (argc != 2)
+    {
+        g_warning ("usage: cubeyuv.exe videolocation\n");
+        return -1;
+    }
+    
+    std::string video_location(argv[1]);
+    
+    /* initialization */
+    gst_init (&argc, &argv);
+    GMainLoop* loop = g_main_loop_new (NULL, FALSE);
+
+    /* create elements */
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+
+    /* watch for messages on the pipeline's bus (note that this will only
+     * work like this when a GLib main loop is running) */
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_watch (bus, bus_call, loop);
+    gst_object_unref (bus);
+
+    /* create elements */
+    GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
+    GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin");
+    GstElement* identity  = gst_element_factory_make ("identity", "identity0");
+    GstElement* textoverlay = gst_element_factory_make ("textoverlay", "textoverlay0");
+    GstElement* glcolorscale = gst_element_factory_make ("glcolorscale", "glcolorscale0");
+    GstElement* glimagesink  = gst_element_factory_make ("glimagesink", "glimagesink0");
+
+
+    if (!videosrc || !decodebin || !identity || !textoverlay ||
+        !glcolorscale || !glimagesink)
+    {
+        g_print ("one element could not be found \n");
+        return -1;
+    }
+
+    GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
+                                           "width", G_TYPE_INT, 640,
+                                           "height", G_TYPE_INT, 480,
+                                           NULL);
+
+    /* configure elements */
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
+    g_object_set(G_OBJECT(videosrc), "location", video_location.c_str(), NULL);
+    g_signal_connect(identity, "handoff", G_CALLBACK(identityCallback), textoverlay) ;
+    g_object_set(G_OBJECT(textoverlay), "font_desc", "Ahafoni CLM Bold 30", NULL);
+    g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
+    
+    /* add elements */
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, decodebin, identity,
+        textoverlay, glcolorscale, glimagesink, NULL);
+
+    /* link elements */
+       gst_element_link_pads (videosrc, "src", decodebin, "sink");
+
+    g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), identity);
+
+    if (!gst_element_link_pads(identity, "src", textoverlay, "video_sink")) 
+    {
+        g_print ("Failed to link identity to textoverlay!\n");
+        return -1;
+    }
+
+       gst_element_link (textoverlay, glcolorscale);
+
+    gboolean link_ok = gst_element_link_filtered(glcolorscale, glimagesink, outcaps) ;
+    gst_caps_unref(outcaps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link textoverlay to glimagesink!\n") ;
+        return -1 ;
+    }
+    
+    /* run */
+    GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE) 
+    {
+        g_print ("Failed to start up pipeline!\n");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+        if (msg) 
+        {
+          GError *err = NULL;
+
+          gst_message_parse_error (msg, &err, NULL);
+          g_print ("ERROR: %s\n", err->message);
+          g_error_free (err);
+          gst_message_unref (msg);
+        }
+        return -1;
+    }
+
+    g_main_loop_run (loop);
+
+    /* clean up */
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+
+    return 0;
+
+}
+    
diff --git a/tests/examples/gl/generic/doublecube/.gitignore b/tests/examples/gl/generic/doublecube/.gitignore
new file mode 100644 (file)
index 0000000..e9f4f13
--- /dev/null
@@ -0,0 +1 @@
+doublecube
diff --git a/tests/examples/gl/generic/doublecube/Makefile.am b/tests/examples/gl/generic/doublecube/Makefile.am
new file mode 100644 (file)
index 0000000..7a9184b
--- /dev/null
@@ -0,0 +1,8 @@
+
+noinst_PROGRAMS = doublecube
+
+doublecube_SOURCES = main.cpp
+
+doublecube_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
+doublecube_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)
+
diff --git a/tests/examples/gl/generic/doublecube/doublecube.vcproj b/tests/examples/gl/generic/doublecube/doublecube.vcproj
new file mode 100644 (file)
index 0000000..db0364b
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="doublecube"
+       ProjectGUID="{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}"
+       RootNamespace="doublecube"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/generic/doublecube/main.cpp b/tests/examples/gl/generic/doublecube/main.cpp
new file mode 100644 (file)
index 0000000..4f28336
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#if __WIN32__ || _WIN32
+# include <GL/glext.h>
+#endif
+#include <gst/gst.h>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+    GMainLoop *loop = (GMainLoop*)data;
+
+    switch (GST_MESSAGE_TYPE (msg)) 
+    {
+        case GST_MESSAGE_EOS:
+              g_print ("End-of-stream\n");
+              g_main_loop_quit (loop);
+              break;
+        case GST_MESSAGE_ERROR: 
+          {
+              gchar *debug = NULL;
+              GError *err = NULL;
+
+              gst_message_parse_error (msg, &err, &debug);
+
+              g_print ("Error: %s\n", err->message);
+              g_error_free (err);
+
+              if (debug) 
+              {
+                  g_print ("Debug details: %s\n", debug);
+                  g_free (debug);
+              }
+
+              g_main_loop_quit (loop);
+              break;
+          } 
+        default:
+          break;
+    }
+
+    return TRUE;
+}
+
+
+//display video framerate
+static GstPadProbeReturn textoverlay_sink_pad_probe_cb (GstPad *pad, GstPadProbeInfo *info, GstElement* textoverlay)
+{
+  static GstClockTime last_timestamp = 0;
+  static gint nbFrames = 0 ;
+
+  //display estimated video FPS 
+  nbFrames++ ;
+  if (GST_BUFFER_TIMESTAMP(info->data) - last_timestamp >= 1000000000)
+  {
+    std::ostringstream oss ;
+    oss << "video framerate = " << nbFrames ;
+    std::string s(oss.str()) ;    
+    g_object_set(G_OBJECT(textoverlay), "text", s.c_str(), NULL);
+    last_timestamp = GST_BUFFER_TIMESTAMP(info->data) ;
+    nbFrames = 0 ; 
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
+
+//client reshape callback
+static void reshapeCallback (GLuint width, GLuint height)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);  
+    glMatrixMode(GL_MODELVIEW);        
+}
+
+
+//client draw callback
+static gboolean drawCallback (GLuint texture, GLuint width, GLuint height)
+{
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;                               
+    static GLfloat     zrot = 0;
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;  
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+    
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        std::cout << "GRAPHIC FPS of the scene which contains the custom cube) = " << nbFrames << std::endl;
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+       
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(xrot,1.0f,0.0f,0.0f);
+    glRotatef(yrot,0.0f,1.0f,0.0f);
+    glRotatef(zrot,0.0f,0.0f,1.0f);
+
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd();
+
+    xrot+=0.03f;
+    yrot+=0.02f;
+    zrot+=0.04f;
+
+    //return TRUE causes a postRedisplay
+    //so you have to return FALSE to synchronise to have a graphic FPS
+    //equals to the input video frame rate
+
+    //Usually, we will not always return TRUE (or FALSE)
+    //For example, if you want a fixed graphic FPS equals to 60
+    //then you have to use the timeclock to return TRUE or FALSE
+    //in order to increase or decrease the FPS in real time
+    //to reach the 60.
+
+    return TRUE;
+}
+
+
+static void cb_new_pad (GstElement* decodebin, GstPad* pad, GstElement* element)
+{
+    GstPad* element_pad = gst_element_get_static_pad (element, "sink");
+    
+    //only link once 
+    if (!element_pad || GST_PAD_IS_LINKED (element_pad)) 
+    {
+        gst_object_unref (element_pad);
+        return;
+    }
+
+    GstCaps* caps = gst_pad_get_current_caps (pad);
+    GstStructure* str = gst_caps_get_structure (caps, 0);
+    
+    GstCaps* caps2 = gst_pad_query_caps (element_pad, NULL);
+    gst_caps_unref (caps2);
+    
+    if (!g_strrstr (gst_structure_get_name (str), "video")) 
+    {
+        gst_caps_unref (caps);
+        gst_object_unref (element_pad);
+        return;
+    }
+    gst_caps_unref (caps);
+
+    GstPadLinkReturn ret = gst_pad_link (pad, element_pad);
+    if (ret != GST_PAD_LINK_OK) 
+        g_warning ("Failed to link with decodebin %d!\n", ret);
+    gst_object_unref (element_pad);
+}
+
+
+gint main (gint argc, gchar *argv[])
+{
+
+    if (argc != 2)
+    {
+        g_warning ("usage: doublecube.exe videolocation\n");
+        return -1;
+    }
+    
+    std::string video_location(argv[1]);
+
+    /* initialization */
+    gst_init (&argc, &argv);
+    GMainLoop* loop = g_main_loop_new (NULL, FALSE);
+
+    /* create elements */
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+
+    /* watch for messages on the pipeline's bus (note that this will only
+     * work like this when a GLib main loop is running) */
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_watch (bus, bus_call, loop);
+    gst_object_unref (bus);
+
+    /* create elements */
+    GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
+    GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
+    GstElement* videoconvert = gst_element_factory_make ("videoscale", "videoconvert0");
+    GstElement* textoverlay = gst_element_factory_make ("textoverlay", "textoverlay0"); //textoverlay required I420
+    GstElement* tee = gst_element_factory_make ("tee", "tee0");
+
+    GstElement* queue0 = gst_element_factory_make ("queue", "queue0");
+    GstElement* glimagesink0  = gst_element_factory_make ("glimagesink", "glimagesink0");
+
+    GstElement* queue1 = gst_element_factory_make ("queue", "queue1");
+    GstElement* glfiltercube  = gst_element_factory_make ("glfiltercube", "glfiltercube");
+    GstElement* glimagesink1  = gst_element_factory_make ("glimagesink", "glimagesink1");
+
+    GstElement* queue2 = gst_element_factory_make ("queue", "queue2");
+    GstElement* glimagesink2  = gst_element_factory_make ("glimagesink", "glimagesink2");
+
+
+    if (!videosrc || !decodebin || !videoconvert || !textoverlay || !tee ||
+        !queue0 || !glimagesink0 ||
+        !queue1 || !glfiltercube || !glimagesink1 ||
+        !queue2 || !glimagesink2) 
+    {
+        g_warning ("one element could not be found \n");
+        return -1;
+    }
+
+    GstCaps* cubecaps = gst_caps_new_simple("video/x-raw",
+                                            "width", G_TYPE_INT, 600,
+                                            "height", G_TYPE_INT, 400,
+                                            NULL);
+
+    /* configure elements */
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 1000, NULL);
+    g_object_set(G_OBJECT(videosrc), "location", video_location.c_str(), NULL);
+    g_object_set(G_OBJECT(textoverlay), "font_desc", "Ahafoni CLM Bold 30", NULL);
+    g_object_set(G_OBJECT(glimagesink0), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(glimagesink0), "client-draw-callback", drawCallback, NULL);
+    
+    /* add elements */
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, decodebin, videoconvert, textoverlay, tee, 
+                                          queue0, glimagesink0,
+                                          queue1, glfiltercube, glimagesink1, 
+                                          queue2, glimagesink2, NULL);
+    
+    GstPad* textoverlay_sink_pad = gst_element_get_static_pad (textoverlay, "video_sink");
+    gst_pad_add_probe (textoverlay_sink_pad, GST_PAD_PROBE_TYPE_BUFFER, 
+                       (GstPadProbeCallback) textoverlay_sink_pad_probe_cb, (gpointer)textoverlay, NULL);
+    gst_object_unref (textoverlay_sink_pad);
+
+    if (!gst_element_link_many(videoconvert, textoverlay, tee, NULL)) 
+    {
+        g_print ("Failed to link videoconvert to tee!\n");
+        return -1;
+    }
+
+    if (!gst_element_link(videosrc, decodebin)) 
+    {
+        g_print ("Failed to link videosrc to decodebin!\n");
+        return -1;
+    }
+
+    g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), videoconvert);
+    
+    if (!gst_element_link_many(tee, queue0, NULL)) 
+    {
+        g_warning ("Failed to link one or more elements bettween tee and queue0!\n");
+        return -1;
+    }
+
+    gboolean link_ok = gst_element_link_filtered(queue0, glimagesink0, cubecaps) ;
+    gst_caps_unref(cubecaps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link queue0 to glimagesink0!\n") ;
+        return -1 ;
+    }
+
+    if (!gst_element_link_many(tee, queue1, glfiltercube, glimagesink1, NULL)) 
+    {
+        g_warning ("Failed to link one or more elements bettween tee and glimagesink1!\n");
+        return -1;
+    }
+
+    if (!gst_element_link_many(tee, queue2, glimagesink2, NULL)) 
+    {
+        g_warning ("Failed to link one or more elements bettween tee and glimagesink2!\n");
+        return -1;
+    }
+    
+    /* run */
+    GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE) 
+    {
+        g_print ("Failed to start up pipeline!\n");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+        if (msg) 
+        {
+          GError *err = NULL;
+
+          gst_message_parse_error (msg, &err, NULL);
+          g_print ("ERROR: %s\n", err->message);
+          g_error_free (err);
+          gst_message_unref (msg);
+        }
+        return -1;
+    }
+
+    g_main_loop_run (loop);
+
+    /* clean up */
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+
+    return 0;
+
+}
+    
diff --git a/tests/examples/gl/generic/generic.sln b/tests/examples/gl/generic/generic.sln
new file mode 100644 (file)
index 0000000..22e86f6
--- /dev/null
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cube", "cube\cube.vcproj", "{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeyuv", "cubeyuv\cubeyuv.vcproj", "{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doublecube", "doublecube\doublecube.vcproj", "{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recordgraphic", "recordgraphic\recordgraphic.vcproj", "{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Debug|Win32.ActiveCfg = Debug|Win32
+               {DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Debug|Win32.Build.0 = Debug|Win32
+               {DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Release|Win32.ActiveCfg = Release|Win32
+               {DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Release|Win32.Build.0 = Release|Win32
+               {6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Debug|Win32.ActiveCfg = Debug|Win32
+               {6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Debug|Win32.Build.0 = Debug|Win32
+               {6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Release|Win32.ActiveCfg = Release|Win32
+               {6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Release|Win32.Build.0 = Release|Win32
+               {4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Debug|Win32.ActiveCfg = Debug|Win32
+               {4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Debug|Win32.Build.0 = Debug|Win32
+               {4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Release|Win32.ActiveCfg = Release|Win32
+               {4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Release|Win32.Build.0 = Release|Win32
+               {E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Debug|Win32.ActiveCfg = Debug|Win32
+               {E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Debug|Win32.Build.0 = Debug|Win32
+               {E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Release|Win32.ActiveCfg = Release|Win32
+               {E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/generic/recordgraphic/.gitignore b/tests/examples/gl/generic/recordgraphic/.gitignore
new file mode 100644 (file)
index 0000000..8127d83
--- /dev/null
@@ -0,0 +1 @@
+recordgraphic
diff --git a/tests/examples/gl/generic/recordgraphic/Makefile.am b/tests/examples/gl/generic/recordgraphic/Makefile.am
new file mode 100644 (file)
index 0000000..4ee21ac
--- /dev/null
@@ -0,0 +1,8 @@
+
+noinst_PROGRAMS = recordgraphic
+
+recordgraphic_SOURCES = main.cpp
+
+recordgraphic_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
+recordgraphic_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_LIBS) $(GL_LIBS)
+
diff --git a/tests/examples/gl/generic/recordgraphic/main.cpp b/tests/examples/gl/generic/recordgraphic/main.cpp
new file mode 100644 (file)
index 0000000..fd0ceb0
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#if __WIN32__ || _WIN32
+# include <GL/glext.h>
+#endif
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+#include <iostream>
+#include <string>
+
+static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+    GMainLoop *loop = (GMainLoop*)data;
+
+    switch (GST_MESSAGE_TYPE (msg)) 
+    {
+        case GST_MESSAGE_EOS:
+              g_print ("End-of-stream\n");
+              g_main_loop_quit (loop);
+              break;
+        case GST_MESSAGE_ERROR: 
+          {
+              gchar *debug = NULL;
+              GError *err = NULL;
+
+              gst_message_parse_error (msg, &err, &debug);
+
+              g_print ("Error: %s\n", err->message);
+              g_error_free (err);
+
+              if (debug) 
+              {
+                  g_print ("Debug details: %s\n", debug);
+                  g_free (debug);
+              }
+
+              g_main_loop_quit (loop);
+              break;
+          } 
+        default:
+          break;
+    }
+
+    return TRUE;
+}
+
+//client reshape callback
+static void reshapeCallback (GLuint width, GLuint height)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);  
+    glMatrixMode(GL_MODELVIEW);        
+}
+
+
+//client draw callback
+static gboolean drawCallback (GLuint width, GLuint height, GLuint texture, gpointer data)
+{
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;                               
+    static GLfloat     zrot = 0;
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;  
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+    
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+  
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+       
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(xrot,1.0f,0.0f,0.0f);
+    glRotatef(yrot,0.0f,1.0f,0.0f);
+    glRotatef(zrot,0.0f,0.0f,1.0f);
+
+    //cube
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd();
+
+    xrot+=0.3f;
+    yrot+=0.2f;
+    zrot+=0.4f;
+
+    //return TRUE causes a postRedisplay
+    return FALSE;
+}
+
+
+//equivalent command line: 
+//gst-launch-1.0 videotestsrc num_buffers=400 ! gleffects effect=0 ! 
+//avenc_mpeg4 ! avimux ! filesink location="record.avi"
+// or
+//gst-launch-1.0 videotestsrc num_buffers=400 ! gleffects effect=0 ! "video/x-raw, width=320, height=240" ! glfiltercube ! "video/x-raw, width=720, height=576" ! 
+//avenc_mpeg4 ! avimux ! filesink location="record.avi"
+gint main (gint argc, gchar *argv[])
+{
+    GstStateChangeReturn ret;
+    GstElement *pipeline, *videosrc, *glfilterapp, *avenc_mpeg4, *avimux, *filesink;
+    GMainLoop *loop;
+    GstBus *bus;
+
+    /* initialization */
+    gst_init (&argc, &argv);
+    loop = g_main_loop_new (NULL, FALSE);
+
+    /* create elements */
+    pipeline = gst_pipeline_new ("pipeline");
+
+    /* watch for messages on the pipeline's bus (note that this will only
+     * work like this when a GLib main loop is running) */
+    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_watch (bus, bus_call, loop);
+    gst_object_unref (bus);
+
+    /* create elements */
+    videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
+    glfilterapp = gst_element_factory_make ("glfilterapp", "glfilterapp0");
+    avenc_mpeg4  = gst_element_factory_make ("avenc_mpeg4", "avenc_mpeg40");
+    avimux  = gst_element_factory_make ("avimux", "avimux0");
+    filesink  = gst_element_factory_make ("filesink", "filesink0");
+
+
+    if (!videosrc || !glfilterapp || !avenc_mpeg4 || !avimux || !filesink) 
+    {
+        g_print ("one element could not be found \n");
+        return -1;
+    }
+
+    /* change video source caps */
+    GstCaps *caps = gst_caps_new_simple("video/x-raw",
+                                        "format", G_TYPE_STRING, "UYVY",
+                                        "width", G_TYPE_INT, 320,
+                                        "height", G_TYPE_INT, 240,
+                                        "framerate", GST_TYPE_FRACTION, 25, 1,
+                                        NULL);
+
+    /* change video source caps */
+    GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
+                                           "width", G_TYPE_INT, 640,
+                                           "height", G_TYPE_INT, 480,
+                                           NULL);
+
+    /* configure elements */
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
+    g_object_set(G_OBJECT(glfilterapp), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(glfilterapp), "client-draw-callback", drawCallback, NULL);
+    g_object_set(G_OBJECT(glfilterapp), "client-data", NULL, NULL);
+    g_object_set(G_OBJECT(filesink), "location", "record.avi", NULL);
+    
+    /* add elements */
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, glfilterapp, 
+        avenc_mpeg4, avimux, filesink, NULL);
+    
+    /* link elements */
+    gboolean link_ok = gst_element_link_filtered(videosrc, glfilterapp, caps) ;
+    gst_caps_unref(caps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link videosrc to glfilterapp!\n") ;
+        return -1 ;
+    }
+
+    link_ok = gst_element_link_filtered(glfilterapp, avenc_mpeg4, outcaps) ;
+    gst_caps_unref(outcaps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link glfilterapp to avenc_mpeg4!\n") ;
+        return -1 ;
+    }
+    if (!gst_element_link_many(avenc_mpeg4, avimux, filesink, NULL)) 
+    {
+        g_print ("Failed to link one or more elements!\n");
+        return -1;
+    }
+
+    
+    /* run */
+    ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE) 
+    {
+        g_print ("Failed to start up pipeline!\n");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+        if (msg) 
+        {
+          GError *err = NULL;
+
+          gst_message_parse_error (msg, &err, NULL);
+          g_print ("ERROR: %s\n", err->message);
+          g_error_free (err);
+          gst_message_unref (msg);
+        }
+        return -1;
+    }
+
+    g_main_loop_run (loop);
+
+    /* clean up */
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+
+    return 0;
+
+}
diff --git a/tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj b/tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj
new file mode 100644 (file)
index 0000000..66df375
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="recordgraphic"
+       ProjectGUID="{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}"
+       RootNamespace="recordgraphic"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/Makefile.am b/tests/examples/gl/gtk/Makefile.am
new file mode 100644 (file)
index 0000000..c64cd4a
--- /dev/null
@@ -0,0 +1,12 @@
+
+SUBDIRS = . gtkvideooverlay filternovideooverlay filtervideooverlay fxtest switchvideooverlay
+
+noinst_LTLIBRARIES = libgstgtkhelper.la
+
+libgstgtkhelper_la_SOURCES = gstgtk.c gstgtk.h
+libgstgtkhelper_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(GTK3_CFLAGS)
+
+if HAVE_WINDOW_COCOA
+libgstgtkhelper_la_CFLAGS += -x objective-c
+endif
+
diff --git a/tests/examples/gl/gtk/README b/tests/examples/gl/gtk/README
new file mode 100644 (file)
index 0000000..76595c6
--- /dev/null
@@ -0,0 +1,27 @@
+--- Description of the GTK examples ---
+
+- gtkvideooverlay:
+Show how to use the videooverlay interface through GTK.
+It's possible to switch bettween GST_STATE through four buttons.
+
+-filternovideooverlay:
+A more complex pipeline is switched bettween the GST states
+without using the videooverlay interface.
+
+-filtervideooverlay:
+A more complex pipeline is switched bettween the GST states.
+using the videooverlay interface.
+
+-fxtest:
+switch bettween effects of the gleffects filter.
+
+-pixbufdrop:
+drag and drop a png file and overlay it using alpha channel.
+It uses gloverlay filter.
+
+-switchvideooverlay:
+change the videooverlay window while the stream is playing.
+
+--- How to build the GTK examples ---
+
+Using autotools or using tests/examples/gtk/gtk.sln
diff --git a/tests/examples/gl/gtk/filternovideooverlay/.gitignore b/tests/examples/gl/gtk/filternovideooverlay/.gitignore
new file mode 100644 (file)
index 0000000..f6e4162
--- /dev/null
@@ -0,0 +1 @@
+filternovideooverlay
diff --git a/tests/examples/gl/gtk/filternovideooverlay/Makefile.am b/tests/examples/gl/gtk/filternovideooverlay/Makefile.am
new file mode 100644 (file)
index 0000000..61526c5
--- /dev/null
@@ -0,0 +1,18 @@
+noinst_PROGRAMS = filternovideooverlay
+
+filternovideooverlay_SOURCES = main.cpp
+
+filternovideooverlay_CXXFLAGS= \
+       -I$(top_srcdir)/gst-libs \
+       -I$(top_builddir)/gst-libs \
+       $(GST_PLUGINS_BASE_CFLAGS) \
+       $(GST_CXXFLAGS) \
+       $(GL_CFLAGS) \
+       $(GTK3_CFLAGS)
+
+filternovideooverlay_LDADD= \
+       $(GTK3_LIBS) \
+       $(GST_PLUGINS_BASE_LIBS) \
+       $(GST_LIBS)  \
+       $(GL_LIBS)
+
diff --git a/tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj b/tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj
new file mode 100644 (file)
index 0000000..473587b
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="filternovideooverlay"
+       ProjectGUID="{F41F3034-3E0B-4630-8D1E-35E14C606863}"
+       RootNamespace="filternovideooverlay"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/filternovideooverlay/main.cpp b/tests/examples/gl/gtk/filternovideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..5b9257c
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2014 Matthew Waters <ystreet00@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+
+static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
+{
+    g_print("End of stream\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    g_print ("GST_STATE_NULL\n");
+}
+
+
+static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    g_print ("GST_STATE_READY\n");
+}
+
+
+static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    g_print ("GST_STATE_PAUSED\n");
+}
+
+
+static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    g_print ("GST_STATE_PLAYING\n");
+}
+
+
+static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
+{
+    //change the video frame rate dynamically
+    return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
+}
+
+
+
+gint main (gint argc, gchar *argv[])
+{
+    gtk_init (&argc, &argv);
+    gst_init (&argc, &argv);
+
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+
+    //window to control the states
+    GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    GdkGeometry geometry;
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
+    gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
+    gtk_window_move (GTK_WINDOW (window_control), 10, 10);
+    GtkWidget* table = gtk_grid_new ();
+    gtk_container_add (GTK_CONTAINER (window_control), table);
+
+    //control state null
+    GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
+    g_signal_connect (G_OBJECT (button_state_null), "clicked",
+        G_CALLBACK (button_state_null_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
+    gtk_widget_show (button_state_null);
+
+    //control state ready
+    GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
+    g_signal_connect (G_OBJECT (button_state_ready), "clicked",
+        G_CALLBACK (button_state_ready_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
+    gtk_widget_show (button_state_ready);
+
+    //control state paused
+    GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
+    g_signal_connect (G_OBJECT (button_state_paused), "clicked",
+        G_CALLBACK (button_state_paused_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
+    gtk_widget_show (button_state_paused);
+
+    //control state playing
+    GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
+    g_signal_connect (G_OBJECT (button_state_playing), "clicked",
+        G_CALLBACK (button_state_playing_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
+    gtk_widget_show (button_state_playing);
+
+    //change framerate
+    GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
+        1, 30, 2);
+    g_signal_connect (G_OBJECT (slider_fps), "format-value",
+        G_CALLBACK (slider_fps_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), slider_fps, 1, 0, 1, 3);
+    gtk_widget_show (slider_fps);
+
+    gtk_widget_show (table);
+    gtk_widget_show (window_control);
+
+    GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
+    GstElement* glfilterlaplacian = gst_element_factory_make ("glfilterblur", "glfilterblur");
+    GstElement* glfiltercube = gst_element_factory_make ("glfiltercube", "glfiltercube");
+    GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
+
+    GstCaps *caps = gst_caps_new_simple("video/x-raw",
+                                        "width", G_TYPE_INT, 640,
+                                        "height", G_TYPE_INT, 480,
+                                        "framerate", GST_TYPE_FRACTION, 25, 1,
+                                        "format", G_TYPE_STRING, "YV12",
+                                        NULL) ;
+
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, glfiltercube, glfilterlaplacian, videosink, NULL);
+
+    gboolean link_ok = gst_element_link_filtered(videosrc, glfiltercube, caps) ;
+    gst_caps_unref(caps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link videosrc to glfiltercube!\n") ;
+        return -1;
+    }
+
+    if(!gst_element_link_many(glfiltercube, glfilterlaplacian, videosink, NULL))
+    {
+        g_warning("Failed to link glfiltercube to videosink!\n") ;
+        return -1;
+    }
+
+    //set window id on this event
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_signal_watch (bus);
+    g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
+    gst_object_unref (bus);
+
+    //start
+    GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        g_print ("Failed to start up pipeline!\n");
+        return -1;
+    }
+
+    gtk_main();
+
+    return 0;
+}
+
diff --git a/tests/examples/gl/gtk/filtervideooverlay/.gitignore b/tests/examples/gl/gtk/filtervideooverlay/.gitignore
new file mode 100644 (file)
index 0000000..c5e1611
--- /dev/null
@@ -0,0 +1 @@
+filtervideooverlay
diff --git a/tests/examples/gl/gtk/filtervideooverlay/Makefile.am b/tests/examples/gl/gtk/filtervideooverlay/Makefile.am
new file mode 100644 (file)
index 0000000..4d7f129
--- /dev/null
@@ -0,0 +1,10 @@
+noinst_PROGRAMS = filtervideooverlay
+
+filtervideooverlay_SOURCES = main.cpp
+
+filtervideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
+       $(GL_CFLAGS) $(GTK3_CFLAGS)
+filtervideooverlay_LDADD=../libgstgtkhelper.la \
+       $(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
+
diff --git a/tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj b/tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj
new file mode 100644 (file)
index 0000000..564daa9
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="filtervideooverlay"
+       ProjectGUID="{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}"
+       RootNamespace="filtervideooverlay"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/filtervideooverlay/main.cpp b/tests/examples/gl/gtk/filtervideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..8ca402d
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "../gstgtk.h"
+
+
+static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
+{
+    // ignore anything but 'prepare-window-handle' element messages
+    if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+        return GST_BUS_PASS;
+
+    if (!gst_is_video_overlay_prepare_window_handle_message (message))
+        return GST_BUS_PASS;
+
+    g_print ("setting window handle %p\n", widget);
+
+    gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
+
+    gst_message_unref (message);
+
+    return GST_BUS_DROP;
+}
+
+
+static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
+{
+    g_print("End of stream\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+
+static gboolean expose_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
+{
+    gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
+    return FALSE;
+}
+
+
+static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
+{
+    g_print("Close\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+
+static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    g_print ("GST_STATE_NULL\n");
+}
+
+
+static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    g_print ("GST_STATE_READY\n");
+}
+
+
+static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    g_print ("GST_STATE_PAUSED\n");
+}
+
+
+static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    g_print ("GST_STATE_PLAYING\n");
+}
+
+
+static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
+{
+    //change the video frame rate dynamically
+    return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
+}
+
+
+
+gint main (gint argc, gchar *argv[])
+{
+    gtk_init (&argc, &argv);
+    gst_init (&argc, &argv);
+
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+
+    //window that contains an area where the video is drawn
+    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request (window, 640, 480);
+    gtk_window_move (GTK_WINDOW (window), 300, 10);
+    gtk_window_set_title (GTK_WINDOW (window), "glimagesink implement the gstvideooverlay interface");
+    GdkGeometry geometry;
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
+
+    //window to control the states
+    GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
+    gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
+    gtk_window_move (GTK_WINDOW (window_control), 10, 10);
+    GtkWidget* grid = gtk_grid_new ();
+    gtk_container_add (GTK_CONTAINER (window_control), grid);
+
+    //control state null
+    GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
+    g_signal_connect (G_OBJECT (button_state_null), "clicked",
+        G_CALLBACK (button_state_null_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (grid), button_state_null, 0, 1, 1, 1);
+    gtk_widget_show (button_state_null);
+
+    //control state ready
+    GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
+    g_signal_connect (G_OBJECT (button_state_ready), "clicked",
+        G_CALLBACK (button_state_ready_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (grid), button_state_ready, 0, 2, 1, 1);
+    gtk_widget_show (button_state_ready);
+
+    //control state paused
+    GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
+    g_signal_connect (G_OBJECT (button_state_paused), "clicked",
+        G_CALLBACK (button_state_paused_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (grid), button_state_paused, 0, 3, 1, 1);
+    gtk_widget_show (button_state_paused);
+
+    //control state playing
+    GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
+    g_signal_connect (G_OBJECT (button_state_playing), "clicked",
+        G_CALLBACK (button_state_playing_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (grid), button_state_playing, 0, 4, 1, 1);
+    gtk_widget_show (button_state_playing);
+
+    //change framerate
+    GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 1, 30, 2);
+    g_signal_connect (G_OBJECT (slider_fps), "format-value",
+        G_CALLBACK (slider_fps_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (grid), slider_fps, 1, 0, 1, 5);
+    gtk_widget_show (slider_fps);
+
+    gtk_widget_show (grid);
+    gtk_widget_show (window_control);
+
+    //configure the pipeline
+    g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
+
+    GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
+    GstElement* glfiltercube = gst_element_factory_make ("glfiltercube", "glfiltercube");
+    GstElement* glfilterlaplacian = gst_element_factory_make ("glfilterlaplacian", "glfilterlaplacian");
+    GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
+
+    GstCaps *caps = gst_caps_new_simple("video/x-raw",
+                                        "width", G_TYPE_INT, 640,
+                                        "height", G_TYPE_INT, 480,
+                                        "framerate", GST_TYPE_FRACTION, 25, 1,
+                                        "format", G_TYPE_STRING, "AYUV",
+                                        NULL) ;
+
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, glfiltercube, glfilterlaplacian, videosink, NULL);
+
+    gboolean link_ok = gst_element_link_filtered(videosrc, glfiltercube, caps) ;
+    gst_caps_unref(caps) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link videosrc to glfiltercube!\n") ;
+        return -1;
+    }
+
+    if(!gst_element_link_many(glfiltercube, glfilterlaplacian, videosink, NULL))
+    {
+        g_warning("Failed to link glfiltercube to videosink!\n") ;
+        return -1;
+    }
+
+    //area where the video is drawn
+    GtkWidget* area = gtk_drawing_area_new();
+    gtk_container_add (GTK_CONTAINER (window), area);
+
+    gtk_widget_realize(area);
+
+    //set window id on this event
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area, NULL);
+    gst_bus_add_signal_watch (bus);
+    g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
+    gst_object_unref (bus);
+
+    //needed when being in GST_STATE_READY, GST_STATE_PAUSED
+    //or resizing/obscuring the window
+    g_signal_connect(area, "draw", G_CALLBACK(expose_cb), videosink);
+
+    //start
+    GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        g_print ("Failed to start up pipeline!\n");
+        return -1;
+    }
+
+    gtk_widget_show_all (window);
+
+    gtk_main();
+
+    return 0;
+}
+
diff --git a/tests/examples/gl/gtk/fxtest/.gitignore b/tests/examples/gl/gtk/fxtest/.gitignore
new file mode 100644 (file)
index 0000000..c355697
--- /dev/null
@@ -0,0 +1,2 @@
+fxtest
+pixbufdrop
diff --git a/tests/examples/gl/gtk/fxtest/Makefile.am b/tests/examples/gl/gtk/fxtest/Makefile.am
new file mode 100644 (file)
index 0000000..c5e5d1a
--- /dev/null
@@ -0,0 +1,18 @@
+noinst_PROGRAMS = fxtest 
+noinst_PROGRAMS += pixbufdrop
+
+fxtest_SOURCES = fxtest.c
+
+fxtest_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       $(GL_CFLAGS) $(GTK3_CFLAGS)
+fxtest_LDADD=../libgstgtkhelper.la \
+       $(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS)  \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
+
+pixbufdrop_SOURCES = pixbufdrop.c
+
+pixbufdrop_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       $(GL_CFLAGS) $(GTK3_CFLAGS)
+pixbufdrop_LDADD=../libgstgtkhelper.la \
+       $(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
diff --git a/tests/examples/gl/gtk/fxtest/fxtest.c b/tests/examples/gl/gtk/fxtest/fxtest.c
new file mode 100644 (file)
index 0000000..a9b41c1
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Filippo Argiolas <filippo.argiolas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "../gstgtk.h"
+
+#include <gst/video/videooverlay.h>
+
+
+/* TODO: use video overlay in the proper way (like suggested in docs, see gtkvideooverlay example) */
+static gboolean
+expose_cb (GtkWidget * widget, gpointer data)
+{
+  GstVideoOverlay *overlay =
+      GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (data),
+          GST_TYPE_VIDEO_OVERLAY));
+
+  gst_video_overlay_set_gtk_window (overlay, widget);
+
+  return FALSE;
+}
+
+static void
+destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
+{
+  g_message ("destroy callback");
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  gtk_main_quit ();
+}
+
+static gboolean
+apply_fx (GtkWidget * widget, gpointer data)
+{
+  gchar *fx;
+  GEnumClass *p_class;
+
+/* heeeellppppp!! */
+  p_class =
+      G_PARAM_SPEC_ENUM (g_object_class_find_property (G_OBJECT_GET_CLASS
+          (G_OBJECT (data)), "effect")
+      )->enum_class;
+
+  fx = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
+  g_print ("setting: %s - %s\n", fx, g_enum_get_value_by_nick (p_class,
+          fx)->value_name);
+  g_object_set (G_OBJECT (data), "effect", g_enum_get_value_by_nick (p_class,
+          fx)->value, NULL);
+  return FALSE;
+}
+
+static gboolean
+play_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("playing");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_PLAYING);
+  return FALSE;
+}
+
+static gboolean
+null_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("nulling");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_NULL);
+  return FALSE;
+}
+
+static gboolean
+ready_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("readying");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_READY);
+  return FALSE;
+}
+
+static gboolean
+pause_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("pausing");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_PAUSED);
+  return FALSE;
+}
+
+gint
+main (gint argc, gchar * argv[])
+{
+  GstStateChangeReturn ret;
+  GstElement *pipeline;
+  GstElement *filter, *sink;
+  GstElement *sourcebin;
+  GError *error = NULL;
+
+  GtkWidget *window;
+  GtkWidget *screen;
+  GtkWidget *vbox, *combo;
+  GtkWidget *hbox;
+  GtkWidget *play, *pause, *null, *ready;
+
+  gchar **source_desc_array = NULL;
+  gchar *source_desc = NULL;
+
+  GOptionContext *context;
+  GOptionEntry options[] = {
+    {"source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array,
+        "Use a custom source bin description (gst-launch style)", NULL}
+    ,
+    {NULL}
+  };
+
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, options, NULL);
+  g_option_context_add_group (context, gst_init_get_option_group ());
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  if (!g_option_context_parse (context, &argc, &argv, &error)) {
+    g_print ("Inizialization error: %s\n", GST_STR_NULL (error->message));
+    return -1;
+  }
+  g_option_context_free (context);
+
+  if (source_desc_array != NULL) {
+    source_desc = g_strjoinv (" ", source_desc_array);
+    g_strfreev (source_desc_array);
+  }
+  if (source_desc == NULL) {
+    source_desc =
+        g_strdup
+        ("videotestsrc ! video/x-raw, width=352, height=288 ! identity");
+  }
+
+  sourcebin =
+      gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error);
+  g_free (source_desc);
+  if (error) {
+    g_print ("Error while parsing source bin description: %s\n",
+        GST_STR_NULL (error->message));
+    return -1;
+  }
+
+  g_set_application_name ("gst-gl-effects test app");
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_container_set_border_width (GTK_CONTAINER (window), 3);
+
+  pipeline = gst_pipeline_new ("pipeline");
+
+  filter = gst_element_factory_make ("gleffects", "flt");
+  sink = gst_element_factory_make ("glimagesink", "glsink");
+
+  gst_bin_add_many (GST_BIN (pipeline), sourcebin, filter, sink, NULL);
+
+  if (!gst_element_link_many (sourcebin, filter, sink, NULL)) {
+    g_print ("Failed to link one or more elements!\n");
+    return -1;
+  }
+
+  g_signal_connect (G_OBJECT (window), "delete-event",
+      G_CALLBACK (destroy_cb), pipeline);
+  g_signal_connect (G_OBJECT (window), "destroy-event",
+      G_CALLBACK (destroy_cb), pipeline);
+
+  screen = gtk_drawing_area_new ();
+
+  gtk_widget_set_size_request (screen, 640, 480);       // 500 x 376
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+
+  gtk_box_pack_start (GTK_BOX (vbox), screen, TRUE, TRUE, 0);
+
+  combo = gtk_combo_box_text_new ();
+
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "identity");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "mirror");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "squeeze");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "stretch");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "fisheye");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "twirl");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "bulge");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "tunnel");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "square");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "heat");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "xpro");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "lumaxpro");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "sepia");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "xray");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "sin");
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "glow");
+
+  g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (apply_fx), filter);
+
+  gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+  play = gtk_button_new_with_label ("PLAY");
+
+  g_signal_connect (G_OBJECT (play), "clicked", G_CALLBACK (play_cb), pipeline);
+
+  pause = gtk_button_new_with_label ("PAUSE");
+
+  g_signal_connect (G_OBJECT (pause), "clicked",
+      G_CALLBACK (pause_cb), pipeline);
+
+  null = gtk_button_new_with_label ("NULL");
+
+  g_signal_connect (G_OBJECT (null), "clicked", G_CALLBACK (null_cb), pipeline);
+
+  ready = gtk_button_new_with_label ("READY");
+
+  g_signal_connect (G_OBJECT (ready), "clicked",
+      G_CALLBACK (ready_cb), pipeline);
+
+  gtk_box_pack_start (GTK_BOX (hbox), null, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), ready, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), play, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), pause, TRUE, TRUE, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  g_signal_connect (screen, "realize", G_CALLBACK (expose_cb), pipeline);
+
+  ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  if (ret == GST_STATE_CHANGE_FAILURE) {
+    g_print ("Failed to start up pipeline!\n");
+    return -1;
+  }
+
+  gtk_widget_show_all (GTK_WIDGET (window));
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/tests/examples/gl/gtk/fxtest/fxtest.vcproj b/tests/examples/gl/gtk/fxtest/fxtest.vcproj
new file mode 100644 (file)
index 0000000..05a2de0
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="fxtest"
+       ProjectGUID="{59075FDD-68CD-4F1A-948B-46D142800798}"
+       RootNamespace="fxtest"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\fxtest.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\gstgtk.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/fxtest/pixbufdrop.c b/tests/examples/gl/gtk/fxtest/pixbufdrop.c
new file mode 100644 (file)
index 0000000..4b26c3e
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Filippo Argiolas <filippo.argiolas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "../gstgtk.h"
+
+#include <gst/video/videooverlay.h>
+
+static gint delay = 0;
+static gint saveddelay = 0;
+static gint method = 1;
+
+struct _SourceData
+{
+  gpointer data;
+  gpointer nick;
+  gpointer value;
+};
+typedef struct _SourceData SourceData;
+
+static GstBusSyncReply
+create_window (GstBus * bus, GstMessage * message, GtkWidget * widget)
+{
+  // ignore anything but 'prepare-window-handle' element messages
+  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+    return GST_BUS_PASS;
+
+  if (!gst_is_video_overlay_prepare_window_handle_message (message))
+    return GST_BUS_PASS;
+
+  gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC
+          (message)), widget);
+
+  gst_message_unref (message);
+
+  return GST_BUS_DROP;
+}
+
+static void
+message_cb (GstBus * bus, GstMessage * message, GstElement * pipeline)
+{
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  gtk_main_quit ();
+}
+
+static gboolean
+expose_cb (GtkWidget * widget, cairo_t * cr, GstElement * videosink)
+{
+  gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
+  return FALSE;
+}
+
+static void
+destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
+{
+  g_message ("destroy callback");
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  gtk_main_quit ();
+}
+
+static gboolean
+play_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("playing");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_PLAYING);
+  return FALSE;
+}
+
+static gboolean
+null_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("nulling");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_NULL);
+  return FALSE;
+}
+
+static gboolean
+ready_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("readying");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_READY);
+  return FALSE;
+}
+
+static gboolean
+pause_cb (GtkWidget * widget, gpointer data)
+{
+  g_message ("pausing");
+  gst_element_set_state (GST_ELEMENT (data), GST_STATE_PAUSED);
+  return FALSE;
+}
+
+static gboolean
+set_location_delayed (gpointer data)
+{
+  SourceData *sdata = (SourceData *) data;
+  delay--;
+  g_print ("%d\n", delay);
+  if (delay > 0) {
+    return TRUE;
+  }
+  g_object_set (G_OBJECT (sdata->data), sdata->nick, sdata->value, NULL);
+  delay = saveddelay;
+  return FALSE;
+}
+
+static void
+on_drag_data_received (GtkWidget * widget,
+    GdkDragContext * context, int x, int y,
+    GtkSelectionData * seldata, guint inf, guint time, gpointer data)
+{
+  SourceData *userdata = g_new0 (SourceData, 1);
+#ifdef G_OS_WIN32
+  gchar *filename =
+      g_filename_from_uri ((const gchar *) seldata->data, NULL, NULL);
+#else
+  GdkPixbufFormat *format;
+  gchar **uris = gtk_selection_data_get_uris (seldata);
+  gchar *filename = NULL;
+
+  g_return_if_fail (uris != NULL);
+  filename = g_filename_from_uri (uris[0], NULL, NULL);
+  g_return_if_fail (filename != NULL);
+  format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
+  g_return_if_fail (format);
+  g_print ("received %s image: %s\n", filename,
+      gdk_pixbuf_format_get_name (format));
+#endif
+
+  userdata->nick = (gchar *) "location";
+  userdata->value = g_strdup (filename);
+  userdata->data = data;
+  saveddelay = delay;
+  if (delay > 0) {
+    g_print ("%d\n", delay);
+    g_timeout_add_seconds (1, set_location_delayed, userdata);
+  } else
+    g_object_set (G_OBJECT (userdata->data), userdata->nick, userdata->value,
+        NULL);
+  g_free (filename);
+}
+
+
+gint
+main (gint argc, gchar * argv[])
+{
+  GstElement *pipeline;
+  GstElement *filter, *sink;
+  GstElement *sourcebin;
+  GstBus *bus;
+  GError *error = NULL;
+
+  GtkWidget *window;
+  GtkWidget *screen;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  GtkWidget *play, *pause, *null, *ready;
+
+  gchar **source_desc_array = NULL;
+  gchar *source_desc = NULL;
+
+  GOptionContext *context;
+  GOptionEntry options[] = {
+    {"source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array,
+        "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"}
+    ,
+    {NULL}
+  };
+
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, options, NULL);
+  g_option_context_add_group (context, gst_init_get_option_group ());
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  if (!g_option_context_parse (context, &argc, &argv, &error)) {
+    g_print ("Inizialization error: %s\n", GST_STR_NULL (error->message));
+    return -1;
+  }
+  g_option_context_free (context);
+
+  if (source_desc_array != NULL) {
+    source_desc = g_strjoinv (" ", source_desc_array);
+    g_strfreev (source_desc_array);
+  }
+  if (source_desc == NULL) {
+    source_desc =
+        g_strdup
+        ("videotestsrc ! video/x-raw, width=352, height=288 ! identity");
+  }
+
+  sourcebin =
+      gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error);
+  g_free (source_desc);
+  if (error) {
+    g_print ("Error while parsing source bin description: %s\n",
+        GST_STR_NULL (error->message));
+    return -1;
+  }
+
+  g_set_application_name ("gst-gl-effects test app");
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_container_set_border_width (GTK_CONTAINER (window), 3);
+
+  pipeline = gst_pipeline_new ("pipeline");
+
+  if (method == 2) {
+    filter = gst_element_factory_make ("gloverlay", "flt");
+  } else {
+    filter = gst_element_factory_make ("gldifferencematte", "flt");
+  }
+  sink = gst_element_factory_make ("glimagesink", "glsink");
+
+  gst_bin_add_many (GST_BIN (pipeline), sourcebin, filter, sink, NULL);
+
+  if (!gst_element_link_many (sourcebin, filter, sink, NULL)) {
+    g_print ("Failed to link one or more elements!\n");
+    return -1;
+  }
+
+  g_signal_connect (G_OBJECT (window), "delete-event",
+      G_CALLBACK (destroy_cb), pipeline);
+  g_signal_connect (G_OBJECT (window), "destroy-event",
+      G_CALLBACK (destroy_cb), pipeline);
+
+  screen = gtk_drawing_area_new ();
+
+  gtk_widget_set_size_request (screen, 640, 480);       // 500 x 376
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+
+  gtk_box_pack_start (GTK_BOX (vbox), screen, TRUE, TRUE, 0);
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+  play = gtk_button_new_with_label ("PLAY");
+
+  g_signal_connect (G_OBJECT (play), "clicked", G_CALLBACK (play_cb), pipeline);
+
+  pause = gtk_button_new_with_label ("PAUSE");
+
+  g_signal_connect (G_OBJECT (pause), "clicked",
+      G_CALLBACK (pause_cb), pipeline);
+
+  null = gtk_button_new_with_label ("NULL");
+
+  g_signal_connect (G_OBJECT (null), "clicked", G_CALLBACK (null_cb), pipeline);
+
+  ready = gtk_button_new_with_label ("READY");
+
+  g_signal_connect (G_OBJECT (ready), "clicked",
+      G_CALLBACK (ready_cb), pipeline);
+
+  gtk_box_pack_start (GTK_BOX (hbox), null, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), ready, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), play, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), pause, TRUE, TRUE, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  gtk_widget_realize (screen);
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, screen,
+      NULL);
+  gst_bus_add_signal_watch (bus);
+  g_signal_connect (bus, "message::error", G_CALLBACK (message_cb), pipeline);
+  g_signal_connect (bus, "message::warning", G_CALLBACK (message_cb), pipeline);
+  g_signal_connect (bus, "message::eos", G_CALLBACK (message_cb), pipeline);
+  gst_object_unref (bus);
+  g_signal_connect (screen, "draw", G_CALLBACK (expose_cb), sink);
+
+  gtk_drag_dest_set (screen, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
+  gtk_drag_dest_add_uri_targets (screen);
+
+  g_signal_connect (screen, "drag-data-received",
+      G_CALLBACK (on_drag_data_received), filter);
+
+  gtk_widget_show_all (GTK_WIDGET (window));
+
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/tests/examples/gl/gtk/gstgtk.c b/tests/examples/gl/gtk/gstgtk.c
new file mode 100644 (file)
index 0000000..b13304c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 David A. Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gl/gl.h>
+#include "gstgtk.h"
+
+#if GST_GL_HAVE_WINDOW_WIN32 && defined(GDK_WINDOWING_WIN32)
+#include <gdk/gdkwin32.h>
+#endif
+#if GST_GL_HAVE_WINDOW_X11 && defined(GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#include <gdk/x11/gdkx11display.h>
+#endif
+#if GST_GL_HAVE_WINDOW_COCOA && defined(GDK_WINDOWING_QUARTZ)
+#include <gdk/gdkquartz.h>
+#endif
+
+
+void
+gst_video_overlay_set_gtk_window (GstVideoOverlay * videooverlay,
+    GtkWidget * widget)
+{
+  GdkWindow *window;
+  GdkDisplay *display;
+  const gchar *user_choice = g_getenv ("GST_GL_WINDOW");
+
+  window = gtk_widget_get_window (widget);
+  display = gdk_window_get_display (window);
+
+#if GST_GL_HAVE_WINDOW_WIN32 && defined(GDK_WINDOWING_WIN32)
+  if (GDK_IS_WIN32_DISPLAY (display) && (!user_choice
+          || g_strcmp0 (user_choice, "win32") == 0)) {
+    gst_video_overlay_set_window_handle (videooverlay,
+        (guintptr) GDK_WINDOW_HWND (window));
+  } else
+#endif
+#if GST_GL_HAVE_WINDOW_COCOA && defined(GDK_WINDOWING_QUARTZ)
+  if (GDK_IS_QUARTZ_DISPLAY (display) && (!user_choice
+          || g_strcmp0 (user_choice, "cocoa") == 0)) {
+    gst_video_overlay_set_window_handle (videooverlay, (guintptr)
+        gdk_quartz_window_get_nswindow (window));
+  } else
+#endif
+#if GST_GL_HAVE_WINDOW_X11 && defined(GDK_WINDOWING_X11)
+  if (GDK_IS_X11_DISPLAY (display) && (!user_choice
+          || g_strcmp0 (user_choice, "x11") == 0)) {
+    gst_video_overlay_set_window_handle (videooverlay, GDK_WINDOW_XID (window));
+  } else
+#endif
+    g_error ("Unsupported Gtk+ backend");
+}
diff --git a/tests/examples/gl/gtk/gstgtk.h b/tests/examples/gl/gtk/gstgtk.h
new file mode 100644 (file)
index 0000000..4ef147f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 David A. Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_GTK_H__
+#define __GST_GTK_H__
+
+#include <gst/video/videooverlay.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void gst_video_overlay_set_gtk_window (GstVideoOverlay *videooverlay, GtkWidget *window);
+
+G_END_DECLS
+
+#endif
+
diff --git a/tests/examples/gl/gtk/gtk.sln b/tests/examples/gl/gtk/gtk.sln
new file mode 100644 (file)
index 0000000..5bf66dc
--- /dev/null
@@ -0,0 +1,50 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filtervideooverlay", "filtervideooverlay\filtervideooverlay.vcproj", "{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtkvideooverlay", "gtkvideooverlay\gtkvideooverlay.vcproj", "{E83070C2-58E4-48AE-AEB3-A4580EDE1212}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fxtest", "fxtest\fxtest.vcproj", "{59075FDD-68CD-4F1A-948B-46D142800798}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pixbufdrop", "pixbufdrop\pixbufdrop.vcproj", "{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filternovideooverlay", "filternovideooverlay\filternovideooverlay.vcproj", "{F41F3034-3E0B-4630-8D1E-35E14C606863}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "switchvideooverlay", "switchvideooverlay\switchvideooverlay.vcproj", "{BA78B4B4-3268-483E-9676-911E29FD2C69}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Debug|Win32.ActiveCfg = Debug|Win32
+               {F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Debug|Win32.Build.0 = Debug|Win32
+               {F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Release|Win32.ActiveCfg = Release|Win32
+               {F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Release|Win32.Build.0 = Release|Win32
+               {E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Debug|Win32.ActiveCfg = Debug|Win32
+               {E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Debug|Win32.Build.0 = Debug|Win32
+               {E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Release|Win32.ActiveCfg = Release|Win32
+               {E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Release|Win32.Build.0 = Release|Win32
+               {59075FDD-68CD-4F1A-948B-46D142800798}.Debug|Win32.ActiveCfg = Debug|Win32
+               {59075FDD-68CD-4F1A-948B-46D142800798}.Debug|Win32.Build.0 = Debug|Win32
+               {59075FDD-68CD-4F1A-948B-46D142800798}.Release|Win32.ActiveCfg = Release|Win32
+               {59075FDD-68CD-4F1A-948B-46D142800798}.Release|Win32.Build.0 = Release|Win32
+               {09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Debug|Win32.ActiveCfg = Debug|Win32
+               {09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Debug|Win32.Build.0 = Debug|Win32
+               {09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Release|Win32.ActiveCfg = Release|Win32
+               {09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Release|Win32.Build.0 = Release|Win32
+               {F41F3034-3E0B-4630-8D1E-35E14C606863}.Debug|Win32.ActiveCfg = Debug|Win32
+               {F41F3034-3E0B-4630-8D1E-35E14C606863}.Debug|Win32.Build.0 = Debug|Win32
+               {F41F3034-3E0B-4630-8D1E-35E14C606863}.Release|Win32.ActiveCfg = Release|Win32
+               {F41F3034-3E0B-4630-8D1E-35E14C606863}.Release|Win32.Build.0 = Release|Win32
+               {BA78B4B4-3268-483E-9676-911E29FD2C69}.Debug|Win32.ActiveCfg = Debug|Win32
+               {BA78B4B4-3268-483E-9676-911E29FD2C69}.Debug|Win32.Build.0 = Debug|Win32
+               {BA78B4B4-3268-483E-9676-911E29FD2C69}.Release|Win32.ActiveCfg = Release|Win32
+               {BA78B4B4-3268-483E-9676-911E29FD2C69}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/gtk/gtkvideooverlay/.gitignore b/tests/examples/gl/gtk/gtkvideooverlay/.gitignore
new file mode 100644 (file)
index 0000000..e4c3e3f
--- /dev/null
@@ -0,0 +1 @@
+gtkvideooverlay
diff --git a/tests/examples/gl/gtk/gtkvideooverlay/Makefile.am b/tests/examples/gl/gtk/gtkvideooverlay/Makefile.am
new file mode 100644 (file)
index 0000000..c9dba8a
--- /dev/null
@@ -0,0 +1,10 @@
+noinst_PROGRAMS = gtkvideooverlay
+
+gtkvideooverlay_SOURCES = main.cpp
+
+gtkvideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
+       $(GL_CFLAGS) $(GTK3_CFLAGS)
+gtkvideooverlay_LDADD=../libgstgtkhelper.la \
+       $(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
+
diff --git a/tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj b/tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj
new file mode 100644 (file)
index 0000000..f818fc6
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="gtkvideooverlay"
+       ProjectGUID="{E83070C2-58E4-48AE-AEB3-A4580EDE1212}"
+       RootNamespace="filtervideooverlay"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/gtkvideooverlay/main.cpp b/tests/examples/gl/gtk/gtkvideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..7024cfc
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "../gstgtk.h"
+
+
+static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
+{
+    // ignore anything but 'prepare-window-handle' element messages
+    if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+        return GST_BUS_PASS;
+
+    if (!gst_is_video_overlay_prepare_window_handle_message (message))
+        return GST_BUS_PASS;
+
+    g_print ("setting window handle\n");
+
+    //do not call gdk_window_ensure_native for the first time here because
+    //we are in a different thread than the main thread
+    //(and the main thread the onne)
+    gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
+
+    gst_message_unref (message);
+
+    return GST_BUS_DROP;
+}
+
+
+static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
+{
+    g_print("End of stream\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+static gboolean draw_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
+{
+    g_print ("draw_cb\n");
+    gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
+    return FALSE;
+}
+
+
+static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
+{
+    g_print("Close\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+
+static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    g_print ("GST_STATE_NULL\n");
+}
+
+
+static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    g_print ("GST_STATE_READY\n");
+}
+
+
+static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    g_print ("GST_STATE_PAUSED\n");
+}
+
+
+static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    g_print ("GST_STATE_PLAYING\n");
+}
+
+
+static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
+{
+    //change the video frame rate dynamically
+    return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
+}
+
+
+
+gint main (gint argc, gchar *argv[])
+{
+    GtkWidget *area;
+    gst_init (&argc, &argv);
+    gtk_init (&argc, &argv);
+
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+    GstElement* videosrc  = gst_element_factory_make ("videotestsrc", "videotestsrc");
+    GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
+
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
+
+    gboolean link_ok = gst_element_link_many(videosrc, videosink, NULL) ;
+    if(!link_ok)
+    {
+        g_warning("Failed to link an element!\n") ;
+        return -1;
+    }
+
+    //set window id on this event
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_add_signal_watch (bus);
+    g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
+
+    gst_element_set_state(pipeline, GST_STATE_READY);
+
+    area = gtk_drawing_area_new();
+    gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area, NULL);
+    gst_object_unref (bus);
+
+    //window that contains an area where the video is drawn
+    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request (window, 640, 480);
+    gtk_window_move (GTK_WINDOW (window), 300, 10);
+    gtk_window_set_title (GTK_WINDOW (window), "glimagesink implement the gstvideooverlay interface");
+    GdkGeometry geometry;
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
+
+    //window to control the states
+    GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
+    gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
+    gtk_window_move (GTK_WINDOW (window_control), 10, 10);
+    GtkWidget* table = gtk_grid_new ();
+    gtk_container_add (GTK_CONTAINER (window_control), table);
+
+    //control state null
+    GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
+    g_signal_connect (G_OBJECT (button_state_null), "clicked",
+        G_CALLBACK (button_state_null_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
+    gtk_widget_show (button_state_null);
+
+    //control state ready
+    GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
+    g_signal_connect (G_OBJECT (button_state_ready), "clicked",
+        G_CALLBACK (button_state_ready_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
+    gtk_widget_show (button_state_ready);
+
+    //control state paused
+    GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
+    g_signal_connect (G_OBJECT (button_state_paused), "clicked",
+        G_CALLBACK (button_state_paused_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
+    gtk_widget_show (button_state_paused);
+
+    //control state playing
+    GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
+    g_signal_connect (G_OBJECT (button_state_playing), "clicked",
+        G_CALLBACK (button_state_playing_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
+    gtk_widget_show (button_state_playing);
+
+    //change framerate
+    GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
+        1, 30, 2);
+    g_signal_connect (G_OBJECT (slider_fps), "format-value",
+        G_CALLBACK (slider_fps_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), slider_fps, 1, 0, 1, 4);
+    gtk_widget_show (slider_fps);
+
+    gtk_widget_show (table);
+    gtk_widget_show (window_control);
+
+    //configure the pipeline
+    g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
+
+    //area where the video is drawn
+    gtk_container_add (GTK_CONTAINER (window), area);
+
+    gtk_widget_realize(area);
+
+    //needed when being in GST_STATE_READY, GST_STATE_PAUSED
+    //or resizing/obscuring the window
+    g_signal_connect(area, "draw", G_CALLBACK(draw_cb), videosink);
+
+    gtk_widget_show_all (window);
+
+    gst_element_set_state(pipeline, GST_STATE_PLAYING);
+
+    gtk_main();
+
+    return 0;
+}
+
diff --git a/tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj b/tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj
new file mode 100644 (file)
index 0000000..d38ecc7
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="pixbufdrop"
+       ProjectGUID="{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}"
+       RootNamespace="pixbufdrop"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gdk_pixbuf-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gdk_pixbuf-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\fxtest\pixbufdrop.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/gtk/switchvideooverlay/.gitignore b/tests/examples/gl/gtk/switchvideooverlay/.gitignore
new file mode 100644 (file)
index 0000000..64c6de4
--- /dev/null
@@ -0,0 +1 @@
+switchvideooverlay
diff --git a/tests/examples/gl/gtk/switchvideooverlay/Makefile.am b/tests/examples/gl/gtk/switchvideooverlay/Makefile.am
new file mode 100644 (file)
index 0000000..12e25e7
--- /dev/null
@@ -0,0 +1,10 @@
+noinst_PROGRAMS = switchvideooverlay
+
+switchvideooverlay_SOURCES = main.cpp
+
+switchvideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
+       $(GL_CFLAGS) $(GTK3_CFLAGS)
+switchvideooverlay_LDADD=../libgstgtkhelper.la \
+       $(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
+       $(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
+
diff --git a/tests/examples/gl/gtk/switchvideooverlay/main.cpp b/tests/examples/gl/gtk/switchvideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..440d5ce
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "../gstgtk.h"
+
+
+static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
+{
+    // ignore anything but 'prepare-window-handle' element messages
+    if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+        return GST_BUS_PASS;
+
+    if (!gst_is_video_overlay_prepare_window_handle_message (message))
+        return GST_BUS_PASS;
+
+    g_print ("setting window handle %p\n", widget);
+
+    gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
+
+    gst_message_unref (message);
+
+    return GST_BUS_DROP;
+}
+
+
+static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
+{
+    g_print("End of stream\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+
+static gboolean expose_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
+{
+    g_print ("expose %p\n", widget);
+    g_print ("event mask: 0x%x, button_press 0x%x\n", gtk_widget_get_events (widget), GDK_BUTTON_PRESS_MASK);
+    gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
+    return FALSE;
+}
+
+static gboolean on_click_drawing_area(GtkWidget* widget, GdkEventButton* event, GstElement* videosink)
+{
+    g_print ("switch the drawing area %p\n", widget);
+    gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (videosink), widget);
+    gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
+    return FALSE;
+}
+
+
+static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
+{
+    g_print("Close\n");
+
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+
+    gtk_main_quit();
+}
+
+
+static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    g_print ("GST_STATE_NULL\n");
+}
+
+
+static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    g_print ("GST_STATE_READY\n");
+}
+
+
+static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    g_print ("GST_STATE_PAUSED\n");
+}
+
+
+static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
+{
+    gst_element_set_state (pipeline, GST_STATE_PLAYING);
+    g_print ("GST_STATE_PLAYING\n");
+}
+
+static void area_realize_cb(GtkWidget* widget, gpointer data)
+{
+    g_print ("realize %p\n", widget);
+    if (!gdk_window_ensure_native (gtk_widget_get_window (widget)))
+        g_error ("Failed to create native window!");
+
+    //avoid flickering when resizing or obscuring the main window
+    gtk_widget_set_app_paintable(widget, TRUE);
+    gtk_widget_set_double_buffered(widget, FALSE);
+}
+
+
+gint main (gint argc, gchar *argv[])
+{
+    gtk_init (&argc, &argv);
+    gst_init (&argc, &argv);
+
+    GstElement* pipeline = gst_pipeline_new ("pipeline");
+
+    //window that contains several ares where the video is drawn
+    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request (window, 640, 240);
+    gtk_window_move (GTK_WINDOW (window), 300, 10);
+    gtk_window_set_title (GTK_WINDOW (window), "click on left, right or outside the main window to switch the drawing area");
+    GdkGeometry geometry;
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
+
+    //window to control the states
+    GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    geometry.min_width = 1;
+    geometry.min_height = 1;
+    geometry.max_width = -1;
+    geometry.max_height = -1;
+    gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
+    gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
+    gtk_window_move (GTK_WINDOW (window_control), 10, 10);
+    GtkWidget* table = gtk_grid_new ();
+    gtk_container_add (GTK_CONTAINER (window_control), table);
+
+    //control state null
+    GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
+    g_signal_connect (G_OBJECT (button_state_null), "clicked",
+        G_CALLBACK (button_state_null_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
+    gtk_widget_show (button_state_null);
+
+    //control state ready
+    GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
+    g_signal_connect (G_OBJECT (button_state_ready), "clicked",
+        G_CALLBACK (button_state_ready_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
+    gtk_widget_show (button_state_ready);
+
+    //control state paused
+    GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
+    g_signal_connect (G_OBJECT (button_state_paused), "clicked",
+        G_CALLBACK (button_state_paused_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
+    gtk_widget_show (button_state_paused);
+
+    //control state playing
+    GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
+    g_signal_connect (G_OBJECT (button_state_playing), "clicked",
+        G_CALLBACK (button_state_playing_cb), pipeline);
+    gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
+    gtk_widget_show (button_state_playing);
+
+    gtk_widget_show (table);
+    gtk_widget_show (window_control);
+
+    //configure the pipeline
+    g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
+
+    GstElement* videosrc  = gst_element_factory_make ("videotestsrc", "videotestsrc");
+    GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
+
+    gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
+
+    gboolean link_ok = gst_element_link_many(videosrc, videosink, NULL);
+    if(!link_ok)
+    {
+        g_warning("Failed to link videosrc to videosink!\n") ;
+        return -1;
+    }
+
+    //areas where the video is drawn
+    GtkWidget* table_areas = gtk_grid_new ();
+    gtk_container_add (GTK_CONTAINER (window), table_areas);
+    GtkWidget* area_top_left = gtk_drawing_area_new();
+    gtk_widget_add_events(area_top_left, GDK_BUTTON_PRESS_MASK);
+    gtk_widget_set_size_request (area_top_left, 320, 240);
+    gtk_grid_attach (GTK_GRID (table_areas), area_top_left, 0, 0, 1, 1);
+    GtkWidget* area_top_right = gtk_drawing_area_new();
+    gtk_widget_add_events(area_top_right, GDK_BUTTON_PRESS_MASK);
+    gtk_widget_set_size_request (area_top_right, 320, 240);
+    gtk_grid_attach (GTK_GRID (table_areas), area_top_right, 1, 0, 1, 1);
+
+    //set window id on this event
+    g_signal_connect(area_top_left, "realize", G_CALLBACK(area_realize_cb), NULL);
+    g_signal_connect(area_top_right, "realize", G_CALLBACK(area_realize_cb), NULL);
+
+    gtk_widget_realize(area_top_left);
+    gtk_widget_realize(area_top_right);
+
+    GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+    gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area_top_right, NULL);
+    gst_bus_add_signal_watch (bus);
+    g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
+    g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
+    gst_object_unref (bus);
+
+    //needed when being in GST_STATE_READY, GST_STATE_PAUSED
+    //or resizing/obscuring the window
+    g_signal_connect(area_top_left, "draw", G_CALLBACK(expose_cb), videosink);
+    g_signal_connect(area_top_right, "draw", G_CALLBACK(expose_cb), videosink);
+
+    //switch the drawing area
+    g_signal_connect(area_top_left, "button-press-event", G_CALLBACK(on_click_drawing_area), videosink);
+    g_signal_connect(area_top_right, "button-press-event", G_CALLBACK(on_click_drawing_area), videosink);
+
+    gtk_widget_show_all (window);
+
+    gst_element_set_state(pipeline, GST_STATE_PLAYING);
+
+    gtk_main();
+
+    return 0;
+}
+
diff --git a/tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj b/tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj
new file mode 100644 (file)
index 0000000..8e48bbe
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="switchvideooverlay"
+       ProjectGUID="{BA78B4B4-3268-483E-9676-911E29FD2C69}"
+       RootNamespace="filtervideooverlay"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\gstgtk.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/qt/Makefile.am b/tests/examples/gl/qt/Makefile.am
new file mode 100644 (file)
index 0000000..629415b
--- /dev/null
@@ -0,0 +1,2 @@
+
+#SUBDIRS = videooverlay qglwidgetvideooverlay mousevideooverlay
diff --git a/tests/examples/gl/qt/README b/tests/examples/gl/qt/README
new file mode 100644 (file)
index 0000000..aa843d6
--- /dev/null
@@ -0,0 +1,23 @@
+--- Description of the Qt examples ---
+
+- mousevideooverlay:
+Show how to use the videooverlay interface through Qt.
+The cube is rotating when moving the mouse (+ click maintained)
+
+- qglvideooverlay:
+Show how to use the videooverlay interface through Qt.
+The cube is rotating automatically into a QGLWidget
+
+- videovdieooverlay:
+Show how to use the videooverlay interface through Qt.
+The video is displayed as normal 2D scene.
+The window is dynamically resized to have the same size as the original video.
+
+--- How to build the Qt examples ---
+
+sudo apt-get install g++
+sudo apt-get install libqt4-dev
+cd qglvideooverlay
+qmake
+make
+./debug/qglvideooverlay
diff --git a/tests/examples/gl/qt/mousevideooverlay/gstthread.cpp b/tests/examples/gl/qt/mousevideooverlay/gstthread.cpp
new file mode 100644 (file)
index 0000000..ce14a47
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gstthread.h"
+
+GstThread::GstThread(const WId winId, const QString videoLocation, QObject *parent):
+    QThread(parent),
+    m_winId(winId),
+    m_videoLocation(videoLocation)
+{
+}
+
+GstThread::~GstThread()
+{
+}
+
+void GstThread::exposeRequested()
+{
+    m_pipeline->exposeRequested();
+}
+
+void GstThread::onMouseMove()
+{
+    m_pipeline->rotateRequested();
+}
+
+void GstThread::show()
+{
+    emit showRequested();
+}
+
+void GstThread::stop()
+{
+    m_pipeline->stop();
+}
+
+void GstThread::run()
+{
+    m_pipeline = new Pipeline(m_winId, m_videoLocation);
+    connect(m_pipeline, SIGNAL(showRequested()), this, SLOT(show()));
+    m_pipeline->start(); //it runs the gmainloop on win32
+
+#ifndef WIN32
+    //works like the gmainloop on linux (GstEvent are handled)
+    connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
+    exec();
+#endif
+    
+    m_pipeline->unconfigure();
+}
diff --git a/tests/examples/gl/qt/mousevideooverlay/gstthread.h b/tests/examples/gl/qt/mousevideooverlay/gstthread.h
new file mode 100644 (file)
index 0000000..74f1322
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GSTTHREAD_H
+#define GSTTHREAD_H
+
+#include <QtGui>
+#include <QtCore/QThread>
+
+#include "pipeline.h"
+
+class GstThread : public QThread
+{
+    Q_OBJECT
+
+public:
+    GstThread(const WId winId, const QString videoLocation, QObject *parent = 0);
+    ~GstThread();
+
+public slots:
+    void exposeRequested();
+    void onMouseMove();
+    void show();
+    void stop();
+
+signals:
+    void showRequested();
+    
+protected:
+    void run();
+
+private:
+    const WId m_winId;
+    const QString m_videoLocation;
+    Pipeline* m_pipeline;
+
+};
+
+#endif
diff --git a/tests/examples/gl/qt/mousevideooverlay/main.cpp b/tests/examples/gl/qt/mousevideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..0cec1b9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QGuiApplication>
+#include "qrenderer.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+
+    QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file", 
+        ".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
+
+    if (videolcoation.isEmpty())
+        return -1;
+
+    QRenderer w(videolcoation);
+    w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
+
+    return a.exec();
+}
diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri
new file mode 100644 (file)
index 0000000..75b23cd
--- /dev/null
@@ -0,0 +1,10 @@
+#Header files
+HEADERS += ./gstthread.h \
+    ./pipeline.h \
+    ./qrenderer.h
+
+#Source files
+SOURCES += ./gstthread.cpp \
+    ./main.cpp \
+    ./pipeline.cpp \
+    ./qrenderer.cpp
diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro
new file mode 100644 (file)
index 0000000..efd69cd
--- /dev/null
@@ -0,0 +1,54 @@
+TEMPLATE = app
+TARGET = mousevideooverlay
+DESTDIR = ./debug
+CONFIG += debug gui widget
+DEFINES += UNICODE
+
+win32 {
+DEFINES += WIN32
+INCLUDEPATH +=  ./GeneratedFiles \
+    ./GeneratedFiles/Debug \
+    C:/gstreamer/include \
+    C:/gstreamer/include/libxml2 \
+    C:/gstreamer/include/glib-2.0 \
+    C:/gstreamer/lib/glib-2.0/include \
+    C:/gstreamer/include/gstreamer-1.0
+LIBS += -L"C:/gstreamer/lib" \
+    -L"C:/gstreamer/bin" \
+    -lgstreamer-1.0 \
+    -lgstvideo-1.0 \
+    -lglib-2.0 \
+    -lgmodule-2.0 \
+    -lgobject-2.0 \
+    -lgthread-2.0 \
+    -lopengl32 \
+    -lglu32
+}
+
+unix {
+DEFINES += UNIX
+INCLUDEPATH += GeneratedFiles \
+    GeneratedFiles/Debug \
+    /usr/include/gstreamer-1.0 \
+    /usr/local/include/gstreamer-1.0 \
+    /usr/include/glib-2.0 \
+    /usr/lib/glib-2.0/include \
+    /usr/include/libxml2
+LIBS += -lgstreamer-video \
+       -lgstvideo-1.0 \
+       -lglib-2.0 \
+       -lgmodule-2.0 \
+       -lgobject-2.0 \
+       -lgthread-2.0 \
+       -lGLU \
+       -lGL
+}    
+    
+DEPENDPATH += .
+MOC_DIR += ./GeneratedFiles/debug
+OBJECTS_DIR += debug
+UI_DIR += ./GeneratedFiles
+RCC_DIR += ./GeneratedFiles
+
+#Include file(s)
+include(mousevideooverlay.pri)
diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln
new file mode 100644 (file)
index 0000000..8d310d8
--- /dev/null
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mousevideooverlay", "mousevideooverlay.vcproj", "{E94F8CAA-628F-4872-8E73-AD56D34899CB}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {E94F8CAA-628F-4872-8E73-AD56D34899CB}.Debug|Win32.ActiveCfg = Debug|Win32
+               {E94F8CAA-628F-4872-8E73-AD56D34899CB}.Debug|Win32.Build.0 = Debug|Win32
+               {E94F8CAA-628F-4872-8E73-AD56D34899CB}.Release|Win32.ActiveCfg = Release|Win32
+               {E94F8CAA-628F-4872-8E73-AD56D34899CB}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj
new file mode 100644 (file)
index 0000000..e4b7b18
--- /dev/null
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="mousevideooverlay"
+       ProjectGUID="{E94F8CAA-628F-4872-8E73-AD56D34899CB}"
+       RootNamespace="mousevideooverlay"
+       Keyword="Qt4VSv1.0"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_NO_DEBUG,NDEBUG,QT_CORE_LIB,QT_GUI_LIB"
+                               RuntimeLibrary="2"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="0"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmain.lib QtCore4.lib QtGui4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="false"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_CORE_LIB,QT_GUI_LIB"
+                               RuntimeLibrary="3"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmaind.lib QtCored4.lib QtGuid4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;cxx;c;def"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\qrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\qrenderer.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Form Files"
+                       Filter="ui"
+                       UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="qrc;*"
+                       UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
+                       ParseFiles="false"
+                       >
+               </Filter>
+               <Filter
+                       Name="Generated Files"
+                       Filter="moc;h;cpp"
+                       UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
+                       SourceControlFiles="false"
+                       >
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_qrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+               <Global
+                       Name="MocDir"
+                       Value=".\GeneratedFiles\$(ConfigurationName)"
+               />
+               <Global
+                       Name="QtVersion"
+                       Value="qt-4.3.0"
+               />
+               <Global
+                       Name="RccDir"
+                       Value=".\GeneratedFiles"
+               />
+               <Global
+                       Name="UicDir"
+                       Value=".\GeneratedFiles"
+               />
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp b/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp
new file mode 100644 (file)
index 0000000..9f8cc76
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/video/videooverlay.h>
+#include <GL/gl.h>
+#include "pipeline.h"
+
+Pipeline::Pipeline(const WId id, const QString videoLocation):
+    m_winId(id),
+    m_videoLocation(videoLocation),
+    m_loop(NULL),
+    m_bus(NULL),
+    m_pipeline(NULL),
+    m_glimagesink(NULL)
+{
+    create();
+}
+
+Pipeline::~Pipeline()
+{
+}
+
+void Pipeline::create()
+{
+    qDebug("Loading video: %s", m_videoLocation.toAscii().data());
+
+    gst_init (NULL, NULL);
+
+#ifdef WIN32
+    m_loop = g_main_loop_new (NULL, FALSE);
+#endif
+    m_pipeline = gst_pipeline_new ("pipeline");
+
+    m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
+    gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
+    gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
+    gst_object_unref (m_bus);
+
+    GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
+    GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
+    m_glimagesink  = gst_element_factory_make ("glimagesink", "sink0");
+    
+    if (!videosrc || !decodebin || !m_glimagesink )
+    {
+        qDebug ("one element could not be found");
+        return;
+    }
+
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
+    g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toAscii().data(), NULL);
+    g_object_set(G_OBJECT(m_glimagesink), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(m_glimagesink), "client-draw-callback", drawCallback, NULL);
+
+    gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glimagesink, NULL);
+
+    gst_element_link_pads (videosrc, "src", decodebin, "sink");
+
+    g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
+}
+
+void Pipeline::start()
+{
+    GstStateChangeReturn ret = gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        qDebug ("Failed to start up pipeline!");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (m_bus, GST_MESSAGE_ERROR, 0);
+        if (msg)
+        {
+            GError *err = NULL;
+            gst_message_parse_error (msg, &err, NULL);
+            qDebug ("ERROR: %s", err->message);
+            g_error_free (err);
+            gst_message_unref (msg);
+        }
+        return;
+    }
+
+#ifdef WIN32
+    g_main_loop_run(m_loop);    
+#endif
+}
+
+//we don't want a thread safe stop in this example
+void Pipeline::stop()
+{
+#ifdef WIN32
+    g_main_loop_quit(m_loop);
+#else
+    emit stopRequested();
+#endif
+}
+
+void Pipeline::unconfigure() const
+{
+    gst_element_set_state (m_pipeline, GST_STATE_NULL);
+    gst_object_unref (m_pipeline);
+}
+
+void Pipeline::show()
+{
+    emit showRequested();
+}
+
+//redraw the current frame in the drawable
+void Pipeline::doExpose() const
+{
+    if (m_pipeline && m_glimagesink)
+        gst_video_overlay_expose (GST_VIDEO_OVERLAY (m_glimagesink));
+}
+
+//post message to g_main_loop in order to call expose
+//in the gt thread
+void Pipeline::exposeRequested()
+{
+    g_idle_add(cb_expose, this);
+}
+
+//rotate the cube
+void Pipeline::doRotate()
+{
+    m_xrot += 3.0f;
+    m_yrot += 2.0f;
+    m_zrot += 4.0f; 
+}
+
+//post message to g_main_loop in order to call rotate
+//in the gt thread
+void Pipeline::rotateRequested()
+{
+    g_idle_add(cb_rotate, this);
+}
+
+//-----------------------------------------------------------------------
+//----------------------------- static members --------------------------
+//-----------------------------------------------------------------------
+
+float Pipeline::m_xrot = 0;
+float Pipeline::m_yrot = 0;                            
+float Pipeline::m_zrot = 0;
+
+//client reshape callback
+void Pipeline::reshapeCallback (uint width, uint height)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);  
+    glMatrixMode(GL_MODELVIEW);        
+}
+
+//client draw callback
+gboolean Pipeline::drawCallback (uint texture, uint width, uint height)
+{
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;  
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+    
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        qDebug ("GRPHIC FPS = %d", nbFrames);
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+  
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+       
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(m_xrot,1.0f,0.0f,0.0f);
+    glRotatef(m_yrot,0.0f,1.0f,0.0f);
+    glRotatef(m_zrot,0.0f,0.0f,1.0f);
+
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd(); 
+
+    //return TRUE causes a postRedisplay
+    return FALSE;
+}
+
+gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
+{
+    switch (GST_MESSAGE_TYPE (msg)) 
+    {
+        case GST_MESSAGE_EOS:
+            qDebug ("End-of-stream");
+            p->stop();
+            break;
+        case GST_MESSAGE_ERROR: 
+        {
+            gchar *debug = NULL;
+            GError *err = NULL;
+            gst_message_parse_error (msg, &err, &debug);
+            qDebug ("Error: %s", err->message);
+            g_error_free (err);
+            if (debug) 
+            {
+                qDebug ("Debug deails: %s", debug);
+                g_free (debug);
+            }
+            p->stop();
+            break;
+        }
+        default:
+            break;
+    }
+
+    return TRUE;
+}
+
+void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
+{
+    GstElement* glimagesink = p->getVideoSink();
+    GstPad* glpad = gst_element_get_pad (glimagesink, "sink");
+    
+    //only link once 
+    if (GST_PAD_IS_LINKED (glpad)) 
+    {
+        gst_object_unref (glpad);
+        return;
+    }
+    
+    GstCaps* caps = gst_pad_get_caps (pad);
+    GstStructure* str = gst_caps_get_structure (caps, 0);
+    if (!g_strrstr (gst_structure_get_name (str), "video")) 
+    {
+        gst_caps_unref (caps);
+        gst_object_unref (glpad);
+        return;
+    }
+    gst_caps_unref (caps);
+
+    GstPadLinkReturn ret = gst_pad_link (pad, glpad);
+    if (ret != GST_PAD_LINK_OK) 
+        g_warning ("Failed to link with decodebin!\n");
+
+    p->show();
+}
+
+gboolean Pipeline::cb_expose (gpointer data)
+{
+    ((Pipeline*)data)->doExpose();
+    return FALSE;
+}
+
+gboolean Pipeline::cb_rotate (gpointer data)
+{
+    ((Pipeline*)data)->doRotate();
+    return FALSE;
+}
+
+GstBusSyncReply Pipeline::create_window (GstBus* bus, GstMessage* message, const Pipeline* p)
+{
+    // ignore anything but 'prepare-window-handle' element messages
+    if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+        return GST_BUS_PASS;
+
+    if (!gst_is_video_overlay_prepare_window_handle_message (message))
+        return GST_BUS_PASS;
+
+    qDebug ("setting window handle");
+
+    //Passing 0 as the window_handle will tell the overlay to stop using that window and create an internal one.
+    //In the directdrawsink's gst_video_overlay_set_window_handle implementation, window_handle (parameter 2) is casted to HWND before it used.
+    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr)p->winId());
+
+    gst_message_unref (message);
+
+    return GST_BUS_DROP;
+}
diff --git a/tests/examples/gl/qt/mousevideooverlay/pipeline.h b/tests/examples/gl/qt/mousevideooverlay/pipeline.h
new file mode 100644 (file)
index 0000000..5cdadaf
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PIPELINE_H
+#define PIPELINE_H
+
+#include <QObject>
+#include <gst/gst.h>
+//#include <QtCore/private/qeventdispatcher_glib_p.h>
+
+class Pipeline : public QObject
+{
+    Q_OBJECT
+
+public:
+    Pipeline(const WId windId, const QString videoLocation);
+    ~Pipeline();
+    void start();
+    void exposeRequested();
+    void rotateRequested();
+    void stop();
+    void unconfigure() const;
+    void show();
+    GstElement* getVideoSink() { return m_glimagesink; } ;
+
+signals:
+    void showRequested();
+    void stopRequested();
+
+private:
+    const WId m_winId;
+    const QString m_videoLocation;
+    GMainLoop* m_loop;
+    GstBus* m_bus;
+    GstElement* m_pipeline;
+    GstElement* m_glimagesink;
+    static float m_xrot;
+    static float m_yrot;
+    static float m_zrot;
+
+    void create();
+    WId winId() const { return m_winId; }
+    void doExpose() const;
+    void doRotate();
+
+    static void reshapeCallback (uint width, uint height);
+    static gboolean drawCallback (uint texture, uint width, uint height);
+    static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
+    static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
+    static gboolean cb_expose (gpointer data);
+    static gboolean cb_rotate (gpointer data);
+    static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
+};
+
+#endif
diff --git a/tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp b/tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp
new file mode 100644 (file)
index 0000000..54e94fc
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "qrenderer.h"
+
+QRenderer::QRenderer(const QString videoLocation, QWidget *parent, Qt::WFlags flags)
+    : QWidget(parent, flags),
+      m_gt(winId(), videoLocation)
+{
+    setAttribute(Qt::WA_NoSystemBackground);
+    setVisible(false);
+    move(20, 10);
+    resize(640, 480);
+
+    QObject::connect(&m_gt, SIGNAL(finished()), this, SLOT(close()));
+    QObject::connect(this, SIGNAL(exposeRequested()), &m_gt, SLOT(exposeRequested()));
+    QObject::connect(this, SIGNAL(closeRequested()), &m_gt, SLOT(stop()), Qt::DirectConnection);
+    QObject::connect(&m_gt, SIGNAL(showRequested()), this, SLOT(show()));
+    QObject::connect(this, SIGNAL(mouseMoved()), &m_gt, SLOT(onMouseMove()));
+    m_gt.start();
+}
+
+QRenderer::~QRenderer()
+{
+}
+
+void QRenderer::paintEvent(QPaintEvent* event)
+{
+    emit exposeRequested();
+}
+
+void QRenderer::mouseMoveEvent(QMouseEvent* event)
+{
+    emit mouseMoved();
+}
+
+void QRenderer::closeEvent(QCloseEvent* event)
+{
+    emit closeRequested();
+    m_gt.wait();
+}
diff --git a/tests/examples/gl/qt/mousevideooverlay/qrenderer.h b/tests/examples/gl/qt/mousevideooverlay/qrenderer.h
new file mode 100644 (file)
index 0000000..771876d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef QRENDERER_H
+#define QRENDERER_H
+
+#include <QWidget>
+#include <QString>
+#include "gstthread.h"
+
+class QRenderer : public QWidget
+{
+    Q_OBJECT
+
+public:
+    QRenderer(const QString videoLocation, QWidget *parent = 0, Qt::WFlags flags = 0);
+    ~QRenderer();
+    void paintEvent(QPaintEvent* event);
+    void mouseMoveEvent(QMouseEvent* event);
+    void closeEvent (QCloseEvent* event);
+
+signals:
+    void exposeRequested();
+    void closeRequested();
+    void mouseMoved();
+
+private:
+    GstThread m_gt;
+};
+
+#endif // QRENDERER_H
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp
new file mode 100644 (file)
index 0000000..a31f8d6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gstthread.h"
+
+GstThread::GstThread(const WId winId, const QString videoLocation, QObject *parent):
+    QThread(parent),
+    m_winId(winId),
+    m_videoLocation(videoLocation)
+{
+}
+
+GstThread::~GstThread()
+{
+}
+
+void GstThread::exposeRequested()
+{
+    m_pipeline->exposeRequested();
+}
+
+void GstThread::show()
+{
+    emit showRequested();
+}
+
+void GstThread::stop()
+{
+    m_pipeline->stop();
+}
+
+void GstThread::run()
+{
+    m_pipeline = new Pipeline(m_winId, m_videoLocation);
+    connect(m_pipeline, SIGNAL(showRequested()), this, SLOT(show()));
+    m_pipeline->start(); //it runs the gmainloop on win32
+
+#ifndef WIN32
+    //works like the gmainloop on linux (GstEvent are handled)
+    connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
+    exec();
+#endif
+    
+    m_pipeline->unconfigure();
+}
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h
new file mode 100644 (file)
index 0000000..676b987
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GSTTHREAD_H
+#define GSTTHREAD_H
+
+#include <QtGui>
+#include <QtCore/QThread>
+
+#include "pipeline.h"
+
+class GstThread : public QThread
+{
+    Q_OBJECT
+
+public:
+    GstThread(const WId winId, const QString videoLocation, QObject *parent = 0);
+    ~GstThread();
+
+public slots:
+    void exposeRequested();
+    void show();
+    void stop();
+
+signals:
+    void showRequested();
+    
+protected:
+    void run();
+
+private:
+    const WId m_winId;
+    const QString m_videoLocation;
+    Pipeline* m_pipeline;
+
+};
+
+#endif
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp
new file mode 100644 (file)
index 0000000..fa54a6b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QtGui/QApplication>
+#include "qglrenderer.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+
+    QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file", 
+        ".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
+
+    if (videolcoation.isEmpty())
+        return -1;
+
+    QGLRenderer w(videolcoation);
+    w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
+
+    return a.exec();
+}
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp
new file mode 100644 (file)
index 0000000..617524a
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/video/videooverlay.h>
+#include <GL/gl.h>
+#include "pipeline.h"
+
+Pipeline::Pipeline(const WId id, const QString videoLocation):
+    m_winId(id),
+    m_videoLocation(videoLocation),
+    m_loop(NULL),
+    m_bus(NULL),
+    m_pipeline(NULL),
+    m_glupload(NULL),
+    m_glimagesink(NULL)
+{
+    create();
+}
+
+Pipeline::~Pipeline()
+{
+}
+
+void Pipeline::create()
+{
+    qDebug("Loading video: %s", m_videoLocation.toAscii().data());
+
+    gst_init (NULL, NULL);
+
+#ifdef WIN32
+    m_loop = g_main_loop_new (NULL, FALSE);
+#endif
+    m_pipeline = gst_pipeline_new ("pipeline");
+
+    m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
+    gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
+    gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
+    gst_object_unref (m_bus);
+
+    GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
+    GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
+    m_glupload  = gst_element_factory_make ("glupload", "glupload0");
+    m_glimagesink  = gst_element_factory_make ("glimagesink", "sink0");
+    
+    if (!videosrc || !decodebin || !m_glupload || !m_glimagesink )
+    {
+        qDebug ("one element could not be found");
+        return;
+    }
+
+    GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
+                                           "width", G_TYPE_INT, 800,
+                                           "height", G_TYPE_INT, 600,
+                                           NULL) ;
+
+    g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
+    g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toAscii().data(), NULL);
+    g_object_set(G_OBJECT(m_glimagesink), "client-reshape-callback", reshapeCallback, NULL);
+    g_object_set(G_OBJECT(m_glimagesink), "client-draw-callback", drawCallback, NULL);
+
+    gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glupload, m_glimagesink, NULL);
+
+    gboolean link_ok = gst_element_link_filtered(m_glupload, m_glimagesink, outcaps) ;
+    gst_caps_unref(outcaps) ;
+    if(!link_ok)
+    {
+        qDebug("Failed to link glupload to glimagesink!\n") ;
+        return;
+    }
+
+    gst_element_link_pads (videosrc, "src", decodebin, "sink");
+
+    g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
+}
+
+void Pipeline::start()
+{
+    GstStateChangeReturn ret = gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        qDebug ("Failed to start up pipeline!");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll (m_bus, GST_MESSAGE_ERROR, 0);
+        if (msg)
+        {
+            GError *err = NULL;
+            gst_message_parse_error (msg, &err, NULL);
+            qDebug ("ERROR: %s", err->message);
+            g_error_free (err);
+            gst_message_unref (msg);
+        }
+        return;
+    }
+
+#ifdef WIN32
+    g_main_loop_run(m_loop);    
+#endif
+}
+
+//we don't want a thread safe stop in this example
+void Pipeline::stop()
+{
+#ifdef WIN32
+    g_main_loop_quit(m_loop);
+#else
+    emit stopRequested();
+#endif
+}
+
+void Pipeline::unconfigure() const
+{
+    gst_element_set_state (m_pipeline, GST_STATE_NULL);
+    gst_object_unref (m_pipeline);
+}
+
+void Pipeline::show()
+{
+    emit showRequested();
+}
+
+//redraw the current frame in the drawable
+void Pipeline::doExpose() const
+{
+    if (m_pipeline && m_glimagesink)
+        gst_video_overlay_expose (GST_VIDEO_OVERLAY (m_glimagesink));
+}
+
+//post message to g_main_loop in order to call expose
+//in the gt thread
+void Pipeline::exposeRequested()
+{
+    g_idle_add(cb_expose, this);
+}
+
+
+//-----------------------------------------------------------------------
+//----------------------------- static members --------------------------
+//-----------------------------------------------------------------------
+
+//client reshape callback
+void Pipeline::reshapeCallback (uint width, uint height)
+{
+    glViewport(0, 0, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);  
+    glMatrixMode(GL_MODELVIEW);        
+}
+
+//client draw callback
+gboolean Pipeline::drawCallback (uint texture, uint width, uint height)
+{
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;                               
+    static GLfloat     zrot = 0;
+    static GTimeVal current_time;
+    static glong last_sec = current_time.tv_sec;
+    static gint nbFrames = 0;  
+
+    g_get_current_time (&current_time);
+    nbFrames++ ;
+    
+    if ((current_time.tv_sec - last_sec) >= 1)
+    {
+        qDebug ("GRPHIC FPS = %d", nbFrames);
+        nbFrames = 0;
+        last_sec = current_time.tv_sec;
+    }
+  
+    glEnable(GL_DEPTH_TEST);
+
+    glEnable (GL_TEXTURE_2D);
+    glBindTexture (GL_TEXTURE_2D, texture);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+       
+    glTranslatef(0.0f,0.0f,-5.0f);
+
+    glRotatef(xrot,1.0f,0.0f,0.0f);
+    glRotatef(yrot,0.0f,1.0f,0.0f);
+    glRotatef(zrot,0.0f,0.0f,1.0f);
+
+    glBegin(GL_QUADS);
+             // Front Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
+             // Back Face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+             // Top Face
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+             glTexCoord2f((gfloat)width, 0.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
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
+             // Right face
+             glTexCoord2f(0.0f, 0.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);
+             glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+             // Left Face
+             glTexCoord2f((gfloat)width, 0.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);
+             glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
+    glEnd(); 
+
+       xrot+=0.03f;
+    yrot+=0.02f;
+    zrot+=0.04f;
+
+    //return TRUE causes a postRedisplay
+    return TRUE;
+}
+
+gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
+{
+    switch (GST_MESSAGE_TYPE (msg)) 
+    {
+        case GST_MESSAGE_EOS:
+            qDebug ("End-of-stream");
+            p->stop();
+            break;
+        case GST_MESSAGE_ERROR: 
+        {
+            gchar *debug = NULL;
+            GError *err = NULL;
+            gst_message_parse_error (msg, &err, &debug);
+            qDebug ("Error: %s", err->message);
+            g_error_free (err);
+            if (debug) 
+            {
+                qDebug ("Debug deails: %s", debug);
+                g_free (debug);
+            }
+            p->stop();
+            break;
+        }
+        default:
+            break;
+    }
+
+    return TRUE;
+}
+
+void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
+{
+    GstElement* glupload = p->getVideoSink();
+    GstPad* glpad = gst_element_get_pad (glupload, "sink");
+    
+    //only link once 
+    if (GST_PAD_IS_LINKED (glpad)) 
+    {
+        gst_object_unref (glpad);
+        return;
+    }
+    
+    GstCaps* caps = gst_pad_get_caps (pad);
+    GstStructure* str = gst_caps_get_structure (caps, 0);
+    if (!g_strrstr (gst_structure_get_name (str), "video")) 
+    {
+        gst_caps_unref (caps);
+        gst_object_unref (glpad);
+        return;
+    }
+    gst_caps_unref (caps);
+
+    GstPadLinkReturn ret = gst_pad_link (pad, glpad);
+    if (ret != GST_PAD_LINK_OK) 
+        g_warning ("Failed to link with decodebin!\n");
+
+    p->show();
+}
+
+gboolean Pipeline::cb_expose (gpointer data)
+{
+    ((Pipeline*)data)->doExpose();
+    return FALSE;
+}
+
+GstBusSyncReply Pipeline::create_window (GstBus* bus, GstMessage* message, const Pipeline* p)
+{
+    // ignore anything but 'prepare-window-handle' element messages
+    if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
+        return GST_BUS_PASS;
+
+    if (!gst_is_video_overlay_prepare_window_handle_message (message))
+        return GST_BUS_PASS;
+
+    qDebug ("setting window handle");
+
+    //Passing 0 as the window_handle will tell the overlay to stop using that window and create an internal one.
+    //In the directdrawsink's gst_video_overlay_set_window_handle implementation, window_handle (parameter 2) is casted to HWND before it used.
+    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr)p->winId());
+
+    gst_message_unref (message);
+
+    return GST_BUS_DROP;
+}
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h
new file mode 100644 (file)
index 0000000..51c48fc
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PIPELINE_H
+#define PIPELINE_H
+
+#include <QtGui>
+#include <gst/gst.h>
+//#include <QtCore/private/qeventdispatcher_glib_p.h>
+
+class Pipeline : public QObject
+{
+    Q_OBJECT
+
+public:
+    Pipeline(const WId windId, const QString videoLocation);
+    ~Pipeline();
+    void start();
+    void exposeRequested();
+    void stop();
+    void unconfigure() const;
+    void show();
+    GstElement* getVideoSink() { return m_glupload; } ;
+
+signals:
+    void showRequested();
+    void stopRequested();
+
+private:
+    const WId m_winId;
+    const QString m_videoLocation;
+    GMainLoop* m_loop;
+    GstBus* m_bus;
+    GstElement* m_pipeline;
+    GstElement* m_glupload;
+    GstElement* m_glimagesink;
+    static float m_xrot;
+    static float m_yrot;
+    static float m_zrot;
+
+    void create();
+    WId winId() const { return m_winId; }
+    void doExpose() const;
+
+    static void reshapeCallback (uint width, uint height);
+    static gboolean drawCallback (uint texture, uint width, uint height);
+    static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
+    static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
+    static gboolean cb_expose (gpointer data);
+    static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
+};
+
+#endif
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp
new file mode 100644 (file)
index 0000000..a54625e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "qglrenderer.h"
+
+QGLRenderer::QGLRenderer(const QString videoLocation, QWidget *parent)
+    : QGLWidget(parent),
+    m_gt(winId(), videoLocation)
+{
+    setAttribute(Qt::WA_NoSystemBackground);
+    setVisible(false);
+    move(20, 10);
+    resize(640, 480);
+
+    QObject::connect(&m_gt, SIGNAL(finished()), this, SLOT(close()));
+    QObject::connect(this, SIGNAL(exposeRequested()), &m_gt, SLOT(exposeRequested()));
+    QObject::connect(this, SIGNAL(closeRequested()), &m_gt, SLOT(stop()), Qt::DirectConnection);
+    QObject::connect(&m_gt, SIGNAL(showRequested()), this, SLOT(show()));
+    m_gt.start();
+}
+
+QGLRenderer::~QGLRenderer()
+{
+}
+
+void QGLRenderer::paintEvent(QPaintEvent* event)
+{
+    emit exposeRequested();
+}
+
+void QGLRenderer::closeEvent(QCloseEvent* event)
+{
+    emit closeRequested();
+    m_gt.wait();
+}
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h
new file mode 100644 (file)
index 0000000..aaf0d02
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef QGLRENDERER_H
+#define QGLRENDERER_H
+
+#include <QGLWidget>
+#include "gstthread.h"
+
+class QGLRenderer : public QGLWidget
+{
+    Q_OBJECT
+
+public:
+    QGLRenderer(const QString videoLocation, QWidget *parent = 0);
+    ~QGLRenderer();
+    void paintEvent(QPaintEvent* event);
+    void closeEvent (QCloseEvent* event);
+
+signals:
+    void exposeRequested();
+    void closeRequested();
+
+private:
+    GstThread m_gt;
+};
+
+#endif // QGLRENDERER_H
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri
new file mode 100644 (file)
index 0000000..772d1d4
--- /dev/null
@@ -0,0 +1,10 @@
+#Header files
+HEADERS += ./gstthread.h \
+    ./pipeline.h \
+    ./qglrenderer.h
+
+#Source files
+SOURCES += ./gstthread.cpp \
+    ./main.cpp \
+    ./pipeline.cpp \
+    ./qglrenderer.cpp
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro
new file mode 100644 (file)
index 0000000..2fa56e8
--- /dev/null
@@ -0,0 +1,55 @@
+TEMPLATE = app
+TARGET = qglwidgetvideooverlay
+DESTDIR = ./debug
+QT += opengl
+CONFIG += debug
+DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
+
+win32 {
+DEFINES += WIN32
+INCLUDEPATH +=  ./GeneratedFiles \
+    ./GeneratedFiles/Debug \
+    C:/gstreamer/include \
+    C:/gstreamer/include/libxml2 \
+    C:/gstreamer/include/glib-2.0 \
+    C:/gstreamer/lib/glib-2.0/include \
+    C:/gstreamer/include/gstreamer-1.0
+LIBS += -L"C:/gstreamer/lib" \
+    -L"C:/gstreamer/bin" \
+    -lgstreamer-1.0 \
+       -lgstvideo-1.0 \
+    -lglib-2.0 \
+    -lgmodule-2.0 \
+    -lgobject-2.0 \
+    -lgthread-2.0 \
+    -lopengl32 \
+    -lglu32
+}
+
+unix {
+DEFINES += UNIX
+INCLUDEPATH += GeneratedFiles \
+    GeneratedFiles/Debug \
+    /usr/include/gstreamer-1.0 \
+    /usr/local/include/gstreamer-1.0 \
+    /usr/include/glib-2.0 \
+    /usr/lib/glib-2.0/include \
+    /usr/include/libxml2
+LIBS += -lgstreamer-1.0 \
+    -lgstvideo-1.0 \
+       -lglib-2.0 \
+       -lgmodule-2.0 \
+       -lgobject-2.0 \
+       -lgthread-2.0 \
+       -lGLU \
+       -lGL
+}
+
+DEPENDPATH += .
+MOC_DIR += ./GeneratedFiles/debug
+OBJECTS_DIR += debug
+UI_DIR += ./GeneratedFiles
+RCC_DIR += ./GeneratedFiles
+
+#Include file(s)
+include(qglwidgetvideooverlay.pri)
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln
new file mode 100644 (file)
index 0000000..3842be0
--- /dev/null
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qglwidgetvideooverlay", "qglwidgetvideooverlay.vcproj", "{F40D2D98-281E-465F-B63F-2D473E1C2616}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {F40D2D98-281E-465F-B63F-2D473E1C2616}.Debug|Win32.ActiveCfg = Debug|Win32
+               {F40D2D98-281E-465F-B63F-2D473E1C2616}.Debug|Win32.Build.0 = Debug|Win32
+               {F40D2D98-281E-465F-B63F-2D473E1C2616}.Release|Win32.ActiveCfg = Release|Win32
+               {F40D2D98-281E-465F-B63F-2D473E1C2616}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj
new file mode 100644 (file)
index 0000000..4abca4b
--- /dev/null
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="qglwidgetvideooverlay"
+       ProjectGUID="{F40D2D98-281E-465F-B63F-2D473E1C2616}"
+       Keyword="Qt4VSv1.0"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include\QtOpenGL&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_NO_DEBUG,NDEBUG,QT_CORE_LIB,QT_GUI_LIB,QT_OPENGL_LIB"
+                               RuntimeLibrary="2"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="0"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmain.lib QtCore4.lib QtGui4.lib QtOpenGL4.lib opengl32.lib glu32.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="false"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include\QtOpenGL&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_CORE_LIB,QT_GUI_LIB,QT_OPENGL_LIB"
+                               RuntimeLibrary="3"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmaind.lib QtCored4.lib QtGuid4.lib QtOpenGLd4.lib opengl32.lib glu32.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;cxx;c;def"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\qglrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1,0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1,0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\qglrenderer.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qglrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qglrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qglrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qglrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qglrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qglrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Form Files"
+                       Filter="ui"
+                       UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="qrc;*"
+                       UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
+                       ParseFiles="false"
+                       >
+               </Filter>
+               <Filter
+                       Name="Generated Files"
+                       Filter="moc;h;cpp"
+                       UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
+                       SourceControlFiles="false"
+                       >
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\generatedfiles\debug\moc_qglrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+               <Global
+                       Name="MocDir"
+                       Value=".\GeneratedFiles\$(ConfigurationName)"
+               />
+               <Global
+                       Name="QtVersion"
+                       Value="qt-4.3.0"
+               />
+               <Global
+                       Name="RccDir"
+                       Value=".\GeneratedFiles"
+               />
+               <Global
+                       Name="UicDir"
+                       Value=".\GeneratedFiles"
+               />
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h b/tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h
new file mode 100644 (file)
index 0000000..4582bcb
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ASYNCQUEUE_H
+#define __ASYNCQUEUE_H
+
+#include <QMutex>
+#include <QWaitCondition>
+#include <QList>
+
+/**
+ * This is the thread safe implementation of the Queue.  It can be
+ * used in classical producers/consumers multithreaded scenario.  The
+ * template parameter is the class which can be put/get to/from the
+ * queue.
+ */
+template<class T>
+class AsyncQueue
+{
+public:
+    AsyncQueue() : waitingReaders(0) {}
+
+    int size()
+    {
+        QMutexLocker locker(&mutex);
+        return this->buffer.size();
+    }
+
+    void put(const T& item)
+    {
+        QMutexLocker locker(&mutex);
+        this->buffer.push_back(item);
+        if(this->waitingReaders)
+            this->bufferIsNotEmpty.wakeOne();
+    }
+
+    T get()
+    {
+        QMutexLocker locker(&mutex);
+        while(this->buffer.size() == 0)
+        {
+            ++(this->waitingReaders);
+            this->bufferIsNotEmpty.wait(&mutex);
+            --(this->waitingReaders);
+        }
+        T item = this->buffer.front();
+        this->buffer.pop_front();
+        return item;
+    }
+
+private:
+    typedef QList<T> Container;
+    QMutex mutex;
+    QWaitCondition bufferIsNotEmpty;
+    Container buffer;
+    short waitingReaders;
+};
+
+
+#endif // __ASYNCQUEUE_H
diff --git a/tests/examples/gl/qt/qglwtextureshare/README b/tests/examples/gl/qt/qglwtextureshare/README
new file mode 100644 (file)
index 0000000..305847c
--- /dev/null
@@ -0,0 +1,29 @@
+This example illustrates how to integrate Gstreamer GL plugin with
+Qt. In particular it uses glupload with fakesink elements to create
+texture with decoded video frame. This texture is shared with
+QGLWidget derived class, which paints a cube with video texture on
+each face.
+
+To compile the example, include and library paths might be adjusted in
+.pro file according to your installation of the gstreamer and
+corresponding development files. Most probably, the adjustments will
+be necessary on Windows.
+
+To run the example simply start executable file after compilation. If
+there is no command line arguments provided, then videotestsrc element
+will be used to generate video. The following pipeline will be created
+in this case:
+
+videotestsrc ! video/x-raw, width=640, height=480, framerate=(fraction)30/1 ! glupload ! fakesink sync=1
+
+It is also possible to provide the video file name as a first command
+line parameter, i.e. ./qglwtextureshare myvideo.ogv . In this case,
+the following pipeline will be executed:
+
+filesrc location=myvideo.ogv ! decodebin2 ! glupload ! fakesink sync=1
+
+I would appreciate any feedback and improvement suggestions for this
+example.
+
+Have fun :-)
+Andrey Nechypurenko (andreynech@gmail.com)
diff --git a/tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm b/tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm
new file mode 100644 (file)
index 0000000..9b1e78b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * GStreamer
+ * Copyright (C) 2010 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#import <Cocoa/Cocoa.h>
+void *qt_current_nsopengl_context()
+{
+    return [NSOpenGLContext currentContext];
+}
diff --git a/tests/examples/gl/qt/qglwtextureshare/glcontextid.h b/tests/examples/gl/qt/qglwtextureshare/glcontextid.h
new file mode 100644 (file)
index 0000000..c6a240c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ * Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GLCONTEXTID_H
+#define __GLCONTEXTID_H
+
+#include <gst/gl/gstglconfig.h>
+
+#if defined(GST_GL_HAVE_PLATFORM_WGL)
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>
+    #include <Wingdi.h>
+    #include <GL/gl.h>
+#elif defined (GST_GL_HAVE_PLATFORM_COCOA)
+    #include <OpenGL/OpenGL.h>
+    class NSOpenGLContext;
+#else
+    #include <X11/Xlib.h>
+    #include <GL/gl.h>
+    #include <GL/glu.h>
+    #include <GL/glx.h>
+#endif
+
+
+#if defined(GST_GL_HAVE_PLATFORM_WGL)
+    typedef struct _tagGLContextID
+    {
+        HGLRC contextId;
+        HDC dc;
+    } GLContextID;
+#elif  defined(GST_GL_HAVE_PLATFORM_COCOA)
+    typedef struct _tagGLContextID
+    {
+        NSOpenGLContext* contextId;
+    } GLContextID;
+#elif defined(GST_GL_HAVE_PLATFORM_GLX)
+    typedef struct _tagGLContextID
+    {
+        GLXContext contextId;
+        Display *display;
+        Window wnd;
+    } GLContextID;
+#endif
+
+#endif // __GLCONTEXTID_H
+
diff --git a/tests/examples/gl/qt/qglwtextureshare/gstthread.cpp b/tests/examples/gl/qt/qglwtextureshare/gstthread.cpp
new file mode 100644 (file)
index 0000000..2a1ff69
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "pipeline.h"
+#include "gstthread.h"
+
+
+GstThread::GstThread(GstGLContext *context,
+        const QString &videoLocation,
+        const char *renderer_slot,
+        QObject *parent):
+    QThread(parent),
+    m_videoLocation(videoLocation)
+{
+    this->context = context;
+    m_pipeline = new Pipeline(this->context, m_videoLocation, this);
+    QObject::connect(m_pipeline, SIGNAL(newFrameReady()), this->parent(), renderer_slot, Qt::QueuedConnection);
+}
+
+GstThread::~GstThread()
+{
+}
+
+void GstThread::stop()
+{
+    if(m_pipeline)
+      m_pipeline->stop();
+}
+
+void GstThread::run()
+{
+    qDebug("Starting gst pipeline");
+    m_pipeline->start(); //it runs the gmainloop on win32
+
+#ifndef Q_WS_WIN
+    //works like the gmainloop on linux (GstEvent are handled)
+    connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
+    exec();
+#endif
+
+    m_pipeline->unconfigure();
+
+    m_pipeline = NULL;
+    // This is not a memory leak. Pipeline will be deleted
+    // when the parent object (this) will be destroyed.
+    // We set m_pipeline to NULL to prevent further attempts
+    // to stop already stopped pipeline
+}
diff --git a/tests/examples/gl/qt/qglwtextureshare/gstthread.h b/tests/examples/gl/qt/qglwtextureshare/gstthread.h
new file mode 100644 (file)
index 0000000..918859e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GSTTHREAD_H
+#define GSTTHREAD_H
+
+#include <QThread>
+
+#include <gst/gl/gstglcontext.h>
+
+#include "glcontextid.h"
+
+class Pipeline;
+
+class GstThread : public QThread
+{
+    Q_OBJECT
+
+public:
+    GstThread(GstGLContext *context,
+            const QString &videoLocation,
+            const char *renderer_slot,
+            QObject *parent = 0);
+
+    ~GstThread();
+
+    Pipeline *getPipeline() {return this->m_pipeline;}
+
+public Q_SLOTS:
+    void stop();
+
+protected:
+    void run();
+
+private:
+    GstGLContext *context;
+    const QString m_videoLocation;
+    Pipeline* m_pipeline;
+};
+
+#endif
diff --git a/tests/examples/gl/qt/qglwtextureshare/main.cpp b/tests/examples/gl/qt/qglwtextureshare/main.cpp
new file mode 100644 (file)
index 0000000..f2eb2f1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QApplication>
+#include "qglrenderer.h"
+
+
+int
+main(int argc, char *argv[])
+{
+  QApplication a(argc, argv);
+  a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+  QGLRenderer w(argc > 1 ? argv[1] : "");
+  w.setWindowTitle("Texture sharing example");
+  w.show();
+  return a.exec();
+}
+
diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp
new file mode 100644 (file)
index 0000000..1787e38
--- /dev/null
@@ -0,0 +1,109 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'gstthread.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "gstthread.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'gstthread.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_GstThread_t {
+    QByteArrayData data[3];
+    char stringdata[17];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_GstThread_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_GstThread_t qt_meta_stringdata_GstThread = {
+    {
+QT_MOC_LITERAL(0, 0, 9),
+QT_MOC_LITERAL(1, 10, 4),
+QT_MOC_LITERAL(2, 15, 0)
+    },
+    "GstThread\0stop\0\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_GstThread[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       1,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+ // slots: name, argc, parameters, tag, flags
+       1,    0,   19,    2, 0x0a,
+
+ // slots: parameters
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void GstThread::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        GstThread *_t = static_cast<GstThread *>(_o);
+        switch (_id) {
+        case 0: _t->stop(); break;
+        default: ;
+        }
+    }
+    Q_UNUSED(_a);
+}
+
+const QMetaObject GstThread::staticMetaObject = {
+    { &QThread::staticMetaObject, qt_meta_stringdata_GstThread.data,
+      qt_meta_data_GstThread,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *GstThread::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *GstThread::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_GstThread.stringdata))
+        return static_cast<void*>(const_cast< GstThread*>(this));
+    return QThread::qt_metacast(_clname);
+}
+
+int GstThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QThread::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 1)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 1;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 1)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 1;
+    }
+    return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp
new file mode 100644 (file)
index 0000000..fdf0cf7
--- /dev/null
@@ -0,0 +1,140 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'pipeline.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "pipeline.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'pipeline.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_Pipeline_t {
+    QByteArrayData data[4];
+    char stringdata[39];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_Pipeline_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_Pipeline_t qt_meta_stringdata_Pipeline = {
+    {
+QT_MOC_LITERAL(0, 0, 8),
+QT_MOC_LITERAL(1, 9, 13),
+QT_MOC_LITERAL(2, 23, 0),
+QT_MOC_LITERAL(3, 24, 13)
+    },
+    "Pipeline\0newFrameReady\0\0stopRequested\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_Pipeline[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       2,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       2,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    0,   24,    2, 0x06,
+       3,    0,   25,    2, 0x06,
+
+ // signals: parameters
+    QMetaType::Void,
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void Pipeline::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        Pipeline *_t = static_cast<Pipeline *>(_o);
+        switch (_id) {
+        case 0: _t->newFrameReady(); break;
+        case 1: _t->stopRequested(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        void **func = reinterpret_cast<void **>(_a[1]);
+        {
+            typedef void (Pipeline::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::newFrameReady)) {
+                *result = 0;
+            }
+        }
+        {
+            typedef void (Pipeline::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::stopRequested)) {
+                *result = 1;
+            }
+        }
+    }
+    Q_UNUSED(_a);
+}
+
+const QMetaObject Pipeline::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_Pipeline.data,
+      qt_meta_data_Pipeline,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *Pipeline::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *Pipeline::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_Pipeline.stringdata))
+        return static_cast<void*>(const_cast< Pipeline*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int Pipeline::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 2)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 2;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 2)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 2;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void Pipeline::newFrameReady()
+{
+    QMetaObject::activate(this, &staticMetaObject, 0, 0);
+}
+
+// SIGNAL 1
+void Pipeline::stopRequested()
+{
+    QMetaObject::activate(this, &staticMetaObject, 1, 0);
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp
new file mode 100644 (file)
index 0000000..5a11b71
--- /dev/null
@@ -0,0 +1,132 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'qglrenderer.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "qglrenderer.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'qglrenderer.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_QGLRenderer_t {
+    QByteArrayData data[4];
+    char stringdata[38];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_QGLRenderer_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_QGLRenderer_t qt_meta_stringdata_QGLRenderer = {
+    {
+QT_MOC_LITERAL(0, 0, 11),
+QT_MOC_LITERAL(1, 12, 14),
+QT_MOC_LITERAL(2, 27, 0),
+QT_MOC_LITERAL(3, 28, 8)
+    },
+    "QGLRenderer\0closeRequested\0\0newFrame\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QGLRenderer[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       2,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       1,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    0,   24,    2, 0x06,
+
+ // slots: name, argc, parameters, tag, flags
+       3,    0,   25,    2, 0x0a,
+
+ // signals: parameters
+    QMetaType::Void,
+
+ // slots: parameters
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void QGLRenderer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        QGLRenderer *_t = static_cast<QGLRenderer *>(_o);
+        switch (_id) {
+        case 0: _t->closeRequested(); break;
+        case 1: _t->newFrame(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        void **func = reinterpret_cast<void **>(_a[1]);
+        {
+            typedef void (QGLRenderer::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QGLRenderer::closeRequested)) {
+                *result = 0;
+            }
+        }
+    }
+    Q_UNUSED(_a);
+}
+
+const QMetaObject QGLRenderer::staticMetaObject = {
+    { &QGLWidget::staticMetaObject, qt_meta_stringdata_QGLRenderer.data,
+      qt_meta_data_QGLRenderer,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *QGLRenderer::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QGLRenderer::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_QGLRenderer.stringdata))
+        return static_cast<void*>(const_cast< QGLRenderer*>(this));
+    return QGLWidget::qt_metacast(_clname);
+}
+
+int QGLRenderer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QGLWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 2)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 2;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 2)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 2;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void QGLRenderer::closeRequested()
+{
+    QMetaObject::activate(this, &staticMetaObject, 0, 0);
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/qglwtextureshare/pipeline.cpp b/tests/examples/gl/qt/qglwtextureshare/pipeline.cpp
new file mode 100644 (file)
index 0000000..a7dd490
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "pipeline.h"
+
+
+Pipeline::Pipeline(GstGLContext *context,
+                   const QString &videoLocation,
+                   QObject *parent)
+  : QObject(parent),
+    m_videoLocation(videoLocation),
+    m_loop(NULL),
+    m_bus(NULL),
+    m_pipeline(NULL)
+{
+    this->context = context;
+    this->configure();
+}
+
+Pipeline::~Pipeline()
+{
+}
+
+void
+Pipeline::configure()
+{
+    gst_init (NULL, NULL);
+
+#ifdef Q_WS_WIN
+    m_loop = g_main_loop_new (NULL, FALSE);
+#endif
+
+    if(m_videoLocation.isEmpty())
+    {
+        qDebug("No video file specified. Using video test source.");
+        m_pipeline =
+            GST_PIPELINE (gst_parse_launch
+                      ("videotestsrc ! "
+                       "video/x-raw, width=640, height=480, "
+                       "framerate=(fraction)30/1 ! "
+                       "gleffects effect=5 ! fakesink sync=1",
+                       NULL));
+    }
+    else
+    {
+        QByteArray ba = m_videoLocation.toLocal8Bit();
+        qDebug("Loading video: %s", ba.data());
+        gchar *pipeline = g_strdup_printf ("filesrc location='%s' ! "
+                               "decodebin ! gleffects effect=5 ! "
+                               "fakesink sync=1", ba.data());
+        m_pipeline = GST_PIPELINE (gst_parse_launch (pipeline, NULL));
+        g_free (pipeline);
+    }
+
+    m_bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
+    gst_bus_add_watch(m_bus, (GstBusFunc) bus_call, this);
+    gst_object_unref(m_bus);
+
+    /* Retrieve the last gl element */
+    GstElement *gl_element = gst_bin_get_by_name(GST_BIN(m_pipeline), "gleffects0");
+    if(!gl_element)
+    {
+        qDebug ("gl element could not be found");
+        return;
+    }
+    g_object_set(G_OBJECT (gl_element), "other-context",
+               this->context, NULL);
+    gst_object_unref(gl_element);
+
+    gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_PAUSED);
+    GstState state = GST_STATE_PAUSED;
+    if(gst_element_get_state(GST_ELEMENT(this->m_pipeline),
+            &state, NULL, GST_CLOCK_TIME_NONE)
+            != GST_STATE_CHANGE_SUCCESS)
+    {
+        qDebug("failed to pause pipeline");
+        return;
+    }
+}
+
+void
+Pipeline::start()
+{
+    // set a callback to retrieve the gst gl textures
+    GstElement *fakesink = gst_bin_get_by_name(GST_BIN(this->m_pipeline),
+        "fakesink0");
+    g_object_set(G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
+    g_signal_connect(fakesink, "handoff", G_CALLBACK (on_gst_buffer), this);
+    gst_object_unref(fakesink);
+
+    GstStateChangeReturn ret =
+    gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        qDebug("Failed to start up pipeline!");
+
+        /* check if there is an error message with details on the bus */
+        GstMessage* msg = gst_bus_poll(this->m_bus, GST_MESSAGE_ERROR, 0);
+        if (msg)
+        {
+            GError *err = NULL;
+            gst_message_parse_error (msg, &err, NULL);
+            qDebug ("ERROR: %s", err->message);
+            g_error_free (err);
+            gst_message_unref (msg);
+        }
+        return;
+    }
+
+#ifdef Q_WS_WIN
+    g_main_loop_run(m_loop);
+#endif
+}
+
+/* fakesink handoff callback */
+void
+Pipeline::on_gst_buffer(GstElement * element,
+                        GstBuffer * buf,
+                        GstPad * pad,
+                        Pipeline* p)
+{
+    Q_UNUSED(pad)
+    Q_UNUSED(element)
+
+    /* ref then push buffer to use it in qt */
+    gst_buffer_ref(buf);
+    p->queue_input_buf.put(buf);
+
+    if (p->queue_input_buf.size() > 3)
+        p->notifyNewFrame();
+
+    /* pop then unref buffer we have finished to use in qt */
+    if (p->queue_output_buf.size() > 3)
+    {
+        GstBuffer *buf_old = (p->queue_output_buf.get());
+        if (buf_old)
+            gst_buffer_unref(buf_old);
+    }
+}
+
+void
+Pipeline::stop()
+{
+#ifdef Q_WS_WIN
+    g_main_loop_quit(m_loop);
+#else
+    emit stopRequested();
+#endif
+}
+
+void
+Pipeline::unconfigure()
+{
+    gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_NULL);
+
+    GstBuffer *buf;
+    while(this->queue_input_buf.size())
+    {
+        buf = (GstBuffer*)(this->queue_input_buf.get());
+        gst_buffer_unref(buf);
+    }
+    while(this->queue_output_buf.size())
+    {
+        buf = (GstBuffer*)(this->queue_output_buf.get());
+        gst_buffer_unref(buf);
+    }
+
+    gst_object_unref(m_pipeline);
+}
+
+gboolean
+Pipeline::bus_call(GstBus *bus, GstMessage *msg, Pipeline* p)
+{
+  Q_UNUSED(bus)
+
+    switch(GST_MESSAGE_TYPE(msg))
+    {
+        case GST_MESSAGE_EOS:
+            qDebug("End-of-stream received. Stopping.");
+            p->stop();
+        break;
+
+        case GST_MESSAGE_ERROR:
+        {
+            gchar *debug = NULL;
+            GError *err = NULL;
+            gst_message_parse_error(msg, &err, &debug);
+            qDebug("Error: %s", err->message);
+            g_error_free (err);
+            if(debug)
+            {
+            qDebug("Debug deails: %s", debug);
+            g_free(debug);
+            }
+            p->stop();
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    return TRUE;
+}
diff --git a/tests/examples/gl/qt/qglwtextureshare/pipeline.h b/tests/examples/gl/qt/qglwtextureshare/pipeline.h
new file mode 100644 (file)
index 0000000..5e59f1a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PIPELINE_H
+#define PIPELINE_H
+
+#include <QObject>
+
+#include <gst/gl/gstglcontext.h>
+
+#include "glcontextid.h"
+#include "AsyncQueue.h"
+
+
+class Pipeline : public QObject
+{
+    Q_OBJECT
+
+public:
+    Pipeline(GstGLContext *context,
+        const QString &videoLocation,
+        QObject *parent);
+    ~Pipeline();
+
+    void configure();
+    void start();
+    void notifyNewFrame() {emit newFrameReady();}
+    void stop();
+    void unconfigure();
+
+    AsyncQueue<GstBuffer*> queue_input_buf;
+    AsyncQueue<GstBuffer*> queue_output_buf;
+
+Q_SIGNALS:
+    void newFrameReady();
+    void stopRequested();
+
+private:
+    GstGLContext *context;
+    const QString m_videoLocation;
+    GMainLoop* m_loop;
+    GstBus* m_bus;
+    GstPipeline* m_pipeline;
+    static float m_xrot;
+    static float m_yrot;
+    static float m_zrot;
+
+    static void on_gst_buffer(GstElement * element, GstBuffer * buf, GstPad * pad, Pipeline* p);
+    static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
+};
+
+#endif
diff --git a/tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp
new file mode 100644 (file)
index 0000000..303e4f1
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ * Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QGLWidget>
+#include <QApplication>
+#include <QCloseEvent>
+
+#include <gst/video/video.h>
+#include <gst/gl/gstglmemory.h>
+
+#include "gstthread.h"
+#include "qglrenderer.h"
+#include "pipeline.h"
+
+#if defined(Q_WS_MAC)
+extern void *qt_current_nsopengl_context();
+#endif
+
+QGLRenderer::QGLRenderer(const QString &videoLocation,
+                         QWidget *parent)
+  : QGLWidget(parent),
+    videoLoc(videoLocation),
+    gst_thread(NULL),
+    closing(false),
+    frame(NULL)
+{
+    move(20, 10);
+    resize(640, 480);
+}
+
+QGLRenderer::~QGLRenderer()
+{
+}
+
+void
+QGLRenderer::initializeGL()
+{
+    GstGLContext *context;
+    GstGLDisplay *display;
+
+    display = gst_gl_display_new ();
+
+    /* FIXME: Allow the choice at runtime */
+#if defined(GST_GL_HAVE_PLATFORM_WGL)
+    context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (), GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
+#elif defined (GST_GL_HAVE_PLATFORM_COCOA)
+    context = gst_gl_context_new_wrapped (display, (guintptr) qt_current_nsopengl_context(), GST_GL_PLATFORM_COCOA, GST_GL_API_OPENGL);
+#elif defined(GST_GL_HAVE_PLATFORM_GLX)
+    context = gst_gl_context_new_wrapped (display, (guintptr) glXGetCurrentContext (), GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
+#endif
+    gst_object_unref (display);
+
+    // We need to unset Qt context before initializing gst-gl plugin.
+    // Otherwise the attempt to share gst-gl context with Qt will fail.
+    this->doneCurrent();
+    this->gst_thread = 
+      new GstThread(context, this->videoLoc, SLOT(newFrame()), this);
+    this->makeCurrent();
+
+    QObject::connect(this->gst_thread, SIGNAL(finished()),
+                   this, SLOT(close()));
+    QObject::connect(this, SIGNAL(closeRequested()),
+                   this->gst_thread, SLOT(stop()), Qt::QueuedConnection);
+
+    qglClearColor(QApplication::palette().color(QPalette::Active,
+                                                QPalette::Window));
+    //glShadeModel(GL_FLAT);
+    //glEnable(GL_DEPTH_TEST);
+    //glEnable(GL_CULL_FACE);
+    glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
+
+    this->gst_thread->start();
+}
+
+void
+QGLRenderer::resizeGL(int width, int height)
+{
+  // Reset The Current Viewport And Perspective Transformation
+  glViewport(0, 0, width, height);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+
+  gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
+  glMatrixMode(GL_MODELVIEW);
+}
+
+void
+QGLRenderer::newFrame()
+{
+    Pipeline *pipeline = this->gst_thread->getPipeline();
+    if(!pipeline)
+      return;
+
+    /* frame is initialized as null */
+    if (this->frame)
+        pipeline->queue_output_buf.put(this->frame);
+
+    this->frame = pipeline->queue_input_buf.get();
+
+    /* direct call to paintGL (no queued) */
+    this->updateGL();
+}
+
+void
+QGLRenderer::paintGL()
+{
+    static GLfloat     xrot = 0;
+    static GLfloat     yrot = 0;
+    static GLfloat     zrot = 0;
+
+    if (this->frame)
+    {
+        guint tex_id;
+        GstMemory *mem;
+        GstVideoInfo v_info;
+        GstVideoFrame v_frame;
+        GstVideoMeta *v_meta;
+
+        mem = gst_buffer_peek_memory (this->frame, 0);
+        v_meta = gst_buffer_get_video_meta (this->frame);
+
+        if (gst_is_gl_memory (mem)) {
+            gst_video_info_set_format (&v_info, v_meta->format, v_meta->width,
+                v_meta->height);
+
+            gst_video_frame_map (&v_frame, &v_info, this->frame,
+                (GstMapFlags) (GST_MAP_READ | GST_MAP_GL));
+
+            tex_id = *(guint *) v_frame.data[0];
+        }
+
+        glEnable(GL_DEPTH_TEST);
+
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, tex_id);
+        if(glGetError () != GL_NO_ERROR)
+        {
+          qDebug ("failed to bind texture that comes from gst-gl");
+          emit closeRequested();
+          return;
+        }
+
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                      GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                      GL_CLAMP_TO_EDGE);
+        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
+
+        glTranslatef(0.0f,0.0f,-5.0f);
+
+        glRotatef(xrot,1.0f,0.0f,0.0f);
+        glRotatef(yrot,0.0f,1.0f,0.0f);
+        glRotatef(zrot,0.0f,0.0f,1.0f);
+
+        glBegin(GL_QUADS);
+            // Front Face
+            glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+            glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+            glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+            // Back Face
+            glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+            glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+            glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+            // Top Face
+            glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+            glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+            glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+            // Bottom Face
+            glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+            glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+            glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+            // Right face
+            glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+            glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+            glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+            // Left Face
+            glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+            glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+            glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+            glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+        glEnd();
+
+        xrot+=0.3f;
+        yrot+=0.2f;
+        zrot+=0.4f;
+
+        glBindTexture(GL_TEXTURE_2D, 0);
+    }
+}
+
+void
+QGLRenderer::closeEvent(QCloseEvent* event)
+{
+    if(this->closing == false)
+    {
+        this->closing = true;
+        emit closeRequested();
+        event->ignore();
+    }
+}
diff --git a/tests/examples/gl/qt/qglwtextureshare/qglrenderer.h b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.h
new file mode 100644 (file)
index 0000000..0bf354b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef QGLRENDERER_H
+#define QGLRENDERER_H
+
+#include <QGLWidget>
+
+#include <gst/gl/gstglcontext.h>
+
+
+class GstThread;
+
+class QGLRenderer : public QGLWidget
+{
+    Q_OBJECT
+
+public:
+    QGLRenderer(const QString &videoLocation, QWidget *parent = 0);
+    ~QGLRenderer();
+
+    void closeEvent(QCloseEvent* event);
+
+Q_SIGNALS:
+    void closeRequested();
+
+public Q_SLOTS:
+    void newFrame();
+
+protected:
+    virtual void initializeGL();
+    virtual void resizeGL(int width, int height);
+    virtual void paintGL();
+
+private:
+    QString videoLoc;
+    GstThread *gst_thread;
+    bool closing;
+    GstBuffer *frame;
+};
+
+#endif // QGLRENDERER_H
diff --git a/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare
new file mode 100755 (executable)
index 0000000..c32aedf
Binary files /dev/null and b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare differ
diff --git a/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro
new file mode 100644 (file)
index 0000000..13014ac
--- /dev/null
@@ -0,0 +1,83 @@
+TEMPLATE = app
+TARGET = qglwtextureshare
+QT += opengl
+
+# Add console to the CONFIG to see debug messages printed in 
+# the console on Windows
+# CONFIG += console
+DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
+
+win32 {
+DEFINES += WIN32
+INCLUDEPATH += \
+    C:/gstreamer/include \
+    C:/gstreamer/include/libxml2 \
+    C:/gstreamer/include/glib-2.0 \
+    C:/gstreamer/lib/glib-2.0/include \
+    C:/gstreamer/include/gstreamer-1.0
+LIBS += -L"C:/gstreamer/lib" \
+    -L"C:/gstreamer/bin" \
+    -lgstreamer-1.0 \
+    -lgstvideo-1.0 \
+    -lglib-2.0 \
+    -lgmodule-2.0 \
+    -lgobject-2.0 \
+    -lgthread-2.0 \
+    -lgstvideo-1.0 \
+    -lopengl32 \
+    -lglu32
+}
+unix:!mac {
+    DEFINES += UNIX
+    INCLUDEPATH += /home/matt/Projects/jhbuild/native/usr/include/gstreamer-1.0 \
+        /home/matt/Projects/jhbuild/native/usr/include/glib-2.0 \
+        /home/matt/Projects/jhbuild/native/usr/lib/glib-2.0/include \
+        /usr/include/gstreamer-1.0 \
+        /usr/local/include/gstreamer-1.0 \
+        /usr/include/glib-2.0 \
+        /usr/lib/glib-2.0/include \
+        /usr/include/libxml2
+    LIBS += -L/home/matt/Projects/jhbuild/native/usr/lib \
+        -lgstreamer-1.0 \
+        -lgstvideo-1.0 \
+        -lglib-2.0 \
+        -lgmodule-2.0 \
+        -lgobject-2.0 \
+        -lgthread-2.0 \
+        -lgstgl-1.0 \
+        -lGLU \
+        -lGL
+}
+mac {
+    DEFINES += MACOSX
+    INCLUDEPATH += /opt/local/include/ \
+        /opt/local/include/gstreamer-1.0/ \
+        /opt/local/include/glib-2.0/ \
+        /opt/local/lib/glib-2.0/include \
+        /opt/local/include/libxml2
+    LIBS += -L/opt/local/lib \
+        -lgstreamer-1.0 \
+        -lgstapp-1.0 \
+        -lgstvideo-1.0 \
+        -lglib-2.0 \
+        -lgobject-2.0 \
+        -lcxcore \
+        -lcvaux \
+        -lcv
+    OBJECTIVE_SOURCES +=  cocoa_utils.mm
+    LIBS += -framework AppKit
+}
+DEPENDPATH += .
+
+# Header files
+HEADERS += gstthread.h \
+    pipeline.h \
+    qglrenderer.h \
+    AsyncQueue.h \
+    glcontextid.h
+
+# Source files
+SOURCES += gstthread.cpp \
+    main.cpp \
+    pipeline.cpp \
+    qglrenderer.cpp
diff --git a/tests/examples/gl/qt/videooverlay/Debug/videooverlay b/tests/examples/gl/qt/videooverlay/Debug/videooverlay
new file mode 100755 (executable)
index 0000000..3651f2b
Binary files /dev/null and b/tests/examples/gl/qt/videooverlay/Debug/videooverlay differ
diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp
new file mode 100644 (file)
index 0000000..7982306
--- /dev/null
@@ -0,0 +1,143 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'gstthread.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "../../gstthread.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'gstthread.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_GstThread_t {
+    QByteArrayData data[8];
+    char stringdata[69];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_GstThread_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_GstThread_t qt_meta_stringdata_GstThread = {
+    {
+QT_MOC_LITERAL(0, 0, 9),
+QT_MOC_LITERAL(1, 10, 15),
+QT_MOC_LITERAL(2, 26, 0),
+QT_MOC_LITERAL(3, 27, 5),
+QT_MOC_LITERAL(4, 33, 6),
+QT_MOC_LITERAL(5, 40, 15),
+QT_MOC_LITERAL(6, 56, 6),
+QT_MOC_LITERAL(7, 63, 4)
+    },
+    "GstThread\0resizeRequested\0\0width\0"
+    "height\0exposeRequested\0resize\0stop\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_GstThread[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       4,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       1,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    2,   34,    2, 0x06,
+
+ // slots: name, argc, parameters, tag, flags
+       5,    0,   39,    2, 0x0a,
+       6,    2,   40,    2, 0x0a,
+       7,    0,   45,    2, 0x0a,
+
+ // signals: parameters
+    QMetaType::Void, QMetaType::Int, QMetaType::Int,    3,    4,
+
+ // slots: parameters
+    QMetaType::Void,
+    QMetaType::Void, QMetaType::Int, QMetaType::Int,    3,    4,
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void GstThread::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        GstThread *_t = static_cast<GstThread *>(_o);
+        switch (_id) {
+        case 0: _t->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
+        case 1: _t->exposeRequested(); break;
+        case 2: _t->resize((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
+        case 3: _t->stop(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        void **func = reinterpret_cast<void **>(_a[1]);
+        {
+            typedef void (GstThread::*_t)(int , int );
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&GstThread::resizeRequested)) {
+                *result = 0;
+            }
+        }
+    }
+}
+
+const QMetaObject GstThread::staticMetaObject = {
+    { &QThread::staticMetaObject, qt_meta_stringdata_GstThread.data,
+      qt_meta_data_GstThread,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *GstThread::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *GstThread::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_GstThread.stringdata))
+        return static_cast<void*>(const_cast< GstThread*>(this));
+    return QThread::qt_metacast(_clname);
+}
+
+int GstThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QThread::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 4)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 4;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 4)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 4;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void GstThread::resizeRequested(int _t1, int _t2)
+{
+    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
+    QMetaObject::activate(this, &staticMetaObject, 0, _a);
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp
new file mode 100644 (file)
index 0000000..dff3f77
--- /dev/null
@@ -0,0 +1,143 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'pipeline.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "../../pipeline.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'pipeline.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_Pipeline_t {
+    QByteArrayData data[6];
+    char stringdata[54];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_Pipeline_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_Pipeline_t qt_meta_stringdata_Pipeline = {
+    {
+QT_MOC_LITERAL(0, 0, 8),
+QT_MOC_LITERAL(1, 9, 15),
+QT_MOC_LITERAL(2, 25, 0),
+QT_MOC_LITERAL(3, 26, 5),
+QT_MOC_LITERAL(4, 32, 6),
+QT_MOC_LITERAL(5, 39, 13)
+    },
+    "Pipeline\0resizeRequested\0\0width\0height\0"
+    "stopRequested\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_Pipeline[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       2,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       2,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    2,   24,    2, 0x06,
+       5,    0,   29,    2, 0x06,
+
+ // signals: parameters
+    QMetaType::Void, QMetaType::Int, QMetaType::Int,    3,    4,
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void Pipeline::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        Pipeline *_t = static_cast<Pipeline *>(_o);
+        switch (_id) {
+        case 0: _t->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
+        case 1: _t->stopRequested(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        void **func = reinterpret_cast<void **>(_a[1]);
+        {
+            typedef void (Pipeline::*_t)(int , int );
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::resizeRequested)) {
+                *result = 0;
+            }
+        }
+        {
+            typedef void (Pipeline::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::stopRequested)) {
+                *result = 1;
+            }
+        }
+    }
+}
+
+const QMetaObject Pipeline::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_Pipeline.data,
+      qt_meta_data_Pipeline,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *Pipeline::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *Pipeline::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_Pipeline.stringdata))
+        return static_cast<void*>(const_cast< Pipeline*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int Pipeline::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 2)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 2;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 2)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 2;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void Pipeline::resizeRequested(int _t1, int _t2)
+{
+    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
+    QMetaObject::activate(this, &staticMetaObject, 0, _a);
+}
+
+// SIGNAL 1
+void Pipeline::stopRequested()
+{
+    QMetaObject::activate(this, &staticMetaObject, 1, 0);
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp
new file mode 100644 (file)
index 0000000..007373b
--- /dev/null
@@ -0,0 +1,150 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'qrenderer.h'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "../../qrenderer.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'qrenderer.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.2.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+struct qt_meta_stringdata_QRenderer_t {
+    QByteArrayData data[7];
+    char stringdata[72];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    offsetof(qt_meta_stringdata_QRenderer_t, stringdata) + ofs \
+        - idx * sizeof(QByteArrayData) \
+    )
+static const qt_meta_stringdata_QRenderer_t qt_meta_stringdata_QRenderer = {
+    {
+QT_MOC_LITERAL(0, 0, 9),
+QT_MOC_LITERAL(1, 10, 15),
+QT_MOC_LITERAL(2, 26, 0),
+QT_MOC_LITERAL(3, 27, 14),
+QT_MOC_LITERAL(4, 42, 15),
+QT_MOC_LITERAL(5, 58, 5),
+QT_MOC_LITERAL(6, 64, 6)
+    },
+    "QRenderer\0exposeRequested\0\0closeRequested\0"
+    "resizeRequested\0width\0height\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QRenderer[] = {
+
+ // content:
+       7,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       3,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       2,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    0,   29,    2, 0x06,
+       3,    0,   30,    2, 0x06,
+
+ // slots: name, argc, parameters, tag, flags
+       4,    2,   31,    2, 0x0a,
+
+ // signals: parameters
+    QMetaType::Void,
+    QMetaType::Void,
+
+ // slots: parameters
+    QMetaType::Void, QMetaType::Int, QMetaType::Int,    5,    6,
+
+       0        // eod
+};
+
+void QRenderer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        QRenderer *_t = static_cast<QRenderer *>(_o);
+        switch (_id) {
+        case 0: _t->exposeRequested(); break;
+        case 1: _t->closeRequested(); break;
+        case 2: _t->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        void **func = reinterpret_cast<void **>(_a[1]);
+        {
+            typedef void (QRenderer::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QRenderer::exposeRequested)) {
+                *result = 0;
+            }
+        }
+        {
+            typedef void (QRenderer::*_t)();
+            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QRenderer::closeRequested)) {
+                *result = 1;
+            }
+        }
+    }
+}
+
+const QMetaObject QRenderer::staticMetaObject = {
+    { &QWidget::staticMetaObject, qt_meta_stringdata_QRenderer.data,
+      qt_meta_data_QRenderer,  qt_static_metacall, 0, 0}
+};
+
+
+const QMetaObject *QRenderer::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QRenderer::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_QRenderer.stringdata))
+        return static_cast<void*>(const_cast< QRenderer*>(this));
+    return QWidget::qt_metacast(_clname);
+}
+
+int QRenderer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 3)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 3;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 3)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 3;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void QRenderer::exposeRequested()
+{
+    QMetaObject::activate(this, &staticMetaObject, 0, 0);
+}
+
+// SIGNAL 1
+void QRenderer::closeRequested()
+{
+    QMetaObject::activate(this, &staticMetaObject, 1, 0);
+}
+QT_END_MOC_NAMESPACE
diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.cpp b/tests/examples/gl/qt/videooverlay/videooverlay.cpp
new file mode 100644 (file)
index 0000000..9a95e90
--- /dev/null
@@ -0,0 +1,80 @@
+/* GStreamer
+ * Copyright (C) <2010> Stefan Kost <ensonic@users.sf.net>
+ *
+ * qt-xoverlay: demonstrate overlay handling using qt
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+
+#include <QApplication>
+#include <QTimer>
+#include <QWidget>
+
+int main(int argc, char *argv[])
+{
+  gst_init (&argc, &argv);
+  QApplication app(argc, argv);
+  app.setQuitOnLastWindowClosed(true);
+
+  /* prepare the pipeline */
+
+  GstElement *pipeline = gst_pipeline_new ("xvoverlay");
+  GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
+  GstElement *sink = gst_element_factory_make ("glimagesink", NULL);
+
+  if (sink == NULL)
+    g_error ("Couldn't create glimagesink.");
+
+  gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
+  gst_element_link (src, sink);
+  
+  /* prepare the ui */
+
+  QWidget window;
+  window.resize(320, 240);
+  window.setWindowTitle("GstVideoOverlay Qt demo");
+  window.show();
+  
+  WId xwinid = window.winId();
+  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
+
+  /* run the pipeline */
+
+  GstStateChangeReturn sret = gst_element_set_state (pipeline,
+      GST_STATE_PLAYING);
+  if (sret == GST_STATE_CHANGE_FAILURE) {
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+    /* Exit application */
+    QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
+  }
+
+  int ret = app.exec();
+  
+  window.hide();
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  return ret;
+}
diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.pri b/tests/examples/gl/qt/videooverlay/videooverlay.pri
new file mode 100644 (file)
index 0000000..0a53a90
--- /dev/null
@@ -0,0 +1,4 @@
+#Header files
+
+#Source files
+SOURCES += videooverlay.cpp
diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.sln b/tests/examples/gl/qt/videooverlay/videooverlay.sln
new file mode 100644 (file)
index 0000000..f566357
--- /dev/null
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "videooverlay", "videooverlay.vcproj", "{7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Debug|Win32.ActiveCfg = Debug|Win32
+               {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Debug|Win32.Build.0 = Debug|Win32
+               {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Release|Win32.ActiveCfg = Release|Win32
+               {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+       GlobalSection(Qt) = preSolution
+               Integration = True
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.vcproj b/tests/examples/gl/qt/videooverlay/videooverlay.vcproj
new file mode 100644 (file)
index 0000000..557f68a
--- /dev/null
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="videooverlay"
+       ProjectGUID="{7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}"
+       Keyword="Qt4VSv1.0"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_NO_DEBUG,NDEBUG,QT_CORE_LIB,QT_GUI_LIB"
+                               RuntimeLibrary="2"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="0"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmain.lib QtCore4.lib QtGui4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="false"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
+                               PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_CORE_LIB,QT_GUI_LIB"
+                               RuntimeLibrary="3"
+                               TreatWChar_tAsBuiltInType="false"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="qtmaind.lib QtCored4.lib QtGuid4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
+                               OutputFile="$(OutDir)\$(ProjectName).exe"
+                               AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;cxx;c;def"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\main.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\qrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\gstthread.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing gstthread.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\pipeline.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing pipeline.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\qrenderer.h"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Moc&apos;ing qrenderer.h..."
+                                               CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
+                                               AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
+                                               Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Form Files"
+                       Filter="ui"
+                       UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="qrc;*"
+                       UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
+                       ParseFiles="false"
+                       >
+               </Filter>
+               <Filter
+                       Name="Generated Files"
+                       Filter="moc;h;cpp"
+                       UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
+                       SourceControlFiles="false"
+                       >
+                       <File
+                               RelativePath=".\GeneratedFiles\Debug\moc_gstthread.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\GeneratedFiles\Debug\moc_pipeline.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\GeneratedFiles\Debug\moc_qrenderer.cpp"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+               <Global
+                       Name="MocDir"
+                       Value=".\GeneratedFiles\$(ConfigurationName)"
+               />
+               <Global
+                       Name="QtVersion"
+                       Value="qt-4.3.0"
+               />
+               <Global
+                       Name="RccDir"
+                       Value=".\GeneratedFiles"
+               />
+               <Global
+                       Name="UicDir"
+                       Value=".\GeneratedFiles"
+               />
+       </Globals>
+</VisualStudioProject>
diff --git a/tests/examples/gl/qt/videooverlay/videovideooverlay.pro b/tests/examples/gl/qt/videooverlay/videovideooverlay.pro
new file mode 100644 (file)
index 0000000..173b8c6
--- /dev/null
@@ -0,0 +1,53 @@
+TEMPLATE = app
+TARGET = videooverlay
+DESTDIR = ./Debug
+CONFIG += debug
+DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
+QT += gui widgets
+
+win32 {
+DEFINES += WIN32
+INCLUDEPATH += ./GeneratedFiles \
+    ./GeneratedFiles/Debug \
+    C:/gstreamer/include \
+    C:/gstreamer/include/libxml2 \
+    C:/gstreamer/include/glib-2.0 \
+    C:/gstreamer/lib/glib-2.0/include \
+    C:/gstreamer/include/gstreamer-1.0
+LIBS += -L"C:/gstreamer/bin" \
+    -L"C:/gstreamer/lib" \
+    -lgstreamer-1.0 \
+    -lgstvideo-1.0 \
+    -lglib-2.0 \
+    -lgmodule-2.0 \
+    -lgobject-2.0 \
+    -lgthread-2.0
+}
+
+unix {
+DEFINES += UNIX
+INCLUDEPATH += GeneratedFiles \
+    GeneratedFiles/Debug \
+    /usr/include/gstreamer-1.0 \
+    /usr/local/include/gstreamer-1.0 \
+    /usr/include/glib-2.0 \
+    /usr/lib/glib-2.0/include \
+    /usr/include/libxml2
+LIBS += -lgstreamer-1.0 \
+    -lgstvideo-1.0 \
+       -lglib-2.0 \
+       -lgmodule-2.0 \
+       -lgobject-2.0 \
+       -lgthread-2.0 \
+       -lGLU \
+       -lGL
+}
+
+DEPENDPATH += .
+MOC_DIR += ./GeneratedFiles/debug
+OBJECTS_DIR += debug
+UI_DIR += ./GeneratedFiles
+RCC_DIR += ./GeneratedFiles
+
+#Include file(s)
+include(videooverlay.pri)
diff --git a/tests/examples/gl/sdl/.gitignore b/tests/examples/gl/sdl/.gitignore
new file mode 100644 (file)
index 0000000..b958bef
--- /dev/null
@@ -0,0 +1 @@
+sdlshare
diff --git a/tests/examples/gl/sdl/Makefile.am b/tests/examples/gl/sdl/Makefile.am
new file mode 100644 (file)
index 0000000..9e0c8c5
--- /dev/null
@@ -0,0 +1,15 @@
+noinst_PROGRAMS = ##
+
+#works on win32 and X
+if HAVE_SDL
+
+noinst_PROGRAMS += sdlshare
+
+sdlshare_SOURCES = sdlshare.c
+
+sdlshare_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CFLAGS) \
+    $(GL_CFLAGS) $(SDL_CFLAGS)
+sdlshare_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) \
+    $(GL_LIBS) $(SDL_LIBS)
+
+endif
diff --git a/tests/examples/gl/sdl/sdl.sln b/tests/examples/gl/sdl/sdl.sln
new file mode 100644 (file)
index 0000000..0ecdd00
--- /dev/null
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdlshare", "sdlshare.vcproj", "{2C29F5A2-5982-428A-8068-9A5788FD2277}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {2C29F5A2-5982-428A-8068-9A5788FD2277}.Debug|Win32.ActiveCfg = Debug|Win32
+               {2C29F5A2-5982-428A-8068-9A5788FD2277}.Debug|Win32.Build.0 = Debug|Win32
+               {2C29F5A2-5982-428A-8068-9A5788FD2277}.Release|Win32.ActiveCfg = Release|Win32
+               {2C29F5A2-5982-428A-8068-9A5788FD2277}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/tests/examples/gl/sdl/sdlshare.c b/tests/examples/gl/sdl/sdlshare.c
new file mode 100644 (file)
index 0000000..f54daf3
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "SDL/SDL.h"
+#include "SDL/SDL_opengl.h"
+
+#ifndef WIN32
+#include <GL/glx.h>
+#include "SDL/SDL_syswm.h"
+#endif
+
+#include <gst/gst.h>
+
+
+/* hack */
+typedef struct _GstGLBuffer GstGLBuffer;
+struct _GstGLBuffer
+{
+  GstBuffer buffer;
+
+  GObject *obj;
+
+  gint width;
+  gint height;
+  GLuint texture;
+};
+
+/* rotation angle for the triangle. */
+float rtri = 0.0f;
+
+/* rotation angle for the quadrilateral. */
+float rquad = 0.0f;
+
+/* A general OpenGL initialization function.  Sets all of the initial parameters. */
+static void
+InitGL (int Width, int Height)  // We call this right after our OpenGL window is created.
+{
+  glViewport (0, 0, Width, Height);
+  glClearColor (0.0f, 0.0f, 0.0f, 0.0f);        // This Will Clear The Background Color To Black
+  glClearDepth (1.0);           // Enables Clearing Of The Depth Buffer
+  glDepthFunc (GL_LESS);        // The Type Of Depth Test To Do
+  glEnable (GL_DEPTH_TEST);     // Enables Depth Testing
+  glShadeModel (GL_SMOOTH);     // Enables Smooth Color Shading
+
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();            // Reset The Projection Matrix
+
+  gluPerspective (45.0f, (GLfloat) Width / (GLfloat) Height, 0.1f, 100.0f);     // Calculate The Aspect Ratio Of The Window
+
+  glMatrixMode (GL_MODELVIEW);
+}
+
+/* The main drawing function. */
+static void
+DrawGLScene (GstGLBuffer * gst_gl_buf)
+{
+  GLuint texture = gst_gl_buf->texture;
+  GLfloat width = (GLfloat) gst_gl_buf->width;
+  GLfloat height = (GLfloat) gst_gl_buf->height;
+
+  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear The Screen And The Depth Buffer
+  glLoadIdentity ();            // Reset The View
+
+  glTranslatef (-1.5f, 0.0f, -6.0f);    // Move Left 1.5 Units And Into The Screen 6.0
+
+  glRotatef (rtri, 0.0f, 1.0f, 0.0f);   // Rotate The Triangle On The Y axis 
+  // draw a triangle (in smooth coloring mode)
+  glBegin (GL_POLYGON);         // start drawing a polygon
+  glColor3f (1.0f, 0.0f, 0.0f); // Set The Color To Red
+  glVertex3f (0.0f, 1.0f, 0.0f);        // Top
+  glColor3f (0.0f, 1.0f, 0.0f); // Set The Color To Green
+  glVertex3f (1.0f, -1.0f, 0.0f);       // Bottom Right
+  glColor3f (0.0f, 0.0f, 1.0f); // Set The Color To Blue
+  glVertex3f (-1.0f, -1.0f, 0.0f);      // Bottom Left  
+  glEnd ();                     // we're done with the polygon (smooth color interpolation)
+
+  glEnable (GL_TEXTURE_2D);
+  glBindTexture (GL_TEXTURE_2D, texture);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+  glLoadIdentity ();            // make sure we're no longer rotated.
+  glTranslatef (1.5f, 0.0f, -6.0f);     // Move Right 3 Units, and back into the screen 6.0
+
+  glRotatef (rquad, 1.0f, 0.0f, 0.0f);  // Rotate The Quad On The X axis 
+  // draw a square (quadrilateral)
+  glColor3f (0.5f, 0.5f, 1.0f); // set color to a blue shade.
+  glBegin (GL_QUADS);           // start drawing a polygon (4 sided)
+  glTexCoord3f (0.0f, height, 0.0f);
+  glVertex3f (-1.0f, 1.0f, 0.0f);       // Top Left
+  glTexCoord3f (width, height, 0.0f);
+  glVertex3f (1.0f, 1.0f, 0.0f);        // Top Right
+  glTexCoord3f (width, 0.0f, 0.0f);
+  glVertex3f (1.0f, -1.0f, 0.0f);       // Bottom Right
+  glTexCoord3f (0.0f, 0.0f, 0.0f);
+  glVertex3f (-1.0f, -1.0f, 0.0f);      // Bottom Left  
+  glEnd ();                     // done with the polygon
+
+  glBindTexture (GL_TEXTURE_2D, 0);
+
+  rtri += 1.0f;                 // Increase The Rotation Variable For The Triangle
+  rquad -= 1.0f;                // Decrease The Rotation Variable For The Quad 
+
+  // swap buffers to display, since we're double buffered.
+  SDL_GL_SwapBuffers ();
+}
+
+static gboolean
+update_sdl_scene (void *fk)
+{
+  GstElement *fakesink = (GstElement *) fk;
+  GMainLoop *loop =
+      (GMainLoop *) g_object_get_data (G_OBJECT (fakesink), "loop");
+  GAsyncQueue *queue_input_buf =
+      (GAsyncQueue *) g_object_get_data (G_OBJECT (fakesink),
+      "queue_input_buf");
+  GAsyncQueue *queue_output_buf =
+      (GAsyncQueue *) g_object_get_data (G_OBJECT (fakesink),
+      "queue_output_buf");
+  GstGLBuffer *gst_gl_buf = (GstGLBuffer *) g_async_queue_pop (queue_input_buf);
+
+  SDL_Event event;
+  while (SDL_PollEvent (&event)) {
+    if (event.type == SDL_QUIT) {
+      g_main_loop_quit (loop);
+    }
+    if (event.type == SDL_KEYDOWN) {
+      if (event.key.keysym.sym == SDLK_ESCAPE) {
+        g_main_loop_quit (loop);
+      }
+    }
+  }
+
+  DrawGLScene (gst_gl_buf);
+
+  /* push buffer so it can be unref later */
+  g_async_queue_push (queue_output_buf, gst_gl_buf);
+
+  return FALSE;
+}
+
+/* fakesink handoff callback */
+static void
+on_gst_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad,
+    gpointer data)
+{
+  GAsyncQueue *queue_input_buf = NULL;
+  GAsyncQueue *queue_output_buf = NULL;
+
+  /* ref then push buffer to use it in sdl */
+  gst_buffer_ref (buf);
+  queue_input_buf =
+      (GAsyncQueue *) g_object_get_data (G_OBJECT (fakesink),
+      "queue_input_buf");
+  g_async_queue_push (queue_input_buf, buf);
+  if (g_async_queue_length (queue_input_buf) > 3)
+    g_idle_add (update_sdl_scene, (gpointer) fakesink);
+
+  /* pop then unref buffer we have finished to use in sdl */
+  queue_output_buf =
+      (GAsyncQueue *) g_object_get_data (G_OBJECT (fakesink),
+      "queue_output_buf");
+  if (g_async_queue_length (queue_output_buf) > 3) {
+    GstBuffer *buf_old = (GstBuffer *) g_async_queue_pop (queue_output_buf);
+    gst_buffer_unref (buf_old);
+  }
+}
+
+/* gst bus signal watch callback */
+static void
+end_stream_cb (GstBus * bus, GstMessage * msg, GMainLoop * loop)
+{
+  switch (GST_MESSAGE_TYPE (msg)) {
+
+    case GST_MESSAGE_EOS:
+      g_print ("End-of-stream\n");
+      g_print
+          ("For more information, try to run: GST_DEBUG=gldisplay:2 ./sdlshare\n");
+      break;
+
+    case GST_MESSAGE_ERROR:
+    {
+      gchar *debug = NULL;
+      GError *err = NULL;
+
+      gst_message_parse_error (msg, &err, &debug);
+
+      g_print ("Error: %s\n", err->message);
+      g_error_free (err);
+
+      if (debug) {
+        g_print ("Debug deails: %s\n", debug);
+        g_free (debug);
+      }
+
+      break;
+    }
+
+    default:
+      break;
+  }
+
+  g_main_loop_quit (loop);
+}
+
+int
+main (int argc, char **argv)
+{
+
+#ifdef WIN32
+  HGLRC sdl_gl_context = 0;
+  HDC sdl_dc = 0;
+#else
+  SDL_SysWMinfo info;
+  Display *sdl_display = NULL;
+  Window sdl_win = 0;
+  GLXContext sdl_gl_context = NULL;
+#endif
+
+  GMainLoop *loop = NULL;
+  GstPipeline *pipeline = NULL;
+  GstBus *bus = NULL;
+  GstElement *glfilter = NULL;
+  GstElement *fakesink = NULL;
+  GstState state;
+  GAsyncQueue *queue_input_buf = NULL;
+  GAsyncQueue *queue_output_buf = NULL;
+
+  /* Initialize SDL for video output */
+  if (SDL_Init (SDL_INIT_VIDEO) < 0) {
+    fprintf (stderr, "Unable to initialize SDL: %s\n", SDL_GetError ());
+    return -1;
+  }
+
+  /* Create a 640x480 OpenGL screen */
+  if (SDL_SetVideoMode (640, 480, 0, SDL_OPENGL) == NULL) {
+    fprintf (stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError ());
+    SDL_Quit ();
+    return -1;
+  }
+
+  /* Set the title bar in environments that support it */
+  SDL_WM_SetCaption ("SDL and gst-plugins-gl", NULL);
+
+
+  /* Loop, drawing and checking events */
+  InitGL (640, 480);
+
+  gst_init (&argc, &argv);
+  loop = g_main_loop_new (NULL, FALSE);
+
+  /* retrieve and turn off sdl opengl context */
+#ifdef WIN32
+  sdl_gl_context = wglGetCurrentContext ();
+  sdl_dc = wglGetCurrentDC ();
+  wglMakeCurrent (0, 0);
+#else
+  SDL_VERSION (&info.version);
+  SDL_GetWMInfo (&info);
+  sdl_display = info.info.x11.display;
+  sdl_win = info.info.x11.window;
+  sdl_gl_context = glXGetCurrentContext ();
+  glXMakeCurrent (sdl_display, None, 0);
+#endif
+
+  pipeline =
+      GST_PIPELINE (gst_parse_launch
+      ("videotestsrc ! video/x-raw, width=320, height=240, framerate=(fraction)30/1 ! "
+          "gleffects effect=5 ! fakesink sync=1", NULL));
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  gst_bus_add_signal_watch (bus);
+  g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), loop);
+  g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), loop);
+  g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), loop);
+  gst_object_unref (bus);
+
+  /* sdl_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */
+  glfilter = gst_bin_get_by_name (GST_BIN (pipeline), "gleffects0");
+  g_object_set (G_OBJECT (glfilter), "external-opengl-context",
+      sdl_gl_context, NULL);
+  gst_object_unref (glfilter);
+
+  /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and
+   * shared with the sdl one */
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
+  state = GST_STATE_PAUSED;
+  if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
+          GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
+    g_debug ("failed to pause pipeline\n");
+    return -1;
+  }
+
+  /* turn on back sdl opengl context */
+#ifdef WIN32
+  wglMakeCurrent (sdl_dc, sdl_gl_context);
+#else
+  glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context);
+#endif
+
+  /* append a gst-gl texture to this queue when you do not need it no more */
+  fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
+  g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
+  g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer), NULL);
+  queue_input_buf = g_async_queue_new ();
+  queue_output_buf = g_async_queue_new ();
+  g_object_set_data (G_OBJECT (fakesink), "queue_input_buf", queue_input_buf);
+  g_object_set_data (G_OBJECT (fakesink), "queue_output_buf", queue_output_buf);
+  g_object_set_data (G_OBJECT (fakesink), "loop", loop);
+  gst_object_unref (fakesink);
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  g_main_loop_run (loop);
+
+  /* before to deinitialize the gst-gl-opengl context,
+   * no shared context (here the sdl one) must be current
+   */
+#ifdef WIN32
+  wglMakeCurrent (0, 0);
+#else
+  glXMakeCurrent (sdl_display, sdl_win, sdl_gl_context);
+#endif
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  /* turn on back sdl opengl context */
+#ifdef WIN32
+  wglMakeCurrent (sdl_dc, sdl_gl_context);
+#else
+  glXMakeCurrent (sdl_display, None, 0);
+#endif
+
+  SDL_Quit ();
+
+  /* make sure there is no pending gst gl buffer in the communication queues 
+   * between sdl and gst-gl
+   */
+  while (g_async_queue_length (queue_input_buf) > 0) {
+    GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_input_buf);
+    gst_buffer_unref (buf);
+  }
+
+  while (g_async_queue_length (queue_output_buf) > 0) {
+    GstBuffer *buf = (GstBuffer *) g_async_queue_pop (queue_output_buf);
+    gst_buffer_unref (buf);
+  }
+
+  return 0;
+}
diff --git a/tests/examples/gl/sdl/sdlshare.vcproj b/tests/examples/gl/sdl/sdlshare.vcproj
new file mode 100644 (file)
index 0000000..760b349
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="sdlshare"
+       ProjectGUID="{2C29F5A2-5982-428A-8068-9A5788FD2277}"
+       RootNamespace="sdlshare"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib sdl.lib sdlmain.lib opengl32.lib glu32.lib"
+                               LinkIncremental="2"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="2"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib sdl.lib sdlmain.lib opengl32.lib glu32.lib"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="C:\gstreamer\lib"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\sdlshare.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>