static KmsIRtpConnection * kms_webrtc_session_create_connection (KmsBaseRtpSession * base_rtp_sess, SdpMediaConfig * mconf, const gchar * name, guint16 min_port, guint16 max_port) { KmsWebrtcSession *self = KMS_WEBRTC_SESSION (base_rtp_sess); GstSDPMedia *media = kms_sdp_media_config_get_sdp_media (mconf); KmsWebRtcBaseConnection *conn; self->min_port = min_port; self->max_port = max_port; if (g_strcmp0 (gst_sdp_media_get_proto (media), "DTLS/SCTP") == 0) { GST_DEBUG_OBJECT (self, "Create SCTP connection"); conn = KMS_WEBRTC_BASE_CONNECTION (kms_webrtc_sctp_connection_new (self->agent, self->context, name, min_port, max_port)); } else { GST_DEBUG_OBJECT (self, "Create RTP connection"); conn = KMS_WEBRTC_BASE_CONNECTION (kms_webrtc_connection_new (self->agent, self->context, name)); } return KMS_I_RTP_CONNECTION (conn); }
static gboolean kms_webrtc_session_gather_candidates (KmsWebrtcSession * self) { KmsBaseRtpSession *base_rtp_sess = KMS_BASE_RTP_SESSION (self); GHashTableIter iter; gpointer key, v; gboolean ret = TRUE; GST_DEBUG_OBJECT (self, "Gather candidates"); KMS_SDP_SESSION_LOCK (self); g_hash_table_iter_init (&iter, base_rtp_sess->conns); while (g_hash_table_iter_next (&iter, &key, &v)) { KmsWebRtcBaseConnection *conn = KMS_WEBRTC_BASE_CONNECTION (v); kms_webrtc_session_set_stun_server_info (self, conn); kms_webrtc_session_set_relay_info (self, conn); if (!kms_ice_base_agent_start_gathering_candidates (conn->agent, conn->stream_id)) { GST_ERROR_OBJECT (self, "Failed to start candidate gathering for '%s'.", conn->name); ret = FALSE; } } KMS_SDP_SESSION_UNLOCK (self); return ret; }
KmsWebRtcBaseConnection * kms_webrtc_session_get_connection (KmsWebrtcSession * self, SdpMediaConfig * mconf) { KmsBaseRtpSession *base_rtp_sess = KMS_BASE_RTP_SESSION (self); KmsIRtpConnection *conn; conn = kms_base_rtp_session_get_connection (base_rtp_sess, mconf); if (conn == NULL) { return NULL; } return KMS_WEBRTC_BASE_CONNECTION (conn); }
static void kms_webrtc_base_connection_finalize (GObject * object) { KmsWebRtcBaseConnection *self = KMS_WEBRTC_BASE_CONNECTION (object); GST_DEBUG_OBJECT (self, "finalize"); nice_agent_remove_stream (self->agent, self->stream_id); g_free (self->name); g_clear_object (&self->agent); g_rec_mutex_clear (&self->mutex); /* chain up */ G_OBJECT_CLASS (kms_webrtc_base_connection_parent_class)->finalize (object); }
KmsWebRtcConnection * kms_webrtc_connection_new (NiceAgent * agent, GMainContext * context, const gchar * name) { GObject *obj; KmsWebRtcBaseConnection *base_conn; KmsWebRtcConnection *conn; KmsWebRtcConnectionPrivate *priv; obj = g_object_new (KMS_TYPE_WEBRTC_CONNECTION, NULL); base_conn = KMS_WEBRTC_BASE_CONNECTION (obj); conn = KMS_WEBRTC_CONNECTION (obj); priv = conn->priv; if (!kms_webrtc_base_connection_configure (base_conn, agent, name)) { g_object_unref (obj); return NULL; } priv->rtp_tr = kms_webrtc_transport_create (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTP); priv->rtcp_tr = kms_webrtc_transport_create (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTCP); if (priv->rtp_tr == NULL || priv->rtcp_tr == NULL) { GST_ERROR_OBJECT (obj, "Cannot create KmsWebRTCConnection."); g_object_unref (obj); return NULL; } g_signal_connect (priv->rtp_tr->dtlssrtpenc, "on-key-set", G_CALLBACK (rtp_connected_cb), conn); g_signal_connect (priv->rtcp_tr->dtlssrtpenc, "on-key-set", G_CALLBACK (rtcp_connected_cb), conn); nice_agent_attach_recv (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTP, context, kms_webrtc_transport_nice_agent_recv_cb, NULL); nice_agent_attach_recv (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTCP, context, kms_webrtc_transport_nice_agent_recv_cb, NULL); return conn; }
static void kms_webrtc_rtcp_mux_connection_collect_latency_stats (KmsIRtpConnection * obj, gboolean enable) { KmsWebRtcRtcpMuxConnection *self = KMS_WEBRTC_RTCP_MUX_CONNECTION (obj); KmsWebRtcBaseConnection *base = KMS_WEBRTC_BASE_CONNECTION (obj); KMS_WEBRTC_BASE_CONNECTION_LOCK (base); if (enable) { kms_webrtc_transport_enable_latency_notification (self->priv->tr, base->cb, base->user_data, NULL); } else { kms_webrtc_transport_disable_latency_notification (self->priv->tr); } kms_webrtc_base_connection_collect_latency_stats (obj, enable); KMS_WEBRTC_BASE_CONNECTION_UNLOCK (base); }
KmsWebRtcConnection * kms_webrtc_connection_new (KmsIceBaseAgent * agent, GMainContext * context, const gchar * name, guint16 min_port, guint16 max_port, gchar * pem_certificate) { GObject *obj; KmsWebRtcBaseConnection *base_conn; KmsWebRtcConnection *conn; KmsWebRtcConnectionPrivate *priv; obj = g_object_new (KMS_TYPE_WEBRTC_CONNECTION, "max-port", max_port, "min-port", min_port, NULL); base_conn = KMS_WEBRTC_BASE_CONNECTION (obj); conn = KMS_WEBRTC_CONNECTION (obj); priv = conn->priv; if (!kms_webrtc_base_connection_configure (base_conn, agent, name)) { g_object_unref (obj); return NULL; } priv->rtp_tr = kms_webrtc_transport_new (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTP, pem_certificate); priv->rtcp_tr = kms_webrtc_transport_new (agent, base_conn->stream_id, NICE_COMPONENT_TYPE_RTCP, pem_certificate); if (priv->rtp_tr == NULL || priv->rtcp_tr == NULL) { GST_ERROR_OBJECT (obj, "Cannot create KmsWebRTCConnection."); g_object_unref (obj); return NULL; } g_signal_connect (priv->rtp_tr->sink->dtlssrtpenc, "on-key-set", G_CALLBACK (rtp_connected_cb), conn); g_signal_connect (priv->rtcp_tr->sink->dtlssrtpenc, "on-key-set", G_CALLBACK (rtcp_connected_cb), conn); return conn; }
static void kms_webrtc_rtp_connection_collect_latency_stats (KmsIRtpConnection * obj, gboolean enable) { KmsWebRtcConnection *self = KMS_WEBRTC_CONNECTION (obj); KmsWebRtcBaseConnection *base = KMS_WEBRTC_BASE_CONNECTION (obj); KMS_WEBRTC_BASE_CONNECTION_LOCK (self); /* Only rtp stream is marked with metadata for statistics */ if (enable) { kms_webrtc_transport_enable_latency_notification (self->priv->rtp_tr, base->cb, base->user_data, NULL); } else { kms_webrtc_transport_disable_latency_notification (self->priv->rtp_tr); } kms_webrtc_base_connection_collect_latency_stats (obj, enable); KMS_WEBRTC_BASE_CONNECTION_UNLOCK (self); }
static void kms_webrtc_session_gathering_done (KmsIceBaseAgent * agent, gchar * stream_id, KmsWebrtcSession * self) { KmsBaseRtpSession *base_rtp_sess = KMS_BASE_RTP_SESSION (self); GHashTableIter iter; gpointer key, v; gboolean done = TRUE; GST_DEBUG_OBJECT (self, "ICE gathering done for '%s' stream.", stream_id); KMS_SDP_SESSION_LOCK (self); g_hash_table_iter_init (&iter, base_rtp_sess->conns); while (g_hash_table_iter_next (&iter, &key, &v)) { KmsWebRtcBaseConnection *conn = KMS_WEBRTC_BASE_CONNECTION (v); if (g_strcmp0 (stream_id, conn->stream_id) == 0) { conn->ice_gathering_done = TRUE; } if (!conn->ice_gathering_done) { done = FALSE; } } if (done) { kms_webrtc_session_local_sdp_add_default_info (self); } KMS_SDP_SESSION_UNLOCK (self); if (done) { g_signal_emit (G_OBJECT (self), kms_webrtc_session_signals[SIGNAL_ON_ICE_GATHERING_DONE], 0); } }