Esempio n. 1
0
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);
    }
  }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
  }
}
Esempio n. 4
0
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);
  }
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}