webrtc: stats: Increase spec compliance for ICE candidate stats

We now fill the foundation, related-address, related-port, username-fragment and
tcp-type fields.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8698>
This commit is contained in:
Philippe Normand 2025-03-26 14:00:33 +00:00 committed by GStreamer Marge Bot
parent ac465ebfe1
commit 4718fc9be7
8 changed files with 376 additions and 39 deletions

View File

@ -190,6 +190,97 @@ and/or use gtk-doc annotations. -->
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_ADDRESS" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_ADDRESS" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_FOUNDATION" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_FOUNDATION" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_PORT" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_PORT" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_PRIORITY" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_PRIORITY" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_PROTOCOL" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_PROTOCOL" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_RELATED_ADDRESS" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_ADDRESS" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_RELATED_PORT" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_PORT" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_RELAY_PROTOCOL" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_RELAY_PROTOCOL" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_STREAM_ID" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_STREAM_ID" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_TYPE" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_TYPE" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_URL" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_URL" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CANDIDATE_STATS_USERNAME_FRAGMENT" c:identifier="GST_WEBRTC_ICE_CANDIDATE_STATS_USERNAME_FRAGMENT" version="1.28" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
<parameter name="c">
</parameter>
</parameters>
</function-macro>
<function-macro name="WEBRTC_ICE_CLASS" c:identifier="GST_WEBRTC_ICE_CLASS" introspectable="0">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<parameters>
@ -1482,37 +1573,67 @@ stops automatic ICE gathering.</doc>
</parameters>
</glib:signal>
</class>
<record name="WebRTCICECandidateStats" c:type="GstWebRTCICECandidateStats" version="1.22" glib:type-name="GstWebRTCICECandidateStats" glib:get-type="gst_webrtc_ice_candidate_stats_get_type" c:symbol-prefix="webrtc_ice_candidate_stats">
<record name="WebRTCICECandidateStats" c:type="GstWebRTCICECandidateStats" glib:type-name="GstWebRTCICECandidateStats" glib:get-type="gst_webrtc_ice_candidate_stats_get_type" c:symbol-prefix="webrtc_ice_candidate_stats">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<field name="ipaddr" writable="1">
<type name="utf8" c:type="gchar*"/>
</field>
<field name="port" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">The network port number used by the candidate (Since: 1.22)</doc>
<type name="guint" c:type="guint"/>
</field>
<field name="stream_id" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">A string that uniquely identifies the object that is being
monitored to produce this set of statistics (Since: 1.22)</doc>
<type name="guint" c:type="guint"/>
</field>
<field name="type" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">The candidate type (Since: 1.22)</doc>
<type name="utf8" c:type="const gchar*"/>
</field>
<field name="proto" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">A string specifying the protocol (tcp or udp) used to transmit data
on the @port (Since: 1.22)</doc>
<type name="utf8" c:type="const gchar*"/>
</field>
<field name="relay_proto" writable="1">
<type name="utf8" c:type="const gchar*"/>
</field>
<field name="prio" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">The candidate's priority, corresponding to RTCIceCandidate.priority (Since: 1.22)</doc>
<type name="guint" c:type="guint"/>
</field>
<field name="url" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h">For local candidates, the url property is the URL of the ICE server
from which the candidate was received (Since: 1.22)</doc>
<type name="utf8" c:type="gchar*"/>
</field>
<field name="_gst_reserved" writable="1">
<union name="ABI" c:type="ABI">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<record name="abi" c:type="abi">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<field name="foundation" writable="1">
<type name="utf8" c:type="gchar*"/>
</field>
<field name="related_address" writable="1">
<type name="utf8" c:type="gchar*"/>
</field>
<field name="related_port" writable="1">
<type name="guint" c:type="guint"/>
</field>
<field name="username_fragment" writable="1">
<type name="utf8" c:type="gchar*"/>
</field>
<field name="tcp_type" writable="1">
<type name="utf8" c:type="const gchar*"/>
</field>
</record>
<field name="_gst_reserved" readable="0" private="1">
<array zero-terminated="0" fixed-size="20">
<type name="gpointer" c:type="gpointer"/>
</array>
</field>
</union>
<method name="copy" c:identifier="gst_webrtc_ice_candidate_stats_copy" version="1.22">
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/webrtc/ice.h"/>
<return-value transfer-ownership="full">

View File

