summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@nokia.com>2011-06-14 20:54:21 +0300
committerMikhail Zabaluev <mikhail.zabaluev@nokia.com>2011-06-14 20:55:17 +0300
commitd547bb11d8eb2fb9dff19b812f6856dd12e9c254 (patch)
treeb840fbf34423b8aa79a79d2dacf370a45ad5020d
parentd960b6a266e60e19480bb9f192448f05d8463463 (diff)
parentdfc026f67a3e82bdb785958e5ad0a808568372a5 (diff)
Merge branch 'codec-updates' into trunk
-rw-r--r--rakia/media-session.c99
-rw-r--r--rakia/media-stream.c300
-rw-r--r--rakia/media-stream.h4
3 files changed, 185 insertions, 218 deletions
diff --git a/rakia/media-session.c b/rakia/media-session.c
index 2766321..a956229 100644
--- a/rakia/media-session.c
+++ b/rakia/media-session.c
@@ -148,6 +148,7 @@ struct _RakiaMediaSessionPrivate
su_home_t *backup_home; /* Sofia memory home for previous generation remote SDP session*/
sdp_session_t *remote_sdp; /* last received remote session */
sdp_session_t *backup_remote_sdp; /* previous remote session */
+ gchar *local_sdp; /* local session as SDP string */
GPtrArray *streams;
gboolean remote_initiated; /*< session is remotely intiated */
gboolean accepted; /*< session has been locally accepted for use */
@@ -499,6 +500,7 @@ rakia_media_session_finalize (GObject *object)
if (priv->backup_home != NULL)
su_home_unref (priv->backup_home);
+ g_free (priv->local_sdp);
g_free (priv->remote_ptime);
g_free (priv->remote_max_ptime);
g_free (priv->local_ip_address);
@@ -1756,17 +1758,18 @@ priv_session_rollback (RakiaMediaSession *session)
rakia_media_session_change_state (session, TPSIP_MEDIA_SESSION_STATE_ACTIVE);
}
-static gboolean
-priv_session_local_sdp (RakiaMediaSession *session,
- GString *user_sdp,
- gboolean authoritative)
+static GString *
+priv_session_generate_sdp (RakiaMediaSession *session,
+ gboolean authoritative)
{
RakiaMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (session);
- gboolean has_supported_media = FALSE;
+ GString *user_sdp;
guint len;
guint i;
- g_return_val_if_fail (priv->local_non_ready == 0, FALSE);
+ g_return_val_if_fail (priv->local_non_ready == 0, NULL);
+
+ user_sdp = g_string_new ("v=0\r\n");
len = priv->streams->len;
if (!authoritative && len > priv->remote_stream_count)
@@ -1775,24 +1778,16 @@ priv_session_local_sdp (RakiaMediaSession *session,
DEBUG("clamped response to %u streams seen in the offer", len);
}
- g_string_append (user_sdp, "v=0\r\n");
-
for (i = 0; i < len; i++)
{
RakiaMediaStream *stream = g_ptr_array_index (priv->streams, i);
if (stream)
- {
- user_sdp = g_string_append (user_sdp,
- rakia_media_stream_local_sdp (stream));
- has_supported_media = TRUE;
- }
+ rakia_media_stream_generate_sdp (stream, user_sdp);
else
- {
- user_sdp = g_string_append (user_sdp, "m=audio 0 RTP/AVP 0\r\n");
- }
+ g_string_append (user_sdp, "m=audio 0 RTP/AVP 0\r\n");
}
- return has_supported_media;
+ return user_sdp;
}
static void
@@ -1805,16 +1800,23 @@ priv_session_invite (RakiaMediaSession *session, gboolean reinvite)
g_return_if_fail (priv->nua_op != NULL);
- user_sdp = g_string_new (NULL);
+ user_sdp = priv_session_generate_sdp (session, TRUE);
- if (priv_session_local_sdp (session, user_sdp, TRUE))
+ g_return_if_fail (user_sdp != NULL);
+
+ if (!reinvite
+ || priv->state == TPSIP_MEDIA_SESSION_STATE_REINVITE_PENDING
+ || tp_strdiff (priv->local_sdp, user_sdp->str))
{
+ g_free (priv->local_sdp);
+ priv->local_sdp = g_string_free (user_sdp, FALSE);
+
/* We need to be prepared to receive media right after the
* offer is sent, so we must set the streams to playing */
priv_session_set_streams_playing (session, TRUE);
nua_invite (priv->nua_op,
- SOATAG_USER_SDP_STR(user_sdp->str),
+ SOATAG_USER_SDP_STR(priv->local_sdp),
SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL),
NUTAG_AUTOANSWER(0),
@@ -1829,53 +1831,46 @@ priv_session_invite (RakiaMediaSession *session, gboolean reinvite)
: TPSIP_MEDIA_SESSION_STATE_INVITE_SENT);
}
else
- WARNING ("cannot send a valid SDP offer, are there no streams?");
-
- g_string_free (user_sdp, TRUE);
+ {
+ DEBUG("SDP unchanged, not sending a re-INVITE");
+ g_string_free (user_sdp, TRUE);
+ }
}
static void
priv_session_respond (RakiaMediaSession *session)
{
RakiaMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (session);
- GString *user_sdp;
+ msg_t *msg;
g_return_if_fail (priv->nua_op != NULL);
- user_sdp = g_string_new (NULL);
-
- if (priv_session_local_sdp (session, user_sdp, FALSE))
- {
- msg_t *msg;
+ {
+ GString *user_sdp = priv_session_generate_sdp (session, FALSE);
- /* We need to be prepared to receive media right after the
- * answer is sent, so we must set the streams to playing */
- priv_session_set_streams_playing (session, TRUE);
+ g_free (priv->local_sdp);
+ priv->local_sdp = g_string_free (user_sdp, FALSE);
+ }
- msg = (priv->saved_event[0])
- ? nua_saved_event_request (priv->saved_event) : NULL;
+ /* We need to be prepared to receive media right after the
+ * answer is sent, so we must set the streams to playing */
+ priv_session_set_streams_playing (session, TRUE);
- nua_respond (priv->nua_op, SIP_200_OK,
- TAG_IF(msg, NUTAG_WITH(msg)),
- SOATAG_USER_SDP_STR (user_sdp->str),
- SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
- SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL),
- NUTAG_AUTOANSWER(0),
- TAG_END());
+ msg = (priv->saved_event[0])
+ ? nua_saved_event_request (priv->saved_event) : NULL;
- if (priv->saved_event[0])
- nua_destroy_event (priv->saved_event);
+ nua_respond (priv->nua_op, SIP_200_OK,
+ TAG_IF(msg, NUTAG_WITH(msg)),
+ SOATAG_USER_SDP_STR(priv->local_sdp),
+ SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
+ SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL),
+ NUTAG_AUTOANSWER(0),
+ TAG_END());
- rakia_media_session_change_state (session, TPSIP_MEDIA_SESSION_STATE_ACTIVE);
- }
- else
- {
- WARNING ("cannot respond with a valid SDP answer, were all streams closed?");
-
- priv_session_rollback (session);
- }
+ if (priv->saved_event[0])
+ nua_destroy_event (priv->saved_event);
- g_string_free (user_sdp, TRUE);
+ rakia_media_session_change_state (session, TPSIP_MEDIA_SESSION_STATE_ACTIVE);
}
static gboolean
diff --git a/rakia/media-stream.c b/rakia/media-stream.c
index f8f659e..5448dda 100644
--- a/rakia/media-stream.c
+++ b/rakia/media-stream.c
@@ -104,8 +104,6 @@ enum
static GPtrArray *rakia_media_stream_relay_info_empty = NULL;
/* private structure */
-typedef struct _RakiaMediaStreamPrivate RakiaMediaStreamPrivate;
-
struct _RakiaMediaStreamPrivate
{
TpDBusDaemon *dbus_daemon;
@@ -119,8 +117,6 @@ struct _RakiaMediaStreamPrivate
gboolean hold_state; /* see gobj. prop. 'hold-state' */
gboolean created_locally; /* see gobj. prop. 'created-locally' */
- gchar *stream_sdp; /* SDP description of the stream */
-
GValue native_codecs; /* intersected codec list */
GValue native_candidates;
@@ -145,30 +141,17 @@ struct _RakiaMediaStreamPrivate
gboolean dispose_has_run;
};
-#define TPSIP_MEDIA_STREAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TPSIP_TYPE_MEDIA_STREAM, RakiaMediaStreamPrivate))
+#define TPSIP_MEDIA_STREAM_GET_PRIVATE(stream) ((stream)->priv)
static void push_remote_codecs (RakiaMediaStream *stream);
static void push_remote_candidates (RakiaMediaStream *stream);
static void push_active_candidate_pair (RakiaMediaStream *stream);
static void priv_update_sending (RakiaMediaStream *stream,
TpMediaStreamDirection direction);
-static void priv_update_local_sdp(RakiaMediaStream *stream);
-static void priv_generate_sdp (RakiaMediaStream *stream);
-
-#if 0
-#ifdef ENABLE_DEBUG
-static const char *debug_tp_protocols[] = {
- "TP_MEDIA_STREAM_PROTO_UDP (0)",
- "TP_MEDIA_STREAM_PROTO_TCP (1)"
-};
-
-static const char *debug_tp_transports[] = {
- "TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL (0)",
- "TP_MEDIA_STREAM_TRANSPORT_TYPE_DERIVED (1)",
- "TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY (2)"
-};
-#endif /* ENABLE_DEBUG */
-#endif /* 0 */
+static void priv_emit_local_ready (RakiaMediaStream *stream);
+static const char *priv_get_preferred_native_candidate (
+ RakiaMediaStreamPrivate *priv,
+ const GPtrArray **transports);
/***********************************************************************
* Set: Gobject interface
@@ -177,10 +160,10 @@ static const char *debug_tp_transports[] = {
static void
rakia_media_stream_init (RakiaMediaStream *self)
{
- RakiaMediaStreamPrivate *priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (self);
+ RakiaMediaStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ TPSIP_TYPE_MEDIA_STREAM, RakiaMediaStreamPrivate);
- priv->playing = FALSE;
- priv->sending = FALSE;
+ self->priv = priv;
g_value_init (&priv->native_codecs, TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST);
g_value_take_boxed (&priv->native_codecs,
@@ -189,12 +172,6 @@ rakia_media_stream_init (RakiaMediaStream *self)
g_value_init (&priv->native_candidates, TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST);
g_value_take_boxed (&priv->native_candidates,
dbus_g_type_specialized_construct (TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST));
-
- priv->native_cands_prepared = FALSE;
- priv->native_codecs_prepared = FALSE;
-
- priv->push_remote_cands_pending = FALSE;
- priv->push_remote_codecs_pending = FALSE;
}
static void
@@ -547,7 +524,6 @@ rakia_media_stream_finalize (GObject *object)
/* free any data held directly by the object here */
g_free (priv->object_path);
- g_free (priv->stream_sdp);
g_value_unset (&priv->native_codecs);
g_value_unset (&priv->native_candidates);
@@ -626,7 +602,7 @@ rakia_media_stream_native_candidates_prepared (TpSvcMediaStreamHandler *iface,
priv->native_cands_prepared = TRUE;
if (priv->native_codecs_prepared)
- priv_generate_sdp (obj);
+ priv_emit_local_ready (obj);
push_active_candidate_pair (obj);
@@ -692,13 +668,6 @@ rakia_media_stream_new_native_candidate (TpSvcMediaStreamHandler *iface,
priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (obj);
- if (priv->stream_sdp != NULL)
- {
- MESSAGE ("Stream %u: SDP already generated, ignoring native candidate '%s'", priv->id, candidate_id);
- tp_svc_media_stream_handler_return_from_new_native_candidate (context);
- return;
- }
-
g_return_if_fail (transports->len >= 1);
/* Rate the preferability of the address */
@@ -743,17 +712,14 @@ priv_set_local_codecs (RakiaMediaStream *self,
const GPtrArray *codecs)
{
RakiaMediaStreamPrivate *priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (self);
- GValue val = { 0, };
- SESSION_DEBUG(priv->session, "putting list of %d locally supported "
+ SESSION_DEBUG(priv->session, "putting list of %u locally supported "
"codecs from stream-engine into cache", codecs->len);
- g_value_init (&val, TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST);
- g_value_set_static_boxed (&val, codecs);
- g_value_copy (&val, &priv->native_codecs);
+ g_value_set_boxed (&priv->native_codecs, codecs);
priv->native_codecs_prepared = TRUE;
if (priv->native_cands_prepared)
- priv_generate_sdp (self);
+ priv_emit_local_ready (self);
}
static void
@@ -777,19 +743,12 @@ rakia_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface,
}
else
{
- GValue val = { 0, };
-
- SESSION_DEBUG(priv->session, "putting list of %d locally supported "
+ SESSION_DEBUG(priv->session, "putting list of %u locally supported "
"codecs from CodecsUpdated into cache", codecs->len);
- g_value_init (&val, TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST);
- g_value_set_static_boxed (&val, codecs);
- g_value_copy (&val, &priv->native_codecs);
+ g_value_set_boxed (&priv->native_codecs, codecs);
- /* This doesn't use priv_generate_sdp because it short-circuits if
- * priv->stream_sdp is already set. We want to update it.
- */
if (priv->native_cands_prepared)
- priv_update_local_sdp (self);
+ g_signal_emit (self, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
tp_svc_media_stream_handler_return_from_codecs_updated (context);
}
@@ -839,10 +798,6 @@ rakia_media_stream_ready (TpSvcMediaStreamHandler *iface,
tp_svc_media_stream_handler_emit_set_stream_sending (
iface, priv->sending);
- priv->native_codecs_prepared = TRUE;
- if (priv->native_cands_prepared)
- priv_generate_sdp (obj);
-
if (priv->push_remote_cands_pending)
{
priv->push_remote_cands_pending = FALSE;
@@ -928,10 +883,10 @@ rakia_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
DEBUG("got codec intersection containing %u codecs from stream-engine",
codecs->len);
- /* Uncomment the line below if there's need to limit the local codec list
- * with the intersection for later SDP negotiations.
- * TODO: Make sure to update the SDP for the stream as well. */
- /* g_value_set_boxed (&priv->native_codecs, codecs); */
+ /* Save the local codecs, but avoid triggering a new
+ * session update at this point. If the stream engine have changed any codec
+ * parameters, it is supposed to follow up with CodecsUpdated. */
+ g_value_set_boxed (&priv->native_codecs, codecs);
if (priv->codec_intersect_pending)
{
@@ -999,17 +954,6 @@ rakia_media_stream_close (RakiaMediaStream *self)
tp_svc_media_stream_handler_emit_close (self);
}
-/**
- * Described the local stream configuration in SDP (RFC2327),
- * or NULL if stream not configured yet.
- */
-const char *rakia_media_stream_local_sdp (RakiaMediaStream *obj)
-{
- RakiaMediaStreamPrivate *priv;
- priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (obj);
- return priv->stream_sdp;
-}
-
TpMediaStreamDirection
rakia_media_stream_direction_from_remote_media (const sdp_media_t *media)
{
@@ -1332,7 +1276,7 @@ rakia_media_stream_set_direction (RakiaMediaStream *stream,
&& priv->native_codecs_prepared
&& priv_get_requested_direction (priv)
!= old_sdp_direction)
- priv_update_local_sdp (stream);
+ g_signal_emit (stream, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
}
/*
@@ -1391,10 +1335,9 @@ rakia_media_stream_get_requested_direction (RakiaMediaStream *self)
*/
gboolean rakia_media_stream_is_local_ready (RakiaMediaStream *self)
{
- RakiaMediaStreamPrivate *priv;
- priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (self);
- g_assert (priv->stream_sdp == NULL || priv->ready_received);
- return (priv->stream_sdp != NULL);
+ RakiaMediaStreamPrivate *priv = self->priv;
+ return (priv->ready_received && priv->native_cands_prepared
+ && priv->native_codecs_prepared);
}
gboolean
@@ -1433,17 +1376,10 @@ rakia_media_stream_request_hold_state (RakiaMediaStream *self, gboolean hold)
}
static void
-priv_generate_sdp (RakiaMediaStream *self)
+priv_emit_local_ready (RakiaMediaStream *self)
{
- RakiaMediaStreamPrivate *priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (self);
-
- if (priv->stream_sdp != NULL)
- return;
-
- priv_update_local_sdp (self);
-
- g_assert (priv->stream_sdp != NULL);
-
+ /* Trigger any session updates that are due in the current session state */
+ g_signal_emit (self, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
g_signal_emit (self, signals[SIG_READY], 0);
}
@@ -1710,20 +1646,18 @@ static void push_remote_candidates (RakiaMediaStream *stream)
static void
push_active_candidate_pair (RakiaMediaStream *stream)
{
- RakiaMediaStreamPrivate *priv;
-
- DEBUG("enter");
+ RakiaMediaStreamPrivate *priv = stream->priv;
- priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (stream);
-
- if (priv->ready_received
- && priv->native_candidate_id != NULL
+ if (priv->ready_received && priv->native_cands_prepared
&& priv->remote_candidate_id != NULL)
{
+ const char *native_candidate_id;
+
+ native_candidate_id = priv_get_preferred_native_candidate (priv, NULL);
DEBUG("emitting SetActiveCandidatePair for %s-%s",
- priv->native_candidate_id, priv->remote_candidate_id);
- tp_svc_media_stream_handler_emit_set_active_candidate_pair (
- stream, priv->native_candidate_id, priv->remote_candidate_id);
+ native_candidate_id, priv->remote_candidate_id);
+ tp_svc_media_stream_handler_emit_set_active_candidate_pair (stream,
+ native_candidate_id, priv->remote_candidate_id);
}
}
@@ -1805,31 +1739,16 @@ priv_append_rtpmaps (const GPtrArray *codecs, GString *mline, GString *alines)
* Refreshes the local SDP based on Farsight stream, and current
* object, state.
*/
-static void
-priv_update_local_sdp(RakiaMediaStream *stream)
+static const char *
+priv_get_preferred_native_candidate (RakiaMediaStreamPrivate *priv,
+ const GPtrArray **transports)
{
- RakiaMediaStreamPrivate *priv;
- GString *mline;
- GString *alines;
- gchar *cline;
- GValue transport = { 0 };
const GPtrArray *candidates;
- gchar *tr_addr = NULL;
- /* gchar *tr_user = NULL; */
- /* gchar *tr_pass = NULL; */
- gchar *tr_subtype = NULL;
- gchar *tr_profile = NULL;
- guint tr_port;
- guint tr_component;
- /* guint tr_type; */
- /* gdouble tr_pref; */
- guint rtcp_port = 0;
- gchar *rtcp_address = NULL;
- const gchar *dirline;
+ const gchar *candidate_id = NULL;
+ const GPtrArray *ca_tports = NULL;
+ GValue transport = { 0 };
int i;
- priv = TPSIP_MEDIA_STREAM_GET_PRIVATE (stream);
-
candidates = g_value_get_boxed (&priv->native_candidates);
g_value_init (&transport, TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT);
@@ -1840,9 +1759,7 @@ priv_update_local_sdp(RakiaMediaStream *stream)
for (i = candidates->len - 1; i >= 0; --i)
{
GValueArray *candidate;
- const gchar *candidate_id;
- const GPtrArray *ca_tports;
- guint tr_proto = TP_MEDIA_STREAM_BASE_PROTO_UDP;
+ guint tr_proto = (guint) -1;
guint j;
candidate = g_ptr_array_index (candidates, i);
@@ -1858,33 +1775,18 @@ priv_update_local_sdp(RakiaMediaStream *stream)
for (j = 0; j < ca_tports->len; j++)
{
+ guint tr_component = 0;
+
g_value_set_static_boxed (&transport,
g_ptr_array_index (ca_tports, j));
+
+ /* Find the RTP component */
dbus_g_type_struct_get (&transport,
0, &tr_component,
+ 3, &tr_proto,
G_MAXUINT);
- switch (tr_component)
- {
- case 1: /* RTP */
- dbus_g_type_struct_get (&transport,
- 1, &tr_addr,
- 2, &tr_port,
- 3, &tr_proto,
- 4, &tr_subtype,
- 5, &tr_profile,
- /* 6, &tr_pref, */
- /* 7, &tr_type, */
- /* 8, &tr_user, */
- /* 9, &tr_pass, */
- G_MAXUINT);
- break;
- case 2: /* RTCP */
- dbus_g_type_struct_get (&transport,
- 1, &rtcp_address,
- 2, &rtcp_port,
- G_MAXUINT);
- break;
- }
+ if (tr_component == 1)
+ break;
}
if (priv->native_candidate_id != NULL)
@@ -1894,28 +1796,100 @@ priv_update_local_sdp(RakiaMediaStream *stream)
}
else if (tr_proto == TP_MEDIA_STREAM_BASE_PROTO_UDP)
{
- g_free (priv->native_candidate_id);
- priv->native_candidate_id = g_strdup (candidate_id);
break;
}
}
- g_return_if_fail (i >= 0);
+
+ if (i < 0)
+ {
+ WARNING ("preferred candidate not found");
+ return NULL;
+ }
+
+ if (transports != NULL)
+ *transports = ca_tports;
+
+ return candidate_id;
+}
+
+/**
+ * Produces the SDP description of the stream based on Farsight state and
+ * current object state.
+ *
+ * @param stream The stream object
+ * @param signal_update If true, emit the signal "local-media-updated".
+ */
+void
+rakia_media_stream_generate_sdp (RakiaMediaStream *stream, GString *out)
+{
+ RakiaMediaStreamPrivate *priv = stream->priv;
+ GString *alines;
+ GValue transport = { 0 };
+ const GPtrArray *transports = NULL;
+ gchar *tr_addr = NULL;
+ /* gchar *tr_user = NULL; */
+ /* gchar *tr_pass = NULL; */
+ gchar *tr_subtype = NULL;
+ gchar *tr_profile = NULL;
+ guint tr_port;
+ /* guint tr_type; */
+ /* gdouble tr_pref; */
+ guint rtcp_port = 0;
+ gchar *rtcp_address = NULL;
+ const gchar *dirline;
+ guint j;
+
+ priv_get_preferred_native_candidate (priv, &transports);
+
+ g_return_if_fail (transports != NULL);
+
+ g_value_init (&transport, TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT);
+
+ for (j = 0; j != transports->len; j++)
+ {
+ guint tr_component;
+
+ g_value_set_static_boxed (&transport,
+ g_ptr_array_index (transports, j));
+
+ dbus_g_type_struct_get (&transport,
+ 0, &tr_component,
+ G_MAXUINT);
+ switch (tr_component)
+ {
+ case 1: /* RTP */
+ dbus_g_type_struct_get (&transport,
+ 1, &tr_addr,
+ 2, &tr_port,
+ 4, &tr_subtype,
+ 5, &tr_profile,
+ /* 6, &tr_pref, */
+ /* 7, &tr_type, */
+ /* 8, &tr_user, */
+ /* 9, &tr_pass, */
+ G_MAXUINT);
+ break;
+ case 2: /* RTCP */
+ dbus_g_type_struct_get (&transport,
+ 1, &rtcp_address,
+ 2, &rtcp_port,
+ G_MAXUINT);
+ break;
+ }
+ }
+
g_return_if_fail (tr_addr != NULL);
g_return_if_fail (tr_subtype != NULL);
g_return_if_fail (tr_profile != NULL);
- mline = g_string_new ("m=");
- g_string_append_printf (mline,
+ g_string_append (out, "m=");
+ g_string_append_printf (out,
"%s %u %s/%s",
priv_media_type_to_str (priv->media_type),
tr_port,
tr_subtype,
tr_profile);
- cline = g_strdup_printf ("c=IN %s %s\r\n",
- (strchr (tr_addr, ':') == NULL)? "IP4" : "IP6",
- tr_addr);
-
switch (priv_get_requested_direction (priv))
{
case TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL:
@@ -1957,13 +1931,13 @@ priv_update_local_sdp(RakiaMediaStream *stream)
}
priv_append_rtpmaps (g_value_get_boxed (&priv->native_codecs),
- mline, alines);
+ out, alines);
+
+ g_string_append_printf (out, "\r\nc=IN %s %s\r\n",
+ (strchr (tr_addr, ':') == NULL)? "IP4" : "IP6",
+ tr_addr);
- g_free(priv->stream_sdp);
- priv->stream_sdp = g_strconcat(mline->str, "\r\n",
- cline,
- alines->str,
- NULL);
+ g_string_append (out, alines->str);
g_free (tr_addr);
g_free (tr_profile);
@@ -1972,11 +1946,7 @@ priv_update_local_sdp(RakiaMediaStream *stream)
/* g_free (tr_pass); */
g_free (rtcp_address);
- g_string_free (mline, TRUE);
- g_free (cline);
g_string_free (alines, TRUE);
-
- g_signal_emit (stream, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
}
static void
diff --git a/rakia/media-stream.h b/rakia/media-stream.h
index 0e09a42..d258a3c 100644
--- a/rakia/media-stream.h
+++ b/rakia/media-stream.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
typedef struct _RakiaMediaStream RakiaMediaStream;
typedef struct _RakiaMediaStreamClass RakiaMediaStreamClass;
+typedef struct _RakiaMediaStreamPrivate RakiaMediaStreamPrivate;
struct _RakiaMediaStreamClass {
GObjectClass parent_class;
@@ -38,6 +39,7 @@ struct _RakiaMediaStreamClass {
struct _RakiaMediaStream {
GObject parent;
+ RakiaMediaStreamPrivate *priv;
};
GType rakia_media_stream_get_type(void);
@@ -63,7 +65,7 @@ GType rakia_media_stream_get_type(void);
void rakia_media_stream_close (RakiaMediaStream *self);
guint rakia_media_stream_get_id (RakiaMediaStream *self);
guint rakia_media_stream_get_media_type (RakiaMediaStream *self);
-const char *rakia_media_stream_local_sdp (RakiaMediaStream *self);
+void rakia_media_stream_generate_sdp (RakiaMediaStream *self, GString *out);
gboolean rakia_media_stream_set_remote_media (RakiaMediaStream *self,
const sdp_media_t *media,
guint direction_up_mask,