examples: add video overlay examples for gtk, qt and qt graphics view
authorStefan Kost <ensonic@users.sf.net>
Tue, 16 Feb 2010 13:43:26 +0000 (15:43 +0200)
committerStefan Kost <ensonic@users.sf.net>
Wed, 17 Feb 2010 07:48:10 +0000 (09:48 +0200)
Add simple videotestsrc ! xvimagesink examples using gtk and qt. This patch also
adds all boilerplate to configure for using c++. The qt based examples are
optional like their gtk counterparts.

configure.ac
gst-libs/gst/interfaces/xoverlay.c
tests/examples/Makefile.am
tests/examples/overlay/Makefile.am [new file with mode: 0644]
tests/examples/overlay/gtk-xoverlay.c [new file with mode: 0644]
tests/examples/overlay/qt-xoverlay.cpp [new file with mode: 0644]
tests/examples/overlay/qtgv-xoverlay.cpp [new file with mode: 0644]
tests/examples/overlay/qtgv-xoverlay.h [new file with mode: 0644]

index ea6f5df..b5e1c88 100644 (file)
@@ -127,6 +127,14 @@ dnl *** checks for programs ***
 
 dnl find a compiler
 AC_PROG_CC
+AC_PROG_CXX
+
+dnl determine if c++ is available on this system
+AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no)
+
+dnl determine c++ preprocessor
+dnl FIXME: do we need this ?
+AC_PROG_CXXCPP
 
 dnl check if the compiler supports '-c' and '-o' options
 AM_PROG_CC_C_O
@@ -273,6 +281,12 @@ PKG_CHECK_MODULES(GTK_X11, gtk+-x11-2.0 >= 2.14.0,
     HAVE_GTK_X11=yes, HAVE_GTK_X11=no)
 AM_CONDITIONAL(HAVE_GTK_X11, test "x$HAVE_GTK_X11" = "xyes")
 
+dnl QT is optional and only used in examples
+PKG_CHECK_MODULES(QT, QtGui >= 4.0, HAVE_QT=yes, HAVE_QT=no)
+AM_CONDITIONAL(HAVE_QT, test "x$HAVE_QT" = "xyes")
+PKG_CHECK_MODULES(QT, QtGui >= 4.6, HAVE_QT_GV=yes, HAVE_QT_GV=no)
+AM_CONDITIONAL(HAVE_QT_GV, test "x$HAVE_QT_GV" = "xyes")
+
 dnl *** set variables based on configure arguments ***
 
 dnl set license and copyright notice
@@ -286,6 +300,9 @@ AG_GST_SET_PLUGINDIR
 dnl define an ERROR_CFLAGS Makefile variable
 AG_GST_SET_ERROR_CFLAGS($GST_GIT)
 
+dnl define an ERROR_CXXFLAGS Makefile variable
+AG_GST_SET_ERROR_CXXFLAGS($GST_GIT)
+
 dnl define correct level for debugging messages
 AG_GST_SET_LEVEL_DEFAULT($GST_GIT)
 
@@ -757,9 +774,12 @@ else
 fi
 AC_SUBST(DEPRECATED_CFLAGS)
 
-dnl every flag in GST_OPTION_CFLAGS can be overridden at make time
+dnl every flag in GST_OPTION_CFLAGS and GST_OPTION_CXXFLAGS can be overridden
+dnl at make time with e.g. make ERROR_CFLAGS=""
 GST_OPTION_CFLAGS="\$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)"
+GST_OPTION_CXXFLAGS="\$(ERROR_CXXFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)"
 AC_SUBST(GST_OPTION_CFLAGS)
+AC_SUBST(GST_OPTION_CXXFLAGS)
 
 dnl our libraries need to be versioned correctly
 AC_SUBST(GST_LT_LDFLAGS)
@@ -772,8 +792,10 @@ AC_SUBST(GST_PLUGINS_BASE_CFLAGS)
 
 dnl FIXME: do we want to rename to GST_ALL_* ?
 dnl add GST_OPTION_CFLAGS, but overridable