@ -9256,6 +9256,11 @@ gst_webrtc_bin_class_init (GstWebRTCBinClass * klass)
* "protocol" G_TYPE_STRING Either "udp" or "tcp". Based on the "transport" defined in RFC 5245
* "relay-protocol" G_TYPE_STRING protocol used by the endpoint to communicate with the TURN server. Only present for local candidates. Either "udp", "tcp" or "tls"
* "url" G_TYPE_STRING URL of the ICE server from which the candidate was obtained. Only present for local candidates
* "foundation" G_TYPE_STRING ICE foundation as defined in RFC 5245 section 15.1 (Since: 1.28)
* "related-address" G_TYPE_STRING ICE rel-addr as defined in RFC 5245 section 15.1. Only set for server-reflexive, peer-reflexive and relay candidates (Since: 1.28)
* "related-port" G_TYPE_UINT ICE rel-port as defined in RFC 5245 section 15.1. Only set for serverreflexive, peer-reflexive and relay candidates (Since: 1.28)
* "username-fragment" G_TYPE_STRING ICE username fragment as defined in RFC 5245 section 7.1.2.3 (Since: 1.28)
* "tcp-type" G_TYPE_STRING ICE candidate TCP type as defined in RTCIceTcpCandidateType (Since: 1.28)
*
* RTCIceCandidatePairStats supported fields (https://www.w3.org/TR/webrtc-stats/#candidatepair-dict*) (Since: 1.22)
*

View File

@ -615,6 +615,11 @@ _get_stats_from_ice_candidates (GstWebRTCBin * webrtc,
long priority;
DOMString url;
DOMString relayProtocol;
DOMString foundation;
DOMString relatedAddress;
long relatedPort;
DOMString usernameFragment;
RTCIceTcpCandidateType tcpType;
*/
if (transport_id)
@ -630,6 +635,21 @@ _get_stats_from_ice_candidates (GstWebRTCBin * webrtc,
NULL);
if (can->url)
gst_structure_set (stats, "url", G_TYPE_STRING, can->url, NULL);
if (can->ABI.abi.foundation)
gst_structure_set (stats, "foundation", G_TYPE_STRING,
can->ABI.abi.foundation, NULL);
if (can->ABI.abi.related_address)
gst_structure_set (stats, "related-address", G_TYPE_STRING,
can->ABI.abi.related_address, NULL);
if (can->ABI.abi.related_port)
gst_structure_set (stats, "related-port", G_TYPE_UINT,
can->ABI.abi.related_port, NULL);
if (can->ABI.abi.username_fragment)
gst_structure_set (stats, "username-fragment", G_TYPE_STRING,
can->ABI.abi.username_fragment, NULL);
if (can->ABI.abi.tcp_type)
gst_structure_set (stats, "tcp-type", G_TYPE_STRING, can->ABI.abi.tcp_type,
NULL);
gst_structure_set (s, id, GST_TYPE_STRUCTURE, stats, NULL);
gst_structure_free (stats);

View File

@ -341,6 +341,9 @@ gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats)
if (stats) {
g_free (stats->ipaddr);
g_free (stats->url);
g_free (stats->ABI.abi.foundation);
g_free (stats->ABI.abi.related_address);
g_free (stats->ABI.abi.username_fragment);
}
g_free (stats);
@ -364,6 +367,9 @@ gst_webrtc_ice_candidate_stats_copy (GstWebRTCICECandidateStats * stats)
copy->ipaddr = g_strdup (stats->ipaddr);
copy->url = g_strdup (stats->url);
copy->ABI.abi.foundation = g_strdup (stats->ABI.abi.foundation);
copy->ABI.abi.related_address = g_strdup (stats->ABI.abi.related_address);
copy->ABI.abi.username_fragment = g_strdup (stats->ABI.abi.username_fragment);
return copy;
}

View File

