AM_CONDITIONAL(HAVE_GTK, test "x$HAVE_GTK" = "xyes")
+dnl GTK is optional and used in examples
+HAVE_GTK3=NO
+if test "x$BUILD_EXAMPLES" = "xyes"; then
+ PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.4, HAVE_GTK3=yes, HAVE_GTK3=no)
+ if test "x$HAVE_GTK3" = "xyes"; then
+ HAVE_GTK=yes
+ GTK_VERSION=`$PKG_CONFIG --variable=gtk_binary_version gtk+-3.0`
+ AC_SUBST(GTK_VERSION)
+ GTK_PREFIX=`$PKG_CONFIG --variable=prefix gdk-pixbuf-2.0`
+ AC_SUBST(GTK_BASE_DIR)
+ fi
+fi
+AC_SUBST(GTK3_LIBS)
+AC_SUBST(GTK3_CFLAGS)
+AC_SUBST(HAVE_GTK3)
+AM_CONDITIONAL(HAVE_GTK3, test "x$HAVE_GTK3" = "xyes")
+
+dnl clutter is optional and used in examples
+HAVE_CLUTTER=no
+HAVE_CLUTTER_X11=no
+HAVE_CLUTTER_GLX=no
+if test "x$BUILD_EXAMPLES" = "xyes"; then
+ PKG_CHECK_MODULES(CLUTTER, clutter-1.0 >= 1.8, HAVE_CLUTTER=yes, HAVE_CLUTTER=no)
+ AC_SUBST(CLUTTER_LIBS)
+ AC_SUBST(CLUTTER_CFLAGS)
+ AC_SUBST(HAVE_CLUTTER)
+
+ PKG_CHECK_MODULES(CLUTTER_GLX, clutter-glx-1.0 >= 1.8, HAVE_CLUTTER_GLX=yes, HAVE_CLUTTER_GLX=no)
+ AC_SUBST(CLUTTER_GLX_LIBS)
+ AC_SUBST(CLUTTER_GLX_CFLAGS)
+ AC_SUBST(HAVE_CLUTTER_GLX)
+
+ PKG_CHECK_MODULES(CLUTTER_X11, clutter-x11-1.0 >= 1.8, HAVE_CLUTTER_X11=yes, HAVE_CLUTTER_X11=no)
+ AC_SUBST(CLUTTER_X11_LIBS)
+ AC_SUBST(CLUTTER_X11_CFLAGS)
+ AC_SUBST(HAVE_CLUTTER_X11)
+fi
+AM_CONDITIONAL(HAVE_CLUTTER, test "x$HAVE_CLUTTER" = "xyes")
+AM_CONDITIONAL(HAVE_CLUTTER_GLX, test "x$HAVE_CLUTTER_GLX" = "xyes")
+AM_CONDITIONAL(HAVE_CLUTTER_X11, test "x$HAVE_CLUTTER_X11" = "xyes")
+
+dnl used in the gl/clutteractor example
+if test "x$BUILD_EXAMPLES" = "xyes"; then
+ PKG_CHECK_MODULES(XCOMPOSITE, xcomposite, HAVE_XCOMPOSITE=yes, HAVE_XCOMPOSITE=no)
+ AC_SUBST(XCOMPOSITE_CFLAGS)
+ AC_SUBST(XCOMPOSITE_LIBS)
+fi
+AM_CONDITIONAL(HAVE_XCOMPOSITE, test "x$HAVE_XCOMPOSITE" = "xyes")
+
+dnl sdl is optional and used in examples
+HAVE_SDL=NO
+if test "x$BUILD_EXAMPLES" = "xyes"; then
+ PKG_CHECK_MODULES(SDL, sdl >= 1.2.0, HAVE_SDL=yes, HAVE_SDL=no)
+ AC_SUBST(SDL_LIBS)
+ AC_SUBST(SDL_CFLAGS)
+ AC_SUBST(SDL_CLUTTER)
+fi
+AM_CONDITIONAL(HAVE_SDL, test "x$HAVE_SDL" = "xyes")
+
dnl Needed for GtkBuilder to autoconnect signals
PKG_CHECK_MODULES(GMODULE_EXPORT, gmodule-export-2.0, HAVE_GMODULE_EXPORT=yes, HAVE_GMODULE_EXPORT=no)
tests/examples/Makefile
tests/examples/camerabin2/Makefile
tests/examples/directfb/Makefile
+tests/examples/gl/Makefile
+tests/examples/gl/cocoa/Makefile
+tests/examples/gl/cocoa/videooverlay/Makefile
+tests/examples/gl/clutter/Makefile
+tests/examples/gl/generic/Makefile
+tests/examples/gl/generic/cube/Makefile
+tests/examples/gl/generic/cubeyuv/Makefile
+tests/examples/gl/generic/doublecube/Makefile
+tests/examples/gl/generic/recordgraphic/Makefile
+tests/examples/gl/gtk/Makefile
+tests/examples/gl/gtk/gtkvideooverlay/Makefile
+tests/examples/gl/gtk/filternovideooverlay/Makefile
+tests/examples/gl/gtk/filtervideooverlay/Makefile
+tests/examples/gl/gtk/fxtest/Makefile
+tests/examples/gl/gtk/switchvideooverlay/Makefile
+tests/examples/gl/qt/Makefile
+tests/examples/gl/sdl/Makefile
tests/examples/mpegts/Makefile
tests/examples/mxf/Makefile
tests/examples/opencv/Makefile
OPENCV_EXAMPLES=opencv
-SUBDIRS= mpegts $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES)
-DIST_SUBDIRS= mpegts camerabin2 directfb mxf opencv uvch264
+if USE_OPENGL
+GL_DIR=gl
+else
+GL_DIR=
+endif
+
+SUBDIRS= mpegts $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES) $(GL_DIR)
+DIST_SUBDIRS= mpegts camerabin2 directfb mxf opencv uvch264 gl
include $(top_srcdir)/common/parallel-subdirs.mak
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
-#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 */
-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 */
-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 */
-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 */
-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 */
-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;
-}
--- /dev/null
+
+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
--- /dev/null
+clutteractor
+clutteractortee
+cluttershare
--- /dev/null
+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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+<?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>
--- /dev/null
+
+if HAVE_WINDOW_COCOA
+SUBDIRS = videooverlay
+endif
--- /dev/null
+--- 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
--- /dev/null
+videooverlay
--- /dev/null
+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
--- /dev/null
+#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;
+}
--- /dev/null
+
+SUBDIRS = cube cubeyuv doublecube recordgraphic
--- /dev/null
+--- 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.
--- /dev/null
+
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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>
--- /dev/null
+/*
+ * 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 (¤t_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;
+
+}
--- /dev/null
+
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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>
--- /dev/null
+/*
+ * 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 (¤t_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;
+
+}
+
--- /dev/null
+doublecube
--- /dev/null
+
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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>
--- /dev/null
+/*
+ * 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 (¤t_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;
+
+}
+
--- /dev/null
+
+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
--- /dev/null
+recordgraphic
--- /dev/null
+
+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)
+
--- /dev/null
+/*
+ * 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 (¤t_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;
+
+}
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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>
--- /dev/null
+
+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
+
--- /dev/null
+--- 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
--- /dev/null
+filternovideooverlay
--- /dev/null
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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>
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+filtervideooverlay
--- /dev/null
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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>
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+fxtest
+pixbufdrop
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=".\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>
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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");
+}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+
+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
--- /dev/null
+gtkvideooverlay
--- /dev/null
+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)
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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>
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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>
--- /dev/null
+switchvideooverlay
--- /dev/null
+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)
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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>
--- /dev/null
+
+#SUBDIRS = videooverlay qglwidgetvideooverlay mousevideooverlay
--- /dev/null
+--- 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+#Header files
+HEADERS += ./gstthread.h \
+ ./pipeline.h \
+ ./qrenderer.h
+
+#Source files
+SOURCES += ./gstthread.cpp \
+ ./main.cpp \
+ ./pipeline.cpp \
+ ./qrenderer.cpp
--- /dev/null
+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)
--- /dev/null
+
+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
--- /dev/null
+<?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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\pipeline.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\qrenderer.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp""
+ />
+ </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>
--- /dev/null
+/*
+ * 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 (¤t_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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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 (¤t_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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+#Header files
+HEADERS += ./gstthread.h \
+ ./pipeline.h \
+ ./qglrenderer.h
+
+#Source files
+SOURCES += ./gstthread.cpp \
+ ./main.cpp \
+ ./pipeline.cpp \
+ ./qglrenderer.cpp
--- /dev/null
+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)
--- /dev/null
+
+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
--- /dev/null
+<?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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";"$(QTDIR)\include\QtOpenGL";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";"$(QTDIR)\include\QtOpenGL";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\pipeline.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1,0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1,0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\qglrenderer.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qglrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qglrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qglrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qglrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qglrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qglrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp""
+ />
+ </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>
--- /dev/null
+/*
+ * 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
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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];
+}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
+
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+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
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/****************************************************************************
+** 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+#Header files
+
+#Source files
+SOURCES += videooverlay.cpp
--- /dev/null
+
+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
--- /dev/null
+<?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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0""
+ 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=""$(QTDIR)\lib";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'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing gstthread.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\pipeline.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing pipeline.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\qrenderer.h"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Moc'ing qrenderer.h..."
+ CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
"
+ AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h"
+ Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp""
+ />
+ </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>
--- /dev/null
+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)
--- /dev/null
+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
--- /dev/null
+
+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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+<?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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0";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>
+++ /dev/null
-/*
- * 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 ();
-}
-
-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;
-}
-
-gboolean
-play_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("playing");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_PLAYING);
- return FALSE;
-}
-
-gboolean
-null_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("nulling");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_NULL);
- return FALSE;
-}
-
-gboolean
-ready_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("readying");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_READY);
- return FALSE;
-}
-
-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;
-}
+++ /dev/null
-/*
- * 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 ();
-}
-
-gboolean
-play_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("playing");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_PLAYING);
- return FALSE;
-}
-
-gboolean
-null_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("nulling");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_NULL);
- return FALSE;
-}
-
-gboolean
-ready_cb (GtkWidget * widget, gpointer data)
-{
- g_message ("readying");
- gst_element_set_state (GST_ELEMENT (data), GST_STATE_READY);
- return FALSE;
-}
-
-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 = "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;
-}
+++ /dev/null
-/*
- * 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 && GDK_WINDOWING_WIN32
-#include <gdk/gdkwin32.h>
-#endif
-#if GST_GL_HAVE_WINDOW_X11 && GDK_WINDOWING_X11
-#include <gdk/gdkx.h>
-#endif
-#if GST_GL_HAVE_WINDOW_COCOA && 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 && 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 && 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 && 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");
-}
+++ /dev/null
-/*
- * 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. */
-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. */
-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 ();
-}
-
-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 */
-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 */
-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;
-}