/pidgin/main: 9b4a94c113b4: Add application media type and APIs
Youness Alaoui <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 9b4a94c113b4367e26dffe6f2dd7b318551450da Author: Youness Alaoui <[email protected]> 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;