ekiga r7059 - trunk/lib/engine/components/gstreamer



Author: jpuydt
Date: Tue Sep 23 05:51:39 2008
New Revision: 7059
URL: http://svn.gnome.org/viewvc/ekiga?rev=7059&view=rev

Log:
Preliminary video input GStreamer code

Added:
   trunk/lib/engine/components/gstreamer/gst-videoinput.cpp
   trunk/lib/engine/components/gstreamer/gst-videoinput.h
Modified:
   trunk/lib/engine/components/gstreamer/Makefile.am
   trunk/lib/engine/components/gstreamer/gst-main.cpp
   trunk/lib/engine/components/gstreamer/gst-main.h

Modified: trunk/lib/engine/components/gstreamer/Makefile.am
==============================================================================
--- trunk/lib/engine/components/gstreamer/Makefile.am	(original)
+++ trunk/lib/engine/components/gstreamer/Makefile.am	Tue Sep 23 05:51:39 2008
@@ -5,10 +5,16 @@
 AM_CXXFLAGS = $(SIGC_CFLAGS) $(GSTREAMER_CFLAGS)
 
 INCLUDES = 						\
-	-I$(top_srcdir)/lib/engine/framework
+	-I$(top_srcdir)/lib/gmconf			\
+	-I$(top_srcdir)/lib/engine/framework		\
+	-I$(top_srcdir)/lib/engine/videoinput/skel	\
+	-I$(top_srcdir)/lib/engine/videooutput/skel	\
+	-I$(top_srcdir)/lib/engine/hal/skel
 
 libgmgstreamer_la_SOURCES = \
 	$(gstreamer_dir)/gst-main.h \
-	$(gstreamer_dir)/gst-main.cpp
+	$(gstreamer_dir)/gst-main.cpp \
+	$(gstreamer_dir)/gst-videoinput.h \
+	$(gstreamer_dir)/gst-videoinput.cpp
 
-libgmgstreamer_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GSTREAMER_LIBS)
+libgmgstreamer_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GSTREAMER_LIBS) -lgstapp-0.10
\ No newline at end of file

Modified: trunk/lib/engine/components/gstreamer/gst-main.cpp
==============================================================================
--- trunk/lib/engine/components/gstreamer/gst-main.cpp	(original)
+++ trunk/lib/engine/components/gstreamer/gst-main.cpp	Tue Sep 23 05:51:39 2008
@@ -35,15 +35,29 @@
  *
  */
 
+#include "videoinput-core.h"
 #include "gst-main.h"
-#include "gst/gst.h"
+#include "gst-videoinput.h"
 
 bool
-gstreamer_init (G_GNUC_UNUSED Ekiga::ServiceCore &services,
-		int *argc,
-		char **argv[])
+gstreamer_init (Ekiga::ServiceCore& core,
+		int* argc,
+		char** argv[])
 {
-  gst_init (argc, argv);
+  bool result = false;
+  Ekiga::VideoInputCore* videoinput_core = NULL;
 
-  return true;
+  videoinput_core
+    = dynamic_cast<Ekiga::VideoInputCore*>(core.get ("videoinput-core"));
+
+  if (videoinput_core != NULL) {
+
+    GST::VideoInputManager* manager = new GST::VideoInputManager ();
+
+    gst_init (argc, argv);
+    videoinput_core->add_manager (*manager);
+    result = true;
+  }
+
+  return result;
 }

Modified: trunk/lib/engine/components/gstreamer/gst-main.h
==============================================================================
--- trunk/lib/engine/components/gstreamer/gst-main.h	(original)
+++ trunk/lib/engine/components/gstreamer/gst-main.h	Tue Sep 23 05:51:39 2008
@@ -41,7 +41,7 @@
 #include "services.h"
 
 bool gstreamer_init (Ekiga::ServiceCore &services,
-		     int *argc,
-		     char **argv[]);
+		     int* argc,
+		     char** argv[]);
 
 #endif