@ -47,6 +47,30 @@ struct _GstWebRTCICE
gpointer _gst_reserved[GST_PADDING];
};
/**
* GstWebRTCICECandidateStats:
* @ipadd: A string containing the address of the candidate. This value may be
* an IPv4 address, an IPv6 address, or a fully-qualified domain name (Since: 1.22)
* @port: The network port number used by the candidate (Since: 1.22)
* @stream_id: A string that uniquely identifies the object that is being
* monitored to produce this set of statistics (Since: 1.22)
* @type: The candidate type (Since: 1.22)
* @proto: A string specifying the protocol (tcp or udp) used to transmit data
* on the @port (Since: 1.22)
* @replay_proto: A string identifying the protocol used by the endpoint for
* communicating with the TURN server; valid values are tcp, udp, and tls (Since: 1.22)
* @prio: The candidate's priority, corresponding to RTCIceCandidate.priority (Since: 1.22)
* @url: For local candidates, the url property is the URL of the ICE server
* from which the candidate was received (Since: 1.22)
* @foundation: The ICE foundation as defined in RFC5245 section 15.1 (Since: 1.28)
* @related_address: The ICE rel-addr defined in RFC5245 section 15.1 Only
* set for serverreflexive, peerreflexive and relay candidates. (Since: 1.28)
* @related_port: The ICE rel-addr defined in RFC5245 section 15.1. Only set
* for serverreflexive, peerreflexive and relay candidates. (Since: 1.28)
* @username_fragment: The ICE username fragment as defined in RFC5245 section 7.1.2.3 (Since: 1.28)
* @tcp_type: The ICE candidate TCP type, (Since: 1.28)
*
*/
struct _GstWebRTCICECandidateStats
{
gchar *ipaddr;
@ -58,9 +82,99 @@ struct _GstWebRTCICECandidateStats
guint prio;
gchar *url;
union {
struct {
gchar *foundation;
gchar *related_address;
guint related_port;
gchar *username_fragment;
const gchar *tcp_type;
} abi;
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
} ABI;
};
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_ADDRESS:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_ADDRESS(c) ((c)->ipaddr)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_PORT:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_PORT(c) ((c)->port)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_STREAM_ID:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_STREAM_ID(c) ((c)->stream_id)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_TYPE:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_TYPE(c) ((c)->type)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_PROTOCOL:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_PROTOCOL(c) ((c)->proto)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_RELAY_PROTOCOL:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_RELAY_PROTOCOL(c) ((c)->relay_proto)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_PRIORITY:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_PRIORITY(c) ((c)->prio)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_URL:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_URL(c) ((c)->url)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_FOUNDATION:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_FOUNDATION(c) ((c)->ABI.abi.foundation)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_ADDRESS:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_ADDRESS(c) ((c)->ABI.abi.related_address)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_PORT:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_PORT(c) ((c)->ABI.abi.related_port)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_USERNAME_FRAGMENT:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_USERNAME_FRAGMENT(c) ((c)->ABI.abi.username_fragment)
/**
* GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE:
*
* Since: 1.28
*/
#define GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE(c) ((c)->ABI.abi.tcp_type)
/**
* GstWebRTCICEOnCandidateFunc:
* @ice: The #GstWebRTCICE

View File

@ -551,6 +551,31 @@ gst_webrtc_nice_add_stream (GstWebRTCICE * ice, guint session_id)
return item->stream;
}
static void
_fill_candidate_credentials (NiceAgent * agent, NiceCandidate * candidate)
{
if (!candidate->username || !candidate->password) {
gboolean got_credentials;
gchar *ufrag, *password;
got_credentials =
nice_agent_get_local_credentials (agent, candidate->stream_id, &ufrag,
&password);
g_warn_if_fail (got_credentials);
if (!candidate->username)
candidate->username = ufrag;
else
g_free (ufrag);
if (!candidate->password)
candidate->password = password;
else
g_free (password);
}
}
static void
_on_new_candidate (NiceAgent * agent, NiceCandidate * candidate,
GstWebRTCNice * ice)
@ -565,24 +590,7 @@ _on_new_candidate (NiceAgent * agent, NiceCandidate * candidate,
return;
}
if (!candidate->username || !candidate->password) {
gboolean got_credentials;
gchar *ufrag, *password;
got_credentials = nice_agent_get_local_credentials (ice->priv->nice_agent,
candidate->stream_id, &ufrag, &password);
g_warn_if_fail (got_credentials);
if (!candidate->username)
candidate->username = ufrag;
else
g_free (ufrag);
if (!candidate->password)
candidate->password = password;
else
g_free (password);
}
_fill_candidate_credentials (agent, candidate);
attr = nice_agent_generate_local_candidate_sdp (agent, candidate);
@ -1084,18 +1092,52 @@ _populate_candidate_stats (GstWebRTCNice * ice, NiceCandidate * cand,
g_assert (cand != NULL);
nice_address_to_string (&cand->addr, ipaddr);
stats->port = nice_address_get_port (&cand->addr);
stats->ipaddr = g_strdup (ipaddr);
stats->stream_id = stream->stream_id;
stats->type = nice_candidate_type_to_string (cand->type);
stats->prio = cand->priority;
stats->proto =
GST_WEBRTC_ICE_CANDIDATE_STATS_PORT (stats) =
nice_address_get_port (&cand->addr);
GST_WEBRTC_ICE_CANDIDATE_STATS_ADDRESS (stats) = g_strdup (ipaddr);
GST_WEBRTC_ICE_CANDIDATE_STATS_STREAM_ID (stats) = stream->stream_id;
GST_WEBRTC_ICE_CANDIDATE_STATS_TYPE (stats) =
nice_candidate_type_to_string (cand->type);
GST_WEBRTC_ICE_CANDIDATE_STATS_PRIORITY (stats) = cand->priority;
GST_WEBRTC_ICE_CANDIDATE_STATS_PROTOCOL (stats) =
cand->transport == NICE_CANDIDATE_TRANSPORT_UDP ? "udp" : "tcp";
if (is_local) {
if (cand->type == NICE_CANDIDATE_TYPE_RELAYED)
stats->relay_proto = gst_webrtc_nice_get_candidate_relay_protocol (ice->priv->turn_server);
stats->url = gst_webrtc_nice_get_candidate_server_url (ice, cand);
if (cand->type == NICE_CANDIDATE_TYPE_RELAYED) {
NiceAddress relay_address;
nice_candidate_relay_address (cand, &relay_address);
GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_ADDRESS (stats) =
nice_address_dup_string (&relay_address);
GST_WEBRTC_ICE_CANDIDATE_STATS_RELATED_PORT (stats) =
nice_address_get_port (&relay_address);
GST_WEBRTC_ICE_CANDIDATE_STATS_RELAY_PROTOCOL (stats) =
gst_webrtc_nice_get_candidate_relay_protocol (ice->priv->turn_server);
}
GST_WEBRTC_ICE_CANDIDATE_STATS_URL (stats) =
gst_webrtc_nice_get_candidate_server_url (ice, cand);
}
GST_WEBRTC_ICE_CANDIDATE_STATS_FOUNDATION (stats) =
g_strdup (cand->foundation);
switch (cand->transport) {
case NICE_CANDIDATE_TRANSPORT_UDP:
GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE (stats) = NULL;
break;
case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE:
GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE (stats) = "active";
break;
case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE:
GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE (stats) = "passive";
break;
case NICE_CANDIDATE_TRANSPORT_TCP_SO:
GST_WEBRTC_ICE_CANDIDATE_STATS_TCP_TYPE (stats) = "so";
break;
};
GST_WEBRTC_ICE_CANDIDATE_STATS_USERNAME_FRAGMENT (stats) =
g_strdup (cand->username);
}
static void
@ -1166,6 +1208,9 @@ gst_webrtc_nice_get_selected_pair (GstWebRTCICE * ice,
if (stream) {
if (nice_agent_get_selected_pair (nice->priv->nice_agent, stream->stream_id,
NICE_COMPONENT_TYPE_RTP, &local_cand, &remote_cand)) {
_fill_candidate_credentials (nice->priv->nice_agent, local_cand);
_fill_candidate_credentials (nice->priv->nice_agent, remote_cand);
*local_stats = g_new0 (GstWebRTCICECandidateStats, 1);
_populate_candidate_stats (nice, local_cand, stream, *local_stats, TRUE);

View File

@ -70,11 +70,6 @@ typedef struct _GstWebRTCDTLSTransportClass GstWebRTCDTLSTransportClass;
typedef struct _GstWebRTCICE GstWebRTCICE;
typedef struct _GstWebRTCICEClass GstWebRTCICEClass;
/**
* GstWebRTCICECandidateStats:
*
* Since: 1.22
*/
typedef struct _GstWebRTCICECandidateStats GstWebRTCICECandidateStats;
/**

View File

@ -1748,6 +1748,7 @@ validate_candidate_stats (const GstStructure * s, const GstStructure * stats)
guint port;
guint64 priority;
gchar *address, *candidateType, *protocol;
gchar *foundation, *username_fragment;
fail_unless (gst_structure_get (s, "address", G_TYPE_STRING, &address, NULL));
fail_unless (gst_structure_get (s, "port", G_TYPE_UINT, &port, NULL));
@ -1759,9 +1760,39 @@ validate_candidate_stats (const GstStructure * s, const GstStructure * stats)
fail_unless (strcmp (protocol, "udp") || strcmp (protocol, "tcp"));
fail_unless (gst_structure_get (s, "foundation", G_TYPE_STRING, &foundation,
NULL));
fail_unless (gst_structure_get (s, "username-fragment", G_TYPE_STRING,
&username_fragment, NULL));
if (strcmp (candidateType, "host")) {
guint related_port;
gchar *related_address;
fail_unless (gst_structure_get (s, "related-address", G_TYPE_STRING,
&related_address, NULL));
fail_unless (gst_structure_get (s, "related-port", G_TYPE_UINT,
&related_port, NULL));
g_free (related_address);
} else {
fail_if (gst_structure_has_field (s, "related-address"));
fail_if (gst_structure_has_field (s, "related-port"));
}
if (!strcmp (protocol, "tcp")) {
gchar *tcp_type;
fail_unless (gst_structure_get (s, "tcp-type", G_TYPE_STRING, &tcp_type,
NULL));
fail_unless (strcmp (tcp_type, "so") || strcmp (tcp_type, "active")
|| strcmp (tcp_type, "passive"));
g_free (tcp_type);
} else {
fail_if (gst_structure_has_field (s, "tcp-type"));
}
g_free (address);
g_free (candidateType);
g_free (protocol);
g_free (foundation);
g_free (username_fragment);
}
static void