예제 #1
0
static void
kms_base_rtp_session_connected_cb (KmsIRtpConnection * conn, gpointer user_data)
{
  KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (user_data);

  kms_base_rtp_session_update_conn_state (self);
}
예제 #2
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);
  }
}
예제 #3
0
static gboolean
kms_webrtc_session_add_connection (KmsWebrtcSession * self,
    KmsSdpSession * sess, SdpMediaConfig * mconf, gboolean offerer)
{
  KmsBaseRtpSession *base_rtp_sess = KMS_BASE_RTP_SESSION (sess);
  gboolean connected, active;
  KmsIRtpConnection *conn;

  conn = kms_base_rtp_session_get_connection (base_rtp_sess, mconf);
  if (conn == NULL) {
    GST_ERROR_OBJECT (self, "No connection created");
    return FALSE;
  }

  g_object_get (conn, "added", &connected, NULL);
  if (connected) {
    GST_DEBUG_OBJECT (self, "Conn already added");
    return TRUE;
  }

  active =
      sdp_utils_media_is_active (kms_sdp_media_config_get_sdp_media (mconf),
      offerer);

  kms_i_rtp_connection_add (conn, GST_BIN (self), active);
  kms_i_rtp_connection_sink_sync_state_with_parent (conn);
  kms_i_rtp_connection_src_sync_state_with_parent (conn);

  return TRUE;
}
예제 #4
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;
}
예제 #5
0
static void
kms_base_rtp_session_finalize (GObject * object)
{
  KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (object);

  GST_DEBUG_OBJECT (self, "finalize");

  g_hash_table_destroy (self->conns);

  /* chain up */
  G_OBJECT_CLASS (kms_base_rtp_session_parent_class)->finalize (object);
}
예제 #6
0
static void
kms_webrtc_session_post_constructor (KmsWebrtcSession * self,
    KmsBaseSdpEndpoint * ep, guint id, KmsIRtpSessionManager * manager,
    GMainContext * context)
{
  KmsBaseRtpSession *base_rtp_session = KMS_BASE_RTP_SESSION (self);

  self->context = g_main_context_ref (context);

  KMS_BASE_RTP_SESSION_CLASS
      (kms_webrtc_session_parent_class)->post_constructor (base_rtp_session, ep,
      id, manager);
}
예제 #7
0
KmsBaseRtpSession *
kms_base_rtp_session_new (KmsBaseSdpEndpoint * ep, guint id,
    KmsIRtpSessionManager * manager)
{
  GObject *obj;
  KmsBaseRtpSession *self;

  obj = g_object_new (KMS_TYPE_BASE_RTP_SESSION, NULL);
  self = KMS_BASE_RTP_SESSION (obj);
  KMS_BASE_RTP_SESSION_CLASS (G_OBJECT_GET_CLASS (self))->post_constructor
      (self, ep, id, manager);

  return self;
}
예제 #8
0
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);
}
예제 #9
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);
}
예제 #10
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);
}
예제 #11
0
static void
kms_base_rtp_session_latency_cb (GstPad * pad, KmsMediaType type,
    GstClockTimeDiff t, gpointer user_data)
{
  KmsBaseRtpSession *self = KMS_BASE_RTP_SESSION (user_data);
  gdouble *prev;

  switch (type) {
    case KMS_MEDIA_TYPE_AUDIO:
      prev = &self->stats->ai;
      break;
    case KMS_MEDIA_TYPE_VIDEO:
      prev = &self->stats->vi;
      break;
    default:
      GST_DEBUG_OBJECT (pad, "No stast calculated for media (%s)",
          str_media_type (type));
      return;
  }

  *prev = KMS_STATS_CALCULATE_LATENCY_AVG (t, *prev);
}
예제 #12
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);
  }
}