Beispiel #1
0
GstStructure *
kms_stats_get_element_stats (GstStructure * stats)
{
  GstStructure *element_stats;
  const GValue *value;

  if (!gst_structure_has_field (stats, KMS_MEDIA_ELEMENT_FIELD)) {
    return NULL;
  }

  value = gst_structure_get_value (stats, KMS_MEDIA_ELEMENT_FIELD);

  if (!GST_VALUE_HOLDS_STRUCTURE (value)) {
    return NULL;
  }

  element_stats = (GstStructure *) gst_value_get_structure (value);

  if (g_strcmp0 (KMS_ELEMENT_STATS_STRUCT_NAME,
          gst_structure_get_name (element_stats)) != 0) {
    return NULL;
  }

  return element_stats;
}
Beispiel #2
0
static void
kms_connection_attr_ext_add_ips (KmsISdpMediaExtension * ext,
    GstSDPMedia * media, GArray * ips)
{
  gint i;

  for (i = 0; i < ips->len; i++) {
    gchar *nettype, *addrtype, *address;
    guint ttl, addr_number;
    const GstStructure *addr;
    GValue *val;

    val = &g_array_index (ips, GValue, i);

    if (!GST_VALUE_HOLDS_STRUCTURE (val)) {
      GST_WARNING_OBJECT (ext, "Inavalid address provided");
      continue;
    }

    addr = gst_value_get_structure (val);
    nettype = addrtype = address = NULL;

    if (gst_structure_get (addr, "nettype", G_TYPE_STRING, &nettype,
            "addrtype", G_TYPE_STRING, &addrtype, "address", G_TYPE_STRING,
            &address, "ttl", G_TYPE_UINT, &ttl, "addrnumber", G_TYPE_UINT,
            &addr_number, NULL)) {
      gst_sdp_media_add_connection (media, nettype, addrtype, address, ttl,
          addr_number);
    }

    g_free (nettype);
    g_free (addrtype);
    g_free (address);
  }
}
Beispiel #3
0
static JsonNode *
snra_json_value_to_node (const GValue *value)
{
  JsonNode *n = NULL;

  if (GST_VALUE_HOLDS_STRUCTURE (value)) {
    const GstStructure *s = gst_value_get_structure (value);
    n = snra_json_from_gst_structure (s);
  }
  else if (GST_VALUE_HOLDS_ARRAY (value)) {
    guint count = gst_value_array_get_size (value);
    guint i;
    JsonArray *arr = json_array_sized_new (count);
    for (i = 0; i < count; i++) {
      const GValue *sub_val = gst_value_array_get_value (value, i);
      JsonNode *tmp = snra_json_value_to_node (sub_val);
      if (tmp)
        json_array_add_element (arr, tmp);
    }
    n = json_node_new (JSON_NODE_ARRAY);
    json_node_take_array (n, arr);
  } else {
    n = json_node_new (JSON_NODE_VALUE);
    json_node_set_value (n, value);
  }

  return n;
}
Beispiel #4
0
static const GstStructure *
get_structure_from_value (const GValue * val)
{
  if (!GST_VALUE_HOLDS_STRUCTURE (val)) {
    return NULL;
  }

  return gst_value_get_structure (val);
}
static void
collectRTCDataChannelStats (std::map <std::string, std::shared_ptr<Stats>>
                            &statsReport, double timestamp, const GstStructure *stats)
{
  gint i, n;

  n = gst_structure_n_fields (stats);

  for (i = 0; i < n; i++) {
    std::shared_ptr<RTCDataChannelStats> rtcDataStats;
    const GValue *value;
    const gchar *name;

    name = gst_structure_nth_field_name (stats, i);

    if (!g_str_has_prefix (name, "data-channel-") ) {
      continue;
    }

    value = gst_structure_get_value (stats, name);

    if (!GST_VALUE_HOLDS_STRUCTURE (value) ) {
      gchar *str_val;

      str_val = g_strdup_value_contents (value);
      GST_WARNING ("Unexpected field type (%s) = %s", name, str_val);
      g_free (str_val);

      continue;
    }

    rtcDataStats = createtRTCDataChannelStats (gst_value_get_structure (value) );
    rtcDataStats->setTimestamp (timestamp);
    statsReport[rtcDataStats->getId ()] = rtcDataStats;
  }

  std::shared_ptr<RTCPeerConnectionStats> peerConnStats =
    createtRTCPeerConnectionStats (stats);
  peerConnStats->setTimestamp (timestamp);
  statsReport[peerConnStats->getId ()] = peerConnStats;
}
static void
remove_not_supported_codecs_from_array (GstElement *element, GArray *codecs)
{
  guint i;

  if (codecs == NULL) {
    return;
  }

  for (i = 0; i < codecs->len; i++) {
    GValue *v = &g_array_index (codecs, GValue, i);
    const GstStructure *s;
    const gchar *codec_name;
    gboolean supported = FALSE;

    if (!GST_VALUE_HOLDS_STRUCTURE (v) ) {
      GST_WARNING_OBJECT (element, "Value into array is not a GstStructure");
      continue;
    }

    s = gst_value_get_structure (v);
    codec_name = gst_structure_get_name (s);

    for (std::vector<std::string>::iterator it = supported_codecs.begin();
         it != supported_codecs.end(); ++it) {
      if (g_str_has_prefix (codec_name, (*it).c_str() ) ) {
        supported = TRUE;
        break;
      }
    }

    if (!supported) {
      GST_INFO_OBJECT (element, "Removing not supported codec '%s'", codec_name);
      g_array_remove_index (codecs, i);
      i--;
    }
  }
}
Beispiel #7
0
const GstStructure *
kms_utils_get_structure_by_name (const GstStructure * str, const gchar * name)
{
  const GValue *value;

  value = gst_structure_get_value (str, name);

  if (value == NULL) {
    return NULL;
  }

  if (!GST_VALUE_HOLDS_STRUCTURE (value)) {
    gchar *str_val;

    str_val = g_strdup_value_contents (value);
    GST_WARNING ("Unexpected field type (%s) = %s", name, str_val);
    g_free (str_val);

    return NULL;
  }

  return gst_value_get_structure (value);
}
Beispiel #8
0
static gboolean
kms_sdp_sdes_ext_add_offer_crypto_attrs (KmsISdpMediaExtension * ext,
    GstSDPMedia * offer, GArray * keys, GError ** error)
{
  gboolean ret = TRUE;
  guint i;

  for (i = 0; i < keys->len; i++) {
    const GstStructure *str;
    SrtpCryptoSuite crypto;
    gchar *key, *lifetime;
    guint tag, *mki, *len;
    GValue *val;

    key = lifetime = NULL;
    mki = len = NULL;

    val = &g_array_index (keys, GValue, i);

    if (!GST_VALUE_HOLDS_STRUCTURE (val)) {
      g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER,
          "Can not add crypto attribute for key %u", i);
      return FALSE;
    }

    str = gst_value_get_structure (val);

    if (!gst_structure_get (str, KMS_SDES_TAG_FIELD, G_TYPE_UINT, &tag,
            KMS_SDES_KEY_FIELD, G_TYPE_STRING, &key, KMS_SDES_CRYPTO,
            G_TYPE_UINT, &crypto, NULL)) {
      g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER,
          "Can not add crypto attribute for key %u", i);
      ret = FALSE;
    }

    if (ret) {
      guint m, l;

      /* get optional parameters */
      gst_structure_get (str, KMS_SDES_LIFETIME, G_TYPE_STRING, &lifetime,
          NULL);

      if (gst_structure_get (str, KMS_SDES_MKI, G_TYPE_UINT, &m,
              KMS_SDES_LENGTH, G_TYPE_UINT, &l, NULL)) {
        mki = &m;
        len = &l;
      }

      ret = kms_sdp_sdes_ext_add_crypto_attr (ext, offer, tag, key, crypto,
          lifetime, mki, len, error);
    }

    g_free (key);
    g_free (lifetime);

    if (!ret) {
      /* Something went wrong */
      break;
    }
  }

  return ret;
}
Beispiel #9
0
static void
handle_player_info (G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
    SnraClient *client)
{
  SoupBuffer *buffer;

  if (msg->status_code < 200 || msg->status_code >= 300)
    return;

  buffer = soup_message_body_flatten (msg->response_body);
  if (json_parser_load_from_data (client->json, buffer->data, buffer->length,
          NULL)) {
    const GValue *v1;
    GArray *player_info = NULL;
    gsize i;
    JsonNode *root = json_parser_get_root (client->json);
    GstStructure *s1 = snra_json_to_gst_structure (root);

    if (s1 == NULL)
      return;                   /* Invalid chunk */

    v1 = gst_structure_get_value (s1, "player-clients");
    if (!GST_VALUE_HOLDS_ARRAY (v1))
      goto failed;

    player_info = g_array_sized_new (TRUE, TRUE,
          sizeof (SnraPlayerInfo), gst_value_array_get_size (v1));

    for (i = 0; i < gst_value_array_get_size (v1); i++) {
      SnraPlayerInfo info;
      const GValue *v2 = gst_value_array_get_value (v1, i);
      const GstStructure *s2;
      gint64 client_id;

      if (!GST_VALUE_HOLDS_STRUCTURE (v2))
        goto failed;

      s2 = gst_value_get_structure (v2);
      if (!snra_json_structure_get_int64 (s2, "client-id", &client_id))
        goto failed;
      info.id = client_id;

      if (!snra_json_structure_get_boolean (s2, "enabled", &info.enabled))
        goto failed;

      if (!snra_json_structure_get_double (s2, "volume", &info.volume))
        goto failed;

      if (!(info.host = g_strdup (gst_structure_get_string (s2, "host"))))
        goto failed;

      g_array_append_val (player_info, info);
    }

    free_player_info (client->player_info);
    client->player_info = player_info;
    player_info = NULL;

    g_signal_emit (client, signals[SIGNAL_PLAYER_INFO_CHANGED], 0);

failed:
    if (player_info)
      free_player_info (player_info);
    gst_structure_free (s1);
  }
}
/* If a parent is non-NULL, collected stream information will be appended to it
 * (and where the information exists, it will be overriden)
 */
