| 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): When "AddTrack" is implemented we should iterate tracks to |
| 237 // find which streams exist, not iterate streams to find tracks. |
| 238 // crbug.com/659137 |
| 239 // TODO(hbos): Return stats of detached tracks. We have to perform stats |
| 240 // gathering at the time of detachment to get accurate stats and timestamps. |
| 241 // crbug.com/659137 |
| 242 if (!streams) |
| 243 return; |
| 244 for (size_t i = 0; i < streams->count(); ++i) { |
| 245 MediaStreamInterface* stream = streams->at(i); |
| 246 |
| 247 std::unique_ptr<RTCMediaStreamStats> stream_stats( |
| 248 new RTCMediaStreamStats("RTCMediaStream_" + stream->label(), |
| 249 timestamp_us)); |
| 250 stream_stats->stream_identifier = stream->label(); |
| 251 stream_stats->track_ids = std::vector<std::string>(); |
| 252 // Audio Tracks |
| 253 for (rtc::scoped_refptr<AudioTrackInterface> audio_track : |
| 254 stream->GetAudioTracks()) { |
| 255 std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
| 256 *audio_track.get()); |
| 257 if (report->Get(id)) { |
| 258 // Skip track, stats already exist for it. |
| 259 continue; |
| 260 } |
| 261 std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats( |
| 262 new RTCMediaStreamTrackStats(id, timestamp_us)); |
| 263 stream_stats->track_ids->push_back(audio_track_stats->id()); |
| 264 SetMediaStreamTrackStatsFromMediaStreamTrackInterface( |
| 265 *audio_track.get(), |
| 266 audio_track_stats.get()); |
| 267 audio_track_stats->remote_source = !is_local; |
| 268 audio_track_stats->detached = false; |
| 269 int signal_level; |
| 270 if (audio_track->GetSignalLevel(&signal_level)) { |
| 271 // Convert signal level from [0,32767] int to [0,1] double. |
| 272 RTC_DCHECK_GE(signal_level, 0); |
| 273 RTC_DCHECK_LE(signal_level, 32767); |
| 274 audio_track_stats->audio_level = signal_level / 32767.0; |
| 275 } |
| 276 if (audio_track->GetAudioProcessor()) { |
| 277 AudioProcessorInterface::AudioProcessorStats audio_processor_stats; |
| 278 audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats); |
| 279 audio_track_stats->echo_return_loss = static_cast<double>( |
| 280 audio_processor_stats.echo_return_loss); |
| 281 audio_track_stats->echo_return_loss_enhancement = static_cast<double>( |
| 282 audio_processor_stats.echo_return_loss_enhancement); |
| 283 } |
| 284 report->AddStats(std::move(audio_track_stats)); |
| 285 } |
| 286 // Video Tracks |
| 287 for (rtc::scoped_refptr<VideoTrackInterface> video_track : |
| 288 stream->GetVideoTracks()) { |
| 289 std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
| 290 *video_track.get()); |
| 291 if (report->Get(id)) { |
| 292 // Skip track, stats already exist for it. |
| 293 continue; |
| 294 } |
| 295 std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats( |
| 296 new RTCMediaStreamTrackStats(id, timestamp_us)); |
| 297 stream_stats->track_ids->push_back(video_track_stats->id()); |
| 298 SetMediaStreamTrackStatsFromMediaStreamTrackInterface( |
| 299 *video_track.get(), |
| 300 video_track_stats.get()); |
| 301 video_track_stats->remote_source = !is_local; |
| 302 video_track_stats->detached = false; |
| 303 if (video_track->GetSource()) { |
| 304 VideoTrackSourceInterface::Stats video_track_source_stats; |
| 305 if (video_track->GetSource()->GetStats(&video_track_source_stats)) { |
| 306 video_track_stats->frame_width = static_cast<uint32_t>( |
| 307 video_track_source_stats.input_width); |
| 308 video_track_stats->frame_height = static_cast<uint32_t>( |
| 309 video_track_source_stats.input_height); |
| 310 } |
| 311 } |
| 312 report->AddStats(std::move(video_track_stats)); |
| 313 } |
| 314 report->AddStats(std::move(stream_stats)); |
| 315 } |
| 316 } |
| 317 |
| 217 } // namespace | 318 } // namespace |
| 218 | 319 |
| 219 rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( | 320 rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( |
| 220 PeerConnection* pc, int64_t cache_lifetime_us) { | 321 PeerConnection* pc, int64_t cache_lifetime_us) { |
| 221 return rtc::scoped_refptr<RTCStatsCollector>( | 322 return rtc::scoped_refptr<RTCStatsCollector>( |
| 222 new rtc::RefCountedObject<RTCStatsCollector>(pc, cache_lifetime_us)); | 323 new rtc::RefCountedObject<RTCStatsCollector>(pc, cache_lifetime_us)); |
| 223 } | 324 } |
| 224 | 325 |
| 225 RTCStatsCollector::RTCStatsCollector(PeerConnection* pc, | 326 RTCStatsCollector::RTCStatsCollector(PeerConnection* pc, |
| 226 int64_t cache_lifetime_us) | 327 int64_t cache_lifetime_us) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 ProduceCertificateStats_s( | 395 ProduceCertificateStats_s( |
| 295 timestamp_us, transport_cert_stats, report.get()); | 396 timestamp_us, transport_cert_stats, report.get()); |
| 296 ProduceIceCandidateAndPairStats_s( | 397 ProduceIceCandidateAndPairStats_s( |
| 297 timestamp_us, session_stats, report.get()); | 398 timestamp_us, session_stats, report.get()); |
| 298 ProduceRTPStreamStats_s( | 399 ProduceRTPStreamStats_s( |
| 299 timestamp_us, session_stats, report.get()); | 400 timestamp_us, session_stats, report.get()); |
| 300 ProduceTransportStats_s( | 401 ProduceTransportStats_s( |
| 301 timestamp_us, session_stats, transport_cert_stats, report.get()); | 402 timestamp_us, session_stats, transport_cert_stats, report.get()); |
| 302 } | 403 } |
| 303 ProduceDataChannelStats_s(timestamp_us, report.get()); | 404 ProduceDataChannelStats_s(timestamp_us, report.get()); |
| 405 ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get()); |
| 304 ProducePeerConnectionStats_s(timestamp_us, report.get()); | 406 ProducePeerConnectionStats_s(timestamp_us, report.get()); |
| 305 | 407 |
| 306 AddPartialResults(report); | 408 AddPartialResults(report); |
| 307 } | 409 } |
| 308 | 410 |
| 309 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( | 411 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( |
| 310 int64_t timestamp_us) { | 412 int64_t timestamp_us) { |
| 311 RTC_DCHECK(worker_thread_->IsCurrent()); | 413 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 312 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( | 414 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( |
| 313 timestamp_us); | 415 timestamp_us); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 static_cast<uint64_t>(info.recv_ping_responses); | 562 static_cast<uint64_t>(info.recv_ping_responses); |
| 461 candidate_pair_stats->responses_sent = | 563 candidate_pair_stats->responses_sent = |
| 462 static_cast<uint64_t>(info.sent_ping_responses); | 564 static_cast<uint64_t>(info.sent_ping_responses); |
| 463 | 565 |
| 464 report->AddStats(std::move(candidate_pair_stats)); | 566 report->AddStats(std::move(candidate_pair_stats)); |
| 465 } | 567 } |
| 466 } | 568 } |
| 467 } | 569 } |
| 468 } | 570 } |
| 469 | 571 |
| 572 void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s( |
| 573 int64_t timestamp_us, RTCStatsReport* report) const { |
| 574 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 575 ProduceMediaStreamAndTrackStats( |
| 576 timestamp_us, pc_->local_streams(), true, report); |
| 577 ProduceMediaStreamAndTrackStats( |
| 578 timestamp_us, pc_->remote_streams(), false, report); |
| 579 } |
| 580 |
| 470 void RTCStatsCollector::ProducePeerConnectionStats_s( | 581 void RTCStatsCollector::ProducePeerConnectionStats_s( |
| 471 int64_t timestamp_us, RTCStatsReport* report) const { | 582 int64_t timestamp_us, RTCStatsReport* report) const { |
| 472 RTC_DCHECK(signaling_thread_->IsCurrent()); | 583 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 473 // TODO(hbos): If data channels are removed from the peer connection this will | 584 // TODO(hbos): If data channels are removed from the peer connection this will |
| 474 // yield incorrect counts. Address before closing crbug.com/636818. See | 585 // yield incorrect counts. Address before closing crbug.com/636818. See |
| 475 // https://w3c.github.io/webrtc-stats/webrtc-stats.html#pcstats-dict*. | 586 // https://w3c.github.io/webrtc-stats/webrtc-stats.html#pcstats-dict*. |
| 476 uint32_t data_channels_opened = 0; | 587 uint32_t data_channels_opened = 0; |
| 477 const std::vector<rtc::scoped_refptr<DataChannel>>& data_channels = | 588 const std::vector<rtc::scoped_refptr<DataChannel>>& data_channels = |
| 478 pc_->sctp_data_channels(); | 589 pc_->sctp_data_channels(); |
| 479 for (const rtc::scoped_refptr<DataChannel>& data_channel : data_channels) { | 590 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) { | 790 const std::string& type) { |
| 680 return CandidateTypeToRTCIceCandidateType(type); | 791 return CandidateTypeToRTCIceCandidateType(type); |
| 681 } | 792 } |
| 682 | 793 |
| 683 const char* DataStateToRTCDataChannelStateForTesting( | 794 const char* DataStateToRTCDataChannelStateForTesting( |
| 684 DataChannelInterface::DataState state) { | 795 DataChannelInterface::DataState state) { |
| 685 return DataStateToRTCDataChannelState(state); | 796 return DataStateToRTCDataChannelState(state); |
| 686 } | 797 } |
| 687 | 798 |
| 688 } // namespace webrtc | 799 } // namespace webrtc |
| OLD | NEW |