webrtcbin: Filter transport stream stats by ssrc

Since the addition of BUNDLE support, the pads and the transceivers
share a single transport stream. When getting stats from the stream,
filter by the ssrc of the current pad to avoid merging the stats for
different pads.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/889
This commit is contained in:
Jan Alexander Steffens (heftig) 2019-03-07 14:13:14 +01:00 committed by Matthew Waters
parent 926ff109b9
commit dc0e95acab

View file

@ -402,7 +402,8 @@ _get_stats_from_dtls_transport (GstWebRTCBin * webrtc,
static void static void
_get_stats_from_transport_channel (GstWebRTCBin * webrtc, _get_stats_from_transport_channel (GstWebRTCBin * webrtc,
TransportStream * stream, const gchar * codec_id, GstStructure * s) TransportStream * stream, const gchar * codec_id, guint ssrc,
GstStructure * s)
{ {
GstWebRTCDTLSTransport *transport; GstWebRTCDTLSTransport *transport;
GObject *rtp_session; GObject *rtp_session;
@ -439,12 +440,15 @@ _get_stats_from_transport_channel (GstWebRTCBin * webrtc,
const GstStructure *stats; const GstStructure *stats;
const GValue *val = g_value_array_get_nth (source_stats, i); const GValue *val = g_value_array_get_nth (source_stats, i);
gboolean internal; gboolean internal;
guint stats_ssrc = 0;
stats = gst_value_get_structure (val); stats = gst_value_get_structure (val);
/* skip internal sources */ /* skip internal or foreign sources */
gst_structure_get (stats, "internal", G_TYPE_BOOLEAN, &internal, NULL); gst_structure_get (stats,
if (internal) "internal", G_TYPE_BOOLEAN, &internal,
"ssrc", G_TYPE_UINT, &stats_ssrc, NULL);
if (internal || (ssrc && stats_ssrc && ssrc != stats_ssrc))
continue; continue;
_get_stats_from_rtp_source_stats (webrtc, stats, codec_id, transport_id, s); _get_stats_from_rtp_source_stats (webrtc, stats, codec_id, transport_id, s);
@ -459,12 +463,13 @@ _get_stats_from_transport_channel (GstWebRTCBin * webrtc,
/* https://www.w3.org/TR/webrtc-stats/#codec-dict* */ /* https://www.w3.org/TR/webrtc-stats/#codec-dict* */
static void static void
_get_codec_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad, _get_codec_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad,
GstStructure * s, gchar ** out_id) GstStructure * s, gchar ** out_id, guint * out_ssrc)
{ {
GstStructure *stats; GstStructure *stats;
GstCaps *caps; GstCaps *caps;
gchar *id; gchar *id;
double ts; double ts;
guint ssrc = 0;
gst_structure_get_double (s, "timestamp", &ts); gst_structure_get_double (s, "timestamp", &ts);
@ -483,6 +488,9 @@ _get_codec_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad,
if (gst_structure_get_int (caps_s, "clock-rate", &clock_rate)) if (gst_structure_get_int (caps_s, "clock-rate", &clock_rate))
gst_structure_set (stats, "clock-rate", G_TYPE_UINT, clock_rate, NULL); gst_structure_set (stats, "clock-rate", G_TYPE_UINT, clock_rate, NULL);
if (gst_structure_get_uint (caps_s, "ssrc", &ssrc))
gst_structure_set (stats, "ssrc", G_TYPE_UINT, ssrc, NULL);
/* FIXME: codecType, mimeType, channels, sdpFmtpLine, implementation, transportId */ /* FIXME: codecType, mimeType, channels, sdpFmtpLine, implementation, transportId */
} }
@ -496,6 +504,9 @@ _get_codec_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad,
*out_id = id; *out_id = id;
else else
g_free (id); g_free (id);
if (out_ssrc)
*out_ssrc = ssrc;
} }
static gboolean static gboolean
@ -504,8 +515,9 @@ _get_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad, GstStructure * s)
GstWebRTCBinPad *wpad = GST_WEBRTC_BIN_PAD (pad); GstWebRTCBinPad *wpad = GST_WEBRTC_BIN_PAD (pad);
TransportStream *stream; TransportStream *stream;
gchar *codec_id; gchar *codec_id;
guint ssrc;
_get_codec_stats_from_pad (webrtc, pad, s, &codec_id); _get_codec_stats_from_pad (webrtc, pad, s, &codec_id, &ssrc);
if (!wpad->trans) if (!wpad->trans)
goto out; goto out;
@ -514,7 +526,7 @@ _get_stats_from_pad (GstWebRTCBin * webrtc, GstPad * pad, GstStructure * s)
if (!stream) if (!stream)
goto out; goto out;
_get_stats_from_transport_channel (webrtc, stream, codec_id, s); _get_stats_from_transport_channel (webrtc, stream, codec_id, ssrc, s);
out: out:
g_free (codec_id); g_free (codec_id);