+GST_CXXFLAGS="$GST_CFLAGS \$(GST_OPTION_CXXFLAGS)"
 GST_CFLAGS="$GST_CFLAGS \$(GST_OPTION_CFLAGS)"
 AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_CXXFLAGS)
 dnl add GCOV libs because libtool strips -fprofile-arcs -ftest-coverage
 GST_LIBS="$GST_LIBS \$(GCOV_LIBS)"
 AC_SUBST(GST_LIBS)
@@ -888,6 +910,7 @@ tests/check/Makefile
 tests/examples/Makefile
 tests/examples/app/Makefile
 tests/examples/dynamic/Makefile
+tests/examples/overlay/Makefile
 tests/examples/seek/Makefile
 tests/examples/volume/Makefile
 tests/examples/snapshot/Makefile
index 26e19ef..224505a 100644 (file)
@@ -59,7 +59,7 @@
  * from the video sink element. To solve this issue a #GstMessage is posted on
  * the bus to inform the application that it should set the Window identifier
  * immediately. Here is an example on how to do that correctly:
- * <programlisting>
+ * |[
  * static GstBusSyncReply
  * create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
  * {
@@ -94,7 +94,7 @@
  *  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, pipeline);
  * ...
  * }
- * </programlisting>
+ * ]|
  * </para>
  * </refsect2>
  * <refsect2>
  * <refsect2>
  * <title>GstXOverlay and Gtk+</title>
  * <para>
- * <programlisting>
+ * |[
  * #include &lt;gtk/gtk.h&gt;
  * #ifdef GDK_WINDOWING_X11
  * #include &lt;gdk/gdkx.h&gt;  // for GDK_WINDOW_XID
  *   gst_element_set_state (pipeline, GST_STATE_PLAYING);
  *   ...
  * }
- * </programlisting>
+ * ]|
  * </para>
  * </refsect2>
  * <refsect2>
  * <title>GstXOverlay and Qt</title>
  * <para>