static GstDiscovererStreamInfo *
parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology,
    GstDiscovererStreamInfo * parent)
{
  GstDiscovererStreamInfo *res = NULL;
  GstCaps *caps = NULL;
  const GValue *nval = NULL;

  GST_DEBUG ("parsing: %" GST_PTR_FORMAT, topology);

  nval = gst_structure_get_value (topology, "next");

  if (nval == NULL || GST_VALUE_HOLDS_STRUCTURE (nval)) {
    GstStructure *st = find_stream_for_node (dc, topology);
    gboolean add_to_list = TRUE;

    if (st) {
      res = collect_information (dc, st, parent);
      gst_structure_free (st);
    } else {
      /* Didn't find a stream structure, so let's just use the caps we have */
      res = collect_information (dc, topology, parent);
    }

    if (nval == NULL) {
      /* FIXME : aggregate with information from main streams */
      GST_DEBUG ("Coudn't find 'next' ! might be the last entry");
    } else {
      GstCaps *caps;
      const GstStructure *st;

      st = gst_value_get_structure (nval);

      GST_DEBUG ("next is a structure %" GST_PTR_FORMAT, st);

      if (!parent)
        parent = res;

      if (gst_structure_id_get (st, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL)) {
        if (gst_caps_can_intersect (parent->caps, caps)) {
          /* We sometimes get an extra sub-stream from the parser. If this is
           * the case, we just replace the parent caps with this stream's caps
           * since they might contain more information */
          gst_caps_unref (parent->caps);
          parent->caps = caps;

          parse_stream_topology (dc, st, parent);
          add_to_list = FALSE;

        } else if (child_is_raw_stream (parent->caps, caps)) {
          /* This is the "raw" stream corresponding to the parent. This
           * contains more information than the parent, tags etc. */
          parse_stream_topology (dc, st, parent);
          add_to_list = FALSE;
          gst_caps_unref (caps);

        } else {
          GstDiscovererStreamInfo *next = parse_stream_topology (dc, st, NULL);
          res->next = next;
          next->previous = res;
        }
      }
    }

    if (add_to_list) {
      dc->priv->current_info->stream_list =
          g_list_append (dc->priv->current_info->stream_list, res);
    }

  } else if (GST_VALUE_HOLDS_LIST (nval)) {
    guint i, len;
    GstDiscovererContainerInfo *cont;
    GstTagList *tags;

    if (!gst_structure_id_get (topology, _CAPS_QUARK,
            GST_TYPE_CAPS, &caps, NULL))
      GST_WARNING ("Couldn't find caps !");

    len = gst_value_list_get_size (nval);
    GST_DEBUG ("next is a list of %d entries", len);

    cont = (GstDiscovererContainerInfo *)
        gst_mini_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO);
    cont->parent.caps = caps;
    res = (GstDiscovererStreamInfo *) cont;

    if (gst_structure_id_has_field (topology, _TAGS_QUARK)) {
      GstTagList *tmp;

      gst_structure_id_get (topology, _TAGS_QUARK,
          GST_TYPE_STRUCTURE, &tags, NULL);

      GST_DEBUG ("Merge tags %" GST_PTR_FORMAT, tags);

      tmp =
          gst_tag_list_merge (cont->parent.tags, (GstTagList *) tags,
          GST_TAG_MERGE_APPEND);
      gst_tag_list_free (tags);
      if (cont->parent.tags)
        gst_tag_list_free (cont->parent.tags);
      cont->parent.tags = tmp;
      GST_DEBUG ("Container info tags %" GST_PTR_FORMAT, tmp);
    }

    for (i = 0; i < len; i++) {
      const GValue *subv = gst_value_list_get_value (nval, i);
      const GstStructure *subst = gst_value_get_structure (subv);
      GstDiscovererStreamInfo *substream;

      GST_DEBUG ("%d %" GST_PTR_FORMAT, i, subst);

      substream = parse_stream_topology (dc, subst, NULL);

      substream->previous = res;
      cont->streams =
          g_list_append (cont->streams,
          gst_discoverer_stream_info_ref (substream));
    }
  }

  return res;
}