mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
webrtc: move some functions to the appropriate files
This commit is contained in:
parent
d2e87e6a31
commit
5ecca0bb22
7 changed files with 230 additions and 201 deletions
|
@ -216,41 +216,6 @@ gst_webrtc_bin_pad_class_init (GstWebRTCBinPadClass * klass)
|
||||||
gobject_class->finalize = gst_webrtc_bin_pad_finalize;
|
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
|
static gboolean
|
||||||
gst_webrtcbin_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
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 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
|
typedef struct
|
||||||
{
|
{
|
||||||
guint session_id;
|
guint session_id;
|
||||||
|
@ -827,7 +768,7 @@ _collate_ice_connection_states (GstWebRTCBin * webrtc)
|
||||||
|
|
||||||
g_object_get (stream, "rtcp-mux", &rtcp_mux, NULL);
|
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 */
|
/* get transport state */
|
||||||
g_object_get (transport, "state", &ice_state, NULL);
|
g_object_get (transport, "state", &ice_state, NULL);
|
||||||
|
@ -835,7 +776,8 @@ _collate_ice_connection_states (GstWebRTCBin * webrtc)
|
||||||
if (ice_state != STATE (CLOSED))
|
if (ice_state != STATE (CLOSED))
|
||||||
all_closed = FALSE;
|
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) {
|
if (!rtcp_mux && rtcp_transport && transport != rtcp_transport) {
|
||||||
g_object_get (rtcp_transport, "state", &ice_state, NULL);
|
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);
|
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 */
|
/* get gathering state */
|
||||||
g_object_get (transport, "gathering-state", &ice_state, NULL);
|
g_object_get (transport, "gathering-state", &ice_state, NULL);
|
||||||
|
@ -929,7 +871,8 @@ _collate_ice_gathering_states (GstWebRTCBin * webrtc)
|
||||||
if (ice_state != STATE (COMPLETE))
|
if (ice_state != STATE (COMPLETE))
|
||||||
all_completed = FALSE;
|
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) {
|
if (!rtcp_mux && rtcp_transport && rtcp_transport != transport) {
|
||||||
g_object_get (rtcp_transport, "gathering-state", &ice_state, NULL);
|
g_object_get (rtcp_transport, "gathering-state", &ice_state, NULL);
|
||||||
|
@ -988,7 +931,7 @@ _collate_peer_connection_states (GstWebRTCBin * webrtc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_object_get (stream, "rtcp-mux", &rtcp_mux, NULL);
|
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 */
|
/* get transport state */
|
||||||
g_object_get (transport, "state", &dtls_state, NULL);
|
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);
|
g_object_get (transport->transport, "state", &ice_state, NULL);
|
||||||
any_ice_state |= (1 << ice_state);
|
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) {
|
if (!rtcp_mux && rtcp_transport && rtcp_transport != transport) {
|
||||||
g_object_get (rtcp_transport, "state", &dtls_state, NULL);
|
g_object_get (rtcp_transport, "state", &dtls_state, NULL);
|
||||||
|
@ -1516,32 +1459,6 @@ _create_transport_channel (GstWebRTCBin * webrtc, guint session_id)
|
||||||
return ret;
|
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 *
|
static TransportStream *
|
||||||
_get_or_create_rtp_transport_channel (GstWebRTCBin * webrtc, guint session_id)
|
_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);
|
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 */
|
/* TODO: use the options argument */
|
||||||
static GstSDPMessage *
|
static GstSDPMessage *
|
||||||
_create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
_create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
|
@ -2491,7 +2360,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_parse_bundle (webrtc, pending_remote->sdp, &bundled))
|
if (!_parse_bundle (pending_remote->sdp, &bundled))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (bundled) {
|
if (bundled) {
|
||||||
|
@ -3520,7 +3389,7 @@ _update_transceivers_from_sdp (GstWebRTCBin * webrtc, SDPSource source,
|
||||||
gboolean should_connect_bundle_stream = FALSE;
|
gboolean should_connect_bundle_stream = FALSE;
|
||||||
TransportStream *bundle_stream = NULL;
|
TransportStream *bundle_stream = NULL;
|
||||||
|
|
||||||
if (!_parse_bundle (webrtc, sdp->sdp, &bundled))
|
if (!_parse_bundle (sdp->sdp, &bundled))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (bundled) {
|
if (bundled) {
|
||||||
|
@ -3607,57 +3476,6 @@ done:
|
||||||
return ret;
|
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
|
struct set_description
|
||||||
{
|
{
|
||||||
GstPromise *promise;
|
GstPromise *promise;
|
||||||
|
@ -3700,7 +3518,7 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_parse_bundle (webrtc, sd->sdp->sdp, &bundled))
|
if (!_parse_bundle (sd->sdp->sdp, &bundled))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (bundled) {
|
if (bundled) {
|
||||||
|
@ -4432,7 +4250,7 @@ on_rtpbin_request_pt_map (GstElement * rtpbin, guint session_id, guint pt,
|
||||||
if (!stream)
|
if (!stream)
|
||||||
goto unknown_session;
|
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_caps_ref (ret);
|
||||||
|
|
||||||
GST_TRACE_OBJECT (webrtc, "Found caps %" GST_PTR_FORMAT " for pt %d in "
|
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);
|
stream = _find_transport_for_session (webrtc, session_id);
|
||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
red_pt = _transport_stream_get_pt (stream, "RED");
|
red_pt = transport_stream_get_pt (stream, "RED");
|
||||||
rtx_pt = _transport_stream_get_pt (stream, "RTX");
|
rtx_pt = transport_stream_get_pt (stream, "RTX");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (red_pt || rtx_pt)
|
if (red_pt || rtx_pt)
|
||||||
ret = gst_bin_new (NULL);
|
ret = gst_bin_new (NULL);
|
||||||
|
|
||||||
if (rtx_pt) {
|
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);
|
GstElement *rtx = gst_element_factory_make ("rtprtxreceive", NULL);
|
||||||
GstStructure *pt_map;
|
GstStructure *pt_map;
|
||||||
const GstStructure *s = gst_caps_get_structure (rtx_caps, 0);
|
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)
|
* example)
|
||||||
*/
|
*/
|
||||||
if (stream)
|
if (stream)
|
||||||
pt = _transport_stream_get_pt (stream, "ULPFEC");
|
pt = transport_stream_get_pt (stream, "ULPFEC");
|
||||||
|
|
||||||
if (pt) {
|
if (pt) {
|
||||||
GST_DEBUG_OBJECT (webrtc, "Creating ULPFEC decoder for pt %d in session %u",
|
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);
|
(FindTransceiverFunc) transceiver_match_for_mline);
|
||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
ulpfec_pt = _transport_stream_get_pt (stream, "ULPFEC");
|
ulpfec_pt = transport_stream_get_pt (stream, "ULPFEC");
|
||||||
red_pt = _transport_stream_get_pt (stream, "RED");
|
red_pt = transport_stream_get_pt (stream, "RED");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ulpfec_pt || red_pt)
|
if (ulpfec_pt || red_pt)
|
||||||
|
@ -4657,7 +4475,7 @@ on_rtpbin_request_fec_encoder (GstElement * rtpbin, guint session_id,
|
||||||
|
|
||||||
if (ulpfec_pt) {
|
if (ulpfec_pt) {
|
||||||
GstElement *fecenc = gst_element_factory_make ("rtpulpfecenc", NULL);
|
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,
|
GST_DEBUG_OBJECT (webrtc,
|
||||||
"Creating ULPFEC encoder for session %d with pt %d", session_id,
|
"Creating ULPFEC encoder for session %d with pt %d", session_id,
|
||||||
|
|
|
@ -40,6 +40,41 @@ enum
|
||||||
PROP_DTLS_CLIENT,
|
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
|
static void
|
||||||
transport_stream_set_property (GObject * object, guint prop_id,
|
transport_stream_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
|
|
@ -70,6 +70,10 @@ struct _TransportStreamClass
|
||||||
|
|
||||||
TransportStream * transport_stream_new (GstWebRTCBin * webrtc,
|
TransportStream * transport_stream_new (GstWebRTCBin * webrtc,
|
||||||
guint session_id);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -736,3 +736,127 @@ _get_sctp_max_message_size_from_media (const GstSDPMedia * media)
|
||||||
|
|
||||||
return 65536;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -81,4 +81,21 @@ int _get_sctp_port_from_media (con
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
guint64 _get_sctp_max_message_size_from_media (const GstSDPMedia * media);
|
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__ */
|
#endif /* __WEBRTC_UTILS_H__ */
|
||||||
|
|
|
@ -69,6 +69,34 @@ webrtc_transceiver_set_transport (WebRTCTransceiver * trans,
|
||||||
(GstObject *) stream->rtcp_transport);
|
(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
|
static void
|
||||||
webrtc_transceiver_set_property (GObject * object, guint prop_id,
|
webrtc_transceiver_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
|
|
@ -58,6 +58,9 @@ WebRTCTransceiver * webrtc_transceiver_new (GstWebRTCBin * webr
|
||||||
void webrtc_transceiver_set_transport (WebRTCTransceiver * trans,
|
void webrtc_transceiver_set_transport (WebRTCTransceiver * trans,
|
||||||
TransportStream * stream);
|
TransportStream * stream);
|
||||||
|
|
||||||
|
GstWebRTCDTLSTransport * webrtc_transceiver_get_dtls_transport (GstWebRTCRTPTransceiver * trans);
|
||||||
|
GstWebRTCDTLSTransport * webrtc_transceiver_get_rtcp_dtls_transport (GstWebRTCRTPTransceiver * trans);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __WEBRTC_TRANSCEIVER_H__ */
|
#endif /* __WEBRTC_TRANSCEIVER_H__ */
|
||||||
|
|
Loading…
Reference in a new issue