Added: trunk/lib/engine/components/gstreamer/gst-videoinput.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/gstreamer/gst-videoinput.cpp	Tue Sep 23 05:51:39 2008
@@ -0,0 +1,288 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * 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.
+ */
+
+
+/*
+ *                         gst-videoinput.h  -  description
+ *                         ------------------------------------
+ *   begin                : Wed 17 September 2008
+ *   copyright            : (C) 2008 by Julien Puydt
+ *   description          : Gstreamer video input code
+ *
+ */
+
+#include "gst-videoinput.h"
+
+#include <gst/interfaces/propertyprobe.h>
+#include <gst/app/gstappsink.h>
+
+GST::VideoInputManager::VideoInputManager (): pipeline(NULL)
+{
+  detect_devices (); // or we won't recognize the devices we'll be asked to use
+}
+
+GST::VideoInputManager::~VideoInputManager ()
+{
+  if (pipeline != NULL)
+    g_object_unref (pipeline);
+  pipeline = NULL;
+}
+
+void
+GST::VideoInputManager::get_devices (std::vector<Ekiga::VideoInputDevice>& devices)
+{
+  detect_devices ();
+
+  for (std::map<std::string, std::string>::const_iterator iter
+	 = devices_by_name.begin ();
+       iter != devices_by_name.end ();
+       ++iter) {
+
+    Ekiga::VideoInputDevice device;
+    device.type = "GStreamer";
+    device.source = "GStreamer";
+    device.name = iter->first;
+    devices.push_back (device);
+  }
+}
+
+bool
+GST::VideoInputManager::set_device (const Ekiga::VideoInputDevice& device,
+				    int channel,
+				    Ekiga::VideoInputFormat format)
+{
+  bool result = false;
+
+  if (device.type == "GStreamer"
+      && device.source == "GStreamer"
+      && devices_by_name.find (device.name) != devices_by_name.end ()) {
+
+    current_state.opened = false;
+    current_state.width = 320;
+    current_state.height = 240;
+    current_state.fps = 30;
+    current_state.device = device;
+    current_state.format = format;
+    current_state.channel = channel;
+
+    result = true;
+  }
+
+  return result;
+}
+
+bool
+GST::VideoInputManager::open (unsigned width,
+			      unsigned height,
+			      unsigned fps)
+{
+  bool result;
+  gchar* command = NULL;
+  GError* error = NULL;
+  GstState current;
+
+  command = g_strdup_printf ("%s ! appsink max_buffers=2 drop=true"
+			     " caps=video/x-raw-yuv"
+			     ",format=(fourcc)I420"
+			     ",width=%d,height=%d"
+			     ",framerate=%d"
+			     " name=ekiga_sink",
+			     devices_by_name[current_state.device.name].c_str (),
+			     width, height, fps);
+  g_print ("Trying to open new pipeline: %s\n", command);
+  pipeline = gst_parse_launch (command, &error);
+
+  if (error == NULL) {
+
+    (void)gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+    // this will make us wait so we can return the right value...
+    (void)gst_element_get_state (pipeline,
+				 &current,
+				 NULL,
+				 GST_SECOND);
+
+    if (current != GST_STATE_PLAYING) {
+
+      gst_object_unref (GST_OBJECT (pipeline));
+      pipeline = NULL;
+      result = false;
+    } else {
+
+      result = true;
+    }
+  } else
+    result = false;
+
+  g_free (command);
+
+  current_state.opened = result;
+  g_print ("Opening %s\n", result?"success":"failure");
+  return result;
+}
+
+void
+GST::VideoInputManager::close ()
+{
+  g_print ("%s\n", __PRETTY_FUNCTION__);
+  if (pipeline != NULL) {
+
+    g_object_unref (pipeline);
+    pipeline = NULL;
+  }
+  current_state.opened = false;
+}
+
+bool
+GST::VideoInputManager::get_frame_data (char* data,
+					G_GNUC_UNUSED unsigned& width,
+					G_GNUC_UNUSED unsigned& height)
+{
+  bool result = false;
+  GstBuffer* buffer = NULL;
+  GstElement* sink = NULL;
+
+  g_return_val_if_fail (GST_IS_BIN (pipeline), false);
+
+  sink = gst_bin_get_by_name (GST_BIN (pipeline), "ekiga_sink");
+
+  if (sink != NULL) {
+
+    buffer = gst_app_sink_pull_buffer (GST_APP_SINK (sink));
+
+    if (buffer != NULL) {
+
+      memcpy (data, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
+      result = true;
+      gst_buffer_unref (buffer);
+    }
+    g_object_unref (sink);
+  }
+
+  return result;
+}
+
+bool
+GST::VideoInputManager::has_device (G_GNUC_UNUSED const std::string& source,
+				    const std::string& device_name,
+				    G_GNUC_UNUSED unsigned capabilities,
+				    G_GNUC_UNUSED Ekiga::VideoInputDevice& device)
+{
+  return (devices_by_name.find (device_name) != devices_by_name.end ());
+}
+
+void
+GST::VideoInputManager::detect_devices ()
+{
+  devices_by_name.clear ();
+  devices_by_name["Video test"] = "videotestsrc";
+  detect_v4l2src_devices ();
+  detect_dv1394src_devices ();
+}
+
+void
+GST::VideoInputManager::detect_v4l2src_devices ()
+{
+  GstElement* elt = NULL;
+
+  elt = gst_element_factory_make ("v4l2src", "v4l2srcpresencetest");
+
+  if (elt != NULL) {
+
+    GstPropertyProbe* probe = NULL;
+    const GParamSpec* pspec = NULL;
+    GValueArray* array = NULL;
+
+    probe = GST_PROPERTY_PROBE (elt);
+    pspec = gst_property_probe_get_property (probe, "device");
+    array = gst_property_probe_probe_and_get_values (probe, pspec);
+
+    if (array != NULL) {
+
+      for (guint index = 0; index < array->n_values; index++) {
+
+	GValue* device = NULL;
+	gchar* name = NULL;
+	gchar* descr = NULL;
+
+	device = g_value_array_get_nth (array, index);
+	g_object_set_property (G_OBJECT (elt), "device", device);
+
+	g_object_get (G_OBJECT (elt), "device-name", &name, NULL);
+	descr = g_strdup_printf ("v4l2src device=%s",
+				 g_value_get_string (device));
+	devices_by_name[name] = descr;
+	g_free (descr);
+      }
+
+      gst_element_set_state (elt, GST_STATE_NULL);
+    }
+    gst_object_unref (GST_OBJECT (elt));
+  }
+}
+
+void
+GST::VideoInputManager::detect_dv1394src_devices ()
+{
+  GstElement* elt = NULL;
+
+  elt = gst_element_factory_make ("dv1394src", "dv1394srcpresencetest");
+
+  if (elt != NULL) {
+
+    GstPropertyProbe* probe = NULL;
+    const GParamSpec* pspec = NULL;
+    GValueArray* array = NULL;
+
+    probe = GST_PROPERTY_PROBE (elt);
+    pspec = gst_property_probe_get_property (probe, "guid");
+    array = gst_property_probe_probe_and_get_values (probe, pspec);
+
+    if (array != NULL) {
+
+      for (guint index = 0; index < array->n_values; index++) {
+
+	GValue* guid = NULL;
+	gchar* name = NULL;
+	gchar* descr = NULL;
+	guid = g_value_array_get_nth (array, index);
+	g_object_set_property (G_OBJECT (elt), "guid", guid);
+
+	g_object_get (G_OBJECT (elt), "device-name", &name, NULL);
+	descr = g_strdup_printf ("dv1394src guid=%Ld"
+				 " ! decodebin"
+				 " ! ffmpegcolorspace",
+				 g_value_get_uint64 (guid));
+	devices_by_name[name] = descr;
+	g_free (descr);
+      }
+
+      gst_element_set_state (elt, GST_STATE_NULL);
+    }
+    gst_object_unref (GST_OBJECT (elt));
+  }
+}

Added: trunk/lib/engine/components/gstreamer/gst-videoinput.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/gstreamer/gst-videoinput.h	Tue Sep 23 05:51:39 2008
@@ -0,0 +1,88 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * 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.
+ */
+
+
+/*
+ *                         gst-videoinput.h  -  description
+ *                         ------------------------------------
+ *   begin                : Wed 17 September 2008
+ *   copyright            : (C) 2008 by Julien Puydt
+ *   description          : Gstreamer video input code
+ *
+ */
+
+#ifndef __GST_VIDEOINPUT_H__
+#define __GST_VIDEOINPUT_H__
+
+#include "videoinput-manager.h"
+#include <gst/gst.h>
+
+namespace GST
+{
+  class VideoInputManager: public Ekiga::VideoInputManager
+  {
+  public:
+
+    VideoInputManager ();
+
+    ~VideoInputManager ();
+
+    void get_devices (std::vector<Ekiga::VideoInputDevice>& devices);
+
+    bool set_device (const Ekiga::VideoInputDevice& device,
+		     int channel,
+		     Ekiga::VideoInputFormat format);
+
+    bool open (unsigned width,
+	       unsigned height,
+	       unsigned fps);
+
+    void close ();
+
+    bool get_frame_data (char* data,
+			 unsigned& width,
+			 unsigned& height);
+
+    bool has_device (const std::string& source,
+		     const std::string& device_name,
+		     unsigned capabilities,
+		     Ekiga::VideoInputDevice& device);
+  private:
+
+    void detect_devices ();
+    void detect_v4l2src_devices ();
+    void detect_dv1394src_devices ();
+
+    /* we take a user-readable name, and get the string describing
+     * the actual device */
+    std::map<std::string, std::string> devices_by_name;
+
+    GstElement* pipeline;
+  };
+};
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]