From 5ecca0bb22c73ba4a59b66417e474944fd867d3a Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 16:07:57 +1100 Subject: [PATCH 1/5] webrtc: move some functions to the appropriate files --- ext/webrtc/gstwebrtcbin.c | 220 +++------------------------------ ext/webrtc/transportstream.c | 35 ++++++ ext/webrtc/transportstream.h | 4 + ext/webrtc/webrtcsdp.c | 124 +++++++++++++++++++ ext/webrtc/webrtcsdp.h | 17 +++ ext/webrtc/webrtctransceiver.c | 28 +++++ ext/webrtc/webrtctransceiver.h | 3 + 7 files changed, 230 insertions(+), 201 deletions(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 77a8e98e75..6f137502fc 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -216,41 +216,6 @@ gst_webrtc_bin_pad_class_init (GstWebRTCBinPadClass * klass) gobject_class->finalize = gst_webrtc_bin_pad_finalize; } -static GstCaps * -_transport_stream_get_caps_for_pt (TransportStream * stream, guint pt) -{ - guint i, len; - - len = stream->ptmap->len; - for (i = 0; i < len; i++) { - PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i); - if (item->pt == pt) - return item->caps; - } - return NULL; -} - -static gint -_transport_stream_get_pt (TransportStream * stream, const gchar * encoding_name) -{ - guint i; - gint ret = 0; - - for (i = 0; i < stream->ptmap->len; i++) { - PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i); - if (!gst_caps_is_empty (item->caps)) { - GstStructure *s = gst_caps_get_structure (item->caps, 0); - if (!g_strcmp0 (gst_structure_get_string (s, "encoding-name"), - encoding_name)) { - ret = item->pt; - break; - } - } - } - - return ret; -} - static gboolean gst_webrtcbin_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { @@ -356,30 +321,6 @@ enum static guint gst_webrtc_bin_signals[LAST_SIGNAL] = { 0 }; -static GstWebRTCDTLSTransport * -_transceiver_get_transport (GstWebRTCRTPTransceiver * trans) -{ - if (trans->sender) { - return trans->sender->transport; - } else if (trans->receiver) { - return trans->receiver->transport; - } - - return NULL; -} - -static GstWebRTCDTLSTransport * -_transceiver_get_rtcp_transport (GstWebRTCRTPTransceiver * trans) -{ - if (trans->sender) { - return trans->sender->rtcp_transport; - } else if (trans->receiver) { - return trans->receiver->rtcp_transport; - } - - return NULL; -} - typedef struct { guint session_id; @@ -827,7 +768,7 @@ _collate_ice_connection_states (GstWebRTCBin * webrtc) g_object_get (stream, "rtcp-mux", &rtcp_mux, NULL); - transport = _transceiver_get_transport (rtp_trans)->transport; + transport = webrtc_transceiver_get_dtls_transport (rtp_trans)->transport; /* get transport state */ g_object_get (transport, "state", &ice_state, NULL); @@ -835,7 +776,8 @@ _collate_ice_connection_states (GstWebRTCBin * webrtc) if (ice_state != STATE (CLOSED)) all_closed = FALSE; - rtcp_transport = _transceiver_get_rtcp_transport (rtp_trans)->transport; + rtcp_transport = + webrtc_transceiver_get_rtcp_dtls_transport (rtp_trans)->transport; if (!rtcp_mux && rtcp_transport && transport != rtcp_transport) { g_object_get (rtcp_transport, "state", &ice_state, NULL); @@ -921,7 +863,7 @@ _collate_ice_gathering_states (GstWebRTCBin * webrtc) g_object_get (stream, "rtcp-mux", &rtcp_mux, NULL); - transport = _transceiver_get_transport (rtp_trans)->transport; + transport = webrtc_transceiver_get_dtls_transport (rtp_trans)->transport; /* get gathering state */ g_object_get (transport, "gathering-state", &ice_state, NULL); @@ -929,7 +871,8 @@ _collate_ice_gathering_states (GstWebRTCBin * webrtc) if (ice_state != STATE (COMPLETE)) all_completed = FALSE; - rtcp_transport = _transceiver_get_rtcp_transport (rtp_trans)->transport; + rtcp_transport = + webrtc_transceiver_get_rtcp_dtls_transport (rtp_trans)->transport; if (!rtcp_mux && rtcp_transport && rtcp_transport != transport) { g_object_get (rtcp_transport, "gathering-state", &ice_state, NULL); @@ -988,7 +931,7 @@ _collate_peer_connection_states (GstWebRTCBin * webrtc) continue; g_object_get (stream, "rtcp-mux", &rtcp_mux, NULL); - transport = _transceiver_get_transport (rtp_trans); + transport = webrtc_transceiver_get_dtls_transport (rtp_trans); /* get transport state */ g_object_get (transport, "state", &dtls_state, NULL); @@ -996,7 +939,7 @@ _collate_peer_connection_states (GstWebRTCBin * webrtc) g_object_get (transport->transport, "state", &ice_state, NULL); any_ice_state |= (1 << ice_state); - rtcp_transport = _transceiver_get_rtcp_transport (rtp_trans); + rtcp_transport = webrtc_transceiver_get_rtcp_dtls_transport (rtp_trans); if (!rtcp_mux && rtcp_transport && rtcp_transport != transport) { g_object_get (rtcp_transport, "state", &dtls_state, NULL); @@ -1516,32 +1459,6 @@ _create_transport_channel (GstWebRTCBin * webrtc, guint session_id) return ret; } -static gboolean -_message_media_is_datachannel (const GstSDPMessage * msg, guint media_id) -{ - const GstSDPMedia *media; - - if (!msg) - return FALSE; - - if (gst_sdp_message_medias_len (msg) <= media_id) - return FALSE; - - media = gst_sdp_message_get_media (msg, media_id); - - if (g_strcmp0 (gst_sdp_media_get_media (media), "application") != 0) - return FALSE; - - if (gst_sdp_media_formats_len (media) != 1) - return FALSE; - - if (g_strcmp0 (gst_sdp_media_get_format (media, 0), - "webrtc-datachannel") != 0) - return FALSE; - - return TRUE; -} - static TransportStream * _get_or_create_rtp_transport_channel (GstWebRTCBin * webrtc, guint session_id) { @@ -2423,54 +2340,6 @@ _get_rtx_target_pt_and_ssrc_from_caps (GstCaps * answer_caps, gint * target_pt, gst_structure_get_uint (s, "ssrc", target_ssrc); } -static gboolean -_parse_bundle (GstWebRTCBin * webrtc, GstSDPMessage * sdp, GStrv * bundled) -{ - const gchar *group; - gboolean ret = FALSE; - - group = gst_sdp_message_get_attribute_val (sdp, "group"); - - if (group && g_str_has_prefix (group, "BUNDLE ")) { - *bundled = g_strsplit (group + strlen ("BUNDLE "), " ", 0); - - if (!(*bundled)[0]) { - GST_ERROR_OBJECT (webrtc, - "Invalid format for BUNDLE group, expected at least one mid (%s)", - group); - goto done; - } - } else { - ret = TRUE; - goto done; - } - - ret = TRUE; - -done: - return ret; -} - -static gboolean -_get_bundle_index (GstSDPMessage * sdp, GStrv bundled, guint * idx) -{ - gboolean ret = FALSE; - guint i; - - for (i = 0; i < gst_sdp_message_medias_len (sdp); i++) { - const GstSDPMedia *media = gst_sdp_message_get_media (sdp, i); - const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid"); - - if (!g_strcmp0 (mid, bundled[0])) { - *idx = i; - ret = TRUE; - break; - } - } - - return ret; -} - /* TODO: use the options argument */ static GstSDPMessage * _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) @@ -2491,7 +2360,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) return NULL; } - if (!_parse_bundle (webrtc, pending_remote->sdp, &bundled)) + if (!_parse_bundle (pending_remote->sdp, &bundled)) goto out; if (bundled) { @@ -3520,7 +3389,7 @@ _update_transceivers_from_sdp (GstWebRTCBin * webrtc, SDPSource source, gboolean should_connect_bundle_stream = FALSE; TransportStream *bundle_stream = NULL; - if (!_parse_bundle (webrtc, sdp->sdp, &bundled)) + if (!_parse_bundle (sdp->sdp, &bundled)) goto done; if (bundled) { @@ -3607,57 +3476,6 @@ done: return ret; } -static void -_get_ice_credentials_from_sdp_media (const GstSDPMessage * sdp, guint media_idx, - gchar ** ufrag, gchar ** pwd) -{ - int i; - - *ufrag = NULL; - *pwd = NULL; - - { - /* search in the corresponding media section */ - const GstSDPMedia *media = gst_sdp_message_get_media (sdp, media_idx); - const gchar *tmp_ufrag = - gst_sdp_media_get_attribute_val (media, "ice-ufrag"); - const gchar *tmp_pwd = gst_sdp_media_get_attribute_val (media, "ice-pwd"); - if (tmp_ufrag && tmp_pwd) { - *ufrag = g_strdup (tmp_ufrag); - *pwd = g_strdup (tmp_pwd); - return; - } - } - - /* then in the sdp message itself */ - for (i = 0; i < gst_sdp_message_attributes_len (sdp); i++) { - const GstSDPAttribute *attr = gst_sdp_message_get_attribute (sdp, i); - - if (g_strcmp0 (attr->key, "ice-ufrag") == 0) { - g_assert (!*ufrag); - *ufrag = g_strdup (attr->value); - } else if (g_strcmp0 (attr->key, "ice-pwd") == 0) { - g_assert (!*pwd); - *pwd = g_strdup (attr->value); - } - } - if (!*ufrag && !*pwd) { - /* Check in the medias themselves. According to JSEP, they should be - * identical FIXME: only for bundle-d streams */ - for (i = 0; i < gst_sdp_message_medias_len (sdp); i++) { - const GstSDPMedia *media = gst_sdp_message_get_media (sdp, i); - const gchar *tmp_ufrag = - gst_sdp_media_get_attribute_val (media, "ice-ufrag"); - const gchar *tmp_pwd = gst_sdp_media_get_attribute_val (media, "ice-pwd"); - if (tmp_ufrag && tmp_pwd) { - *ufrag = g_strdup (tmp_ufrag); - *pwd = g_strdup (tmp_pwd); - break; - } - } - } -} - struct set_description { GstPromise *promise; @@ -3700,7 +3518,7 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd) goto out; } - if (!_parse_bundle (webrtc, sd->sdp->sdp, &bundled)) + if (!_parse_bundle (sd->sdp->sdp, &bundled)) goto out; if (bundled) { @@ -4432,7 +4250,7 @@ on_rtpbin_request_pt_map (GstElement * rtpbin, guint session_id, guint pt, if (!stream) goto unknown_session; - if ((ret = _transport_stream_get_caps_for_pt (stream, pt))) + if ((ret = transport_stream_get_caps_for_pt (stream, pt))) gst_caps_ref (ret); GST_TRACE_OBJECT (webrtc, "Found caps %" GST_PTR_FORMAT " for pt %d in " @@ -4530,15 +4348,15 @@ on_rtpbin_request_aux_receiver (GstElement * rtpbin, guint session_id, stream = _find_transport_for_session (webrtc, session_id); if (stream) { - red_pt = _transport_stream_get_pt (stream, "RED"); - rtx_pt = _transport_stream_get_pt (stream, "RTX"); + red_pt = transport_stream_get_pt (stream, "RED"); + rtx_pt = transport_stream_get_pt (stream, "RTX"); } if (red_pt || rtx_pt) ret = gst_bin_new (NULL); if (rtx_pt) { - GstCaps *rtx_caps = _transport_stream_get_caps_for_pt (stream, rtx_pt); + GstCaps *rtx_caps = transport_stream_get_caps_for_pt (stream, rtx_pt); GstElement *rtx = gst_element_factory_make ("rtprtxreceive", NULL); GstStructure *pt_map; const GstStructure *s = gst_caps_get_structure (rtx_caps, 0); @@ -4615,7 +4433,7 @@ on_rtpbin_request_fec_decoder (GstElement * rtpbin, guint session_id, * example) */ if (stream) - pt = _transport_stream_get_pt (stream, "ULPFEC"); + pt = transport_stream_get_pt (stream, "ULPFEC"); if (pt) { GST_DEBUG_OBJECT (webrtc, "Creating ULPFEC decoder for pt %d in session %u", @@ -4648,8 +4466,8 @@ on_rtpbin_request_fec_encoder (GstElement * rtpbin, guint session_id, (FindTransceiverFunc) transceiver_match_for_mline); if (stream) { - ulpfec_pt = _transport_stream_get_pt (stream, "ULPFEC"); - red_pt = _transport_stream_get_pt (stream, "RED"); + ulpfec_pt = transport_stream_get_pt (stream, "ULPFEC"); + red_pt = transport_stream_get_pt (stream, "RED"); } if (ulpfec_pt || red_pt) @@ -4657,7 +4475,7 @@ on_rtpbin_request_fec_encoder (GstElement * rtpbin, guint session_id, if (ulpfec_pt) { GstElement *fecenc = gst_element_factory_make ("rtpulpfecenc", NULL); - GstCaps *caps = _transport_stream_get_caps_for_pt (stream, ulpfec_pt); + GstCaps *caps = transport_stream_get_caps_for_pt (stream, ulpfec_pt); GST_DEBUG_OBJECT (webrtc, "Creating ULPFEC encoder for session %d with pt %d", session_id, diff --git a/ext/webrtc/transportstream.c b/ext/webrtc/transportstream.c index 87a2a78ae7..01fa2dc919 100644 --- a/ext/webrtc/transportstream.c +++ b/ext/webrtc/transportstream.c @@ -40,6 +40,41 @@ enum PROP_DTLS_CLIENT, }; +GstCaps * +transport_stream_get_caps_for_pt (TransportStream * stream, guint pt) +{ + guint i, len; + + len = stream->ptmap->len; + for (i = 0; i < len; i++) { + PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i); + if (item->pt == pt) + return item->caps; + } + return NULL; +} + +int +transport_stream_get_pt (TransportStream * stream, const gchar * encoding_name) +{ + guint i; + gint ret = 0; + + for (i = 0; i < stream->ptmap->len; i++) { + PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i); + if (!gst_caps_is_empty (item->caps)) { + GstStructure *s = gst_caps_get_structure (item->caps, 0); + if (!g_strcmp0 (gst_structure_get_string (s, "encoding-name"), + encoding_name)) { + ret = item->pt; + break; + } + } + } + + return ret; +} + static void transport_stream_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) diff --git a/ext/webrtc/transportstream.h b/ext/webrtc/transportstream.h index 5728176a99..8b90a946ab 100644 --- a/ext/webrtc/transportstream.h +++ b/ext/webrtc/transportstream.h @@ -70,6 +70,10 @@ struct _TransportStreamClass TransportStream * transport_stream_new (GstWebRTCBin * webrtc, guint session_id); +int transport_stream_get_pt (TransportStream * stream, + const gchar * encoding_name); +GstCaps * transport_stream_get_caps_for_pt (TransportStream * stream, + guint pt); G_END_DECLS diff --git a/ext/webrtc/webrtcsdp.c b/ext/webrtc/webrtcsdp.c index 5d1b43c730..7269ada27a 100644 --- a/ext/webrtc/webrtcsdp.c +++ b/ext/webrtc/webrtcsdp.c @@ -736,3 +736,127 @@ _get_sctp_max_message_size_from_media (const GstSDPMedia * media) return 65536; } + +gboolean +_message_media_is_datachannel (const GstSDPMessage * msg, guint media_id) +{ + const GstSDPMedia *media; + + if (!msg) + return FALSE; + + if (gst_sdp_message_medias_len (msg) <= media_id) + return FALSE; + + media = gst_sdp_message_get_media (msg, media_id); + + if (g_strcmp0 (gst_sdp_media_get_media (media), "application") != 0) + return FALSE; + + if (gst_sdp_media_formats_len (media) != 1) + return FALSE; + + if (g_strcmp0 (gst_sdp_media_get_format (media, 0), + "webrtc-datachannel") != 0) + return FALSE; + + return TRUE; +} + +void +_get_ice_credentials_from_sdp_media (const GstSDPMessage * sdp, guint media_idx, + gchar ** ufrag, gchar ** pwd) +{ + int i; + + *ufrag = NULL; + *pwd = NULL; + + { + /* search in the corresponding media section */ + const GstSDPMedia *media = gst_sdp_message_get_media (sdp, media_idx); + const gchar *tmp_ufrag = + gst_sdp_media_get_attribute_val (media, "ice-ufrag"); + const gchar *tmp_pwd = gst_sdp_media_get_attribute_val (media, "ice-pwd"); + if (tmp_ufrag && tmp_pwd) { + *ufrag = g_strdup (tmp_ufrag); + *pwd = g_strdup (tmp_pwd); + return; + } + } + + /* then in the sdp message itself */ + for (i = 0; i < gst_sdp_message_attributes_len (sdp); i++) { + const GstSDPAttribute *attr = gst_sdp_message_get_attribute (sdp, i); + + if (g_strcmp0 (attr->key, "ice-ufrag") == 0) { + g_assert (!*ufrag); + *ufrag = g_strdup (attr->value); + } else if (g_strcmp0 (attr->key, "ice-pwd") == 0) { + g_assert (!*pwd); + *pwd = g_strdup (attr->value); + } + } + if (!*ufrag && !*pwd) { + /* Check in the medias themselves. According to JSEP, they should be + * identical FIXME: only for bundle-d streams */ + for (i = 0; i < gst_sdp_message_medias_len (sdp); i++) { + const GstSDPMedia *media = gst_sdp_message_get_media (sdp, i); + const gchar *tmp_ufrag = + gst_sdp_media_get_attribute_val (media, "ice-ufrag"); + const gchar *tmp_pwd = gst_sdp_media_get_attribute_val (media, "ice-pwd"); + if (tmp_ufrag && tmp_pwd) { + *ufrag = g_strdup (tmp_ufrag); + *pwd = g_strdup (tmp_pwd); + break; + } + } + } +} + +gboolean +_parse_bundle (GstSDPMessage * sdp, GStrv * bundled) +{ + const gchar *group; + gboolean ret = FALSE; + + group = gst_sdp_message_get_attribute_val (sdp, "group"); + + if (group && g_str_has_prefix (group, "BUNDLE ")) { + *bundled = g_strsplit (group + strlen ("BUNDLE "), " ", 0); + + if (!(*bundled)[0]) { + GST_ERROR ("Invalid format for BUNDLE group, expected at least " + "one mid (%s)", group); + goto done; + } + } else { + ret = TRUE; + goto done; + } + + ret = TRUE; + +done: + return ret; +} + +gboolean +_get_bundle_index (GstSDPMessage * sdp, GStrv bundled, guint * idx) +{ + gboolean ret = FALSE; + guint i; + + for (i = 0; i < gst_sdp_message_medias_len (sdp); i++) { + const GstSDPMedia *media = gst_sdp_message_get_media (sdp, i); + const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid"); + + if (!g_strcmp0 (mid, bundled[0])) { + *idx = i; + ret = TRUE; + break; + } + } + + return ret; +} diff --git a/ext/webrtc/webrtcsdp.h b/ext/webrtc/webrtcsdp.h index d5ea777b35..15a8e92702 100644 --- a/ext/webrtc/webrtcsdp.h +++ b/ext/webrtc/webrtcsdp.h @@ -81,4 +81,21 @@ int _get_sctp_port_from_media (con G_GNUC_INTERNAL guint64 _get_sctp_max_message_size_from_media (const GstSDPMedia * media); +G_GNUC_INTERNAL +void _get_ice_credentials_from_sdp_media (const GstSDPMessage * sdp, + guint media_idx, + gchar ** ufrag, + gchar ** pwd); +G_GNUC_INTERNAL +gboolean _message_media_is_datachannel (const GstSDPMessage * msg, + guint media_id); + +G_GNUC_INTERNAL +gboolean _get_bundle_index (GstSDPMessage * sdp, + GStrv bundled, + guint * idx); +G_GNUC_INTERNAL +gboolean _parse_bundle (GstSDPMessage * sdp, + GStrv * bundled); + #endif /* __WEBRTC_UTILS_H__ */ diff --git a/ext/webrtc/webrtctransceiver.c b/ext/webrtc/webrtctransceiver.c index 1735b1a8aa..c1a3faa1c2 100644 --- a/ext/webrtc/webrtctransceiver.c +++ b/ext/webrtc/webrtctransceiver.c @@ -69,6 +69,34 @@ webrtc_transceiver_set_transport (WebRTCTransceiver * trans, (GstObject *) stream->rtcp_transport); } +GstWebRTCDTLSTransport * +webrtc_transceiver_get_dtls_transport (GstWebRTCRTPTransceiver * trans) +{ + g_return_val_if_fail (WEBRTC_IS_TRANSCEIVER (trans), NULL); + + if (trans->sender) { + return trans->sender->transport; + } else if (trans->receiver) { + return trans->receiver->transport; + } + + return NULL; +} + +GstWebRTCDTLSTransport * +webrtc_transceiver_get_rtcp_dtls_transport (GstWebRTCRTPTransceiver * trans) +{ + g_return_val_if_fail (WEBRTC_IS_TRANSCEIVER (trans), NULL); + + if (trans->sender) { + return trans->sender->rtcp_transport; + } else if (trans->receiver) { + return trans->receiver->rtcp_transport; + } + + return NULL; +} + static void webrtc_transceiver_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) diff --git a/ext/webrtc/webrtctransceiver.h b/ext/webrtc/webrtctransceiver.h index 25bb24e821..f1e338f66d 100644 --- a/ext/webrtc/webrtctransceiver.h +++ b/ext/webrtc/webrtctransceiver.h @@ -58,6 +58,9 @@ WebRTCTransceiver * webrtc_transceiver_new (GstWebRTCBin * webr void webrtc_transceiver_set_transport (WebRTCTransceiver * trans, TransportStream * stream); +GstWebRTCDTLSTransport * webrtc_transceiver_get_dtls_transport (GstWebRTCRTPTransceiver * trans); +GstWebRTCDTLSTransport * webrtc_transceiver_get_rtcp_dtls_transport (GstWebRTCRTPTransceiver * trans); + G_END_DECLS #endif /* __WEBRTC_TRANSCEIVER_H__ */ -- GitLab From 3a2566c61feb57aeea0c4f65e7ddb93a32988302 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 16:12:03 +1100 Subject: [PATCH 2/5] webrtc: remove extra 'pad' from log line --- ext/webrtc/gstwebrtcbin.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 6f137502fc..957ae422f5 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -265,8 +265,7 @@ gst_webrtc_bin_pad_new (const gchar * name, GstPadDirection direction) G_DEFINE_TYPE_WITH_CODE (GstWebRTCBin, gst_webrtc_bin, GST_TYPE_BIN, G_ADD_PRIVATE (GstWebRTCBin) GST_DEBUG_CATEGORY_INIT (gst_webrtc_bin_debug, "webrtcbin", 0, - "webrtcbin element"); - ); + "webrtcbin element");); static GstPad *_connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad); @@ -3149,8 +3148,7 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc, gst_object_unref (pad); } else { GST_DEBUG_OBJECT (webrtc, - "creating new pad send pad for transceiver %" GST_PTR_FORMAT, - trans); + "creating new send pad for transceiver %" GST_PTR_FORMAT, trans); pad = _create_pad_for_sdp_media (webrtc, GST_PAD_SINK, media_idx); pad->trans = gst_object_ref (rtp_trans); _connect_input_stream (webrtc, pad); -- GitLab From 6f91a191de3d3edf7217c78210f12fac0563e619 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 16:20:02 +1100 Subject: [PATCH 3/5] webrtcbin: factor out dtls fingerprint setting --- ext/webrtc/gstwebrtcbin.c | 94 ++++++++++++--------------------------- 1 file changed, 28 insertions(+), 66 deletions(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 957ae422f5..fd0fdbc4c1 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -265,7 +265,8 @@ gst_webrtc_bin_pad_new (const gchar * name, GstPadDirection direction) G_DEFINE_TYPE_WITH_CODE (GstWebRTCBin, gst_webrtc_bin, GST_TYPE_BIN, G_ADD_PRIVATE (GstWebRTCBin) GST_DEBUG_CATEGORY_INIT (gst_webrtc_bin_debug, "webrtcbin", 0, - "webrtcbin element");); + "webrtcbin element"); + ); static GstPad *_connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad); @@ -1911,6 +1912,26 @@ _media_add_ssrcs (GstSDPMedia * media, GstCaps * caps, GstWebRTCBin * webrtc, (GstStructureForeachFunc) _media_add_rtx_ssrc, &data); } +static void +_add_fingerprint_to_media (GstWebRTCDTLSTransport * transport, + GstSDPMedia * media) +{ + gchar *cert, *fingerprint, *val; + + g_object_get (transport, "certificate", &cert, NULL); + + fingerprint = + _generate_fingerprint_from_certificate (cert, G_CHECKSUM_SHA256); + g_free (cert); + val = + g_strdup_printf ("%s %s", + _g_checksum_to_webrtc_string (G_CHECKSUM_SHA256), fingerprint); + g_free (fingerprint); + + gst_sdp_media_add_attribute (media, "fingerprint", val); + g_free (val); +} + /* based off https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-18#section-5.2.1 */ static gboolean sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media, @@ -2035,8 +2056,6 @@ sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media, g_free (sdp_mid); if (trans->sender) { - gchar *cert, *fingerprint, *val; - if (!trans->sender->transport) { TransportStream *item; @@ -2047,18 +2066,7 @@ sdp_media_from_transceiver (GstWebRTCBin * webrtc, GstSDPMedia * media, webrtc_transceiver_set_transport (WEBRTC_TRANSCEIVER (trans), item); } - g_object_get (trans->sender->transport, "certificate", &cert, NULL); - - fingerprint = - _generate_fingerprint_from_certificate (cert, G_CHECKSUM_SHA256); - g_free (cert); - val = - g_strdup_printf ("%s %s", - _g_checksum_to_webrtc_string (G_CHECKSUM_SHA256), fingerprint); - g_free (fingerprint); - - gst_sdp_media_add_attribute (media, "fingerprint", val); - g_free (val); + _add_fingerprint_to_media (trans->sender->transport, media); } gst_caps_unref (caps); @@ -2188,23 +2196,7 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options) _get_or_create_data_channel_transports (webrtc, bundled_mids ? 0 : webrtc->priv->transceivers->len); - { - gchar *cert, *fingerprint, *val; - - g_object_get (webrtc->priv->sctp_transport->transport, "certificate", - &cert, NULL); - - fingerprint = - _generate_fingerprint_from_certificate (cert, G_CHECKSUM_SHA256); - g_free (cert); - val = - g_strdup_printf ("%s %s", - _g_checksum_to_webrtc_string (G_CHECKSUM_SHA256), fingerprint); - g_free (fingerprint); - - gst_sdp_media_add_attribute (&media, "fingerprint", val); - g_free (val); - } + _add_fingerprint_to_media (webrtc->priv->sctp_transport->transport, &media); gst_sdp_message_add_media (ret, &media); } @@ -2405,7 +2397,6 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) GstWebRTCRTPTransceiverDirection offer_dir, answer_dir; GstWebRTCDTLSSetup offer_setup, answer_setup; GstCaps *offer_caps, *answer_caps = NULL; - gchar *cert; guint j; guint k; gint target_pt = -1; @@ -2502,23 +2493,8 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) g_string_append_printf (bundled_mids, " %s", mid); } - { - gchar *cert, *fingerprint, *val; - - g_object_get (webrtc->priv->sctp_transport->transport, "certificate", - &cert, NULL); - - fingerprint = - _generate_fingerprint_from_certificate (cert, G_CHECKSUM_SHA256); - g_free (cert); - val = - g_strdup_printf ("%s %s", - _g_checksum_to_webrtc_string (G_CHECKSUM_SHA256), fingerprint); - g_free (fingerprint); - - gst_sdp_media_add_attribute (media, "fingerprint", val); - g_free (val); - } + _add_fingerprint_to_media (webrtc->priv->sctp_transport->transport, + media); } else if (g_strcmp0 (gst_sdp_media_get_media (offer_media), "audio") == 0 || g_strcmp0 (gst_sdp_media_get_media (offer_media), "video") == 0) { gst_sdp_media_set_proto (media, "UDP/TLS/RTP/SAVPF"); @@ -2653,23 +2629,9 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) } webrtc_transceiver_set_transport (trans, item); } - /* set the a=fingerprint: for this transport */ - g_object_get (trans->stream->transport, "certificate", &cert, NULL); - { - gchar *fingerprint, *val; - - fingerprint = - _generate_fingerprint_from_certificate (cert, G_CHECKSUM_SHA256); - g_free (cert); - val = - g_strdup_printf ("%s %s", - _g_checksum_to_webrtc_string (G_CHECKSUM_SHA256), fingerprint); - g_free (fingerprint); - - gst_sdp_media_add_attribute (media, "fingerprint", val); - g_free (val); - } + /* set the a=fingerprint: for this transport */ + _add_fingerprint_to_media (trans->stream->transport, media); gst_caps_unref (offer_caps); } else { -- GitLab From a42fdbb012e344bb4240fc649ccf3c3e92e544cb Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 16:21:19 +1100 Subject: [PATCH 4/5] webrtc: add a few comments on bundle and src pad exposure --- ext/webrtc/gstwebrtcbin.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index fd0fdbc4c1..090e9536d4 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -62,7 +62,21 @@ * * On the receiving side, RTPTransceiver's are created in response to setting * a remote description. Output pads for the receiving streams in the set - * description are also created. + * description are also created when data is received. + * + * A TransportStream is created when needed in order to transport the data over + * the necessary DTLS/ICE channel to the peer. The exact configuration depends + * on the negotiated SDP's between the peers based on the bundle and rtcp + * configuration. Some cases are outlined below for a simple single + * audio/video/data session: + * + * - max-bundle (requires rtcp-muxing) uses a single transport for all + * media/data transported. Renegotiation involves adding/removing the + * necessary streams to the existing transports. + * - max-compat without rtcp-mux involves two TransportStream per media stream + * to transport the rtp and the rtcp packets and a single TransportStream for + * all data channels. Each stream change involves modifying the associated + * TransportStream/s as necessary. */ /* @@ -2908,6 +2922,9 @@ _connect_output_stream (GstWebRTCBin * webrtc, g_free (pad_name); gst_element_sync_state_with_parent (GST_ELEMENT (stream->receive_bin)); + + /* The webrtcbin src_%u output pads will be created when rtpbin receives + * data on that stream in on_rtpbin_pad_added() */ } typedef struct -- GitLab From 14ee6f9d35c95ff8c00e7662fb873ba7f55d2e94 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 16:21:58 +1100 Subject: [PATCH 5/5] webrtc: fix typo in RTCRemoteOutboundRTPStreamStats --- ext/webrtc/gstwebrtcbin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 090e9536d4..142df17192 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -5070,7 +5070,7 @@ gst_webrtc_bin_class_init (GstWebRTCBinClass * klass) * * RTCInboundRTPStreamStats supported fields (https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*) * - * "remote-id" G_TYPE_STRING identifier for the associated RTCRemoteOutboundRTPSTreamStats + * "remote-id" G_TYPE_STRING identifier for the associated RTCRemoteOutboundRTPStreamStats * * RTCRemoteInboundRTPStreamStats supported fields (https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*) * -- GitLab