void kms_base_rtp_session_start_transport_send (KmsBaseRtpSession * self, gboolean offerer) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); GSList *item = kms_sdp_message_context_get_medias (sdp_sess->neg_sdp_ctx); GSList *remote_media_list = kms_sdp_message_context_get_medias (sdp_sess->remote_sdp_ctx); kms_base_rtp_session_check_conn_status (self); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *neg_mconf = item->data; gint mid = kms_sdp_media_config_get_id (neg_mconf); SdpMediaConfig *remote_mconf; if (kms_sdp_media_config_is_inactive (neg_mconf)) { GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", mid); continue; } remote_mconf = g_slist_nth_data (remote_media_list, mid); if (remote_mconf == NULL) { GST_WARNING_OBJECT (self, "Media (id=%d) is not in the remote SDP", mid); continue; } if (!kms_base_rtp_session_configure_connection (self, neg_mconf, remote_mconf, offerer)) { GST_WARNING_OBJECT (self, "Cannot configure connection for media %d.", mid); } } }
static gboolean kms_webrtc_session_local_sdp_add_default_info (KmsWebrtcSession * self) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx; const GstSDPMessage *sdp = kms_sdp_message_context_get_sdp_message (local_sdp_ctx); const GSList *item = kms_sdp_message_context_get_medias (local_sdp_ctx); gboolean use_ipv6; GstSDPConnection *conn; conn = (GstSDPConnection *) gst_sdp_message_get_connection (sdp); gst_sdp_connection_clear (conn); use_ipv6 = kms_sdp_session_get_use_ipv6 (sdp_sess); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *mconf = item->data; if (kms_sdp_media_config_is_inactive (mconf)) { gint mid = kms_sdp_media_config_get_id (mconf); GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", mid); continue; } if (!kms_webrtc_session_sdp_media_add_default_info (self, mconf, use_ipv6)) { return FALSE; } } return TRUE; }
static void kms_base_rtp_session_e2e_latency_cb (GstPad * pad, KmsMediaType type, GstClockTimeDiff t, KmsList * mdata, gpointer user_data) { KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (user_data); KmsListIter iter; gpointer key, value; gchar *name; name = gst_element_get_name (KMS_SDP_SESSION (self)->ep); kms_list_iter_init (&iter, mdata); while (kms_list_iter_next (&iter, &key, &value)) { gchar *id = (gchar *) key; StreamE2EAvgStat *stat; if (!g_str_has_prefix (id, name)) { /* This element did not add this mark to the metada */ continue; } stat = (StreamE2EAvgStat *) value; stat->avg = KMS_STATS_CALCULATE_LATENCY_AVG (t, stat->avg); } }
void kms_webrtc_session_remote_sdp_add_ice_candidate (KmsWebrtcSession * self, KmsIceCandidate * candidate, guint8 index) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); SdpMessageContext *remote_sdp_ctx = sdp_sess->remote_sdp_ctx; GSList *medias; SdpMediaConfig *mconf; if (remote_sdp_ctx == NULL) { GST_INFO_OBJECT (self, "Cannot update remote SDP until it is set."); return; } medias = kms_sdp_message_context_get_medias (remote_sdp_ctx); mconf = g_slist_nth_data (medias, index); if (mconf == NULL) { GST_WARNING_OBJECT (self, "Media not found in remote SDP for index %" G_GUINT16_FORMAT, index); } else { GstSDPMedia *media = kms_sdp_media_config_get_sdp_media (mconf); sdp_media_add_ice_candidate (media, self->agent, candidate); } }
static void kms_base_rtp_session_post_constructor (KmsBaseRtpSession * self, KmsBaseSdpEndpoint * ep, guint id, KmsIRtpSessionManager * manager) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); self->manager = manager; KMS_SDP_SESSION_CLASS (kms_base_rtp_session_parent_class)->post_constructor (sdp_sess, ep, id); }
KmsSdpSession * kms_sdp_session_new (KmsBaseSdpEndpoint * ep, guint id) { GObject *obj; KmsSdpSession *self; obj = g_object_new (KMS_TYPE_SDP_SESSION, NULL); self = KMS_SDP_SESSION (obj); KMS_SDP_SESSION_CLASS (G_OBJECT_GET_CLASS (self))->post_constructor (self, ep, id); return self; }
static KmsIceCandidate * kms_ice_nice_agent_get_default_local_candidate (KmsIceBaseAgent * self, const char *stream_id, guint component_id) { KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self); NiceCandidate *nice_cand; KmsIceCandidate *ret = NULL; guint id = atoi (stream_id); KmsSdpSession *sdp_sess = KMS_SDP_SESSION (nice_agent->priv->session); SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx; const GSList *item = kms_sdp_message_context_get_medias (local_sdp_ctx); nice_cand = nice_agent_get_default_local_candidate (nice_agent->priv->agent, id, component_id); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *mconf = item->data; gint idx = kms_sdp_media_config_get_id (mconf); const gchar *mid; gchar *media_stream_id; if (kms_sdp_media_config_is_inactive (mconf)) { GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", idx); continue; } media_stream_id = kms_webrtc_session_get_stream_id (nice_agent->priv->session, mconf); if (media_stream_id == NULL) { goto end; } if (media_stream_id != stream_id) { goto end; } mid = kms_sdp_media_config_get_mid (mconf); if (mid != NULL) { ret = kms_ice_candidate_new_from_nice (nice_agent->priv->agent, nice_cand, mid, idx); goto end; } } end: nice_candidate_free (nice_cand); return ret; }
gboolean kms_webrtc_session_set_remote_ice_candidate (KmsWebrtcSession * self, KmsIceCandidate * candidate) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx; guint8 index; GSList *medias; SdpMediaConfig *mconf; gboolean ret; if (local_sdp_ctx == NULL) { GST_INFO_OBJECT (self, "Cannot add candidate until local SDP is generated."); return TRUE; /* We do not know if the candidate is valid until it is set */ } medias = kms_sdp_message_context_get_medias (local_sdp_ctx); index = kms_ice_candidate_get_sdp_m_line_index (candidate); mconf = g_slist_nth_data (medias, index); if (mconf == NULL) { GST_WARNING_OBJECT (self, "Media not found in local SDP for index %" G_GUINT16_FORMAT, index); return FALSE; } else if (kms_sdp_media_config_is_inactive (mconf)) { GST_DEBUG_OBJECT (self, "Media inactive for index %" G_GUINT16_FORMAT, index); return TRUE; } else { gchar *stream_id; stream_id = kms_webrtc_session_get_stream_id (self, mconf); if (stream_id == NULL) { return FALSE; } if (!kms_ice_base_agent_add_ice_candidate (self->agent, candidate, stream_id)) { GST_WARNING_OBJECT (self, "Cannot add candidate: '%s'in stream_id: %s.", kms_ice_candidate_get_candidate (candidate), stream_id); ret = FALSE; } else { GST_TRACE_OBJECT (self, "Candidate added: '%s' in stream_id: %s.", kms_ice_candidate_get_candidate (candidate), stream_id); ret = TRUE; } } return ret; }
static void kms_ice_nice_agent_sdp_msg_add_ice_candidate (KmsWebrtcSession * self, NiceAgent * agent, NiceCandidate * nice_cand, KmsIceBaseAgent * parent) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx; const GSList *item = kms_sdp_message_context_get_medias (local_sdp_ctx); GList *list = NULL, *iterator = NULL; KMS_SDP_SESSION_LOCK (self); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *mconf = item->data; gint idx = kms_sdp_media_config_get_id (mconf); const gchar *mid; if (kms_sdp_media_config_is_inactive (mconf)) { GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", idx); continue; } mid = kms_ice_nice_agent_sdp_media_add_ice_candidate (self, mconf, agent, nice_cand); if (mid != NULL) { KmsIceCandidate *candidate = kms_ice_candidate_new_from_nice (agent, nice_cand, mid, idx); list = g_list_append (list, candidate); } } KMS_SDP_SESSION_UNLOCK (self); for (iterator = list; iterator; iterator = iterator->next) { g_signal_emit_by_name (parent, "on-ice-candidate", KMS_ICE_CANDIDATE (iterator->data)); } g_list_free_full (list, g_object_unref); }
static void kms_sdp_session_finalize (GObject * object) { KmsSdpSession *self = KMS_SDP_SESSION (object); GST_DEBUG_OBJECT (self, "finalize"); if (self->local_sdp_ctx != NULL) { kms_sdp_message_context_unref (self->local_sdp_ctx); } if (self->remote_sdp_ctx != NULL) { kms_sdp_message_context_unref (self->remote_sdp_ctx); } g_clear_object (&self->ptmanager); g_clear_object (&self->agent); g_free (self->id_str); g_rec_mutex_clear (&self->mutex); /* chain up */ G_OBJECT_CLASS (kms_sdp_session_parent_class)->finalize (object); }
void kms_webrtc_session_start_transport_send (KmsWebrtcSession * self, gboolean offerer) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); const GstSDPMessage *sdp = kms_sdp_message_context_get_sdp_message (sdp_sess->remote_sdp_ctx); const GSList *item = kms_sdp_message_context_get_medias (sdp_sess->neg_sdp_ctx); GSList *remote_media_list = kms_sdp_message_context_get_medias (sdp_sess->remote_sdp_ctx); const gchar *ufrag, *pwd; /* [rfc5245#section-5.2] * The agent that generated the offer which * started the ICE processing MUST take the controlling role, and the * other MUST take the controlled role. */ // TODO: This code should be independent of the ice implementation if (KMS_IS_ICE_NICE_AGENT (self->agent)) { KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self->agent); g_object_set (kms_ice_nice_agent_get_agent (nice_agent), "controlling-mode", offerer, NULL); } /* Configure specific webrtc connection such as SCTP if negotiated */ kms_webrtc_session_configure_connections (self, sdp_sess, offerer); ufrag = gst_sdp_message_get_attribute_val (sdp, SDP_ICE_UFRAG_ATTR); pwd = gst_sdp_message_get_attribute_val (sdp, SDP_ICE_PWD_ATTR); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *neg_mconf = item->data; gint mid = kms_sdp_media_config_get_id (neg_mconf); SdpMediaConfig *remote_mconf; KmsWebRtcBaseConnection *conn; if (kms_sdp_media_config_is_inactive (neg_mconf)) { GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", mid); continue; } conn = kms_webrtc_session_get_connection (self, neg_mconf); if (conn == NULL) { continue; } remote_mconf = g_slist_nth_data (remote_media_list, mid); if (remote_mconf == NULL) { GST_WARNING_OBJECT (self, "Media (id=%d) is not in the remote SDP", mid); continue; } gst_media_add_remote_candidates (remote_mconf, conn, ufrag, pwd); } kms_webrtc_session_add_stored_ice_candidates (self); g_slist_foreach (self->remote_candidates, kms_webrtc_session_remote_sdp_add_stored_ice_candidates, self); }