GST_END_TEST
GST_START_TEST (media_from_caps_rtcp_fb_pt_101)
{
  GstSDPResult ret = GST_SDP_OK;
  GstSDPMessage *message;
  glong length = -1;
  GstSDPMedia *media_caps;
  const GstSDPMedia *media_sdp;
  GstCaps *caps;
  const gchar *attr_val_caps1, *attr_val_sdp1;

  caps = gst_caps_from_string (caps_video_rtcp_fb_pt_101);

  gst_sdp_media_new (&media_caps);
  fail_unless (media_caps != NULL);

  ret = gst_sdp_media_set_media_from_caps (caps, media_caps);
  fail_unless (ret == GST_SDP_OK);
  gst_caps_unref (caps);

  gst_sdp_message_new (&message);
  gst_sdp_message_parse_buffer ((guint8 *) sdp_rtcp_fb, length, message);

  media_sdp = gst_sdp_message_get_media (message, 0);
  fail_unless (media_sdp != NULL);

  attr_val_caps1 = gst_sdp_media_get_attribute_val (media_caps, "rtcp-fb");
  attr_val_sdp1 = gst_sdp_media_get_attribute_val_n (media_sdp, "rtcp-fb", 3);

  fail_if (g_strcmp0 (attr_val_caps1, attr_val_sdp1) != 0);

  gst_sdp_media_free (media_caps);
  gst_sdp_message_free (message);
}
Example #2
0
gint
kms_sdp_media_config_get_abs_send_time_id (SdpMediaConfig * mconf)
{
  GstSDPMedia *media = kms_sdp_media_config_get_sdp_media (mconf);
  guint a;

  for (a = 0;; a++) {
    const gchar *attr;
    gchar **tokens;

    attr = gst_sdp_media_get_attribute_val_n (media, EXT_MAP, a);
    if (attr == NULL) {
      break;
    }

    tokens = g_strsplit (attr, " ", 0);
    if (g_strcmp0 (RTP_HDR_EXT_ABS_SEND_TIME_URI, tokens[1]) == 0) {
      gint ret = atoi (tokens[0]);

      g_strfreev (tokens);
      return ret;
    }

    g_strfreev (tokens);
  }

  return -1;
}
static gboolean
kms_sdp_rtp_avpf_media_handler_filter_rtcp_fb_attrs (KmsSdpMediaHandler *
    handler, const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error)
{
  KmsSdpRtpAvpfMediaHandler *self = KMS_SDP_RTP_AVPF_MEDIA_HANDLER (handler);
  guint i;

  for (i = 0;; i++) {
    const gchar *val;
    gchar **opts;

    val = gst_sdp_media_get_attribute_val_n (offer, SDP_MEDIA_RTCP_FB, i);

    if (val == NULL) {
      return TRUE;
    }

    opts = g_strsplit (val, " ", 0);

    if (!format_supported (answer, opts[0] /* format */ )) {
      /* Ignore rtcp-fb attribute */
      g_strfreev (opts);
      continue;
    }

    if (g_strcmp0 (opts[1] /* rtcp-fb-val */ , SDP_MEDIA_RTCP_FB_NACK) == 0
        && !self->priv->nack) {
      /* ignore rtcp-fb nack attribute */
      g_strfreev (opts);
      continue;
    }

    if (g_strcmp0 (opts[1] /* rtcp-fb-val */ , SDP_MEDIA_RTCP_FB_GOOG_REMB) == 0
        && !self->priv->remb) {
      /* ignore rtcp-fb goog-remb attribute */
      g_strfreev (opts);
      continue;
    }

    if (!supported_rtcp_fb_val (opts[1] /* rtcp-fb-val */ )) {
      /* ignore unsupported rtcp-fb attribute */
      g_strfreev (opts);
      continue;
    }

    if (gst_sdp_media_add_attribute (answer, SDP_MEDIA_RTCP_FB,
            val) != GST_SDP_OK) {
      g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR,
          "Cannot add media attribute 'a=%s:%s'", SDP_MEDIA_RTCP_FB, val);
      g_strfreev (opts);
      return FALSE;
    }

    g_strfreev (opts);
  }

  return TRUE;
}
static gboolean
kms_sdp_rtp_avpf_media_handler_add_rtcp_fb_attrs (KmsSdpMediaHandler * handler,
    GstSDPMedia * media, GError ** error)
{
  const gchar *media_str;
  guint i;

  media_str = gst_sdp_media_get_media (media);

  if (g_strcmp0 (media_str, "video") != 0) {
    /* Only nack video rtcp_fb attributes are supported */
    /* [rfc4585] 4.2                                    */
    return TRUE;
  }

  for (i = 0;; i++) {
    const gchar *val;
    gchar **codec;

    val = gst_sdp_media_get_attribute_val_n (media, "rtpmap", i);

    if (val == NULL) {
      break;
    }

    codec = g_strsplit (val, " ", 0);
    if (!is_supported_encoder (codec[1] /* encoder */ )) {
      g_strfreev (codec);
      continue;
    }

    if (!kms_sdp_rtp_avpf_media_handler_rtcp_fb_attrs (handler, media,
            codec[0] /* format */ ,
            codec[1] /* encoder */ , error)) {
      g_strfreev (codec);
      return FALSE;
    }

    g_strfreev (codec);
  }

  return TRUE;
}
static const gchar *
gst_sdp_get_attribute_for_pt (const GstSDPMedia * media, const gchar * name,
    gint pt)
{
  guint i;

  for (i = 0;; i++) {
    const gchar *attr;
    gint val;

    if ((attr = gst_sdp_media_get_attribute_val_n (media, name, i)) == NULL)
      break;

    if (sscanf (attr, "%d ", &val) != 1)
      continue;

    if (val == pt)
      return attr;
  }
  return NULL;
}
Example #6
0
static gboolean
kms_sdp_sdes_ext_add_answer_attributes (KmsISdpMediaExtension * ext,
    const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error)
{
  GValue key = G_VALUE_INIT;
  gboolean ret = TRUE, supported;
  GArray *keys;
  guint i;

  if ((gst_sdp_media_get_attribute_val (answer, "keymgt")) != NULL) {
    /* rfc4568 [7.5] */
    /* If the answerer supports both "a=crypto" and "a=keymgt", the answer */
    /* MUST include either "a=crypto" or "a=keymgt", but not both.         */
    return TRUE;
  }

  if (answer->key.type != NULL) {
    /* rfc4568: [7.5] */
    /* If the answerer supports both "a=crypto" and "k=", the answer */
    /* MUST include either "a=crypto" or "k=" but not both.          */
    return TRUE;
  }

  keys = g_array_sized_new (FALSE, FALSE, sizeof (GValue), 3);

  /* Sets a function to clear an element of array */
  g_array_set_clear_func (keys, (GDestroyNotify) g_value_unset);

  for (i = 0;; i++) {
    GValue val = G_VALUE_INIT;
    const gchar *attr_val;

    attr_val = gst_sdp_media_get_attribute_val_n (offer, CRYPTO_ATTR, i);

    if (attr_val == NULL) {
      break;
    }

    if (!kms_sdp_sdes_ext_parse_key_attr (ext, attr_val, &val)) {
      if (G_IS_VALUE (&val)) {
        g_value_unset (&val);
      }
      continue;
    }

    g_array_append_val (keys, val);
  }

  if (!ret || keys->len == 0) {
    goto end;
  }

  g_signal_emit (G_OBJECT (ext), obj_signals[SIGNAL_ON_ANSWER_KEYS], 0, keys,
      &key, &supported);

  if (!supported) {
    /* If none of the crypto attributes are valid or none of the valid ones */
    /* are supported, the offered media stream MUST be rejected             */
    GST_WARNING_OBJECT (ext,
        "Rejecting offer because no crypto attributes are supported");
    gst_sdp_media_set_port_info (answer, 0, 1);
    goto end;
  }

  if (!selected_valid_key (keys, &key)) {
    /* Same tag and crypto-suite must be selected in the answer */
    GST_WARNING_OBJECT (ext, "Asnwer key does not match with offered key");
    gst_sdp_media_set_port_info (answer, 0, 1);
  } else {
    ret = kms_sdp_sdes_ext_add_answer_key (ext, answer, &key, error);
  }

  g_value_unset (&key);

end:
  g_array_unref (keys);

  return ret;
}