/pidgin/main: 9b4a94c113b4: Add application media type and APIs

Youness Alaoui kakaroto at kakaroto.homelinux.net
Mon Mar 16 14:24:26 EDT 2015


Changeset: 9b4a94c113b4367e26dffe6f2dd7b318551450da
Author:	 Youness Alaoui <kakaroto at kakaroto.homelinux.net>
Date:	 2014-07-21 17:53 -0400
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/9b4a94c113b4

Description:

Add application media type and APIs

Fixes #16315

diffstat:

 configure.ac                  |   14 +
 libpurple/Makefile.am         |    2 +
 libpurple/media-gst.h         |    2 +
 libpurple/media.h             |    4 +-
 libpurple/media/backend-fs2.c |   60 +++-
 libpurple/media/codec.c       |    4 +-
 libpurple/media/enum-types.c  |    6 +
 libpurple/media/enum-types.h  |    6 +-
 libpurple/mediamanager.c      |  673 +++++++++++++++++++++++++++++++++++++++++-
 libpurple/mediamanager.h      |   89 +++++
 10 files changed, 852 insertions(+), 8 deletions(-)

diffs (truncated from 1142 to 300 lines):

diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1191,6 +1191,20 @@ fi
 AM_CONDITIONAL(USE_VV, test "x$enable_vv" != "xno")
 
 dnl #######################################################################
+dnl # Check for Raw data streams support in Farstream 
+dnl #######################################################################
+if test "x$enable_vv" != "xno" -a "x$with_gstreamer" == "x1.0"; then
+	AC_MSG_CHECKING(for raw data support in Farstream)
+	PKG_CHECK_MODULES(GSTAPP, [gstreamer-app-1.0], [
+		AC_DEFINE(USE_GSTAPP, 1, [Use GStreamer Video Overlay support])
+		AC_SUBST(GSTAPP_CFLAGS)
+		AC_SUBST(GSTAPP_LIBS)
+		AC_DEFINE(HAVE_MEDIA_APPLICATION, 1, [Define if we have support for application media type.])
+		AC_MSG_RESULT(yes)
+		], [AC_MSG_RESULT(no)])
+fi
+
+dnl #######################################################################
 dnl # Check for Internationalized Domain Name support
 dnl #######################################################################
 
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -419,6 +419,7 @@ libpurple_la_LIBADD = \
 	$(FARSTREAM_LIBS) \
 	$(GSTREAMER_LIBS) \
 	$(GSTVIDEO_LIBS) \
+	$(GSTAPP_LIBS) \
 	$(GSTINTERFACES_LIBS) \
 	$(IDN_LIBS) \
 	$(JSON_LIBS) \
@@ -435,6 +436,7 @@ AM_CPPFLAGS = \
 	$(FARSTREAM_CFLAGS) \
 	$(GSTREAMER_CFLAGS) \
 	$(GSTVIDEO_CFLAGS) \
+	$(GSTAPP_CFLAGS) \
 	$(GSTINTERFACES_CFLAGS) \
 	$(IDN_CFLAGS) \
 	$(NETWORKMANAGER_CFLAGS) \
