#define ICE_LOCK(w) (g_mutex_lock (ICE_GET_LOCK(w)))
#define ICE_UNLOCK(w) (g_mutex_unlock (ICE_GET_LOCK(w)))
+#define DC_GET_LOCK(w) (&w->priv->dc_lock)
+#define DC_LOCK(w) (g_mutex_lock (DC_GET_LOCK(w)))
+#define DC_UNLOCK(w) (g_mutex_unlock (DC_GET_LOCK(w)))
/* The extra time for the rtpstorage compared to the RTP jitterbuffer (in ms) */
#define RTPSTORAGE_EXTRA_TIME (50)
return channel->parent.id == *id;
}
+/* always called with dc_lock held */
static WebRTCDataChannel *
_find_data_channel_for_id (GstWebRTCBin * webrtc, gint id)
{
if (!webrtc->priv->sctp_transport)
return;
+ DC_LOCK (webrtc);
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
GstWebRTCDataChannel *channel
= g_ptr_array_index (webrtc->priv->data_channels, i);
sctp_priority = MAX (sctp_priority, channel->priority);
}
+ DC_UNLOCK (webrtc);
/* Default priority is low means DSCP field is left as 0 */
if (sctp_priority == 0)
if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
gboolean found;
+ DC_LOCK (webrtc);
found = g_ptr_array_remove (webrtc->priv->pending_data_channels, channel);
if (found == FALSE) {
GST_FIXME_OBJECT (webrtc, "Received open for unknown data channel");
+ DC_UNLOCK (webrtc);
return;
}
g_ptr_array_add (webrtc->priv->data_channels, gst_object_ref (channel));
+ DC_UNLOCK (webrtc);
gst_webrtc_bin_update_sctp_priority (webrtc);
} else if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
gboolean found;
+ DC_LOCK (webrtc);
found = g_ptr_array_remove (webrtc->priv->pending_data_channels, channel)
|| g_ptr_array_remove (webrtc->priv->data_channels, channel);
if (found == FALSE) {
GST_FIXME_OBJECT (webrtc, "Received close for unknown data channel");
}
+ DC_UNLOCK (webrtc);
}
}
if (sscanf (GST_PAD_NAME (pad), "src_%u", &stream_id) != 1)
return;
- PC_LOCK (webrtc);
+ DC_LOCK (webrtc);
channel = _find_data_channel_for_id (webrtc, stream_id);
if (!channel) {
channel = g_object_new (WEBRTC_TYPE_DATA_CHANNEL, NULL);
g_ptr_array_add (webrtc->priv->pending_data_channels, channel);
}
+ DC_UNLOCK (webrtc);
g_signal_connect (channel, "notify::ready-state",
G_CALLBACK (_on_data_channel_ready_state), webrtc);
GST_WARNING_OBJECT (channel, "Failed to link sctp pad %s with channel %"
GST_PTR_FORMAT, GST_PAD_NAME (pad), channel);
gst_object_unref (sink_pad);
- PC_UNLOCK (webrtc);
}
static void
if (state == GST_WEBRTC_SCTP_TRANSPORT_STATE_CONNECTED) {
int i;
- PC_LOCK (webrtc);
GST_DEBUG_OBJECT (webrtc, "SCTP association established");
+ DC_LOCK (webrtc);
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
WebRTCDataChannel *channel;
if (!channel->parent.negotiated && !channel->opened)
webrtc_data_channel_start_negotiation (channel);
}
- PC_UNLOCK (webrtc);
+ DC_UNLOCK (webrtc);
}
}
if (!webrtc->priv->data_channel_transport) {
TransportStream *stream;
GstWebRTCSCTPTransport *sctp_transport;
- int i;
stream = _find_transport_for_session (webrtc, session_id);
GST_ELEMENT (stream->send_bin), "data_sink"))
g_warn_if_reached ();
- for (i = 0; i < webrtc->priv->data_channels->len; i++) {
- WebRTCDataChannel *channel;
-
- channel = g_ptr_array_index (webrtc->priv->data_channels, i);
-
- webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
- }
-
gst_element_sync_state_with_parent (GST_ELEMENT (stream->send_bin));
gst_element_sync_state_with_parent (GST_ELEMENT (stream->receive_bin));
}
webrtc->priv->sctp_transport = sctp_transport;
+
gst_webrtc_bin_update_sctp_priority (webrtc);
}
remote_port, NULL);
}
+ DC_LOCK (webrtc);
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
WebRTCDataChannel *channel;
webrtc_data_channel_start_negotiation (channel);
}
}
+ DC_UNLOCK (webrtc);
stream->active = TRUE;
return NULL;
PC_LOCK (webrtc);
+ DC_LOCK (webrtc);
/* check if the id has been used already */
if (id != -1) {
WebRTCDataChannel *channel = _find_data_channel_for_id (webrtc, id);
GST_ELEMENT_WARNING (webrtc, LIBRARY, SETTINGS,
("Attempting to add a data channel with a duplicate ID: %i", id),
NULL);
+ DC_UNLOCK (webrtc);
PC_UNLOCK (webrtc);
return NULL;
}
if (id == -1) {
GST_ELEMENT_WARNING (webrtc, RESOURCE, NOT_FOUND,
("%s", "Failed to generate an identifier for a data channel"), NULL);
+ DC_UNLOCK (webrtc);
PC_UNLOCK (webrtc);
return NULL;
}
"max-retransmits", max_retransmits, "protocol", protocol,
"negotiated", negotiated, "id", id, "priority", priority, NULL);
- if (ret) {
- gst_bin_add (GST_BIN (webrtc), ret->appsrc);
- gst_bin_add (GST_BIN (webrtc), ret->appsink);
+ if (!ret) {
+ DC_UNLOCK (webrtc);
+ PC_UNLOCK (webrtc);
+ return ret;
+ }
- gst_element_sync_state_with_parent (ret->appsrc);
- gst_element_sync_state_with_parent (ret->appsink);
+ gst_bin_add (GST_BIN (webrtc), ret->appsrc);
+ gst_bin_add (GST_BIN (webrtc), ret->appsink);
- ret = gst_object_ref (ret);
- ret->webrtcbin = webrtc;
- g_ptr_array_add (webrtc->priv->data_channels, ret);
- gst_webrtc_bin_update_sctp_priority (webrtc);
- webrtc_data_channel_link_to_sctp (ret, webrtc->priv->sctp_transport);
- if (webrtc->priv->sctp_transport &&
- webrtc->priv->sctp_transport->association_established
- && !ret->parent.negotiated) {
- webrtc_data_channel_start_negotiation (ret);
- } else {
- _update_need_negotiation (webrtc);
- }
+ gst_element_sync_state_with_parent (ret->appsrc);
+ gst_element_sync_state_with_parent (ret->appsink);
+
+ ret = gst_object_ref (ret);
+ ret->webrtcbin = webrtc;
+ g_ptr_array_add (webrtc->priv->data_channels, ret);
+ DC_UNLOCK (webrtc);
+
+ gst_webrtc_bin_update_sctp_priority (webrtc);
+ webrtc_data_channel_link_to_sctp (ret, webrtc->priv->sctp_transport);
+ if (webrtc->priv->sctp_transport &&
+ webrtc->priv->sctp_transport->association_established
+ && !ret->parent.negotiated) {
+ webrtc_data_channel_start_negotiation (ret);
+ } else {
+ _update_need_negotiation (webrtc);
}
PC_UNLOCK (webrtc);
gst_webrtc_session_description_free (webrtc->priv->last_generated_offer);
webrtc->priv->last_generated_offer = NULL;
+ g_mutex_clear (DC_GET_LOCK (webrtc));
g_mutex_clear (ICE_GET_LOCK (webrtc));
g_mutex_clear (PC_GET_LOCK (webrtc));
g_cond_clear (PC_GET_COND (webrtc));
g_cond_init (PC_GET_COND (webrtc));
g_mutex_init (ICE_GET_LOCK (webrtc));
+ g_mutex_init (DC_GET_LOCK (webrtc));
webrtc->rtpbin = _create_rtpbin (webrtc);
gst_bin_add (GST_BIN (webrtc), webrtc->rtpbin);