webrtc: Track stats for data channels opened and closed

Track data channel stats for `dataChannelsOpened` and
`dataChannelsClosed` in `RTCPeerConnectionStats` as specified by
https://www.w3.org/TR/webrtc-stats/#dictionary-rtcpeerconnectionstats-members

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4638>
This commit is contained in:
Martin Nordholts 2023-05-15 11:14:24 +02:00 committed by GStreamer Marge Bot
parent ad70dd64f9
commit 85e3f31740
3 changed files with 38 additions and 6 deletions

View file

@ -1252,6 +1252,20 @@ gst_webrtc_bin_enqueue_task (GstWebRTCBin * webrtc, GstWebRTCBinFunc func,
return TRUE;
}
void
gst_webrtc_bin_get_peer_connection_stats (GstWebRTCBin * webrtc,
guint * data_channels_opened, guint * data_channels_closed)
{
DC_LOCK (webrtc);
if (data_channels_opened) {
*data_channels_opened = webrtc->priv->data_channels_opened;
}
if (data_channels_closed) {
*data_channels_closed = webrtc->priv->data_channels_closed;
}
DC_UNLOCK (webrtc);
}
/* https://www.w3.org/TR/webrtc/#dom-rtciceconnectionstate */
static GstWebRTCICEConnectionState
_collate_ice_connection_states (GstWebRTCBin * webrtc)
@ -2541,6 +2555,7 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
}
g_ptr_array_add (webrtc->priv->data_channels, gst_object_ref (channel));
webrtc->priv->data_channels_opened++;
DC_UNLOCK (webrtc);
gst_webrtc_bin_update_sctp_priority (webrtc);
@ -2548,14 +2563,19 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
g_signal_emit (webrtc, gst_webrtc_bin_signals[ON_DATA_CHANNEL_SIGNAL], 0,
channel);
} else if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
gboolean found_pending;
gboolean found;
DC_LOCK (webrtc);
found = g_ptr_array_remove (webrtc->priv->pending_data_channels, channel)
found_pending =
g_ptr_array_remove (webrtc->priv->pending_data_channels, channel);
found = found_pending
|| g_ptr_array_remove (webrtc->priv->data_channels, channel);
if (found == FALSE) {
GST_FIXME_OBJECT (webrtc, "Received close for unknown data channel");
} else if (found_pending == FALSE) {
webrtc->priv->data_channels_closed++;
}
DC_UNLOCK (webrtc);
}
@ -7261,6 +7281,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
ret = gst_object_ref (ret);
webrtc_data_channel_set_webrtcbin (ret, webrtc);
g_ptr_array_add (webrtc->priv->data_channels, ret);
webrtc->priv->data_channels_opened++;
DC_UNLOCK (webrtc);
gst_webrtc_bin_update_sctp_priority (webrtc);

View file

@ -108,11 +108,15 @@ struct _GstWebRTCBinPrivate
gboolean bundle;
GPtrArray *transceivers;
GPtrArray *transports;
/* stats according to https://www.w3.org/TR/webrtc-stats/#dictionary-rtcpeerconnectionstats-members */
guint data_channels_opened;
guint data_channels_closed;
GPtrArray *data_channels;
/* list of data channels we've received a sctp stream for but no data
* channel protocol for */
GPtrArray *pending_data_channels;
/* dc_lock protects data_channels and pending_data_channels */
/* dc_lock protects data_channels and pending_data_channels
* and data_channels_opened and data_channels_closed */
/* lock ordering is pc_lock first, then dc_lock */
GMutex dc_lock;
@ -172,6 +176,10 @@ gboolean gst_webrtc_bin_enqueue_task (GstWebRTCBin * pc,
GDestroyNotify notify,
GstPromise *promise);
void gst_webrtc_bin_get_peer_connection_stats(GstWebRTCBin * pc,
guint * data_channels_opened,
guint * data_channels_closed);
G_END_DECLS
#endif /* __GST_WEBRTC_BIN_H__ */

View file

@ -71,11 +71,14 @@ _set_base_stats (GstStructure * s, GstWebRTCStatsType type, double ts,
static GstStructure *
_get_peer_connection_stats (GstWebRTCBin * webrtc)
{
GstStructure *s = gst_structure_new_empty ("unused");
guint opened;
guint closed;
GstStructure *s = gst_structure_new_empty ("peer-connection-stats");
/* FIXME: datachannel */
gst_structure_set (s, "data-channels-opened", G_TYPE_UINT, 0,
"data-channels-closed", G_TYPE_UINT, 0, "data-channels-requested",
gst_webrtc_bin_get_peer_connection_stats (webrtc, &opened, &closed);
gst_structure_set (s, "data-channels-opened", G_TYPE_UINT, opened,
"data-channels-closed", G_TYPE_UINT, closed, "data-channels-requested",
G_TYPE_UINT, 0, "data-channels-accepted", G_TYPE_UINT, 0, NULL);
return s;