diff options
author | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2011-06-14 20:54:21 +0300 |
---|---|---|
committer | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2011-06-14 20:55:17 +0300 |
commit | d547bb11d8eb2fb9dff19b812f6856dd12e9c254 (patch) | |
tree | b840fbf34423b8aa79a79d2dacf370a45ad5020d | |
parent | d960b6a266e60e19480bb9f192448f05d8463463 (diff) | |
parent | dfc026f67a3e82bdb785958e5ad0a808568372a5 (diff) |
Merge branch 'codec-updates' into trunk
-rw-r--r-- | rakia/media-session.c | 99 | ||||
-rw-r--r-- | rakia/media-stream.c | 300 | ||||
-rw-r--r-- | rakia/media-stream.h | 4 |
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, |