static gboolean kms_webrtc_session_local_sdp_add_default_info (KmsWebrtcSession * self) { KmsSdpSession *sdp_sess = KMS_SDP_SESSION (self); SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx; const GstSDPMessage *sdp = kms_sdp_message_context_get_sdp_message (local_sdp_ctx); const GSList *item = kms_sdp_message_context_get_medias (local_sdp_ctx); gboolean use_ipv6; GstSDPConnection *conn; conn = (GstSDPConnection *) gst_sdp_message_get_connection (sdp); gst_sdp_connection_clear (conn); use_ipv6 = kms_sdp_session_get_use_ipv6 (sdp_sess); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *mconf = item->data; if (kms_sdp_media_config_is_inactive (mconf)) { gint mid = kms_sdp_media_config_get_id (mconf); GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", mid); continue; } if (!kms_webrtc_session_sdp_media_add_default_info (self, mconf, use_ipv6)) { return FALSE; } } return TRUE; }
static void kms_rtp_endpoint_start_transport_send (KmsBaseSdpEndpoint * base_sdp_endpoint, gboolean offerer) { KmsRtpEndpoint *self = KMS_RTP_ENDPOINT (base_sdp_endpoint); SdpMessageContext *remote_ctx = kms_base_sdp_endpoint_get_remote_sdp_ctx (base_sdp_endpoint); const GstSDPMessage *sdp = kms_sdp_message_context_get_sdp_message (remote_ctx); const GSList *item = kms_sdp_message_context_get_medias (remote_ctx); const GstSDPConnection *msg_conn = gst_sdp_message_get_connection (sdp); /* Chain up */ KMS_BASE_SDP_ENDPOINT_CLASS (parent_class)->start_transport_send (base_sdp_endpoint, offerer); for (; item != NULL; item = g_slist_next (item)) { SdpMediaConfig *mconf = item->data; GstSDPMedia *media = kms_sdp_media_config_get_sdp_media (mconf); const GstSDPConnection *media_con; KmsRtpBaseConnection *conn; guint port; if (media->port == 0) { continue; } if (gst_sdp_media_connections_len (media) != 0) { media_con = gst_sdp_media_get_connection (media, 0); } else { media_con = msg_conn; } if (media_con == NULL || media_con->address == NULL || media_con->address[0] == '\0') { const gchar *media_str = gst_sdp_media_get_media (media); GST_WARNING_OBJECT (self, "Missing connection information for '%s'", media_str); continue; } conn = kms_rtp_endpoint_media_get_connection (self, mconf); if (conn == NULL) { continue; } port = gst_sdp_media_get_port (media); kms_rtp_base_connection_set_remote_info (conn, media_con->address, port, port + 1); /* TODO: get rtcp port from attr if it exists */ } }
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; } }
GST_END_TEST GST_START_TEST (negotiation_offerer) { GArray *audio_codecs_array, *video_codecs_array; gchar *audio_codecs[] = { "OPUS/48000/1", "AMR/8000/1", NULL }; gchar *video_codecs[] = { "H263-1998/90000", "VP8/90000", NULL }; gchar *offerer_sess_id, *answerer_sess_id; GstElement *offerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *answerer = gst_element_factory_make ("rtpendpoint", NULL); GstSDPMessage *offer = NULL, *answer = NULL; GstSDPMessage *offerer_local_sdp = NULL, *offerer_remote_sdp = NULL; gchar *offerer_local_sdp_str, *offerer_remote_sdp_str; GstSDPMessage *answerer_local_sdp = NULL, *answerer_remote_sdp = NULL; gchar *answerer_local_sdp_str, *answerer_remote_sdp_str; gchar *sdp_str = NULL; const GstSDPConnection *connection; gboolean answer_ok; audio_codecs_array = create_codecs_array (audio_codecs); video_codecs_array = create_codecs_array (video_codecs); g_object_set (offerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_object_set (answerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_array_unref (audio_codecs_array); g_array_unref (video_codecs_array); /* Session creation */ g_signal_emit_by_name (offerer, "create-session", &offerer_sess_id); GST_DEBUG_OBJECT (offerer, "Created session with id '%s'", offerer_sess_id); g_signal_emit_by_name (answerer, "create-session", &answerer_sess_id); GST_DEBUG_OBJECT (answerer, "Created session with id '%s'", answerer_sess_id); /* SDP negotiation */ g_signal_emit_by_name (offerer, "generate-offer", offerer_sess_id, &offer); fail_unless (offer != NULL); GST_DEBUG ("Offer:\n%s", (sdp_str = gst_sdp_message_as_text (offer))); g_free (sdp_str); sdp_str = NULL; connection = gst_sdp_message_get_connection (offer); fail_unless (g_strcmp0 (connection->address, "0.0.0.0")); fail_unless (g_strcmp0 (connection->address, "::")); g_signal_emit_by_name (answerer, "process-offer", answerer_sess_id, offer, &answer); fail_unless (answer != NULL); GST_DEBUG ("Answer:\n%s", (sdp_str = gst_sdp_message_as_text (answer))); g_free (sdp_str); sdp_str = NULL; g_signal_emit_by_name (offerer, "process-answer", offerer_sess_id, answer, &answer_ok); fail_unless (answer_ok); gst_sdp_message_free (offer); gst_sdp_message_free (answer); g_signal_emit_by_name (offerer, "get-local-sdp", offerer_sess_id, &offerer_local_sdp); fail_unless (offerer_local_sdp != NULL); g_signal_emit_by_name (offerer, "get-remote-sdp", offerer_sess_id, &offerer_remote_sdp); fail_unless (offerer_remote_sdp != NULL); g_signal_emit_by_name (answerer, "get-local-sdp", answerer_sess_id, &answerer_local_sdp); fail_unless (answerer_local_sdp != NULL); g_signal_emit_by_name (answerer, "get-remote-sdp", answerer_sess_id, &answerer_remote_sdp); fail_unless (answerer_remote_sdp != NULL); offerer_local_sdp_str = gst_sdp_message_as_text (offerer_local_sdp); offerer_remote_sdp_str = gst_sdp_message_as_text (offerer_remote_sdp); answerer_local_sdp_str = gst_sdp_message_as_text (answerer_local_sdp); answerer_remote_sdp_str = gst_sdp_message_as_text (answerer_remote_sdp); GST_DEBUG ("Offerer local SDP\n%s", offerer_local_sdp_str); GST_DEBUG ("Offerer remote SDPr\n%s", offerer_remote_sdp_str); GST_DEBUG ("Answerer local SDP\n%s", answerer_local_sdp_str); GST_DEBUG ("Answerer remote SDP\n%s", answerer_remote_sdp_str); fail_unless (g_strcmp0 (offerer_local_sdp_str, answerer_remote_sdp_str) == 0); fail_unless (g_strcmp0 (offerer_remote_sdp_str, answerer_local_sdp_str) == 0); g_free (offerer_local_sdp_str); g_free (offerer_remote_sdp_str); g_free (answerer_local_sdp_str); g_free (answerer_remote_sdp_str); gst_sdp_message_free (offerer_local_sdp); gst_sdp_message_free (offerer_remote_sdp); gst_sdp_message_free (answerer_local_sdp); gst_sdp_message_free (answerer_remote_sdp); g_object_unref (offerer); g_object_unref (answerer); g_free (offerer_sess_id); g_free (answerer_sess_id); }