Source/ThirdParty/libwebrtc:
[WebKit-https.git] / Source / WebCore / Modules / mediastream / libwebrtc / LibWebRTCStatsCollector.cpp
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26 #include "LibWebRTCStatsCollector.h"
27
28 #if USE(LIBWEBRTC)
29
30 #include "JSDOMMapLike.h"
31 #include "JSRTCStatsReport.h"
32 #include "Performance.h"
33 #include <wtf/MainThread.h>
34
35 namespace WebCore {
36
37 LibWebRTCStatsCollector::LibWebRTCStatsCollector(CollectorCallback&& callback)
38     : m_callback(WTFMove(callback))
39 {
40 }
41
42 LibWebRTCStatsCollector::~LibWebRTCStatsCollector()
43 {
44     if (!m_callback)
45         return;
46
47     callOnMainThread([callback = WTFMove(m_callback)]() mutable {
48         callback(nullptr);
49     });
50 }
51
52 static inline String fromStdString(const std::string& value)
53 {
54     return String::fromUTF8(value.data(), value.length());
55 }
56
57 static inline void fillRTCStats(RTCStatsReport::Stats& stats, const webrtc::RTCStats& rtcStats)
58 {
59     stats.timestamp = Performance::reduceTimeResolution(Seconds::fromMicroseconds(rtcStats.timestamp_us())).milliseconds();
60     stats.id = fromStdString(rtcStats.id());
61 }
62
63 static inline void fillRTCRTPStreamStats(RTCStatsReport::RTCRTPStreamStats& stats, const webrtc::RTCRTPStreamStats& rtcStats)
64 {
65     fillRTCStats(stats, rtcStats);
66
67     if (rtcStats.ssrc.is_defined())
68         stats.ssrc = *rtcStats.ssrc;
69     if (rtcStats.is_remote.is_defined())
70         stats.isRemote = *rtcStats.is_remote;
71     if (rtcStats.media_type.is_defined())
72         stats.mediaType = fromStdString(*rtcStats.media_type);
73     if (rtcStats.track_id.is_defined())
74         stats.trackId = fromStdString(*rtcStats.track_id);
75     if (rtcStats.transport_id.is_defined())
76         stats.transportId = fromStdString(*rtcStats.transport_id);
77     if (rtcStats.codec_id.is_defined())
78         stats.codecId = fromStdString(*rtcStats.codec_id);
79     if (rtcStats.fir_count.is_defined())
80         stats.firCount = *rtcStats.fir_count;
81     if (rtcStats.pli_count.is_defined())
82         stats.pliCount = *rtcStats.pli_count;
83     if (rtcStats.nack_count.is_defined())
84         stats.nackCount = *rtcStats.nack_count;
85     if (rtcStats.sli_count.is_defined())
86         stats.sliCount = *rtcStats.sli_count;
87     if (rtcStats.qp_sum.is_defined())
88         stats.qpSum = *rtcStats.qp_sum;
89     stats.qpSum = 0;
90 }
91
92 static inline void fillInboundRTPStreamStats(RTCStatsReport::InboundRTPStreamStats& stats, const webrtc::RTCInboundRTPStreamStats& rtcStats)
93 {
94     fillRTCRTPStreamStats(stats, rtcStats);
95
96     // FIXME: Add support for decoder_implementation
97     if (rtcStats.packets_received.is_defined())
98         stats.packetsReceived = *rtcStats.packets_received;
99     if (rtcStats.bytes_received.is_defined())
100         stats.bytesReceived = *rtcStats.bytes_received;
101     if (rtcStats.packets_lost.is_defined())
102         stats.packetsLost = *rtcStats.packets_lost;
103     if (rtcStats.jitter.is_defined())
104         stats.jitter = *rtcStats.jitter;
105     // FIXME: Add support back for fractionLost.
106     if (rtcStats.packets_discarded.is_defined())
107         stats.packetsDiscarded = *rtcStats.packets_discarded;
108     if (rtcStats.packets_repaired.is_defined())
109         stats.packetsRepaired = *rtcStats.packets_repaired;
110     if (rtcStats.burst_packets_lost.is_defined())
111         stats.burstPacketsLost = *rtcStats.burst_packets_lost;
112     if (rtcStats.burst_packets_discarded.is_defined())
113         stats.burstPacketsDiscarded = *rtcStats.burst_packets_discarded;
114     if (rtcStats.burst_loss_count.is_defined())
115         stats.burstLossCount = *rtcStats.burst_loss_count;
116     if (rtcStats.burst_discard_count.is_defined())
117         stats.burstDiscardCount = *rtcStats.burst_discard_count;
118     if (rtcStats.burst_loss_rate.is_defined())
119         stats.burstLossRate = *rtcStats.burst_loss_rate;
120     if (rtcStats.burst_discard_rate.is_defined())
121         stats.burstDiscardRate = *rtcStats.burst_discard_rate;
122     if (rtcStats.gap_loss_rate.is_defined())
123         stats.gapLossRate = *rtcStats.gap_loss_rate;
124     if (rtcStats.gap_discard_rate.is_defined())
125         stats.gapDiscardRate = *rtcStats.gap_discard_rate;
126     if (rtcStats.frames_decoded.is_defined())
127         stats.framesDecoded = *rtcStats.frames_decoded;
128 }
129
130 static inline void fillOutboundRTPStreamStats(RTCStatsReport::OutboundRTPStreamStats& stats, const webrtc::RTCOutboundRTPStreamStats& rtcStats)
131 {
132     fillRTCRTPStreamStats(stats, rtcStats);
133
134     // FIXME: Add support for encoder_implementation
135     if (rtcStats.packets_sent.is_defined())
136         stats.packetsSent = *rtcStats.packets_sent;
137     if (rtcStats.bytes_sent.is_defined())
138         stats.bytesSent = *rtcStats.bytes_sent;
139     if (rtcStats.target_bitrate.is_defined())
140         stats.targetBitrate = *rtcStats.target_bitrate;
141     if (rtcStats.frames_encoded.is_defined())
142         stats.framesEncoded = *rtcStats.frames_encoded;
143     if (rtcStats.media_source_id.is_defined())
144         stats.mediaSourceId = fromStdString(*rtcStats.media_source_id);
145 }
146
147 static inline void fillRTCMediaStreamTrackStats(RTCStatsReport::MediaStreamTrackStats& stats, const webrtc::RTCMediaStreamTrackStats& rtcStats)
148 {
149     fillRTCStats(stats, rtcStats);
150
151     if (rtcStats.track_identifier.is_defined())
152         stats.trackIdentifier = fromStdString(*rtcStats.track_identifier);
153     if (rtcStats.remote_source.is_defined())
154         stats.remoteSource = *rtcStats.remote_source;
155     if (rtcStats.ended.is_defined())
156         stats.ended = *rtcStats.ended;
157     if (rtcStats.detached.is_defined())
158         stats.detached = *rtcStats.detached;
159     if (rtcStats.frame_width.is_defined())
160         stats.frameWidth = *rtcStats.frame_width;
161     if (rtcStats.frame_height.is_defined())
162         stats.frameHeight = *rtcStats.frame_height;
163     if (rtcStats.frames_per_second.is_defined())
164         stats.framesPerSecond = *rtcStats.frames_per_second;
165     if (rtcStats.frames_sent.is_defined())
166         stats.framesSent = *rtcStats.frames_sent;
167     if (rtcStats.frames_received.is_defined())
168         stats.framesReceived = *rtcStats.frames_received;
169     if (rtcStats.frames_decoded.is_defined())
170         stats.framesDecoded = *rtcStats.frames_decoded;
171     if (rtcStats.frames_dropped.is_defined())
172         stats.framesDropped = *rtcStats.frames_dropped;
173     if (rtcStats.partial_frames_lost.is_defined())
174         stats.partialFramesLost = *rtcStats.partial_frames_lost;
175     if (rtcStats.full_frames_lost.is_defined())
176         stats.fullFramesLost = *rtcStats.full_frames_lost;
177     if (rtcStats.audio_level.is_defined())
178         stats.audioLevel = *rtcStats.audio_level;
179     if (rtcStats.echo_return_loss.is_defined())
180         stats.echoReturnLoss = *rtcStats.echo_return_loss;
181     if (rtcStats.echo_return_loss_enhancement.is_defined())
182         stats.echoReturnLossEnhancement = *rtcStats.echo_return_loss_enhancement;
183 }
184
185 static inline void fillRTCDataChannelStats(RTCStatsReport::DataChannelStats& stats, const webrtc::RTCDataChannelStats& rtcStats)
186 {
187     fillRTCStats(stats, rtcStats);
188
189     if (rtcStats.label.is_defined())
190         stats.label = fromStdString(*rtcStats.label);
191     if (rtcStats.protocol.is_defined())
192         stats.protocol = fromStdString(*rtcStats.protocol);
193     if (rtcStats.datachannelid.is_defined())
194         stats.datachannelid = *rtcStats.datachannelid;
195     if (rtcStats.state.is_defined())
196         stats.state = fromStdString(*rtcStats.state);
197     if (rtcStats.messages_sent.is_defined())
198         stats.messagesSent = *rtcStats.messages_sent;
199     if (rtcStats.bytes_sent.is_defined())
200         stats.bytesSent = *rtcStats.bytes_sent;
201     if (rtcStats.messages_received.is_defined())
202         stats.messagesReceived = *rtcStats.messages_received;
203     if (rtcStats.bytes_received.is_defined())
204         stats.bytesReceived = *rtcStats.bytes_received;
205 }
206
207 static inline RTCStatsReport::IceCandidatePairState iceCandidatePairState(const std::string& state)
208 {
209     if (state == "frozen")
210         return RTCStatsReport::IceCandidatePairState::Frozen;
211     if (state == "waiting")
212         return RTCStatsReport::IceCandidatePairState::Waiting;
213     if (state == "in-progress")
214         return RTCStatsReport::IceCandidatePairState::Inprogress;
215     if (state == "failed")
216         return RTCStatsReport::IceCandidatePairState::Failed;
217     if (state == "succeeded")
218         return RTCStatsReport::IceCandidatePairState::Succeeded;
219     if (state == "cancelled")
220         return RTCStatsReport::IceCandidatePairState::Cancelled;
221     ASSERT_NOT_REACHED();
222     return RTCStatsReport::IceCandidatePairState::Frozen;
223 }
224
225 static inline void fillRTCIceCandidatePairStats(RTCStatsReport::IceCandidatePairStats& stats, const webrtc::RTCIceCandidatePairStats& rtcStats)
226 {
227     fillRTCStats(stats, rtcStats);
228
229     if (rtcStats.transport_id.is_defined())
230         stats.transportId = fromStdString(*rtcStats.transport_id);
231     if (rtcStats.local_candidate_id.is_defined())
232         stats.localCandidateId = fromStdString(*rtcStats.local_candidate_id);
233     if (rtcStats.remote_candidate_id.is_defined())
234         stats.remoteCandidateId = fromStdString(*rtcStats.remote_candidate_id);
235     if (rtcStats.state.is_defined())
236         stats.state = iceCandidatePairState(*rtcStats.state);
237
238     if (rtcStats.priority.is_defined())
239         stats.priority = *rtcStats.priority;
240     if (rtcStats.nominated.is_defined())
241         stats.nominated = *rtcStats.nominated;
242     if (rtcStats.writable.is_defined())
243         stats.writable = *rtcStats.writable;
244     if (rtcStats.readable.is_defined())
245         stats.readable = *rtcStats.readable;
246
247     if (rtcStats.bytes_sent.is_defined())
248         stats.bytesSent = *rtcStats.bytes_sent;
249     if (rtcStats.bytes_received.is_defined())
250         stats.bytesReceived = *rtcStats.bytes_received;
251     if (rtcStats.total_round_trip_time.is_defined())
252         stats.totalRoundTripTime = *rtcStats.total_round_trip_time;
253     if (rtcStats.current_round_trip_time.is_defined())
254         stats.currentRoundTripTime = *rtcStats.current_round_trip_time;
255     if (rtcStats.available_outgoing_bitrate.is_defined())
256         stats.availableOutgoingBitrate = *rtcStats.available_outgoing_bitrate;
257     if (rtcStats.available_incoming_bitrate.is_defined())
258         stats.availableIncomingBitrate = *rtcStats.available_incoming_bitrate;
259
260     if (rtcStats.requests_received.is_defined())
261         stats.requestsReceived = *rtcStats.requests_received;
262     if (rtcStats.requests_sent.is_defined())
263         stats.requestsSent = *rtcStats.requests_sent;
264     if (rtcStats.responses_received.is_defined())
265         stats.responsesReceived = *rtcStats.responses_received;
266     if (rtcStats.responses_sent.is_defined())
267         stats.responsesSent = *rtcStats.responses_sent;
268
269     if (rtcStats.requests_received.is_defined())
270         stats.retransmissionsReceived = *rtcStats.requests_received;
271     if (rtcStats.requests_sent.is_defined())
272         stats.retransmissionsSent = *rtcStats.requests_sent;
273     if (rtcStats.responses_received.is_defined())
274         stats.consentRequestsReceived = *rtcStats.responses_received;
275     if (rtcStats.responses_sent.is_defined())
276         stats.consentRequestsSent = *rtcStats.responses_sent;
277     if (rtcStats.responses_received.is_defined())
278         stats.consentResponsesReceived = *rtcStats.responses_received;
279     if (rtcStats.responses_sent.is_defined())
280         stats.consentResponsesSent = *rtcStats.responses_sent;
281 }
282
283 static inline Optional<RTCStatsReport::IceCandidateType> iceCandidateState(const std::string& state)
284 {
285     if (state == "host")
286         return RTCStatsReport::IceCandidateType::Host;
287     if (state == "srflx")
288         return RTCStatsReport::IceCandidateType::Srflx;
289     if (state == "prflx")
290         return RTCStatsReport::IceCandidateType::Prflx;
291     if (state == "relay")
292         return RTCStatsReport::IceCandidateType::Relay;
293
294     return { };
295 }
296
297 static inline void fillRTCIceCandidateStats(RTCStatsReport::IceCandidateStats& stats, const webrtc::RTCIceCandidateStats& rtcStats)
298 {
299     stats.type = rtcStats.type() == webrtc::RTCRemoteIceCandidateStats::kType ? RTCStatsReport::Type::RemoteCandidate : RTCStatsReport::Type::LocalCandidate;
300
301     fillRTCStats(stats, rtcStats);
302
303     if (rtcStats.transport_id.is_defined())
304         stats.transportId = fromStdString(*rtcStats.transport_id);
305     if (rtcStats.ip.is_defined())
306         stats.address = fromStdString(*rtcStats.ip);
307     if (rtcStats.port.is_defined())
308         stats.port = *rtcStats.port;
309     if (rtcStats.protocol.is_defined())
310         stats.protocol = fromStdString(*rtcStats.protocol);
311
312     if (rtcStats.candidate_type.is_defined())
313         stats.candidateType = iceCandidateState(*rtcStats.candidate_type);
314
315     if (!stats.candidateType || stats.candidateType == RTCStatsReport::IceCandidateType::Prflx || stats.candidateType == RTCStatsReport::IceCandidateType::Host)
316         stats.address = { };
317
318     if (rtcStats.priority.is_defined())
319         stats.priority = *rtcStats.priority;
320     if (rtcStats.url.is_defined())
321         stats.url = fromStdString(*rtcStats.url);
322     if (rtcStats.deleted.is_defined())
323         stats.deleted = *rtcStats.deleted;
324 }
325
326 static inline void fillRTCCertificateStats(RTCStatsReport::CertificateStats& stats, const webrtc::RTCCertificateStats& rtcStats)
327 {
328     fillRTCStats(stats, rtcStats);
329
330     if (rtcStats.fingerprint.is_defined())
331         stats.fingerprint = fromStdString(*rtcStats.fingerprint);
332     if (rtcStats.fingerprint_algorithm.is_defined())
333         stats.fingerprintAlgorithm = fromStdString(*rtcStats.fingerprint_algorithm);
334     if (rtcStats.base64_certificate.is_defined())
335         stats.base64Certificate = fromStdString(*rtcStats.base64_certificate);
336     if (rtcStats.issuer_certificate_id.is_defined())
337         stats.issuerCertificateId = fromStdString(*rtcStats.issuer_certificate_id);
338 }
339
340 static inline void fillRTCCodecStats(RTCStatsReport::CodecStats& stats, const webrtc::RTCCodecStats& rtcStats)
341 {
342     fillRTCStats(stats, rtcStats);
343
344     if (rtcStats.payload_type.is_defined())
345         stats.payloadType = *rtcStats.payload_type;
346     if (rtcStats.mime_type.is_defined())
347         stats.mimeType = fromStdString(*rtcStats.mime_type);
348     if (rtcStats.clock_rate.is_defined())
349         stats.clockRate = *rtcStats.clock_rate;
350     if (rtcStats.channels.is_defined())
351         stats.channels = *rtcStats.channels;
352     if (rtcStats.sdp_fmtp_line.is_defined())
353         stats.sdpFmtpLine = fromStdString(*rtcStats.sdp_fmtp_line);
354 }
355
356 static inline void fillRTCTransportStats(RTCStatsReport::TransportStats& stats, const webrtc::RTCTransportStats& rtcStats)
357 {
358     fillRTCStats(stats, rtcStats);
359
360     if (rtcStats.bytes_sent.is_defined())
361         stats.bytesSent = *rtcStats.bytes_sent;
362     if (rtcStats.bytes_received.is_defined())
363         stats.bytesReceived = *rtcStats.bytes_received;
364     if (rtcStats.rtcp_transport_stats_id.is_defined())
365         stats.rtcpTransportStatsId = fromStdString(*rtcStats.rtcp_transport_stats_id);
366     if (rtcStats.selected_candidate_pair_id.is_defined())
367         stats.selectedCandidatePairId = fromStdString(*rtcStats.selected_candidate_pair_id);
368     if (rtcStats.local_certificate_id.is_defined())
369         stats.localCertificateId = fromStdString(*rtcStats.local_certificate_id);
370     if (rtcStats.remote_certificate_id.is_defined())
371         stats.remoteCertificateId = fromStdString(*rtcStats.remote_certificate_id);
372 }
373
374 static inline void fillRTCPeerConnectionStats(RTCStatsReport::PeerConnectionStats& stats, const webrtc::RTCPeerConnectionStats& rtcStats)
375 {
376     fillRTCStats(stats, rtcStats);
377
378     if (rtcStats.data_channels_opened.is_defined())
379         stats.dataChannelsOpened = *rtcStats.data_channels_opened;
380     if (rtcStats.data_channels_closed.is_defined())
381         stats.dataChannelsClosed = *rtcStats.data_channels_closed;
382 }
383
384 static inline void fillRTCMediaSourceStats(RTCStatsReport::MediaSourceStats& stats, const webrtc::RTCMediaSourceStats& rtcStats)
385 {
386     fillRTCStats(stats, rtcStats);
387     if (rtcStats.track_identifier.is_defined())
388         stats.trackIdentifier = fromStdString(*rtcStats.track_identifier);
389     if (rtcStats.kind.is_defined())
390         stats.kind = fromStdString(*rtcStats.kind);
391 }
392
393 static inline void fillRTCAudioSourceStats(RTCStatsReport::AudioSourceStats& stats, const webrtc::RTCAudioSourceStats& rtcStats)
394 {
395     fillRTCMediaSourceStats(stats, rtcStats);
396     if (rtcStats.audio_level.is_defined())
397         stats.audioLevel = *rtcStats.audio_level;
398     if (rtcStats.total_audio_energy.is_defined())
399         stats.totalAudioEnergy = *rtcStats.total_audio_energy;
400     if (rtcStats.total_samples_duration.is_defined())
401         stats.totalSamplesDuration = *rtcStats.total_samples_duration;
402 }
403
404 static inline void fillRTCVideoSourceStats(RTCStatsReport::VideoSourceStats& stats, const webrtc::RTCVideoSourceStats& rtcStats)
405 {
406     fillRTCMediaSourceStats(stats, rtcStats);
407
408     if (rtcStats.width.is_defined())
409         stats.width = *rtcStats.width;
410     if (rtcStats.height.is_defined())
411         stats.height = *rtcStats.height;
412     if (rtcStats.frames.is_defined())
413         stats.frames = *rtcStats.frames;
414     if (rtcStats.frames_per_second.is_defined())
415         stats.framesPerSecond = *rtcStats.frames_per_second;
416 }
417
418 static inline void initializeRTCStatsReportBackingMap(DOMMapAdapter& report, const webrtc::RTCStatsReport& rtcReport)
419 {
420     for (const auto& rtcStats : rtcReport) {
421         if (rtcStats.type() == webrtc::RTCInboundRTPStreamStats::kType) {
422             RTCStatsReport::InboundRTPStreamStats stats;
423             fillInboundRTPStreamStats(stats, static_cast<const webrtc::RTCInboundRTPStreamStats&>(rtcStats));
424             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::InboundRTPStreamStats>>(stats.id, WTFMove(stats));
425         } else if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
426             RTCStatsReport::OutboundRTPStreamStats stats;
427             fillOutboundRTPStreamStats(stats, static_cast<const webrtc::RTCOutboundRTPStreamStats&>(rtcStats));
428             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::OutboundRTPStreamStats>>(stats.id, WTFMove(stats));
429         } else if (rtcStats.type() == webrtc::RTCMediaStreamTrackStats::kType) {
430             RTCStatsReport::MediaStreamTrackStats stats;
431             fillRTCMediaStreamTrackStats(stats, static_cast<const webrtc::RTCMediaStreamTrackStats&>(rtcStats));
432             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::MediaStreamTrackStats>>(stats.id, WTFMove(stats));
433         } else if (rtcStats.type() == webrtc::RTCDataChannelStats::kType) {
434             RTCStatsReport::DataChannelStats stats;
435             fillRTCDataChannelStats(stats, static_cast<const webrtc::RTCDataChannelStats&>(rtcStats));
436             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::DataChannelStats>>(stats.id, WTFMove(stats));
437         } else if (rtcStats.type() == webrtc::RTCIceCandidatePairStats::kType) {
438             RTCStatsReport::IceCandidatePairStats stats;
439             fillRTCIceCandidatePairStats(stats, static_cast<const webrtc::RTCIceCandidatePairStats&>(rtcStats));
440             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::IceCandidatePairStats>>(stats.id, WTFMove(stats));
441         } else if (rtcStats.type() == webrtc::RTCRemoteIceCandidateStats::kType || rtcStats.type() == webrtc::RTCLocalIceCandidateStats::kType) {
442             RTCStatsReport::IceCandidateStats stats;
443             fillRTCIceCandidateStats(stats, static_cast<const webrtc::RTCIceCandidateStats&>(rtcStats));
444             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::IceCandidateStats>>(stats.id, WTFMove(stats));
445         } else if (rtcStats.type() == webrtc::RTCCertificateStats::kType) {
446             RTCStatsReport::CertificateStats stats;
447             fillRTCCertificateStats(stats, static_cast<const webrtc::RTCCertificateStats&>(rtcStats));
448             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::CertificateStats>>(stats.id, WTFMove(stats));
449         } else if (rtcStats.type() == webrtc::RTCCodecStats::kType) {
450             RTCStatsReport::CodecStats stats;
451             fillRTCCodecStats(stats, static_cast<const webrtc::RTCCodecStats&>(rtcStats));
452             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::CodecStats>>(stats.id, WTFMove(stats));
453         } else if (rtcStats.type() == webrtc::RTCTransportStats::kType) {
454             RTCStatsReport::TransportStats stats;
455             fillRTCTransportStats(stats, static_cast<const webrtc::RTCTransportStats&>(rtcStats));
456             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::TransportStats>>(stats.id, WTFMove(stats));
457         } else if (rtcStats.type() == webrtc::RTCPeerConnectionStats::kType) {
458             RTCStatsReport::PeerConnectionStats stats;
459             fillRTCPeerConnectionStats(stats, static_cast<const webrtc::RTCPeerConnectionStats&>(rtcStats));
460             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::PeerConnectionStats>>(stats.id, WTFMove(stats));
461         } else if (rtcStats.type() == webrtc::RTCAudioSourceStats::kType) {
462             RTCStatsReport::AudioSourceStats stats;
463             fillRTCAudioSourceStats(stats, static_cast<const webrtc::RTCAudioSourceStats&>(rtcStats));
464             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::AudioSourceStats>>(stats.id, WTFMove(stats));
465         } else if (rtcStats.type() == webrtc::RTCVideoSourceStats::kType) {
466             RTCStatsReport::VideoSourceStats stats;
467             fillRTCVideoSourceStats(stats, static_cast<const webrtc::RTCVideoSourceStats&>(rtcStats));
468             report.set<IDLDOMString, IDLDictionary<RTCStatsReport::VideoSourceStats>>(stats.id, WTFMove(stats));
469         }
470     }
471 }
472
473 void LibWebRTCStatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>& rtcReport)
474 {
475     callOnMainThread([this, protectedThis = rtc::scoped_refptr<LibWebRTCStatsCollector>(this), rtcReport]() {
476         m_callback(RTCStatsReport::create([rtcReport](auto& mapAdapter) {
477             if (rtcReport)
478                 initializeRTCStatsReportBackingMap(mapAdapter, *rtcReport);
479         }));
480     });
481 }
482
483 }; // namespace WTF
484
485
486 #endif // USE(LIBWEBRTC)