OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/api/rtcstatscollector.h" | 11 #include "webrtc/api/rtcstatscollector.h" |
12 | 12 |
13 #include <memory> | 13 #include <memory> |
14 #include <utility> | 14 #include <utility> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "webrtc/api/peerconnection.h" | 17 #include "webrtc/api/peerconnection.h" |
18 #include "webrtc/api/peerconnectioninterface.h" | |
19 #include "webrtc/api/mediastreaminterface.h" | |
18 #include "webrtc/api/webrtcsession.h" | 20 #include "webrtc/api/webrtcsession.h" |
19 #include "webrtc/base/checks.h" | 21 #include "webrtc/base/checks.h" |
20 #include "webrtc/base/timeutils.h" | 22 #include "webrtc/base/timeutils.h" |
21 #include "webrtc/media/base/mediachannel.h" | 23 #include "webrtc/media/base/mediachannel.h" |
22 #include "webrtc/p2p/base/candidate.h" | 24 #include "webrtc/p2p/base/candidate.h" |
23 #include "webrtc/p2p/base/p2pconstants.h" | 25 #include "webrtc/p2p/base/p2pconstants.h" |
24 #include "webrtc/p2p/base/port.h" | 26 #include "webrtc/p2p/base/port.h" |
25 | 27 |
26 namespace webrtc { | 28 namespace webrtc { |
27 | 29 |
28 namespace { | 30 namespace { |
29 | 31 |
30 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { | 32 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { |
31 return "RTCCertificate_" + fingerprint; | 33 return "RTCCertificate_" + fingerprint; |
32 } | 34 } |
33 | 35 |
34 std::string RTCIceCandidatePairStatsIDFromConnectionInfo( | 36 std::string RTCIceCandidatePairStatsIDFromConnectionInfo( |
35 const cricket::ConnectionInfo& info) { | 37 const cricket::ConnectionInfo& info) { |
36 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + | 38 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + |
37 info.remote_candidate.id(); | 39 info.remote_candidate.id(); |
38 } | 40 } |
39 | 41 |
42 std::string RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( | |
43 const MediaStreamTrackInterface& track) { | |
44 return "RTCMediaStreamTrack_" + track.id(); | |
45 } | |
46 | |
40 std::string RTCTransportStatsIDFromTransportChannel( | 47 std::string RTCTransportStatsIDFromTransportChannel( |
41 const std::string& transport_name, int channel_component) { | 48 const std::string& transport_name, int channel_component) { |
42 return "RTCTransport_" + transport_name + "_" + | 49 return "RTCTransport_" + transport_name + "_" + |
43 rtc::ToString<>(channel_component); | 50 rtc::ToString<>(channel_component); |
44 } | 51 } |
45 | 52 |
46 std::string RTCTransportStatsIDFromBaseChannel( | 53 std::string RTCTransportStatsIDFromBaseChannel( |
47 const ProxyTransportMap& proxy_to_transport, | 54 const ProxyTransportMap& proxy_to_transport, |
48 const cricket::BaseChannel& base_channel) { | 55 const cricket::BaseChannel& base_channel) { |
49 auto proxy_it = proxy_to_transport.find(base_channel.content_name()); | 56 auto proxy_it = proxy_to_transport.find(base_channel.content_name()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 case DataChannelInterface::kClosing: | 93 case DataChannelInterface::kClosing: |
87 return RTCDataChannelState::kClosing; | 94 return RTCDataChannelState::kClosing; |
88 case DataChannelInterface::kClosed: | 95 case DataChannelInterface::kClosed: |
89 return RTCDataChannelState::kClosed; | 96 return RTCDataChannelState::kClosed; |
90 default: | 97 default: |
91 RTC_NOTREACHED(); | 98 RTC_NOTREACHED(); |
92 return nullptr; | 99 return nullptr; |
93 } | 100 } |
94 } | 101 } |
95 | 102 |
103 void SetMediaStreamTrackStatsFromMediaStreamTrackInterface( | |
104 const MediaStreamTrackInterface& track, | |
105 RTCMediaStreamTrackStats* track_stats) { | |
106 track_stats->track_identifier = track.id(); | |
107 track_stats->ended = (track.state() == MediaStreamTrackInterface::kEnded); | |
108 } | |
109 | |
96 void SetInboundRTPStreamStatsFromMediaReceiverInfo( | 110 void SetInboundRTPStreamStatsFromMediaReceiverInfo( |
97 const cricket::MediaReceiverInfo& media_receiver_info, | 111 const cricket::MediaReceiverInfo& media_receiver_info, |
98 RTCInboundRTPStreamStats* inbound_stats) { | 112 RTCInboundRTPStreamStats* inbound_stats) { |
99 RTC_DCHECK(inbound_stats); | 113 RTC_DCHECK(inbound_stats); |
100 inbound_stats->ssrc = rtc::ToString<>(media_receiver_info.ssrc()); | 114 inbound_stats->ssrc = rtc::ToString<>(media_receiver_info.ssrc()); |
101 // TODO(hbos): Support the remote case. crbug.com/657855 | 115 // TODO(hbos): Support the remote case. crbug.com/657855 |
102 inbound_stats->is_remote = false; | 116 inbound_stats->is_remote = false; |
103 // TODO(hbos): Set |codec_id| when we have |RTCCodecStats|. Maybe relevant: | 117 // TODO(hbos): Set |codec_id| when we have |RTCCodecStats|. Maybe relevant: |
104 // |media_receiver_info.codec_name|. crbug.com/657854, 657855, 659117 | 118 // |media_receiver_info.codec_name|. crbug.com/657854, 657855, 659117 |
105 inbound_stats->packets_received = | 119 inbound_stats->packets_received = |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 candidate_stats->priority = static_cast<int32_t>(candidate.priority()); | 221 candidate_stats->priority = static_cast<int32_t>(candidate.priority()); |
208 | 222 |
209 stats = candidate_stats.get(); | 223 stats = candidate_stats.get(); |
210 report->AddStats(std::move(candidate_stats)); | 224 report->AddStats(std::move(candidate_stats)); |
211 } | 225 } |
212 RTC_DCHECK_EQ(stats->type(), is_local ? RTCLocalIceCandidateStats::kType | 226 RTC_DCHECK_EQ(stats->type(), is_local ? RTCLocalIceCandidateStats::kType |
213 : RTCRemoteIceCandidateStats::kType); | 227 : RTCRemoteIceCandidateStats::kType); |
214 return stats->id(); | 228 return stats->id(); |
215 } | 229 } |
216 | 230 |
231 void ProduceMediaStreamAndTrackStats( | |
232 int64_t timestamp_us, | |
233 rtc::scoped_refptr<StreamCollectionInterface> streams, | |
234 bool is_local, | |
235 RTCStatsReport* report) { | |
236 // TODO(hbos): This gets the current stream/track stats. The spec says that | |
237 // stream/track stats should appear in the stats as soon as they have been | |
238 // attached. This means we need to invalidate the collector's cache upon | |
239 // attaching or in some other way make sure that the new streams/tracks are | |
240 // accounted for. crbug.com/659137 | |
241 // TODO(hbos): Also return detached tracks' stats (no longer present when | |
242 // iterating). The spec says the state should be a snapshot of the track at | |
243 // the moment of detachment. This means we have to either keep the track as-is | |
244 // after detachment or perform stats collection upon detachment. | |
245 // crbug.com/659137 | |
hbos
2016/11/02 11:54:44
Is it not the case that a stream can be detached a
hta-webrtc
2016/11/03 14:34:21
The spec has strongly deemphasized streams. In fac
hbos
2016/11/03 18:10:30
Acknowledged.
| |
246 if (!streams) | |
247 return; | |
248 for (size_t i = 0; i < streams->count(); ++i) { | |
249 MediaStreamInterface* stream = streams->at(i); | |
250 | |
251 std::unique_ptr<RTCMediaStreamStats> stream_stats( | |
252 new RTCMediaStreamStats("RTCMediaStream_" + stream->label(), | |
253 timestamp_us)); | |
254 stream_stats->stream_identifier = stream->label(); | |
255 stream_stats->track_ids = std::vector<std::string>(); | |
256 // Audio Tracks | |
257 for (rtc::scoped_refptr<AudioTrackInterface> audio_track : | |
258 stream->GetAudioTracks()) { | |
259 std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats( | |
260 new RTCMediaStreamTrackStats( | |
261 RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( | |
262 *audio_track.get()), | |
263 timestamp_us)); | |
264 stream_stats->track_ids->push_back(audio_track_stats->id()); | |
hta-webrtc
2016/11/03 14:34:21
Consider what happens here if a track is a member
hbos
2016/11/03 18:10:30
Done. Skipping if already exists.
| |
265 SetMediaStreamTrackStatsFromMediaStreamTrackInterface( | |
266 *audio_track.get(), | |
267 audio_track_stats.get()); | |
268 audio_track_stats->remote_source = !is_local; | |
269 audio_track_stats->detached = false; | |
270 int signal_level; | |
271 if (audio_track->GetSignalLevel(&signal_level)) { | |
272 // Convert signal level from [0,32767] int to [0,1] double. | |
273 RTC_DCHECK_GE(signal_level, 0); | |
274 RTC_DCHECK_LE(signal_level, 32767); | |
275 audio_track_stats->audio_level = signal_level / 32767.0; | |
hta-webrtc
2016/11/03 14:34:21
Check this one with Niklas. Audio levels are awful
hbos
2016/11/03 18:10:30
+niklase: Is this the correct way to get the audio
| |
276 } | |
277 if (audio_track->GetAudioProcessor()) { | |
278 AudioProcessorInterface::AudioProcessorStats audio_processor_stats; | |
279 audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats); | |
280 audio_track_stats->echo_return_loss = static_cast<double>( | |
281 audio_processor_stats.echo_return_loss); | |
282 audio_track_stats->echo_return_loss_enhancement = static_cast<double>( | |
283 audio_processor_stats.echo_return_loss_enhancement); | |
284 } | |
285 report->AddStats(std::move(audio_track_stats)); | |
286 } | |
287 // Video Tracks | |
288 for (rtc::scoped_refptr<VideoTrackInterface> video_track : | |
289 stream->GetVideoTracks()) { | |
290 std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats( | |
291 new RTCMediaStreamTrackStats( | |
292 RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( | |
293 *video_track.get()), | |
294 timestamp_us)); | |
295 stream_stats->track_ids->push_back(video_track_stats->id()); | |
296 SetMediaStreamTrackStatsFromMediaStreamTrackInterface( | |
297 *video_track.get(), | |
298 video_track_stats.get()); | |
299 video_track_stats->remote_source = !is_local; | |
300 video_track_stats->detached = false; | |
301 if (video_track->GetSource()) { | |
302 VideoTrackSourceInterface::Stats video_track_source_stats; | |
303 if (video_track->GetSource()->GetStats(&video_track_source_stats)) { | |
304 video_track_stats->frame_width = static_cast<uint32_t>( | |
305 video_track_source_stats.input_width); | |
306 video_track_stats->frame_height = static_cast<uint32_t>( | |
307 video_track_source_stats.input_height); | |
hbos
2016/11/02 11:44:55
I wonder if this is the right value. What if the s
hbos
2016/11/02 11:48:41
And there are similar stats to the spec in Video[S
hta-webrtc
2016/11/03 14:34:21
Yes. More work needed both for getSettings and for
hta-webrtc
2016/11/03 14:34:21
It should be the downscaled value. I have a TODO t
hbos
2016/11/03 18:10:30
What are you referring to when you say "getSetting
hta-webrtc
2016/11/04 16:30:01
https://w3c.github.io/mediacapture-main/getusermed
| |
308 } | |
309 } | |
310 report->AddStats(std::move(video_track_stats)); | |
311 } | |
312 report->AddStats(std::move(stream_stats)); | |
313 } | |
314 } | |
315 | |
217 } // namespace | 316 } // namespace |
218 | 317 |
219 rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( | 318 rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( |
220 PeerConnection* pc, int64_t cache_lifetime_us) { | 319 PeerConnection* pc, int64_t cache_lifetime_us) { |
221 return rtc::scoped_refptr<RTCStatsCollector>( | 320 return rtc::scoped_refptr<RTCStatsCollector>( |
222 new rtc::RefCountedObject<RTCStatsCollector>(pc, cache_lifetime_us)); | 321 new rtc::RefCountedObject<RTCStatsCollector>(pc, cache_lifetime_us)); |
223 } | 322 } |
224 | 323 |
225 RTCStatsCollector::RTCStatsCollector(PeerConnection* pc, | 324 RTCStatsCollector::RTCStatsCollector(PeerConnection* pc, |
226 int64_t cache_lifetime_us) | 325 int64_t cache_lifetime_us) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 ProduceCertificateStats_s( | 393 ProduceCertificateStats_s( |
295 timestamp_us, transport_cert_stats, report.get()); | 394 timestamp_us, transport_cert_stats, report.get()); |
296 ProduceIceCandidateAndPairStats_s( | 395 ProduceIceCandidateAndPairStats_s( |
297 timestamp_us, session_stats, report.get()); | 396 timestamp_us, session_stats, report.get()); |
298 ProduceRTPStreamStats_s( | 397 ProduceRTPStreamStats_s( |
299 timestamp_us, session_stats, report.get()); | 398 timestamp_us, session_stats, report.get()); |
300 ProduceTransportStats_s( | 399 ProduceTransportStats_s( |
301 timestamp_us, session_stats, transport_cert_stats, report.get()); | 400 timestamp_us, session_stats, transport_cert_stats, report.get()); |
302 } | 401 } |
303 ProduceDataChannelStats_s(timestamp_us, report.get()); | 402 ProduceDataChannelStats_s(timestamp_us, report.get()); |
403 ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get()); | |
304 ProducePeerConnectionStats_s(timestamp_us, report.get()); | 404 ProducePeerConnectionStats_s(timestamp_us, report.get()); |
305 | 405 |
306 AddPartialResults(report); | 406 AddPartialResults(report); |
307 } | 407 } |
308 | 408 |
309 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( | 409 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( |
310 int64_t timestamp_us) { | 410 int64_t timestamp_us) { |
311 RTC_DCHECK(worker_thread_->IsCurrent()); | 411 RTC_DCHECK(worker_thread_->IsCurrent()); |
312 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( | 412 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( |
313 timestamp_us); | 413 timestamp_us); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 static_cast<uint64_t>(info.recv_ping_responses); | 560 static_cast<uint64_t>(info.recv_ping_responses); |
461 candidate_pair_stats->responses_sent = | 561 candidate_pair_stats->responses_sent = |
462 static_cast<uint64_t>(info.sent_ping_responses); | 562 static_cast<uint64_t>(info.sent_ping_responses); |
463 | 563 |
464 report->AddStats(std::move(candidate_pair_stats)); | 564 report->AddStats(std::move(candidate_pair_stats)); |
465 } | 565 } |
466 } | 566 } |
467 } | 567 } |
468 } | 568 } |
469 | 569 |
570 void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s( | |
571 int64_t timestamp_us, RTCStatsReport* report) const { | |
572 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
573 ProduceMediaStreamAndTrackStats( | |
574 timestamp_us, pc_->local_streams(), true, report); | |
575 ProduceMediaStreamAndTrackStats( | |
576 timestamp_us, pc_->remote_streams(), false, report); | |
577 } | |
578 | |
470 void RTCStatsCollector::ProducePeerConnectionStats_s( | 579 void RTCStatsCollector::ProducePeerConnectionStats_s( |
471 int64_t timestamp_us, RTCStatsReport* report) const { | 580 int64_t timestamp_us, RTCStatsReport* report) const { |
472 RTC_DCHECK(signaling_thread_->IsCurrent()); | 581 RTC_DCHECK(signaling_thread_->IsCurrent()); |
473 // TODO(hbos): If data channels are removed from the peer connection this will | 582 // TODO(hbos): If data channels are removed from the peer connection this will |
474 // yield incorrect counts. Address before closing crbug.com/636818. See | 583 // yield incorrect counts. Address before closing crbug.com/636818. See |
475 // https://w3c.github.io/webrtc-stats/webrtc-stats.html#pcstats-dict*. | 584 // https://w3c.github.io/webrtc-stats/webrtc-stats.html#pcstats-dict*. |
476 uint32_t data_channels_opened = 0; | 585 uint32_t data_channels_opened = 0; |
477 const std::vector<rtc::scoped_refptr<DataChannel>>& data_channels = | 586 const std::vector<rtc::scoped_refptr<DataChannel>>& data_channels = |
478 pc_->sctp_data_channels(); | 587 pc_->sctp_data_channels(); |
479 for (const rtc::scoped_refptr<DataChannel>& data_channel : data_channels) { | 588 for (const rtc::scoped_refptr<DataChannel>& data_channel : data_channels) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 const std::string& type) { | 788 const std::string& type) { |
680 return CandidateTypeToRTCIceCandidateType(type); | 789 return CandidateTypeToRTCIceCandidateType(type); |
681 } | 790 } |
682 | 791 |
683 const char* DataStateToRTCDataChannelStateForTesting( | 792 const char* DataStateToRTCDataChannelStateForTesting( |
684 DataChannelInterface::DataState state) { | 793 DataChannelInterface::DataState state) { |
685 return DataStateToRTCDataChannelState(state); | 794 return DataStateToRTCDataChannelState(state); |
686 } | 795 } |
687 | 796 |
688 } // namespace webrtc | 797 } // namespace webrtc |
OLD | NEW |