[telepathy-sofiasip/master] Added properties InitialAudio and InitialVideo to media stream
Mikhail Zabaluev
mikhail.zabaluev at nokia.com
Fri Jan 8 10:38:34 PST 2010
---
src/media-factory.c | 74 ++++++++++++++++++++++++++++++++++++++++++++--
src/sip-media-channel.c | 43 +++++++++++++++++++++++++++
2 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/src/media-factory.c b/src/media-factory.c
index 7da29bf..59dab89 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -35,6 +35,11 @@
#define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
#include "debug.h"
+typedef enum {
+ TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO = 1 << 0,
+ TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO = 1 << 1,
+} TpsipMediaChannelCreationFlags;
+
static void channel_manager_iface_init (gpointer, gpointer);
static void tpsip_media_factory_constructed (GObject *object);
static void tpsip_media_factory_close_all (TpsipMediaFactory *fac);
@@ -255,13 +260,16 @@ media_channel_closed_cb (TpsipMediaChannel *chan, gpointer user_data)
static TpsipMediaChannel *
new_media_channel (TpsipMediaFactory *fac,
TpHandle initiator,
- TpHandle maybe_peer)
+ TpHandle maybe_peer,
+ TpsipMediaChannelCreationFlags flags)
{
TpsipMediaFactoryPrivate *priv;
TpsipMediaChannel *chan = NULL;
TpBaseConnection *conn;
gchar *object_path;
const gchar *nat_traversal = "none";
+ gboolean initial_audio;
+ gboolean initial_video;
g_assert (initiator != 0);
@@ -273,6 +281,9 @@ new_media_channel (TpsipMediaFactory *fac,
DEBUG("channel object path %s", object_path);
+ initial_audio = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO) != 0);
+ initial_video = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO) != 0);
+
if (priv->stun_server != NULL)
{
nat_traversal = "stun";
@@ -283,6 +294,8 @@ new_media_channel (TpsipMediaFactory *fac,
"object-path", object_path,
"handle", maybe_peer,
"initiator", initiator,
+ "initial-audio", initial_audio,
+ "initial-video", initial_video,
"nat-traversal", nat_traversal,
NULL);
@@ -302,6 +315,33 @@ new_media_channel (TpsipMediaFactory *fac,
return chan;
}
+static guint
+initial_media_flags_from_sdp (const sdp_session_t *sdp)
+{
+ const sdp_media_t *media;
+ guint flags = 0;
+
+ for (media = sdp->sdp_media; media != NULL; media = media->m_next)
+ {
+ if (media->m_rejected || media->m_port == 0)
+ continue;
+
+ switch (media->m_type)
+ {
+ case sdp_media_audio:
+ flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO;
+ break;
+ case sdp_media_video:
+ flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return flags;
+}
+
static gboolean
tpsip_nua_i_invite_cb (TpBaseConnection *conn,
const TpsipNuaEvent *ev,
@@ -311,6 +351,9 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
TpsipMediaChannel *channel;
TpHandleRepoIface *contact_repo;
TpHandle handle;
+ guint channel_flags = 0;
+ const sdp_session_t *sdp = NULL;
+ int offer_recv = 0;
/* figure out a handle for the identity */
@@ -327,7 +370,15 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
DEBUG("Got incoming invite from <%s>",
tp_handle_inspect (contact_repo, handle));
- channel = new_media_channel (fac, handle, handle);
+ tl_gets(tags,
+ NUTAG_OFFER_RECV_REF(offer_recv),
+ SOATAG_REMOTE_SDP_REF(sdp),
+ TAG_END());
+
+ if (offer_recv && sdp != NULL)
+ channel_flags = initial_media_flags_from_sdp (sdp);
+
+ channel = new_media_channel (fac, handle, handle, channel_flags);
tpsip_media_channel_receive_invite (channel, ev->nua_handle);
@@ -414,12 +465,16 @@ static const gchar * const media_channel_fixed_properties[] = {
static const gchar * const named_channel_allowed_properties[] = {
TP_IFACE_CHANNEL ".TargetHandle",
TP_IFACE_CHANNEL ".TargetID",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo",
NULL
};
/* not advertised in foreach_channel_class - can only be requested with
* RequestChannel, not with CreateChannel/EnsureChannel */
static const gchar * const anon_channel_allowed_properties[] = {
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo",
NULL
};
@@ -468,6 +523,7 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
TpsipMediaChannel *channel = NULL;
GError *error = NULL;
GSList *request_tokens;
+ guint chan_flags = 0;
gboolean require_target_handle;
gboolean add_peer_to_remote_pending;
@@ -514,6 +570,14 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
handle = tp_asv_get_uint32 (request_properties,
TP_IFACE_CHANNEL ".TargetHandle", NULL);
+ if (tp_asv_get_boolean (request_properties,
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio", NULL))
+ chan_flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO;
+
+ if (tp_asv_get_boolean (request_properties,
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo", NULL))
+ chan_flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO;
+
switch (handle_type)
{
case TP_HANDLE_TYPE_NONE:
@@ -532,7 +596,7 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
&error))
goto error;
- channel = new_media_channel (self, conn->self_handle, 0);
+ channel = new_media_channel (self, conn->self_handle, 0, chan_flags);
break;
case TP_HANDLE_TYPE_CONTACT:
@@ -562,13 +626,15 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
}
}
- channel = new_media_channel (self, conn->self_handle, handle);
+ channel = new_media_channel (self, conn->self_handle, handle, chan_flags);
if (add_peer_to_remote_pending)
{
if (!_tpsip_media_channel_add_member ((GObject *) channel, handle,
"", &error))
{
+ /* FIXME: do we really want to emit Closed in this case?
+ * There wasn't a NewChannel/NewChannels emission */
tpsip_media_channel_close (channel);
goto error;
}
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c
index 0f97556..cedc518 100644
--- a/src/sip-media-channel.c
+++ b/src/sip-media-channel.c
@@ -104,6 +104,8 @@ enum
PROP_INTERFACES,
PROP_CHANNEL_DESTROYED,
PROP_CHANNEL_PROPERTIES,
+ PROP_INITIAL_AUDIO,
+ PROP_INITIAL_VIDEO,
/* Telepathy properties (see below too) */
PROP_NAT_TRAVERSAL,
PROP_STUN_SERVER,
@@ -139,6 +141,8 @@ struct _TpsipMediaChannelPrivate
TpHandle initiator;
GHashTable *call_states;
+ gboolean initial_audio;
+ gboolean initial_video;
gboolean closed;
gboolean dispose_has_run;
};
@@ -253,12 +257,23 @@ tpsip_media_channel_class_init (TpsipMediaChannelClass *klass)
{ "Requested", "requested", NULL },
{ NULL }
};
+ static TpDBusPropertiesMixinPropImpl streamed_media_props[] = {
+ { "InitialAudio", "initial-audio", NULL },
+ { "InitialVideo", "initial-video", NULL },
+ { NULL }
+ };
+
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CHANNEL,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
channel_props,
},
+ { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ streamed_media_props,
+ },
{ NULL }
};
@@ -341,6 +356,20 @@ tpsip_media_channel_class_init (TpsipMediaChannelClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
+ param_spec = g_param_spec_boolean ("initial-audio", "InitialAudio",
+ "Whether the channel initially contained an audio stream",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
+ param_spec);
+
+ param_spec = g_param_spec_boolean ("initial-video", "InitialVideo",
+ "Whether the channel initially contained a video stream",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
+ param_spec);
+
tp_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpsipMediaChannelClass, properties_class),
media_channel_property_signatures, NUM_TP_PROPS, NULL);
@@ -430,8 +459,16 @@ tpsip_media_channel_get_property (GObject *object,
TP_IFACE_CHANNEL, "InitiatorID",
TP_IFACE_CHANNEL, "Requested",
TP_IFACE_CHANNEL, "Interfaces",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialAudio",
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialVideo",
NULL));
break;
+ case PROP_INITIAL_AUDIO:
+ g_value_set_boolean (value, priv->initial_audio);
+ break;
+ case PROP_INITIAL_VIDEO:
+ g_value_set_boolean (value, priv->initial_video);
+ break;
default:
/* Some properties live in the mixin */
{
@@ -492,6 +529,12 @@ tpsip_media_channel_set_property (GObject *object,
/* similarly we can't ref this yet */
priv->initiator = g_value_get_uint (value);
break;
+ case PROP_INITIAL_AUDIO:
+ priv->initial_audio = g_value_get_boolean (value);
+ break;
+ case PROP_INITIAL_VIDEO:
+ priv->initial_video = g_value_get_boolean (value);
+ break;
default:
/* some properties live in the mixin */
{
--
1.5.6.5
More information about the telepathy-commits
mailing list