/pidgin/main: 4fe1034f3dce: Add application media type and APIs
Youness Alaoui
kakaroto at kakaroto.homelinux.net
Mon Mar 16 14:26:35 EDT 2015
Changeset: 4fe1034f3dce1c5cd3c929ab8c58db8e27655beb
Author: Youness Alaoui <kakaroto at kakaroto.homelinux.net>
Date: 2014-07-21 17:53 -0400
Branch: release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/4fe1034f3dce
Description:
Add application media type and APIs
Fixes #16315
diffstat:
configure.ac | 14 +
libpurple/Makefile.am | 2 +
libpurple/media-gst.h | 1 +
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 +++++
9 files changed, 849 insertions(+), 6 deletions(-)
diffs (truncated from 1118 to 300 lines):
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -916,6 +916,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
@@ -309,6 +309,7 @@ libpurple_la_LIBADD = \
$(FARSTREAM_LIBS) \
$(GSTREAMER_LIBS) \
$(GSTVIDEO_LIBS) \
+ $(GSTAPP_LIBS) \
$(GSTINTERFACES_LIBS) \
$(IDN_LIBS) \
ciphers/libpurple-ciphers.la \
@@ -326,6 +327,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 enum {
PURPLE_MEDIA_ELEMENT_SRC = 1 << 9, /** can be set as an active src */
PURPLE_MEDIA_ELEMENT_SINK = 1 << 10, /** can be set as an active sink */
+ PURPLE_MEDIA_ELEMENT_APPLICATION = 1 << 11, /** supports application data */
} PurpleMediaElementType;
#ifdef __cplusplus
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
@@ -577,6 +577,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;
}
@@ -585,7 +589,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))
@@ -593,6 +597,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;
}
@@ -611,6 +623,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;
}
@@ -1367,7 +1386,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"));
@@ -1790,6 +1810,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"),
@@ -2004,6 +2039,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),
@@ -2366,6 +2416,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,
@@ -2389,6 +2442,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
@@ -188,7 +188,7 @@ purple_media_codec_class_init(PurpleMedi
g_object_class_install_property(gobject_class, 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));
@@ -402,6 +402,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
@@ -182,10 +182,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
@@ -94,8 +94,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;
/** Media state-changed types */
diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c
--- a/libpurple/mediamanager.c
+++ b/libpurple/mediamanager.c
@@ -44,6 +44,9 @@
#else
#include <farstream/fs-element-added-notifier.h>
#endif
+#ifdef HAVE_MEDIA_APPLICATION
+#include <gst/app/app.h>
+#endif
#if GST_CHECK_VERSION(1,0,0)
#include <gst/video/videooverlay.h>
@@ -97,14 +100,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;
+ guint sample_offset;
+ gboolean writable;
+ gboolean connected;
+ guint writable_timer_id;
+ guint readable_timer_id;
+ GCond readable_cond;
+} PurpleMediaAppDataInfo;
+#endif
+
#define PURPLE_MEDIA_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_MANAGER, PurpleMediaManagerPrivate))
#define PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_ELEMENT_INFO, PurpleMediaElementInfoPrivate))
static void purple_media_manager_class_init (PurpleMediaManagerClass *klass);
static void purple_media_manager_init (PurpleMediaManager *media);
static void purple_media_manager_finalize (GObject *object);
+#ifdef HAVE_MEDIA_APPLICATION
+static void free_appdata_info_locked (PurpleMediaAppDataInfo *info);
+#endif
static GObjectClass *parent_class = NULL;
@@ -190,8 +224,10 @@ purple_media_manager_init (PurpleMediaMa
media->priv->medias = NULL;
media->priv->private_medias = NULL;
More information about the Commits
mailing list