Example #1
0
static void
kms_webrtc_session_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  KmsWebrtcSession *self = KMS_WEBRTC_SESSION (object);

  KMS_SDP_SESSION_LOCK (self);

  switch (prop_id) {
    case PROP_STUN_SERVER_IP:
      g_value_set_string (value, self->stun_server_ip);
      break;
    case PROP_STUN_SERVER_PORT:
      g_value_set_uint (value, self->stun_server_port);
      break;
    case PROP_TURN_URL:
      g_value_set_string (value, self->turn_url);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  KMS_SDP_SESSION_UNLOCK (self);
}
Example #2
0
static void
kms_base_rtp_session_update_conn_state (KmsBaseRtpSession * self)
{
  GHashTableIter iter;
  gpointer key, v;
  gboolean emit = FALSE;
  KmsConnectionState new_state = KMS_CONNECTION_STATE_CONNECTED;

  KMS_SDP_SESSION_LOCK (self);

  g_hash_table_iter_init (&iter, self->conns);
  while (g_hash_table_iter_next (&iter, &key, &v)) {
    KmsIRtpConnection *conn = KMS_I_RTP_CONNECTION (v);
    gboolean connected;

    g_object_get (conn, "connected", &connected, NULL);
    if (!connected) {
      new_state = KMS_CONNECTION_STATE_DISCONNECTED;
      break;
    }
  }

  if (self->conn_state != new_state) {
    GST_DEBUG_OBJECT (self, "Connection state changed to '%d'", new_state);
    self->conn_state = new_state;
    emit = TRUE;
  }

  KMS_SDP_SESSION_UNLOCK (self);

  if (emit) {
    g_signal_emit (G_OBJECT (self), obj_signals[CONNECTION_STATE_CHANGED], 0,
        new_state);
  }
}
Example #3
0
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;
}
Example #4
0
static void
rtp_ssrc_demux_new_ssrc_pad (GstElement * ssrcdemux, guint ssrc, GstPad * pad,
    KmsBaseRtpSession * self)
{
  const gchar *rtp_pad_name = GST_OBJECT_NAME (pad);
  gchar *rtcp_pad_name;
  SdpMediaConfig *mconf;
  GstPad *src, *sink;

  GST_DEBUG_OBJECT (self, "pad: %" GST_PTR_FORMAT " ssrc: %" G_GUINT32_FORMAT,
      pad, ssrc);

  KMS_SDP_SESSION_LOCK (self);

  if (self->remote_audio_ssrc == ssrc
      || ssrcs_are_mapped (ssrcdemux, self->local_audio_ssrc, ssrc)) {
    mconf = self->audio_neg_mconf;
  } else if (self->remote_video_ssrc == ssrc
      || ssrcs_are_mapped (ssrcdemux, self->local_video_ssrc, ssrc)) {
    mconf = self->video_neg_mconf;
  } else {
    if (!kms_i_rtp_session_manager_custom_ssrc_management (self->manager, self,
            ssrcdemux, ssrc, pad)) {
      GST_ERROR_OBJECT (pad, "SSRC %" G_GUINT32_FORMAT " not matching.", ssrc);
    }
    goto end;
  }

  /* RTP */
  sink =
      kms_i_rtp_session_manager_request_rtp_sink (self->manager, self, mconf);
  kms_base_rtp_session_link_pads (pad, sink);
  g_object_unref (sink);

  /* RTCP */
  rtcp_pad_name = g_strconcat ("rtcp_", rtp_pad_name, NULL);
  src = gst_element_get_static_pad (ssrcdemux, rtcp_pad_name);
  g_free (rtcp_pad_name);
  sink =
      kms_i_rtp_session_manager_request_rtcp_sink (self->manager, self, mconf);
  kms_base_rtp_session_link_pads (src, sink);
  g_object_unref (src);
  g_object_unref (sink);

end:
  KMS_SDP_SESSION_UNLOCK (self);
}
Example #5
0
static void
kms_base_rtp_session_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (object);

  KMS_SDP_SESSION_LOCK (self);

  switch (property_id) {
    case PROP_CONNECTION_STATE:
      g_value_set_enum (value, self->conn_state);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }

  KMS_SDP_SESSION_UNLOCK (self);
}
Example #6
0
static void
kms_base_rtp_session_check_conn_status (KmsBaseRtpSession * self)
{
  GHashTableIter iter;
  gpointer key, v;

  KMS_SDP_SESSION_LOCK (self);

  g_hash_table_iter_init (&iter, self->conns);
  while (g_hash_table_iter_next (&iter, &key, &v)) {
    KmsIRtpConnection *conn = KMS_I_RTP_CONNECTION (v);

    g_signal_connect_data (conn, "connected",
        G_CALLBACK (kms_base_rtp_session_connected_cb), self, NULL, 0);
  }

  KMS_SDP_SESSION_UNLOCK (self);

  kms_base_rtp_session_update_conn_state (self);
}
Example #7
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);
}
Example #8
0
static void
kms_base_rtp_session_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (object);

  KMS_SDP_SESSION_LOCK (self);

  switch (property_id) {
    case PROP_CONNECTION_STATE:
      g_value_set_enum (value, self->conn_state);
      break;
    case PROP_STATS:{
      gchar *struct_name, *obj_name;
      GstStructure *s;

      obj_name = gst_element_get_name (self);
      struct_name = g_strdup_printf ("%s-stats", obj_name);
      g_free (obj_name);

      /* Video and audio latencies are avery small values in */
      /* nano seconds so there is no harm in casting them to */
      /* uint64 even we might lose a bit of preccision.      */

      s = gst_structure_new (struct_name, "video-e2e-latency",
          G_TYPE_UINT64, (guint64) self->stats->vi, "audio-e2e-latency",
          G_TYPE_UINT64, (guint64) self->stats->ai, NULL);

      g_free (struct_name);
      g_value_take_boxed (value, s);

      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }

  KMS_SDP_SESSION_UNLOCK (self);
}
Example #9
0
static gboolean
kms_webrtc_session_add_ice_candidate (KmsWebrtcSession * self,
    KmsIceCandidate * candidate)
{
  guint8 index;
  gboolean ret;

  GST_DEBUG_OBJECT (self, "Add ICE candidate '%s'",
      kms_ice_candidate_get_candidate (candidate));

  KMS_SDP_SESSION_LOCK (self);
  self->remote_candidates =
      g_slist_append (self->remote_candidates, g_object_ref (candidate));

  ret = kms_webrtc_session_set_remote_ice_candidate (self, candidate);

  index = kms_ice_candidate_get_sdp_m_line_index (candidate);
  kms_webrtc_session_remote_sdp_add_ice_candidate (self, candidate, index);
  KMS_SDP_SESSION_UNLOCK (self);

  return ret;
}
Example #10
0
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);
  }
}