[farsight2/master] Add python bindings

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:20:28 PST 2008


---
 .gitignore                    |    2 +
 Makefile.am                   |   12 +-
 configure.ac                  |   17 ++
 python/Makefile.am            |   46 ++++
 python/pyfarsight-filter.defs |   29 ++
 python/pyfarsight.defs        |  552 +++++++++++++++++++++++++++++++++++++
 python/pyfarsight.override    |  599 +++++++++++++++++++++++++++++++++++++++++
 python/pyfarsightmodule.c     |   26 ++
 python/rebuild-defs.sh        |   22 ++
 9 files changed, 1299 insertions(+), 6 deletions(-)
 create mode 100644 python/Makefile.am
 create mode 100644 python/pyfarsight-filter.defs
 create mode 100644 python/pyfarsight.defs
 create mode 100644 python/pyfarsight.override
 create mode 100644 python/pyfarsightmodule.c
 create mode 100755 python/rebuild-defs.sh

diff --git a/.gitignore b/.gitignore
index f9d37d4..e66c30a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,8 @@ docs/libs/html
 docs/libs/tmpl
 docs/libs/xml
 
+python/pyfarsight.c
+
 tests/check/test-registry.xml
 tests/check/*/.dirstamp
 tests/check/base/fscodec
diff --git a/Makefile.am b/Makefile.am
index ba5bf09..ff23e97 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,26 +2,26 @@ DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
 
 SUBDIRS_EXT =
 
+if WANT_PYTHON
+PYTHON_SUBDIR = python
+endif
+
 SUBDIRS = 			\
 	gst-libs 		\
 	gst $(SUBDIRS_EXT)	\
 	transmitters		\
+	$(PYTHON_SUBDIR)	\
 	tests 			\
 	docs
-#
-
-#	docs			\
 #	pkgconfig
 
 DIST_SUBDIRS = 			\
 	gst-libs		\
 	gst $(SUBDIRS_EXT)	\
 	transmitters		\
+	python			\
 	tests 			\
 	docs
-#
-
-#	docs			\
 #	pkgconfig
 
 EXTRA_DIST = \
diff --git a/configure.ac b/configure.ac
index 7c3a7ba..68b0974 100644
--- a/configure.ac
+++ b/configure.ac
@@ -329,6 +329,22 @@ dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
 FS2_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS"
 AC_SUBST(FS2_PLUGIN_LDFLAGS)
 
+
+AC_ARG_ENABLE([python],
+	AC_HELP_STRING([--disable-python], [Disable Python bindings]),
+	[case "${enableval}" in
+	    yes) WANT_PYTHON=yes ;;
+	    no)  WANT_PYTHON=no ;;
+	    *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
+        esac],
+	WANT_PYTHON=yes)
+if test "x$WANT_PYTHON" = "xyes"; then
+   AM_PATH_PYTHON
+   PKG_CHECK_MODULES(PYFARSIGHT, [ pygobject-2.0 gst-python-0.10 ] )
+fi
+AM_CONDITIONAL(WANT_PYTHON, test "x$WANT_PYTHON" = "xyes")
+
+
 dnl *** output files ***
 
 AC_CONFIG_FILES(
@@ -350,6 +366,7 @@ tests/rtp/Makefile
 docs/Makefile
 docs/libs/Makefile
 docs/version.entities
+python/Makefile
 dnl docs/plugins/Makefile
 )
 AC_OUTPUT
diff --git a/python/Makefile.am b/python/Makefile.am
new file mode 100644
index 0000000..2a762d1
--- /dev/null
+++ b/python/Makefile.am
@@ -0,0 +1,46 @@
+PYDEFS=`pkg-config --variable=defsdir pygtk-2.0`
+GSTPYDEFS=`pkg-config --variable=defsdir gst-python-0.10`
+
+AM_CPPFLAGS =						\
+	-I.						\
+	-I$(top_srcdir)/gst-libs/gst/farsight/		\
+	-DDATADIR=\""$(datadir)"\"			\
+	$(PYFARSIGHT_CFLAGS)				\
+	`python-config --cflags`			\
+	$(FS2_INTERNAL_CFLAGS) 				\
+	$(FS2_CFLAGS) 					\
+	$(WARN_CFLAGS)
+
+BUILT_SOURCES =						\
+	pyfarsight.c					 
+
+pyfarsightdir = $(pyexecdir)
+pyfarsight_LTLIBRARIES = farsight.la
+
+farsight_la_SOURCES =					\
+	pyfarsightmodule.c				\
+	pyfarsight.c
+
+farsight_la_LIBADD =					\
+	$(PYFARSIGHT_LIBS)				\
+	$(top_builddir)/gst-libs/gst/farsight/libgstfarsight- at GST_MAJORMINOR@.la
+
+farsight_la_LDFLAGS =					\
+	`python-config --libs`				\
+	-module -avoid-version
+
+pyfarsight.c: pyfarsight.override pyfarsight.defs
+	pygtk-codegen-2.0					\
+		--prefix fs					\
+		--register $(PYDEFS)/gnome.defs			\
+		--register $(PYDEFS)/gdk-types.defs		\
+		--register $(PYDEFS)/gtk-types.defs		\
+		--register $(GSTPYDEFS)/gst-types.defs		\
+		--override pyfarsight.override			\
+		pyfarsight.defs > $@ 
+
+EXTRA_DIST =			\
+	pyfarsight.override	\
+	pyfarsight.defs
+
+CLEANFILES = $(BUILT_SOURCES)
diff --git a/python/pyfarsight-filter.defs b/python/pyfarsight-filter.defs
new file mode 100644
index 0000000..b6b7f23
--- /dev/null
+++ b/python/pyfarsight-filter.defs
@@ -0,0 +1,29 @@
+(define-interface Conference
+  (in-module "Fs")
+  (c-name "FsConference")
+  (gtype-id "FS_TYPE_CONFERENCE")
+)
+
+(define-boxed Codec
+  (in-module "Fs")
+  (c-name "FsCodec")
+  (gtype-id "FS_TYPE_CODEC")
+  (copy-func fs_codec_copy)
+  (release-func fs_codec_destroy)
+)
+
+
+(define-boxed Candidate
+  (in-module "Fs")
+  (c-name "FsCandidate")
+  (gtype-id "FS_TYPE_CANDIDATE")
+  (copy-func fs_candidate_copy)
+  (release-func fs_candidate_destroy)
+)
+
+
+(define-function fs_candidate_new
+  (c-name "fs_candidate_new")
+  (is-constructor-of "FsCandidate")
+  (return-type "FsCandidate*")
+)
diff --git a/python/pyfarsight.defs b/python/pyfarsight.defs
new file mode 100644
index 0000000..91cb021
--- /dev/null
+++ b/python/pyfarsight.defs
@@ -0,0 +1,552 @@
+(define-interface Conference
+  (in-module "Fs")
+  (c-name "FsConference")
+  (gtype-id "FS_TYPE_CONFERENCE")
+)
+
+(define-boxed Codec
+  (in-module "Fs")
+  (c-name "FsCodec")
+  (gtype-id "FS_TYPE_CODEC")
+  (copy-func fs_codec_copy)
+  (release-func fs_codec_destroy)
+)
+
+
+(define-boxed Candidate
+  (in-module "Fs")
+  (c-name "FsCandidate")
+  (gtype-id "FS_TYPE_CANDIDATE")
+  (copy-func fs_candidate_copy)
+  (release-func fs_candidate_destroy)
+)
+
+
+(define-function fs_candidate_new
+  (c-name "fs_candidate_new")
+  (is-constructor-of "FsCandidate")
+  (return-type "FsCandidate*")
+)
+;; -*- scheme -*-
+; object definitions ...
+;; Enumerations and flags ...
+
+(define-enum MediaType
+  (in-module "Fs")
+  (c-name "FsMediaType")
+  (gtype-id "FS_TYPE_MEDIA_TYPE")
+  (values
+    '("audio" "FS_MEDIA_TYPE_AUDIO")
+    '("video" "FS_MEDIA_TYPE_VIDEO")
+    '("application" "FS_MEDIA_TYPE_APPLICATION")
+    '("last" "FS_MEDIA_TYPE_LAST")
+  )
+)
+
+
+;; From fs-codec.h
+
+(define-function fs_codec_get_type
+  (c-name "fs_codec_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_codec_list_get_type
+  (c-name "fs_codec_list_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_codec_new
+  (c-name "fs_codec_new")
+  (is-constructor-of "FsCodec")
+  (return-type "FsCodec*")
+  (parameters
+    '("int" "id")
+    '("const-char*" "encoding_name")
+    '("FsMediaType" "media_type")
+    '("guint" "clock_rate")
+  )
+)
+
+(define-method destroy
+  (of-object "FsCodec")
+  (c-name "fs_codec_destroy")
+  (return-type "none")
+)
+
+(define-method copy
+  (of-object "FsCodec")
+  (c-name "fs_codec_copy")
+  (return-type "FsCodec*")
+)
+
+(define-function fs_codec_list_destroy
+  (c-name "fs_codec_list_destroy")
+  (return-type "none")
+  (parameters
+    '("GList*" "codec_list")
+  )
+)
+
+(define-function fs_codec_list_copy
+  (c-name "fs_codec_list_copy")
+  (return-type "GList*")
+  (parameters
+    '("const-GList*" "codec_list")
+  )
+)
+
+(define-function fs_codec_list_from_keyfile
+  (c-name "fs_codec_list_from_keyfile")
+  (return-type "GList*")
+  (parameters
+    '("const-gchar*" "filename")
+  )
+)
+
+(define-method to_string
+  (of-object "FsCodec")
+  (c-name "fs_codec_to_string")
+  (return-type "gchar*")
+)
+
+(define-method are_equal
+  (of-object "FsCodec")
+  (c-name "fs_codec_are_equal")
+  (return-type "gboolean")
+  (parameters
+    '("const-FsCodec*" "codec2")
+  )
+)
+
+(define-method to_gst_caps
+  (of-object "FsCodec")
+  (c-name "fs_codec_to_gst_caps")
+  (return-type "GstCaps*")
+)
+
+(define-method to_string
+  (of-object "FsMediaType")
+  (c-name "fs_media_type_to_string")
+  (return-type "const-gchar*")
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+;; Enumerations and flags ...
+
+(define-enum CandidateType
+  (in-module "Fs")
+  (c-name "FsCandidateType")
+  (gtype-id "FS_TYPE_CANDIDATE_TYPE")
+  (values
+    '("host" "FS_CANDIDATE_TYPE_HOST")
+    '("srflx" "FS_CANDIDATE_TYPE_SRFLX")
+    '("prflx" "FS_CANDIDATE_TYPE_PRFLX")
+    '("relay" "FS_CANDIDATE_TYPE_RELAY")
+  )
+)
+
+(define-enum NetworkProtocol
+  (in-module "Fs")
+  (c-name "FsNetworkProtocol")
+  (gtype-id "FS_TYPE_NETWORK_PROTOCOL")
+  (values
+    '("udp" "FS_NETWORK_PROTOCOL_UDP")
+    '("tcp" "FS_NETWORK_PROTOCOL_TCP")
+  )
+)
+
+(define-enum ComponentType
+  (in-module "Fs")
+  (c-name "FsComponentType")
+  (gtype-id "FS_TYPE_COMPONENT_TYPE")
+  (values
+    '("p" "FS_COMPONENT_RTP")
+    '("cp" "FS_COMPONENT_RTCP")
+  )
+)
+
+
+;; From fs-candidate.h
+
+(define-function fs_candidate_get_type
+  (c-name "fs_candidate_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_candidate_list_get_type
+  (c-name "fs_candidate_list_get_type")
+  (return-type "GType")
+)
+
+(define-method destroy
+  (of-object "FsCandidate")
+  (c-name "fs_candidate_destroy")
+  (return-type "none")
+)
+
+(define-method copy
+  (of-object "FsCandidate")
+  (c-name "fs_candidate_copy")
+  (return-type "FsCandidate*")
+)
+
+(define-function fs_candidate_list_destroy
+  (c-name "fs_candidate_list_destroy")
+  (return-type "none")
+  (parameters
+    '("GList*" "candidate_list")
+  )
+)
+
+(define-function fs_candidate_list_copy
+  (c-name "fs_candidate_list_copy")
+  (return-type "GList*")
+  (parameters
+    '("const-GList*" "candidate_list")
+  )
+)
+
+(define-function fs_candidate_get_by_id
+  (c-name "fs_candidate_get_by_id")
+  (return-type "FsCandidate*")
+  (parameters
+    '("const-GList*" "candidate_list")
+    '("const-gchar*" "candidate_id")
+  )
+)
+
+(define-method are_equal
+  (of-object "FsCandidate")
+  (c-name "fs_candidate_are_equal")
+  (return-type "gboolean")
+  (parameters
+    '("const-FsCandidate*" "cand2")
+  )
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+;; Enumerations and flags ...
+
+(define-enum Error
+  (in-module "Fs")
+  (c-name "FsError")
+  (gtype-id "FS_TYPE_ERROR")
+  (values
+    '("construction" "FS_ERROR_CONSTRUCTION")
+    '("invalid-arguments" "FS_ERROR_INVALID_ARGUMENTS")
+    '("internal" "FS_ERROR_INTERNAL")
+    '("network" "FS_ERROR_NETWORK")
+    '("not-implemented" "FS_ERROR_NOT_IMPLEMENTED")
+    '("negotiation-failed" "FS_ERROR_NEGOTIATION_FAILED")
+    '("unknown-codec" "FS_ERROR_UNKNOWN_CODEC")
+    '("unknown-cname" "FS_ERROR_UNKNOWN_CNAME")
+  )
+)
+
+
+;; From fs-conference-iface.h
+
+(define-function fs_conference_get_type
+  (c-name "fs_conference_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_error_quark
+  (c-name "fs_error_quark")
+  (return-type "GQuark")
+)
+
+(define-method new_session
+  (of-object "FsConference")
+  (c-name "fs_conference_new_session")
+  (return-type "FsSession*")
+  (parameters
+    '("FsMediaType" "media_type")
+    '("GError**" "error")
+  )
+)
+
+(define-method new_participant
+  (of-object "FsConference")
+  (c-name "fs_conference_new_participant")
+  (return-type "FsParticipant*")
+  (parameters
+    '("gchar*" "cname")
+    '("GError**" "error")
+  )
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+(define-object Session
+  (in-module "Fs")
+  (parent "GObject")
+  (c-name "FsSession")
+  (gtype-id "FS_TYPE_SESSION")
+)
+
+;; Enumerations and flags ...
+
+(define-enum DTMFEvent
+  (in-module "Fs")
+  (c-name "FsDTMFEvent")
+  (gtype-id "FS_TYPE_DTMF_EVENT")
+  (values
+    '("0" "FS_DTMF_EVENT_0")
+    '("1" "FS_DTMF_EVENT_1")
+    '("2" "FS_DTMF_EVENT_2")
+    '("3" "FS_DTMF_EVENT_3")
+    '("4" "FS_DTMF_EVENT_4")
+    '("5" "FS_DTMF_EVENT_5")
+    '("6" "FS_DTMF_EVENT_6")
+    '("7" "FS_DTMF_EVENT_7")
+    '("8" "FS_DTMF_EVENT_8")
+    '("9" "FS_DTMF_EVENT_9")
+    '("star" "FS_DTMF_EVENT_STAR")
+    '("pound" "FS_DTMF_EVENT_POUND")
+    '("a" "FS_DTMF_EVENT_A")
+    '("b" "FS_DTMF_EVENT_B")
+    '("c" "FS_DTMF_EVENT_C")
+    '("d" "FS_DTMF_EVENT_D")
+  )
+)
+
+(define-enum DTMFMethod
+  (in-module "Fs")
+  (c-name "FsDTMFMethod")
+  (gtype-id "FS_TYPE_DTMF_METHOD")
+  (values
+    '("auto" "FS_DTMF_METHOD_AUTO")
+    '("rtp-rfc4733" "FS_DTMF_METHOD_RTP_RFC4733")
+    '("in-band" "FS_DTMF_METHOD_IN_BAND")
+  )
+)
+
+
+;; From fs-session.h
+
+(define-function fs_session_get_type
+  (c-name "fs_session_get_type")
+  (return-type "GType")
+)
+
+(define-method new_stream
+  (of-object "FsSession")
+  (c-name "fs_session_new_stream")
+  (return-type "FsStream*")
+  (parameters
+    '("FsParticipant*" "participant")
+    '("FsStreamDirection" "direction")
+    '("const-gchar*" "transmitter")
+    '("guint" "stream_transmitter_n_parameters")
+    '("GParameter*" "stream_transmitter_parameters")
+    '("GError**" "error")
+  )
+)
+
+(define-method start_telephony_event
+  (of-object "FsSession")
+  (c-name "fs_session_start_telephony_event")
+  (return-type "gboolean")
+  (parameters
+    '("guint8" "event")
+    '("guint8" "volume")
+    '("FsDTMFMethod" "method")
+  )
+)
+
+(define-method stop_telephony_event
+  (of-object "FsSession")
+  (c-name "fs_session_stop_telephony_event")
+  (return-type "gboolean")
+  (parameters
+    '("FsDTMFMethod" "method")
+  )
+)
+
+(define-method set_send_codec
+  (of-object "FsSession")
+  (c-name "fs_session_set_send_codec")
+  (return-type "gboolean")
+  (parameters
+    '("FsCodec*" "send_codec")
+    '("GError**" "error")
+  )
+)
+
+(define-method emit_error
+  (of-object "FsSession")
+  (c-name "fs_session_emit_error")
+  (return-type "none")
+  (parameters
+    '("gint" "error_no")
+    '("gchar*" "error_msg")
+    '("gchar*" "debug_msg")
+  )
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+(define-object Participant
+  (in-module "Fs")
+  (parent "GObject")
+  (c-name "FsParticipant")
+  (gtype-id "FS_TYPE_PARTICIPANT")
+)
+
+;; Enumerations and flags ...
+
+
+;; From fs-participant.h
+
+(define-function fs_participant_get_type
+  (c-name "fs_participant_get_type")
+  (return-type "GType")
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+(define-object Stream
+  (in-module "Fs")
+  (parent "GObject")
+  (c-name "FsStream")
+  (gtype-id "FS_TYPE_STREAM")
+)
+
+;; Enumerations and flags ...
+
+(define-enum StreamDirection
+  (in-module "Fs")
+  (c-name "FsStreamDirection")
+  (gtype-id "FS_TYPE_STREAM_DIRECTION")
+  (values
+    '("none" "FS_DIRECTION_NONE")
+    '("send" "FS_DIRECTION_SEND")
+    '("recv" "FS_DIRECTION_RECV")
+    '("both" "FS_DIRECTION_BOTH")
+  )
+)
+
+
+;; From fs-stream.h
+
+(define-function fs_stream_get_type
+  (c-name "fs_stream_get_type")
+  (return-type "GType")
+)
+
+(define-method add_remote_candidate
+  (of-object "FsStream")
+  (c-name "fs_stream_add_remote_candidate")
+  (return-type "gboolean")
+  (parameters
+    '("FsCandidate*" "candidate")
+    '("GError**" "error")
+  )
+)
+
+(define-method remote_candidates_added
+  (of-object "FsStream")
+  (c-name "fs_stream_remote_candidates_added")
+  (return-type "none")
+)
+
+(define-method select_candidate_pair
+  (of-object "FsStream")
+  (c-name "fs_stream_select_candidate_pair")
+  (return-type "gboolean")
+  (parameters
+    '("gchar*" "lfoundation")
+    '("gchar*" "rfoundation")
+    '("GError**" "error")
+  )
+)
+
+(define-method preload_recv_codec
+  (of-object "FsStream")
+  (c-name "fs_stream_preload_recv_codec")
+  (return-type "gboolean")
+  (parameters
+    '("FsCodec*" "codec")
+    '("GError**" "error")
+  )
+)
+
+(define-method set_remote_codecs
+  (of-object "FsStream")
+  (c-name "fs_stream_set_remote_codecs")
+  (return-type "gboolean")
+  (parameters
+    '("GList*" "remote_codecs")
+    '("GError**" "error")
+  )
+)
+
+(define-method emit_error
+  (of-object "FsStream")
+  (c-name "fs_stream_emit_error")
+  (return-type "none")
+  (parameters
+    '("gint" "error_no")
+    '("gchar*" "error_msg")
+    '("gchar*" "debug_msg")
+  )
+)
+
+
+;; -*- scheme -*-
+; object definitions ...
+;; Enumerations and flags ...
+
+
+;; From fs-enum-types.h
+
+(define-function fs_candidate_type_get_type
+  (c-name "fs_candidate_type_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_network_protocol_get_type
+  (c-name "fs_network_protocol_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_component_type_get_type
+  (c-name "fs_component_type_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_media_type_get_type
+  (c-name "fs_media_type_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_dtmf_event_get_type
+  (c-name "fs_dtmf_event_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_dtmf_method_get_type
+  (c-name "fs_dtmf_method_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_stream_direction_get_type
+  (c-name "fs_stream_direction_get_type")
+  (return-type "GType")
+)
+
+(define-function fs_error_get_type
+  (c-name "fs_error_get_type")
+  (return-type "GType")
+)
+
+
diff --git a/python/pyfarsight.override b/python/pyfarsight.override
new file mode 100644
index 0000000..bd0771a
--- /dev/null
+++ b/python/pyfarsight.override
@@ -0,0 +1,599 @@
+%%
+headers
+#include <Python.h>
+#include <pygobject.h>
+
+#include <gst/gst.h>
+
+#include "fs-conference-iface.h"
+#include "fs-enum-types.h"
+
+#include "fs-transmitter.h"
+
+
+static PyObject *
+_fs_boxed_list_from_value (const GValue *value, GType type)
+{
+  PyObject *list = PyList_New (0);
+  GList *item;
+
+  if (G_VALUE_TYPE(value) != type)
+  {
+    PyErr_Format(PyExc_TypeError, "Must be a List of %s", g_type_name (type));
+    return NULL;
+  }
+
+  for (item = g_list_first (g_value_get_boxed (value));
+       item;
+       item = g_list_next (item))
+    PyList_Append (list, pyg_boxed_new (type, item->data, TRUE, TRUE));
+
+  return list;
+}
+
+typedef void* (*StructCopyFunc) (void*);
+
+static int
+_fs_boxed_list_to_value (GValue *value, PyObject *obj, GType type,
+    StructCopyFunc copy_func)
+{
+  int i;
+  GList *boxed = NULL;
+
+  if (!PyList_Check (obj)) {
+    PyErr_Format(PyExc_TypeError, "Must be a List of %s", g_type_name (type));
+    return -1;
+  }
+
+  for (i = 0; i < PyList_Size (obj); i++)
+  {
+    PyObject *item = PyList_GetItem (obj, i);
+
+    if (!pyg_boxed_check (item, type))
+    {
+      PyErr_Format(PyExc_TypeError,
+          "The parameter must be a List of %s", g_type_name (type));
+      return -1;
+    }
+  }
+
+  for (i = 0; i < PyList_Size (obj); i++)
+  {
+    PyObject *item = PyList_GetItem (obj, i);
+
+    boxed = g_list_append (boxed,
+        copy_func (
+            pyg_boxed_get (item, void*)));
+  }
+
+  g_value_take_boxed (value, boxed);
+
+  return 0;
+}
+
+static PyObject *
+_fs_codec_list_from_value (const GValue *value)
+{
+  return _fs_boxed_list_from_value (value, FS_TYPE_CODEC_LIST);
+}
+
+static int
+_fs_codec_list_to_value (GValue *value, PyObject *obj)
+{
+  return _fs_boxed_list_to_value (value, obj, FS_TYPE_CODEC_LIST,
+      (StructCopyFunc) fs_codec_copy);
+}
+
+static PyObject *
+_fs_candidate_list_from_value (const GValue *value)
+{
+  return _fs_boxed_list_from_value (value, FS_TYPE_CANDIDATE_LIST);
+}
+
+static int
+_fs_candidate_list_to_value (GValue *value, PyObject *obj)
+{
+  return _fs_boxed_list_to_value (value, obj, FS_TYPE_CANDIDATE_LIST,
+      (StructCopyFunc) fs_candidate_copy);
+}
+
+%%
+modulename farsight
+%%
+ignore-glob
+        *_get_type
+        fs_*_list_copy
+        fs_*_list_destroy
+%%
+ignore
+        fs_error_quark
+        fs_candidate_get_by_id
+%%
+import gobject.GObject as PyGObject_Type
+%%
+init
+pyg_register_gtype_custom (FS_TYPE_CODEC_LIST,
+    _fs_codec_list_from_value,
+    _fs_codec_list_to_value);
+pyg_register_gtype_custom (FS_TYPE_CANDIDATE_LIST,
+    _fs_candidate_list_from_value,
+    _fs_candidate_list_to_value);
+%%
+override fs_session_new_stream kwargs
+static PyObject *
+_wrap_fs_session_new_stream(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+  static char *kwlist[] = {"participant", "direction", "transmitter",
+                           "transmitter_parameters", NULL};
+
+  PyObject *participant = NULL;
+  gint direction;
+  const gchar *transmitter_name = NULL;
+  PyObject *st_params = NULL;
+  int pos = 0, i = 0;
+  PyObject *key, *value;
+  FsTransmitter *transmitter = NULL;
+  GObjectClass *st_class  = NULL;
+  GError *error = NULL;
+  FsStream *stream = NULL;
+  guint n_parameters = 0;
+  GParameter *parameters = NULL;
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!is|O!:FsSession.new_stream",
+          kwlist,
+          &PyFsParticipant_Type, &participant,
+          &direction,
+          &transmitter_name,
+          &PyDict_Type, &st_params))
+    return NULL;
+
+  if (st_params)
+  {
+    n_parameters = PyDict_Size (st_params);
+
+    parameters = g_new0 (GParameter, n_parameters);
+
+    transmitter = fs_transmitter_new (transmitter_name, 2, &error);
+    if (!transmitter)
+      goto error;
+
+    st_class = g_type_class_ref (
+        fs_transmitter_get_stream_transmitter_type (
+            transmitter, &error));
+    if (!st_class)
+      goto error;
+
+    if (!FS_IS_STREAM_TRANSMITTER_CLASS (st_class))
+    {
+      PyErr_SetString (PyExc_TypeError, "Invalid transmitter name passed");
+      goto error;
+    }
+
+    while (PyDict_Next(st_params, &pos, &key, &value))
+    {
+      GParamSpec *spec;
+
+      if (!PyString_Check (key))
+      {
+        PyErr_SetString (PyExc_TypeError,
+            "Expected Stream Parameter key to be a string");
+        goto error;
+      }
+
+      spec = g_object_class_find_property (st_class, PyString_AsString (key));
+
+      if (!spec)
+      {
+        PyErr_Format (PyExc_TypeError, "Received unknown key %s",
+            PyString_AsString (key));
+        goto error;
+      }
+
+      g_value_init (&parameters[i].value, G_PARAM_SPEC_VALUE_TYPE(spec));
+
+      parameters[i].name = PyString_AsString (key);
+
+      if (pyg_value_from_pyobject (&parameters[i].value , value) < 0)
+      {
+        PyErr_Format (PyExc_TypeError, "Expected parameter %s to be a %s",
+            PyString_AsString (key),
+            g_type_name (G_PARAM_SPEC_VALUE_TYPE(spec)));
+        goto error;
+      }
+
+      i++;
+    }
+  }
+
+  stream = fs_session_new_stream (FS_SESSION (pygobject_get (self)),
+      FS_PARTICIPANT (pygobject_get (participant)),
+      direction,
+      transmitter_name, n_parameters, parameters,
+      &error);
+
+  if (!stream)
+    goto error;
+
+  if (parameters)
+  {
+    g_type_class_unref (st_class);
+    g_free (parameters);
+    g_object_unref (transmitter);
+  }
+
+  return pygobject_new (G_OBJECT (stream));
+
+ error:
+  if (error)
+    pyg_error_check (&error);
+
+  if (st_class)
+    g_type_class_unref (st_class);
+  if (parameters)
+    g_free (parameters);
+  if (transmitter)
+    g_object_unref (transmitter);
+
+  return NULL;
+}
+%%
+override-slot FsCodec.tp_setattr
+static int
+_wrap_fs_codec_tp_setattr(PyObject *self, char *attr, PyObject *value)
+{
+  FsCodec *codec;
+
+  codec = pyg_boxed_get(self, FsCodec);
+
+  if (!strcmp (attr, "id"))
+  {
+    if (!PyInt_Check(value))
+    {
+      PyErr_Format(PyExc_TypeError, "%s must be an int", attr);
+      return -1;
+    }
+    codec->id = (gint)PyInt_AsLong(value);
+  }
+  else if (!strcmp (attr, "encoding_name"))
+  {
+    if (value == NULL || PyString_Check(value))
+    {
+      g_free (codec->encoding_name);
+      codec->encoding_name = g_strdup (PyString_AsString (value));
+    }
+    else
+    {
+      PyErr_Format(PyExc_TypeError, "%s must be a string", attr);
+      return -1;
+    }
+  }
+  else if (!strcmp (attr, "media_type"))
+  {
+    gint media_type;
+    if (pyg_enum_get_value(FS_TYPE_MEDIA_TYPE, value, &media_type))
+      return -1;
+    codec->media_type = media_type;
+  }
+  else if (!strcmp (attr, "clock_rate"))
+  {
+    if (!PyInt_Check(value) || PyInt_AsLong(value) < 0)
+    {
+      PyErr_Format(PyExc_TypeError, "%s must be an non-negative int", attr);
+      return -1;
+    }
+    codec->clock_rate = (guint)PyInt_AsLong(value);
+  }
+  else if (!strcmp (attr, "channels"))
+  {
+    if (!PyInt_Check(value) || PyInt_AsLong(value) < 0)
+    {
+      PyErr_Format(PyExc_TypeError, "%s must be an non-negative int", attr);
+      return -1;
+    }
+    codec->channels = (guint)PyInt_AsLong(value);
+  }
+  else if (!strcmp (attr, "optional_params"))
+  {
+    GList *p;
+    GList *newlist = NULL;
+    int i = 0;
+
+    if (value == NULL)
+      goto none;
+
+    if (!PyList_Check (value))
+    {
+      PyErr_Format(PyExc_TypeError, "%s must be a list of (name, value)", attr);
+      return -1;
+    }
+
+    for (i = 0; i < PyList_Size (value); i++)
+    {
+      PyObject *item = PyList_GetItem (value, i);
+
+      if (!PyTuple_Check (item) ||
+          !PyTuple_Size (item) != 2 ||
+          !PyString_Check (PyTuple_GetItem (item, 0)) ||
+          !PyString_Check (PyTuple_GetItem (item, 1)))
+      {
+        PyErr_Format(PyExc_TypeError, "%s must be a list of (name, value)",
+            attr);
+        return -1;
+      }
+    }
+
+    for (i = 0; i < PyList_Size (value); i++)
+    {
+      PyObject *item = PyList_GetItem (value, i);
+      FsCodecParameter *param = g_new0 (FsCodecParameter, 1);
+
+      param->name = g_strdup (PyString_AsString (PyTuple_GetItem (item, 0)));
+      param->value = g_strdup (PyString_AsString (PyTuple_GetItem (item, 1)));
+      newlist = g_list_append (newlist, param);
+    }
+
+  none:
+
+    for (p = g_list_first (codec->optional_params); p; p = g_list_next (p))
+    {
+      FsCodecParameter *param = p->data;
+      g_free (param->name);
+      g_free (param->value);
+      g_free (p->data);
+    }
+    g_list_free (codec->optional_params);
+    codec->optional_params = newlist;
+  }
+  else
+  {
+    PyErr_Format(PyExc_AttributeError,
+        "Attribute %s does not exist for FsCodec", attr);
+    return -1;
+  }
+
+  return 0;
+}
+%%
+override-slot FsCodec.tp_getattr
+static PyObject *
+_wrap_fs_codec_tp_getattr(PyObject *self, char *attr)
+{
+  FsCodec *codec;
+
+  codec = pyg_boxed_get(self, FsCodec);
+
+  if (!strcmp (attr, "id"))
+  {
+    return PyInt_FromLong(codec->id);
+  }
+  else if (!strcmp (attr, "encoding_name"))
+  {
+    return PyString_FromString (codec->encoding_name);
+  }
+  else if (!strcmp (attr, "media_type"))
+  {
+    return pyg_enum_from_gtype(FS_TYPE_MEDIA_TYPE, codec->media_type);
+  }
+  else if (!strcmp (attr, "clock_rate"))
+  {
+    return PyInt_FromLong(codec->clock_rate);
+  }
+  else if (!strcmp (attr, "channels"))
+  {
+    return PyInt_FromLong(codec->channels);
+  }
+  else if (!strcmp (attr, "optional_params"))
+  {
+    PyObject *list = PyList_New (0);
+    GList *p;
+
+    for (p = g_list_first (codec->optional_params); p; p = g_list_next (p))
+    {
+      PyObject *tuple = PyTuple_New (2);
+      FsCodecParameter *param = p->data;
+
+      if (PyTuple_SetItem (tuple, 0, PyString_FromString (param->name)) < 0 ||
+          PyTuple_SetItem (tuple, 1, PyString_FromString (param->value)) < 0 ||
+          PyList_Append (list, tuple) < 0)
+      {
+        Py_DECREF (list);
+        Py_DECREF (tuple);
+        Py_INCREF(Py_None);
+        return Py_None;
+      }
+    }
+
+    return list;
+  }
+  else
+  {
+    return Py_FindMethod((PyMethodDef*)_PyFsCodec_methods, self, attr);
+  }
+}
+%%
+override fs_candidate_new noargs
+static int
+_wrap_fs_candidate_new(PyGBoxed *self)
+{
+  self->gtype = FS_TYPE_CANDIDATE;
+  self->free_on_dealloc = FALSE;
+  self->boxed = g_new0 (FsCandidate, 1);
+
+  if (!self->boxed) {
+    PyErr_SetString(PyExc_RuntimeError, "could not create FsCodec object");
+    return -1;
+  }
+  self->free_on_dealloc = TRUE;
+
+  return 0;
+}
+%%
+new-constructor FS_TYPE_CANDIDATE
+%%
+override-slot FsCandidate.tp_setattr
+static int
+_wrap_fs_candidate_tp_setattr(PyObject *self, char *attr, PyObject *value)
+{
+  FsCandidate *candidate;
+
+  candidate = pyg_boxed_get(self, FsCandidate);
+
+#define CHECK_SET_INT(var, min, max)                                    \
+  do {                                                                  \
+    if (!PyInt_Check(value) ||                                          \
+        PyInt_AsLong(value) < (min) ||                                  \
+        PyInt_AsLong(value) > (max))                                    \
+    {                                                                   \
+      PyErr_Format(PyExc_TypeError, "%s must be an int between %d and %d", \
+          attr, min, max);                                              \
+      return -1;                                                        \
+    }                                                                   \
+    candidate->var = PyInt_AsLong(value);                               \
+  } while (0)
+#define CHECK_SET_STR(var)                                              \
+  do {                                                                  \
+    if (value && !PyString_Check (value))                               \
+    {                                                                   \
+      PyErr_Format(PyExc_TypeError, "%s must be a string", attr);       \
+      return -1;                                                        \
+    }                                                                   \
+    g_free ((gpointer*)candidate->var);                                 \
+    candidate->var = g_strdup (PyString_AsString (value));              \
+  } while(0)
+
+
+
+  if (!strcmp (attr, "candidate_id"))
+    CHECK_SET_STR (candidate_id);
+  else if (!strcmp (attr, "foundation"))
+    CHECK_SET_STR (foundation);
+  else if (!strcmp (attr, "component_id"))
+    CHECK_SET_INT (component_id, 1, 256);
+  else if (!strcmp (attr, "ip"))
+    CHECK_SET_STR (ip);
+  else if (!strcmp (attr, "port"))
+    CHECK_SET_INT (port, 0, G_MAXUINT16);
+  else if (!strcmp (attr, "base_ip"))
+    CHECK_SET_STR (base_ip);
+  else if (!strcmp (attr, "base_port"))
+    CHECK_SET_INT (base_port, 0, G_MAXUINT16);
+  else if (!strcmp (attr, "priority"))
+    CHECK_SET_INT (priority, G_MININT, G_MAXINT);
+  else if (!strcmp (attr, "username"))
+    CHECK_SET_STR (username);
+  else if (!strcmp (attr, "password"))
+    CHECK_SET_STR (password);
+  else if (!strcmp (attr, "proto"))
+  {
+   gint proto;
+    if (pyg_enum_get_value(FS_TYPE_NETWORK_PROTOCOL, value, &proto))
+      return -1;
+    candidate->proto = proto;
+  }
+  else if (!strcmp (attr, "type"))
+  {
+    gint type;
+    if (pyg_enum_get_value(FS_TYPE_CANDIDATE_TYPE, value, &type))
+      return -1;
+    candidate->type = type;
+  }
+  else
+  {
+    PyErr_Format(PyExc_AttributeError,
+        "Attribute %s does not exist for FsCandidate", attr);
+    return -1;
+  }
+
+  return 0;
+#undef CHECK_SET_INT
+#undef CHECK_SET_STR
+}
+%%
+override-slot FsCandidate.tp_getattr
+static PyObject *
+_wrap_fs_candidate_tp_getattr(PyObject *self, char *attr)
+{
+  FsCandidate *candidate;
+
+  candidate = pyg_boxed_get(self, FsCandidate);
+
+  if (!strcmp (attr, "candidate_id"))
+    return PyString_FromString (candidate->candidate_id);
+  else if (!strcmp (attr, "foundation"))
+    return PyString_FromString (candidate->foundation);
+  else if (!strcmp (attr, "component_id"))
+    return PyInt_FromLong(candidate->component_id);
+  else if (!strcmp (attr, "ip"))
+    return PyString_FromString (candidate->ip);
+  else if (!strcmp (attr, "port"))
+    return PyInt_FromLong(candidate->port);
+  else if (!strcmp (attr, "base_ip"))
+    return PyString_FromString (candidate->base_ip);
+  else if (!strcmp (attr, "base_port"))
+    return PyInt_FromLong(candidate->base_port);
+  else if (!strcmp (attr, "priority"))
+    return PyInt_FromLong(candidate->priority);
+  else if (!strcmp (attr, "username"))
+    return PyString_FromString (candidate->username);
+  else if (!strcmp (attr, "password"))
+    return PyString_FromString (candidate->password);
+  else if (!strcmp (attr, "proto"))
+    return pyg_enum_from_gtype(FS_TYPE_NETWORK_PROTOCOL, candidate->proto);
+  else if (!strcmp (attr, "type"))
+    return pyg_enum_from_gtype(FS_TYPE_CANDIDATE_TYPE, candidate->type);
+  else
+    return Py_FindMethod((PyMethodDef*)_PyFsCodec_methods, self, attr);
+}
+%%
+override fs_stream_set_remote_codecs onearg
+static PyObject *
+_wrap_fs_stream_set_remote_codecs (PyGObject *self, PyObject *arg)
+{
+  gboolean ret = FALSE;
+  GError *error = NULL;
+  GList *codecs = NULL;
+  int i;
+
+  if (!PyList_Check (arg))
+  {
+    PyErr_SetString (PyExc_TypeError,
+        "The parameter must be a List of FsCodec");
+    return NULL;
+  }
+
+  if (PyList_Size (arg) == 0)
+  {
+    PyErr_SetString (PyExc_TypeError,
+        "Empty list invalid");
+    return NULL;
+  }
+
+  for (i = 0; i < PyList_Size (arg); i++)
+  {
+    PyObject *item = PyList_GetItem (arg, i);
+
+    if (!pyg_boxed_check (item, FS_TYPE_CODEC))
+    {
+      PyErr_SetString(PyExc_TypeError,
+          "The parameter must be a List of FsCodec");
+      return NULL;
+    }
+  }
+
+  for (i = 0; i < PyList_Size (arg); i++)
+  {
+    PyObject *item = PyList_GetItem (arg, i);
+
+    codecs = g_list_append (codecs, pyg_boxed_get (item, FsCodec));
+  }
+
+  ret = fs_stream_set_remote_codecs (FS_STREAM(self->obj), codecs, &error);
+
+  g_list_free (codecs);
+
+  if (pyg_error_check(&error))
+    return NULL;
+
+  return PyBool_FromLong (ret);
+}
+%%
diff --git a/python/pyfarsightmodule.c b/python/pyfarsightmodule.c
new file mode 100644
index 0000000..cb52676
--- /dev/null
+++ b/python/pyfarsightmodule.c
@@ -0,0 +1,26 @@
+#include <pygobject.h>
+
+void fs_register_classes (PyObject *d);
+void fs_add_constants(PyObject *module, const gchar *strip_prefix);
+
+DL_EXPORT(void) initfarsight(void);
+extern PyMethodDef fs_functions[];
+
+DL_EXPORT(void)
+initfarsight(void)
+{
+  PyObject *m, *d;
+
+  init_pygobject ();
+
+  m = Py_InitModule ("farsight", fs_functions);
+  d = PyModule_GetDict (m);
+
+  fs_register_classes (d);
+  fs_add_constants(m, "FS_");
+
+  if (PyErr_Occurred ()) {
+    PyErr_Print();
+    Py_FatalError ("can't initialise module farsight");
+  }
+}
diff --git a/python/rebuild-defs.sh b/python/rebuild-defs.sh
new file mode 100755
index 0000000..42e478c
--- /dev/null
+++ b/python/rebuild-defs.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+HEADERS=" \
+    fs-codec.h \
+    fs-candidate.h \
+    fs-conference-iface.h \
+    fs-session.h \
+    fs-participant.h \
+    fs-stream.h \
+    fs-enum-types.h"
+
+srcdir=../gst-libs/gst/farsight/
+
+output=pyfarsight.defs
+filter=pyfarsight-filter.defs
+
+cat ${filter} > ${output}
+
+for h in $HEADERS; do
+    python /usr/share/pygtk/2.0/codegen/h2def.py \
+	--defsfilter=${filter} ${srcdir}/$h >> $output
+done
-- 
1.5.6.5




More information about the farsight-commits mailing list