static GstSDPMedia * reject_media_answer (const GstSDPMedia * offered) { GstSDPMedia *media; const gchar *mid; guint i, len; gst_sdp_media_new (&media); /* [rfc3264] To reject an offered stream, the port number in the */ /* corresponding stream in the answer MUST be set to zero. Any */ /* media formats listed are ignored. */ gst_sdp_media_set_media (media, gst_sdp_media_get_media (offered)); gst_sdp_media_set_port_info (media, 0, 1); gst_sdp_media_set_proto (media, gst_sdp_media_get_proto (offered)); len = gst_sdp_media_formats_len (offered); for (i = 0; i < len; i++) { const gchar *format; format = gst_sdp_media_get_format (offered, i); gst_sdp_media_insert_format (media, i, format); } /* [rfc5888] mid attribute must be present in answer as well */ mid = gst_sdp_media_get_attribute_val (offered, "mid"); if (mid == NULL) { return media; } gst_sdp_media_add_attribute (media, "mid", mid); return media; }
static gboolean accept_fmtp_attribute (const GstSDPMedia * offer, const GstSDPAttribute * attr, GstSDPMedia * media, SdpMessageContext * ctx) { guint i, len; gchar **fmtp; gboolean ret = FALSE; fmtp = g_strsplit (attr->value, " ", 0); /* Check that answer supports this format */ len = gst_sdp_media_formats_len (media); for (i = 0; i < len; i++) { const gchar *fmt; fmt = gst_sdp_media_get_format (media, i); if (g_strcmp0 (fmt, fmtp[0] /* format */ ) == 0) { ret = TRUE; break; } } g_strfreev (fmtp); return ret; }
GST_END_TEST GST_START_TEST (media_from_caps) { GstSDPResult ret = GST_SDP_OK; GstSDPMessage *message; glong length = -1; GstSDPMedia *media_video, *media_audio; const GstSDPMedia *result_video, *result_audio; GstCaps *caps_video, *caps_audio; const gchar *media1_text, *media2_text, *media3_text, *media4_text; caps_video = gst_caps_from_string (caps_video_string1); caps_audio = gst_caps_from_string (caps_audio_string); gst_sdp_media_new (&media_video); fail_unless (media_video != NULL); gst_sdp_media_new (&media_audio); fail_unless (media_audio != NULL); ret = gst_sdp_media_set_media_from_caps (caps_video, media_video); fail_unless (ret == GST_SDP_OK); gst_caps_unref (caps_video); ret = gst_sdp_media_set_media_from_caps (caps_audio, media_audio); fail_unless (ret == GST_SDP_OK); gst_caps_unref (caps_audio); gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message); result_video = gst_sdp_message_get_media (message, 0); fail_unless (result_video != NULL); result_audio = gst_sdp_message_get_media (message, 2); fail_unless (result_audio != NULL); media1_text = gst_sdp_media_get_attribute_val (media_video, "rtpmap"); media2_text = gst_sdp_media_get_attribute_val (result_video, "rtpmap"); media3_text = gst_sdp_media_get_format (media_audio, 0); media4_text = gst_sdp_media_get_format (result_audio, 0); fail_if (g_strcmp0 (media1_text, media2_text) != 0); fail_if (g_strcmp0 (media3_text, media4_text) != 0); gst_sdp_media_free (media_video); gst_sdp_media_free (media_audio); gst_sdp_message_free (message); }
static gboolean format_supported (const GstSDPMedia * media, const gchar * fmt) { guint i, len; len = gst_sdp_media_formats_len (media); for (i = 0; i < len; i++) { const gchar *format; format = gst_sdp_media_get_format (media, i); if (g_strcmp0 (format, fmt) == 0) { return TRUE; } } return FALSE; }
static gboolean kms_sdp_reject_media_handler_init_answer (KmsSdpMediaHandler * handler, const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error) { guint i, len; if (gst_sdp_media_set_media (answer, gst_sdp_media_get_media (offer)) != GST_SDP_OK) { g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set '%s' media ttribute", gst_sdp_media_get_media (offer)); return FALSE; } if (gst_sdp_media_set_proto (answer, gst_sdp_media_get_proto (offer)) != GST_SDP_OK) { g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set proto '%s' attribute", gst_sdp_media_get_proto (offer)); return FALSE; } if (gst_sdp_media_set_port_info (answer, 0, 1) != GST_SDP_OK) { g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set port info attribute"); return FALSE; } len = gst_sdp_media_formats_len (offer); for (i = 0; i < len; i++) { const gchar *format; format = gst_sdp_media_get_format (offer, i); gst_sdp_media_insert_format (answer, i, format); } return TRUE; }
static GstSDPStream * gst_sdp_demux_create_stream (GstSDPDemux * demux, GstSDPMessage * sdp, gint idx) { GstSDPStream *stream; const gchar *payload, *rtcp; const GstSDPMedia *media; const GstSDPConnection *conn; /* get media, should not return NULL */ media = gst_sdp_message_get_media (sdp, idx); if (media == NULL) return NULL; stream = g_new0 (GstSDPStream, 1); stream->parent = demux; /* we mark the pad as not linked, we will mark it as OK when we add the pad to * the element. */ stream->last_ret = GST_FLOW_OK; stream->added = FALSE; stream->disabled = FALSE; stream->id = demux->numstreams++; stream->eos = FALSE; /* we must have a payload. No payload means we cannot create caps */ /* FIXME, handle multiple formats. */ if ((payload = gst_sdp_media_get_format (media, 0))) { stream->pt = atoi (payload); /* convert caps */ stream->caps = gst_sdp_demux_media_to_caps (stream->pt, media); if (stream->pt >= 96) { /* If we have a dynamic payload type, see if we have a stream with the * same payload number. If there is one, they are part of the same * container and we only need to add one pad. */ if (find_stream (demux, GINT_TO_POINTER (stream->pt), (gpointer) find_stream_by_pt)) { stream->container = TRUE; } } } if (!(conn = gst_sdp_media_get_connection (media, 0))) { if (!(conn = gst_sdp_message_get_connection (sdp))) goto no_connection; } stream->destination = conn->address; stream->ttl = conn->ttl; stream->multicast = is_multicast_address (stream->destination); stream->rtp_port = gst_sdp_media_get_port (media); if ((rtcp = gst_sdp_media_get_attribute_val (media, "rtcp"))) { /* FIXME, RFC 3605 */ stream->rtcp_port = stream->rtp_port + 1; } else { stream->rtcp_port = stream->rtp_port + 1; } GST_DEBUG_OBJECT (demux, "stream %d, (%p)", stream->id, stream); GST_DEBUG_OBJECT (demux, " pt: %d", stream->pt); GST_DEBUG_OBJECT (demux, " container: %d", stream->container); GST_DEBUG_OBJECT (demux, " caps: %" GST_PTR_FORMAT, stream->caps); /* we keep track of all streams */ demux->streams = g_list_append (demux->streams, stream); return stream; /* ERRORS */ no_connection: { gst_sdp_demux_stream_free (demux, stream); return NULL; } }