diff --git a/libpurple/media-gst.h b/libpurple/media-gst.h
--- a/libpurple/media-gst.h
+++ b/libpurple/media-gst.h
@@ -71,6 +71,7 @@ typedef GstElement *(*PurpleMediaElement
  *                                     time
  * @PURPLE_MEDIA_ELEMENT_SRC:          can be set as an active src
  * @PURPLE_MEDIA_ELEMENT_SINK:         can be set as an active sink
+ * @PURPLE_MEDIA_ELEMENT_APPLICATION:  supports application data
  */
 typedef enum {
 	PURPLE_MEDIA_ELEMENT_NONE = 0,
@@ -89,6 +90,7 @@ typedef enum {
 	PURPLE_MEDIA_ELEMENT_UNIQUE = 1 << 8,
 	PURPLE_MEDIA_ELEMENT_SRC = 1 << 9,
 	PURPLE_MEDIA_ELEMENT_SINK = 1 << 10,
+	PURPLE_MEDIA_ELEMENT_APPLICATION = 1 << 11,
 } PurpleMediaElementType;
 
 G_BEGIN_DECLS
diff --git a/libpurple/media.h b/libpurple/media.h
--- a/libpurple/media.h
+++ b/libpurple/media.h
@@ -324,10 +324,10 @@ GList *purple_media_get_active_remote_ca
  * purple_media_set_remote_codecs:
  * @media: The media object to find the session in.
  * @sess_id: The session id of the session find the stream in.
- * @participant: The name of the remote user to set the candidates from.
+ * @participant: The name of the remote user to set the codecs for.
  * @codecs: The list of remote codecs to set.
  *
- * Sets remote candidates from the stream.
+ * Sets remote codecs from the stream.
  *
  * Returns: %TRUE The codecs were set successfully, or %FALSE otherwise.
  */
diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
--- a/libpurple/media/backend-fs2.c
+++ b/libpurple/media/backend-fs2.c
@@ -578,6 +578,10 @@ session_type_to_fs_media_type(PurpleMedi
 		return FS_MEDIA_TYPE_AUDIO;
 	else if (type & PURPLE_MEDIA_VIDEO)
 		return FS_MEDIA_TYPE_VIDEO;
+#ifdef HAVE_MEDIA_APPLICATION
+	else if (type & PURPLE_MEDIA_APPLICATION)
+		return FS_MEDIA_TYPE_APPLICATION;
+#endif
 	else
 		return 0;
 }
@@ -586,7 +590,7 @@ static FsStreamDirection
 session_type_to_fs_stream_direction(PurpleMediaSessionType type)
 {
 	if ((type & PURPLE_MEDIA_AUDIO) == PURPLE_MEDIA_AUDIO ||
-			(type & PURPLE_MEDIA_VIDEO) == PURPLE_MEDIA_VIDEO)
+		(type & PURPLE_MEDIA_VIDEO) == PURPLE_MEDIA_VIDEO)
 		return FS_DIRECTION_BOTH;
 	else if ((type & PURPLE_MEDIA_SEND_AUDIO) ||
 			(type & PURPLE_MEDIA_SEND_VIDEO))
@@ -594,6 +598,14 @@ session_type_to_fs_stream_direction(Purp
 	else if ((type & PURPLE_MEDIA_RECV_AUDIO) ||
 			(type & PURPLE_MEDIA_RECV_VIDEO))
 		return FS_DIRECTION_RECV;
+#ifdef HAVE_MEDIA_APPLICATION
+	else if ((type & PURPLE_MEDIA_APPLICATION) == PURPLE_MEDIA_APPLICATION)
+		return FS_DIRECTION_BOTH;
+	else if (type & PURPLE_MEDIA_SEND_APPLICATION)
+		return FS_DIRECTION_SEND;
+	else if (type & PURPLE_MEDIA_RECV_APPLICATION)
+		return FS_DIRECTION_RECV;
+#endif
 	else
 		return FS_DIRECTION_NONE;
 }
@@ -612,6 +624,13 @@ session_type_from_fs(FsMediaType type, F
 			result |= PURPLE_MEDIA_SEND_VIDEO;
 		if (direction & FS_DIRECTION_RECV)
 			result |= PURPLE_MEDIA_RECV_VIDEO;
+#ifdef HAVE_MEDIA_APPLICATION
+	} else if (type == FS_MEDIA_TYPE_APPLICATION) {
+		if (direction & FS_DIRECTION_SEND)
+			result |= PURPLE_MEDIA_SEND_APPLICATION;
+		if (direction & FS_DIRECTION_RECV)
+			result |= PURPLE_MEDIA_RECV_APPLICATION;
+#endif
 	}
 	return result;
 }
@@ -1368,7 +1387,8 @@ gst_handle_message_error(GstBus *bus, Gs
 				& PURPLE_MEDIA_AUDIO)
 			purple_media_error(priv->media,
 					_("Error with your microphone"));
-		else
+		else if (purple_media_get_session_type(priv->media,
+                        sessions->data) & PURPLE_MEDIA_VIDEO)
 			purple_media_error(priv->media,
 					_("Error with your webcam"));
 
@@ -1791,6 +1811,21 @@ create_session(PurpleMediaBackendFs2 *se
 	session->session = fs_conference_new_session(priv->conference,
 			session_type_to_fs_media_type(type), &err);
 
+#ifdef HAVE_MEDIA_APPLICATION
+	if (type == PURPLE_MEDIA_APPLICATION) {
+		GstCaps *caps;
+		GObject *rtpsession = NULL;
+
+		caps = gst_caps_new_empty_simple ("application/octet-stream");
+		fs_session_set_allowed_caps (session->session, caps, caps, NULL);
+		gst_caps_unref (caps);
+		g_object_get (session->session, "internal-session", &rtpsession, NULL);
+		if (rtpsession) {
+			g_object_set (rtpsession, "probation", 0, NULL);
+			g_object_unref (rtpsession);
+		}
+	}
+#endif
 	if (err != NULL) {
 		purple_media_error(priv->media,
 				_("Error creating session: %s"),
@@ -2005,6 +2040,21 @@ src_pad_added_cb(FsStream *fsstream, Gst
 			gst_bin_add(GST_BIN(priv->confbin), sink);
 			gst_element_set_state(sink, GST_STATE_PLAYING);
 			stream->fakesink = sink;
+#ifdef HAVE_MEDIA_APPLICATION
+		} else if (codec->media_type == FS_MEDIA_TYPE_APPLICATION) {
+#if GST_CHECK_VERSION(1,0,0)
+			stream->src = gst_element_factory_make("funnel", NULL);
+#else
+			stream->src = gst_element_factory_make("fsfunnel", NULL);
+#endif
+			sink = purple_media_manager_get_element(
+					purple_media_get_manager(priv->media),
+					PURPLE_MEDIA_RECV_APPLICATION, priv->media,
+					stream->session->id,
+					stream->participant);
+			gst_bin_add(GST_BIN(priv->confbin), sink);
+			gst_element_set_state(sink, GST_STATE_PLAYING);
+#endif
 		}
 		stream->tee = gst_element_factory_make("tee", NULL);
 		gst_bin_add_many(GST_BIN(priv->confbin),
@@ -2367,6 +2417,9 @@ purple_media_backend_fs2_codecs_ready(Pu
 			return FALSE;
 
 		if (session->type & (PURPLE_MEDIA_SEND_AUDIO |
+#ifdef HAVE_MEDIA_APPLICATION
+				PURPLE_MEDIA_SEND_APPLICATION |
+#endif
 				PURPLE_MEDIA_SEND_VIDEO)) {
 #ifdef HAVE_FARSIGHT
 			g_object_get(session->session,
@@ -2390,6 +2443,9 @@ purple_media_backend_fs2_codecs_ready(Pu
 			PurpleMediaBackendFs2Session *session = values->data;
 
 			if (session->type & (PURPLE_MEDIA_SEND_AUDIO |
+#ifdef HAVE_MEDIA_APPLICATION
+					PURPLE_MEDIA_SEND_APPLICATION |
+#endif
 					PURPLE_MEDIA_SEND_VIDEO)) {
 #ifdef HAVE_FARSIGHT
 				g_object_get(session->session,
diff --git a/libpurple/media/codec.c b/libpurple/media/codec.c
--- a/libpurple/media/codec.c
+++ b/libpurple/media/codec.c
@@ -194,7 +194,7 @@ purple_media_codec_class_init(PurpleMedi
 
 	properties[PROP_MEDIA_TYPE] = g_param_spec_flags("media-type",
 			"Media Type",
-			"Whether this is an audio of video codec.",
+			"Whether this is an audio, video or application codec.",
 			PURPLE_TYPE_MEDIA_SESSION_TYPE,
 			PURPLE_MEDIA_NONE,
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
@@ -411,6 +411,8 @@ purple_media_codec_to_string(const Purpl
 		media_type_str = "audio";
 	else if (priv->media_type & PURPLE_MEDIA_VIDEO)
 		media_type_str = "video";
+	else if (priv->media_type & PURPLE_MEDIA_APPLICATION)
+		media_type_str = "application";
 
 	g_string_printf(string, "%d: %s %s clock:%d channels:%d", priv->id,
 			media_type_str, priv->encoding_name,
diff --git a/libpurple/media/enum-types.c b/libpurple/media/enum-types.c
--- a/libpurple/media/enum-types.c
+++ b/libpurple/media/enum-types.c
@@ -177,10 +177,16 @@ purple_media_session_type_get_type()
 				"PURPLE_MEDIA_RECV_VIDEO", "recv-video" },
 			{ PURPLE_MEDIA_SEND_VIDEO,
 				"PURPLE_MEDIA_SEND_VIDEO", "send-video" },
+			{ PURPLE_MEDIA_RECV_APPLICATION,
+				"PURPLE_MEDIA_RECV_APPLICATION", "recv-application" },
+			{ PURPLE_MEDIA_SEND_APPLICATION,
+				"PURPLE_MEDIA_SEND_APPLICATION", "send-application" },
 			{ PURPLE_MEDIA_AUDIO,
 				"PURPLE_MEDIA_AUDIO", "audio" },
 			{ PURPLE_MEDIA_VIDEO,
 				"PURPLE_MEDIA_VIDEO", "video" },
+			{ PURPLE_MEDIA_APPLICATION,
+				"PURPLE_MEDIA_APPLICATION", "application" },
 			{ 0, NULL, NULL }
 		};
 		type = g_flags_register_static(
diff --git a/libpurple/media/enum-types.h b/libpurple/media/enum-types.h
--- a/libpurple/media/enum-types.h
+++ b/libpurple/media/enum-types.h
@@ -119,8 +119,12 @@ typedef enum {
 	PURPLE_MEDIA_SEND_AUDIO = 1 << 1,
 	PURPLE_MEDIA_RECV_VIDEO = 1 << 2,
 	PURPLE_MEDIA_SEND_VIDEO = 1 << 3,
+	PURPLE_MEDIA_RECV_APPLICATION = 1 << 4,
+	PURPLE_MEDIA_SEND_APPLICATION = 1 << 5,
 	PURPLE_MEDIA_AUDIO = PURPLE_MEDIA_RECV_AUDIO | PURPLE_MEDIA_SEND_AUDIO,
-	PURPLE_MEDIA_VIDEO = PURPLE_MEDIA_RECV_VIDEO | PURPLE_MEDIA_SEND_VIDEO
+	PURPLE_MEDIA_VIDEO = PURPLE_MEDIA_RECV_VIDEO | PURPLE_MEDIA_SEND_VIDEO,
+	PURPLE_MEDIA_APPLICATION = PURPLE_MEDIA_RECV_APPLICATION |
+                                   PURPLE_MEDIA_SEND_APPLICATION
 } PurpleMediaSessionType;
 
 /**
diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c
--- a/libpurple/mediamanager.c
+++ b/libpurple/mediamanager.c
@@ -44,6 +44,9 @@
 #else
 #include <gst/interfaces/xoverlay.h>
 #endif
+#ifdef HAVE_MEDIA_APPLICATION
+#include <gst/app/app.h>
+#endif
 
 /** @copydoc _PurpleMediaOutputWindow */
 typedef struct _PurpleMediaOutputWindow PurpleMediaOutputWindow;
@@ -76,14 +79,45 @@ struct _PurpleMediaManagerPrivate
 	PurpleMediaElementInfo *video_sink;
 	PurpleMediaElementInfo *audio_src;
 	PurpleMediaElementInfo *audio_sink;
+
+#ifdef HAVE_MEDIA_APPLICATION
+	/* Application data streams */
+	GList *appdata_info; /* holds PurpleMediaAppDataInfo */
+	GMutex appdata_mutex;
+#endif
 };
 
+#ifdef HAVE_MEDIA_APPLICATION
+typedef struct {
+	PurpleMedia *media;
+	GWeakRef media_ref;
+	gchar *session_id;
+	gchar *participant;
+	PurpleMediaAppDataCallbacks callbacks;
+	gpointer user_data;
+	GDestroyNotify notify;
+	GstAppSrc *appsrc;
+	GstAppSink *appsink;
+	gint num_samples;
+	GstSample *current_sample;



More information about the Commits mailing list