- * FIXME: write me
+ * |[
+ * #include &lt;glib.h&gt;
+ * #include &lt;gst/gst.h&gt;
+ * #include &lt;gst/interfaces/xoverlay.h&gt;
+ * 
+ * #include &lt;QApplication&gt;
+ * #include &lt;QTimer&gt;
+ * #include &lt;QWidget&gt;
+ * 
+ * int main(int argc, char *argv[])
+ * {
+ *   if (!g_thread_supported ())
+ *     g_thread_init (NULL);
+ * 
+ *   gst_init (&argc, &argv);
+ *   QApplication app(argc, argv);
+ *   app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
+ * 
+ *   // prepare the pipeline
+ * 
+ *   GstElement *pipeline = gst_pipeline_new ("xvoverlay");
+ *   GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
+ *   GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
+ *   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.show();
+ *   
+ *   WId xwinid = window.winId();
+ *   gst_x_overlay_set_xwindow_id (GST_X_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;
+ * }
+ * ]|
  * </para>
  * </refsect2>
  */
index e269308..7c4e1f8 100644 (file)
@@ -8,6 +8,6 @@ if USE_GIO
 GIO_SUBDIRS = gio
 endif
 
-SUBDIRS = app $(FT2_SUBDIRS) $(GIO_SUBDIRS) volume dynamic v4l
+SUBDIRS = app $(FT2_SUBDIRS) $(GIO_SUBDIRS) volume dynamic v4l overlay
 
-DIST_SUBDIRS = app seek volume dynamic snapshot gio v4l
+DIST_SUBDIRS = app seek volume dynamic snapshot gio v4l overlay
diff --git a/tests/examples/overlay/Makefile.am b/tests/examples/overlay/Makefile.am
new file mode 100644 (file)
index 0000000..6e9d286
--- /dev/null
@@ -0,0 +1,47 @@
+EXAMPLES =
+
+if USE_X
+
+if HAVE_GTK_X11
+EXAMPLES += gtk-xoverlay
+
+gtk_xoverlay_SOURCES = gtk-xoverlay.c
+gtk_xoverlay_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS) $(GTK_CFLAGS)
+gtk_xoverlay_LDADD = $(GST_LIBS) $(X_LIBS) $(LIBM) $(GTK_LIBS) \
+       $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la
+endif
+
+if HAVE_QT
+EXAMPLES += qt-xoverlay
+
+qt_xoverlay_SOURCES = qt-xoverlay.cpp
+qt_xoverlay_CXXFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(X_CFLAGS) $(QT_CFLAGS)
+qt_xoverlay_LDADD = $(GST_LIBS) $(X_LIBS) $(LIBM) $(QT_LIBS) \
+       $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la
+
+endif
+
+if HAVE_QT_GV
+EXAMPLES += qtgv-xoverlay
+
+qtgv_xoverlay_SOURCES = qtgv-xoverlay.cpp
+qtgv_xoverlay_CXXFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(X_CFLAGS) $(QT_CFLAGS)
+qtgv_xoverlay_LDADD = $(GST_LIBS) $(X_LIBS) $(LIBM) $(QT_LIBS) \
+       $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la
+
+# qt moc support, according to http://qtnode.net/wiki/Qt_with_autotools
+
+nodist_qtgv_xoverlay_SOURCES = moc_qtgv-xoverlay.cpp
+
+moc_%.cpp:%.h
+       moc $< -o $@
+
+EXTRA_DIST = $(nodist_qtgv_xoverlay_SOURCES:moc_%.cpp=%.h) 
+CLEANFILES = $(nodist_qtgv_xoverlay_SOURCES)
+
+endif
+
+endif
+
+noinst_PROGRAMS = $(EXAMPLES)
+
diff --git a/tests/examples/overlay/gtk-xoverlay.c b/tests/examples/overlay/gtk-xoverlay.c
new file mode 100644 (file)
index 0000000..84718ef
--- /dev/null
@@ -0,0 +1,92 @@
+/* GStreamer
+ * Copyright (C) <2010> Stefan Kost <ensonic@users.sf.net>
+ *
+ * gtk-xoverlay: demonstrate overlay handling using gtk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+static void
+window_closed (GtkWidget * widget, GdkEvent * event, gpointer user_data)
+{
+  GstElement *pipeline = user_data;
+
+  gtk_widget_hide_all (widget);
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gtk_main_quit ();
+}
+
+int
+main (int argc, char **argv)
+{
+  GtkWidget *window, *video_window;
+  GstElement *pipeline, *src, *sink;
+  gulong embed_xid;
+  GstStateChangeReturn sret;
+
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  gst_init (&argc, &argv);
+  gtk_init (&argc, &argv);
+
+  /* prepare the pipeline */
+
+  pipeline = gst_pipeline_new ("xvoverlay");
+  src = gst_element_factory_make ("videotestsrc", NULL);
+  sink = gst_element_factory_make ("xvimagesink", NULL);
+  gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
+  gst_element_link (src, sink);
+
+  /* prepare the ui */
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (G_OBJECT (window), "delete-event",
+      G_CALLBACK (window_closed), (gpointer) pipeline);
+  gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);
+
+  video_window = gtk_drawing_area_new ();
+  gtk_widget_set_double_buffered (video_window, FALSE);
+  gtk_container_add (GTK_CONTAINER (window), video_window);
+
+  gtk_widget_show_all (window);
+  gtk_widget_realize (window);
+
+  embed_xid = GDK_WINDOW_XID (video_window->window);
+  gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sink), embed_xid);
+
+  /* run the pipeline */
+
+  sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  if (sret == GST_STATE_CHANGE_FAILURE)
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+  else
+    gtk_main ();
+
+  gst_object_unref (pipeline);
+  return 0;
+}
diff --git a/tests/examples/overlay/qt-xoverlay.cpp b/tests/examples/overlay/qt-xoverlay.cpp
new file mode 100644 (file)
index 0000000..a1ba7c3
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include <QApplication>
+#include <QTimer>
+#include <QWidget>
+
+int main(int argc, char *argv[])
+{
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  gst_init (&argc, &argv);
+  QApplication app(argc, argv);
+  app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
+
+  /* prepare the pipeline */
+
+  GstElement *pipeline = gst_pipeline_new ("xvoverlay");
+  GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
+  GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
+  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.show();
+  
+  WId xwinid = window.winId();
+  gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sink), xwinid);
+
+  /* run the pipeline */
+
+  GstStateChangeReturn sret = gst_element_set_state (pipeline,
+      GST_STATE_PLAYING);
+  if (sret == GST_STATE_CHANGE_FAILURE) {
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+    /* Exit application */
+    QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
+  }
+
+  int ret = app.exec();
+  
+  window.hide();
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+
+  return ret;
+}
diff --git a/tests/examples/overlay/qtgv-xoverlay.cpp b/tests/examples/overlay/qtgv-xoverlay.cpp
new file mode 100644 (file)
index 0000000..74159c4
--- /dev/null
@@ -0,0 +1,88 @@
+/* GStreamer
+ * Copyright (C) <2010> Alexander Bokovoy <ab@samba.org>
+ *
+ * qtgv-xoverlay: demonstrate overlay handling using qt graphics view
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "qtgv-xoverlay.h"
+
+#include <QApplication>
+#include <QTimer>
+
+#include <gst/interfaces/xoverlay.h>
+
+SinkPipeline::SinkPipeline(QGraphicsView *parent) : QObject(parent)
+{
+  pipeline = gst_pipeline_new ("xvoverlay");
+  src = gst_element_factory_make ("videotestsrc", NULL);
+  sink = gst_element_factory_make ("xvimagesink", NULL);
+  gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
+  gst_element_link (src, sink);
+  xwinid = parent->winId();
+}
+
+SinkPipeline::~SinkPipeline()
+{
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+}
+
+void SinkPipeline::startPipeline()
+{
+  GstStateChangeReturn sret;
+
+  /* we know what the video sink is in this case (xvimagesink), so we can
+   * just set it directly here now (instead of waiting for a prepare-xwindow-id
+   * element message in a sync bus handler and setting it there) */
+
+  gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sink), xwinid);
+
+  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 main( int argc, char **argv )
+{
+    QApplication app(argc, argv);
+
+    QGraphicsScene scene;
+    scene.setSceneRect( -100.0, -100.0, 200.0, 200.0 );
+
+    QGraphicsView view( &scene );
+    view.resize(320, 240);
+    view.show();
+
+    gst_init (&argc, &argv);
+    SinkPipeline pipeline(&view);
+    pipeline.startPipeline();
+
+    int ret = app.exec();
+
+    view.hide();
+    
+    return ret;
+}
diff --git a/tests/examples/overlay/qtgv-xoverlay.h b/tests/examples/overlay/qtgv-xoverlay.h
new file mode 100644 (file)
index 0000000..091fff8
--- /dev/null
@@ -0,0 +1,45 @@
+/* GStreamer
+ * Copyright (C) <2010> Alexander Bokovoy <ab@samba.org>
+ *
+ * qtgv-xoverlay: demonstrate overlay handling using qt graphics view
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef QTGV_XOVERLAY_H
+#define QTGV_XOVERLAY_H
+
+#include <QGraphicsView>
+#include <gst/gst.h>
+
+
+class SinkPipeline : public QObject
+{
+    Q_OBJECT
+public:
+    SinkPipeline(QGraphicsView *parent = 0);
+    ~SinkPipeline();
+
+    void startPipeline();
+
+private:
+    GstElement *pipeline;
+    GstElement *sink;
+    GstElement *src;
+    WId xwinid;
+};
+
+#endif // QTGV_XOVERLAY_H