[ekiga/ds-clutter: 6/8] Clutter GST: Added a new clutter gst videooutput.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga/ds-clutter: 6/8] Clutter GST: Added a new clutter gst videooutput.
- Date: Mon, 30 Dec 2013 09:36:44 +0000 (UTC)
commit d7c97cf56fb832be926db651ab779cbf01501f5b
Author: Damien Sandras <dsandras beip be>
Date: Sun Dec 29 14:35:04 2013 +0100
Clutter GST: Added a new clutter gst videooutput.
This is using the GStreamer and Clutter APIs to display frames.
The new videooutput designs requires the videooutput to display frames
onto a surface whatever its size, position and states are. That's
implemented by the current code which will output frames on a
ClutterActor. The part of the GUI managing the ClutterActor is
responsible to size it appropriately following the natural size of the
video.
configure.ac | 17 ++-
lib/Makefile.am | 17 ++-
.../videooutput-main-clutter-gst.cpp | 67 +++++
.../videooutput-main-clutter-gst.h | 47 ++++
.../videooutput-manager-clutter-gst.cpp | 271 ++++++++++++++++++++
.../videooutput-manager-clutter-gst.h | 104 ++++++++
6 files changed, 521 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d5c7e08..7cd4a00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -170,6 +170,21 @@ AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
+dnl ##########################################
+dnl Mandatory GST Clutter & Clutter support
+dnl ##########################################
+PKG_CHECK_MODULES([CLUTTER], [clutter-1.0])
+PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-1.0])
+PKG_CHECK_MODULES([CLUTTER_GST], [clutter-gst-2.0 gstreamer-app-1.0 gstreamer-plugins-base-1.0
gstreamer-plugins-base-1.0])
+
+AC_SUBST(CLUTTER_CFLAGS)
+AC_SUBST(CLUTTER_LIBS)
+AC_SUBST(CLUTTER_GTK_CFLAGS)
+AC_SUBST(CLUTTER_GTK_LIBS)
+AC_SUBST(CLUTTER_GST_CFLAGS)
+AC_SUBST(CLUTTER_GST_LIBS)
+
+
dnl ###############################
dnl Mandatory BOOST support
dnl ###############################
@@ -514,7 +529,7 @@ AM_CONDITIONAL(HAVE_AVAHI, test "x$found_avahi" = "xyes")
dnl ###############################
-dnl GStreamer Support
+dnl GStreamer Plugins Support
dnl ###############################
GSTREAMER="disabled"
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 295d6d6..8262057 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -154,7 +154,7 @@ libekiga_la_SOURCES += \
if !WIN32
libekiga_la_SOURCES += \
- gui/xwindow.cpp \
+ gui/xwindow.cpp \
gui/xwindow.h
endif
@@ -666,3 +666,18 @@ libekiga_la_SOURCES += \
libekiga_la_LDFLAGS += $(DX_LIBS)
endif
+
+##
+# Sources of the Clutter video output component
+##
+
+AM_CPPFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS) $(CLUTTER_GST_CFLAGS) \
+ -I$(top_srcdir)/lib/engine/components/clutter-gst-videooutput
+
+libekiga_la_SOURCES += \
+ engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.cpp \
+ engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.h \
+ engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.cpp \
+ engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.h
+
+libekiga_la_LDFLAGS += $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(CLUTTER_GST_LIBS)
diff --git a/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.cpp
b/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.cpp
new file mode 100644
index 0000000..72bc5b2
--- /dev/null
+++ b/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.cpp
@@ -0,0 +1,67 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * videooutput-main-clutter.cpp - description
+ * --------------------------------------------
+ * begin : Sun 15 December 2013
+ * copyright : (c) 2013 by Damien Sandras
+ * description : code to hook the Clutter display manager into the main program
+ *
+ */
+
+#include <clutter/clutter.h>
+#include <gst/gst.h>
+#include <clutter-gtk/clutter-gtk.h>
+
+#include "videooutput-core.h"
+
+#include "videooutput-main-clutter-gst.h"
+#include "videooutput-manager-clutter-gst.h"
+
+bool
+videooutput_clutter_gst_init (Ekiga::ServiceCore &core,
+ G_GNUC_UNUSED int *argc,
+ G_GNUC_UNUSED char **argv[])
+{
+ bool result = false;
+ boost::shared_ptr<Ekiga::VideoOutputCore> videooutput_core =
+ core.get<Ekiga::VideoOutputCore> ("videooutput-core");
+
+ if (videooutput_core) {
+
+ gst_init (argc, argv);
+ gtk_clutter_init (argc, argv);
+ GMVideoOutputManager_clutter_gst *videooutput_manager = new GMVideoOutputManager_clutter_gst (core);
+
+ videooutput_core->add_manager (*videooutput_manager);
+ result = true;
+ }
+
+ return result;
+}
diff --git a/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.h
b/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.h
new file mode 100644
index 0000000..17af9ea
--- /dev/null
+++ b/lib/engine/components/clutter-gst-videooutput/videooutput-main-clutter-gst.h
@@ -0,0 +1,47 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * videooutput-main-clutter-gst.h - description
+ * -----------------------------------------------
+ * begin : Sun 15 December 2013
+ * copyright : (c) 2013 by Damien Sandras
+ * description : code to hook the Clutter display manager into the main program
+ *
+ */
+
+#ifndef __VIDEOOUTPUT_MAIN_CLUTTER_GST_H__
+#define __VIDEOOUTPUT_MAIN_CLUTTER_GST_H__
+
+#include "services.h"
+
+bool videooutput_clutter_gst_init (Ekiga::ServiceCore &core,
+ int *argc,
+ char **argv[]);
+
+#endif
diff --git a/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.cpp
b/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.cpp
new file mode 100644
index 0000000..ca0ab69
--- /dev/null
+++ b/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.cpp
@@ -0,0 +1,271 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * videooutput-manager-clutter-gst.cpp - description
+ * ---------------------------------------------------
+ * begin : Sun 15 December 2013
+ * copyright : (c) 2013 by Damien Sandras
+ * description : Clutter VideoOutput Manager code.
+ *
+ */
+
+
+#include <ptlib.h>
+
+#include <gtk/gtk.h>
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#include <clutter-gtk/clutter-gtk.h>
+
+#include "videooutput-manager-clutter-gst.h"
+#include "videooutput-info.h"
+#include "videoinput-info.h"
+
+#include "runtime.h"
+
+
+GMVideoOutputManager_clutter_gst::GMVideoOutputManager_clutter_gst (G_GNUC_UNUSED Ekiga::ServiceCore & _core)
+{
+ devices_nbr = 0;
+
+ for (int i = 0 ; i < 3 ; i++) {
+ texture[i] = NULL;
+ pipeline[i] = NULL;
+ }
+}
+
+
+GMVideoOutputManager_clutter_gst::~GMVideoOutputManager_clutter_gst ()
+{
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::quit ()
+{
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::open ()
+{
+ GstElement *appsrc = NULL;
+ GstElement *videosink = NULL;
+ GstElement *conv = NULL;
+ GstCaps *caps = NULL;
+ PWaitAndSignal m(device_mutex);
+
+ for (int i = 0 ; i < 3 ; ++i) {
+
+ std::ostringstream name;
+ name << std::string ("appsrc") << i;
+ pipeline[i] = gst_pipeline_new (NULL);
+ videosink = gst_element_factory_make ("autocluttersink", "videosink");
+ if (videosink == NULL)
+ videosink = gst_element_factory_make ("cluttersink", "videosink");
+ g_object_set (videosink, "texture", texture[i], NULL);
+
+ appsrc = gst_element_factory_make ("appsrc", name.str ().c_str ());
+ conv = gst_element_factory_make ("videoconvert", NULL);
+
+ /* set the caps on the source */
+ current_width[i] = 0;
+ current_height[i]= 0;
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "I420",
+ "framerate", GST_TYPE_FRACTION, 0, 1,
+ "pixel-aspect-ratio" ,GST_TYPE_FRACTION, 1, 1,
+ "width", G_TYPE_INT, 704,
+ "height", G_TYPE_INT, 576,
+ "red_mask", G_TYPE_INT, 0x00ff0000,
+ "green_mask", G_TYPE_INT, 0x0000ff00,
+ "blue_mask", G_TYPE_INT, 0x000000ff,
+ "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
+ NULL);
+
+ if (!videosink || !appsrc || !conv || !pipeline[i]) {
+
+ Ekiga::Runtime::run_in_main (boost::bind (&GMVideoOutputManager_clutter_gst::device_error_in_main,
+ this,
+ Ekiga::VO_ERROR));
+ break;
+ }
+
+ gst_app_src_set_caps (GST_APP_SRC (appsrc), caps);
+ g_object_set (G_OBJECT (appsrc),
+ "block", TRUE,
+ "max-bytes", MAX_VIDEO_SIZE*3/2,
+ "stream-type", GST_APP_STREAM_TYPE_STREAM,
+ NULL);
+ gst_bin_add_many (GST_BIN (pipeline[i]), appsrc, conv, videosink, NULL);
+ gst_element_link_many (appsrc, conv, videosink, NULL);
+ gst_caps_unref (caps);
+ }
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::close ()
+{
+ PWaitAndSignal m(device_mutex);
+ for (int i = 0 ; i < 2 ; i++) {
+ if (!pipeline[i])
+ continue;
+
+ std::ostringstream name;
+ name << std::string ("appsrc") << i;
+ GstElement *appsrc = gst_bin_get_by_name (GST_BIN (pipeline[i]), name.str ().c_str ());
+ gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
+ gst_element_set_state (pipeline[i], GST_STATE_NULL);
+ gst_object_unref (pipeline[i]);
+ pipeline[i] = NULL;
+ }
+ devices_nbr = 0;
+
+ Ekiga::Runtime::run_in_main (boost::bind (&GMVideoOutputManager_clutter_gst::device_closed_in_main,
+ this));
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::set_frame_data (const char *data,
+ unsigned width,
+ unsigned height,
+ unsigned i,
+ int _devices_nbr)
+{
+ GstBuffer *buffer = NULL;
+ GstMapInfo info;
+ int buffer_size = width*height*3/2;
+ std::ostringstream name;
+
+ info.memory = NULL;
+ info.flags = GST_MAP_WRITE;
+ info.data = NULL;
+ info.size = 0;
+ info.maxsize = buffer_size;
+
+ PWaitAndSignal m(device_mutex);
+
+ if (!pipeline[i]) {
+ PTRACE (1, "GMVideoOutputManager_clutter_gst\tTrying to upload frame to closed pipeline " << i);
+ return;
+ }
+
+ if (_devices_nbr != devices_nbr) {
+ Ekiga::Runtime::run_in_main
+ (boost::bind (&GMVideoOutputManager_clutter_gst::device_opened_in_main,
+ this,
+ (_devices_nbr > 1),
+ (_devices_nbr > 2)));
+ devices_nbr = (unsigned) _devices_nbr;
+ }
+
+ if (devices_nbr == 1) { // Only one video stream (either local or remote)
+ // Force whatever stream is received to be displayed as the remote
+ // video (the big one).
+ i = 1;
+ }
+ name << std::string ("appsrc") << i;
+ GstElement *appsrc = gst_bin_get_by_name (GST_BIN (pipeline[i]), name.str ().c_str ());
+
+ if (current_width[i] != width || current_height[i] != height) {
+
+ GstCaps *caps = gst_app_src_get_caps (GST_APP_SRC (appsrc));
+ GstCaps *new_caps = gst_caps_copy (caps);
+ gst_caps_set_simple (new_caps,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height, NULL);
+ gst_app_src_set_caps (GST_APP_SRC (appsrc), new_caps);
+ gst_caps_unref (caps);
+ gst_caps_unref (new_caps);
+
+ current_height[i] = height;
+ current_width[i] = width;
+
+ Ekiga::Runtime::run_in_main (boost::bind (&GMVideoOutputManager_clutter_gst::size_changed_in_main,
+ this,
+ width,
+ height,
+ i));
+ }
+
+ buffer = gst_buffer_new_and_alloc (buffer_size);
+ gst_buffer_map (buffer, &info, GST_MAP_WRITE);
+ memcpy ((void *) info.data, (const void *) data, buffer_size);
+ info.size = buffer_size;
+ gst_buffer_unmap (buffer, &info);
+ gst_app_src_push_buffer (GST_APP_SRC (appsrc), buffer);
+
+ gst_element_set_state (pipeline[i], GST_STATE_PLAYING);
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::set_display_info (const gpointer _local_video,
+ const gpointer _remote_video)
+{
+ texture[0] = CLUTTER_ACTOR (_local_video);
+ texture[1] = CLUTTER_ACTOR (_remote_video);
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::set_ext_display_info (const gpointer _ext_video)
+{
+ texture[2] = CLUTTER_ACTOR (_ext_video);
+}
+
+
+void
+GMVideoOutputManager_clutter_gst::size_changed_in_main (unsigned width,
+ unsigned height,
+ unsigned type)
+{
+ size_changed (width, height, type);
+}
+
+void
+GMVideoOutputManager_clutter_gst::device_opened_in_main (bool both,
+ bool ext)
+{
+ device_opened (both, ext);
+}
+
+void
+GMVideoOutputManager_clutter_gst::device_closed_in_main ()
+{
+ device_closed ();
+}
+
+void
+GMVideoOutputManager_clutter_gst::device_error_in_main (Ekiga::VideoOutputErrorCodes code)
+{
+ device_error (code);
+}
diff --git a/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.h
b/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.h
new file mode 100644
index 0000000..7aae0f4
--- /dev/null
+++ b/lib/engine/components/clutter-gst-videooutput/videooutput-manager-clutter-gst.h
@@ -0,0 +1,104 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * videooutput-manager-clutter-gst.h - description
+ * -------------------------------------------------
+ * begin : Sun 15 December 2013
+ * copyright : (c) 2013 by Damien Sandras
+ * description : Clutter VideoOutput Manager code.
+ *
+ */
+
+#ifndef _VIDEOOUTPUT_MANAGER_CLUTTER_GST_H_
+#define _VIDEOOUTPUT_MANAGER_CLUTTER_GST_H_
+
+#include "services.h"
+#include "videooutput-manager.h"
+#include "videooutput-info.h"
+
+#include <glib.h>
+
+/**
+ * @addtogroup videooutput
+ * @{
+ */
+
+class GMVideoOutputManager_clutter_gst : public Ekiga::VideoOutputManager
+{
+public:
+ GMVideoOutputManager_clutter_gst (Ekiga::ServiceCore & _core);
+
+ ~GMVideoOutputManager_clutter_gst ();
+
+ void quit ();
+
+ void open ();
+
+ void close ();
+
+ void set_frame_data (const char *data,
+ unsigned width,
+ unsigned height,
+ unsigned type,
+ int devices_nbr);
+
+ void set_display_info (const gpointer local_video,
+ const gpointer remote_video);
+
+ void set_ext_display_info (const gpointer ext_video);
+
+private:
+ void size_changed_in_main (unsigned width,
+ unsigned height,
+ unsigned type);
+
+ void device_opened_in_main (bool both,
+ bool ext);
+
+ void device_closed_in_main ();
+
+ void device_error_in_main (Ekiga::VideoOutputErrorCodes code);
+
+ // Variables
+ PMutex device_mutex;
+
+ // 0 = local, 1 = remote, 2 = extended
+ unsigned current_width[3];
+ unsigned current_height[3];
+ GstElement *pipeline[3];
+ ClutterActor *texture[3];
+
+ int devices_nbr;
+};
+
+/**
+ * @}
+ */
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]