Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: webrtc/api/rtcstatscollector.cc

Issue 2456463002: RTCOutboundRTPStreamStats added. (Closed)
Patch Set: Rebase and TODO for target_bitrate Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/rtcstatscollector.h ('k') | webrtc/api/rtcstatscollector_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/webrtcsession.h" 18 #include "webrtc/api/webrtcsession.h"
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/base/timeutils.h"
21 #include "webrtc/media/base/mediachannel.h"
20 #include "webrtc/p2p/base/candidate.h" 22 #include "webrtc/p2p/base/candidate.h"
21 #include "webrtc/p2p/base/p2pconstants.h" 23 #include "webrtc/p2p/base/p2pconstants.h"
22 #include "webrtc/p2p/base/port.h" 24 #include "webrtc/p2p/base/port.h"
23 25
24 namespace webrtc { 26 namespace webrtc {
25 27
26 namespace { 28 namespace {
27 29
28 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { 30 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) {
29 return "RTCCertificate_" + fingerprint; 31 return "RTCCertificate_" + fingerprint;
30 } 32 }
31 33
32 std::string RTCIceCandidatePairStatsIDFromConnectionInfo( 34 std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
33 const cricket::ConnectionInfo& info) { 35 const cricket::ConnectionInfo& info) {
34 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + 36 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" +
35 info.remote_candidate.id(); 37 info.remote_candidate.id();
36 } 38 }
37 39
38 std::string RTCTransportStatsIDFromTransportChannel( 40 std::string RTCTransportStatsIDFromTransportChannel(
39 const std::string& transport_name, int channel_component) { 41 const std::string& transport_name, int channel_component) {
40 return "RTCTransport_" + transport_name + "_" + 42 return "RTCTransport_" + transport_name + "_" +
41 rtc::ToString<>(channel_component); 43 rtc::ToString<>(channel_component);
42 } 44 }
43 45
46 std::string RTCTransportStatsIDFromBaseChannel(
47 const ProxyTransportMap& proxy_to_transport,
48 const cricket::BaseChannel& base_channel) {
49 auto proxy_it = proxy_to_transport.find(base_channel.content_name());
50 if (proxy_it == proxy_to_transport.cend())
51 return "";
52 return RTCTransportStatsIDFromTransportChannel(
53 proxy_it->second, cricket::ICE_CANDIDATE_COMPONENT_RTP);
54 }
55
56 std::string RTCOutboundRTPStreamStatsIDFromSSRC(bool audio, uint32_t ssrc) {
57 return audio ? "RTCOutboundRTPAudioStream_" + rtc::ToString<>(ssrc)
58 : "RTCOutboundRTPVideoStream_" + rtc::ToString<>(ssrc);
59 }
60
44 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { 61 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) {
45 if (type == cricket::LOCAL_PORT_TYPE) 62 if (type == cricket::LOCAL_PORT_TYPE)
46 return RTCIceCandidateType::kHost; 63 return RTCIceCandidateType::kHost;
47 if (type == cricket::STUN_PORT_TYPE) 64 if (type == cricket::STUN_PORT_TYPE)
48 return RTCIceCandidateType::kSrflx; 65 return RTCIceCandidateType::kSrflx;
49 if (type == cricket::PRFLX_PORT_TYPE) 66 if (type == cricket::PRFLX_PORT_TYPE)
50 return RTCIceCandidateType::kPrflx; 67 return RTCIceCandidateType::kPrflx;
51 if (type == cricket::RELAY_PORT_TYPE) 68 if (type == cricket::RELAY_PORT_TYPE)
52 return RTCIceCandidateType::kRelay; 69 return RTCIceCandidateType::kRelay;
53 RTC_NOTREACHED(); 70 RTC_NOTREACHED();
(...skipping 10 matching lines...) Expand all
64 case DataChannelInterface::kClosing: 81 case DataChannelInterface::kClosing:
65 return RTCDataChannelState::kClosing; 82 return RTCDataChannelState::kClosing;
66 case DataChannelInterface::kClosed: 83 case DataChannelInterface::kClosed:
67 return RTCDataChannelState::kClosed; 84 return RTCDataChannelState::kClosed;
68 default: 85 default:
69 RTC_NOTREACHED(); 86 RTC_NOTREACHED();
70 return nullptr; 87 return nullptr;
71 } 88 }
72 } 89 }
73 90
91 void SetOutboundRTPStreamStatsFromMediaSenderInfo(
92 const cricket::MediaSenderInfo& media_sender_info,
93 RTCOutboundRTPStreamStats* outbound_stats) {
94 RTC_DCHECK(outbound_stats);
95 outbound_stats->ssrc = rtc::ToString<>(media_sender_info.ssrc());
96 // TODO(hbos): Support the remote case. crbug.com/657856
97 outbound_stats->is_remote = false;
98 // TODO(hbos): Set |codec_id| when we have |RTCCodecStats|. Maybe relevant:
99 // |media_sender_info.codec_name|. crbug.com/657854, 657856, 659117
100 outbound_stats->packets_sent =
101 static_cast<uint32_t>(media_sender_info.packets_sent);
102 outbound_stats->bytes_sent =
103 static_cast<uint64_t>(media_sender_info.bytes_sent);
104 outbound_stats->round_trip_time =
105 static_cast<double>(media_sender_info.rtt_ms) / rtc::kNumMillisecsPerSec;
106 }
107
108 void SetOutboundRTPStreamStatsFromVoiceSenderInfo(
109 const cricket::VoiceSenderInfo& voice_sender_info,
110 RTCOutboundRTPStreamStats* outbound_audio) {
111 SetOutboundRTPStreamStatsFromMediaSenderInfo(
112 voice_sender_info, outbound_audio);
113 outbound_audio->media_type = "audio";
114 // |fir_count|, |pli_count| and |sli_count| are only valid for video and are
115 // purposefully left undefined for audio.
116 }
117
118 void SetOutboundRTPStreamStatsFromVideoSenderInfo(
119 const cricket::VideoSenderInfo& video_sender_info,
120 RTCOutboundRTPStreamStats* outbound_video) {
121 SetOutboundRTPStreamStatsFromMediaSenderInfo(
122 video_sender_info, outbound_video);
123 outbound_video->media_type = "video";
124 outbound_video->fir_count =
125 static_cast<uint32_t>(video_sender_info.firs_rcvd);
126 outbound_video->pli_count =
127 static_cast<uint32_t>(video_sender_info.plis_rcvd);
128 outbound_video->nack_count =
129 static_cast<uint32_t>(video_sender_info.nacks_rcvd);
130 }
131
74 void ProduceCertificateStatsFromSSLCertificateStats( 132 void ProduceCertificateStatsFromSSLCertificateStats(
75 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, 133 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats,
76 RTCStatsReport* report) { 134 RTCStatsReport* report) {
77 RTCCertificateStats* prev_certificate_stats = nullptr; 135 RTCCertificateStats* prev_certificate_stats = nullptr;
78 for (const rtc::SSLCertificateStats* s = &certificate_stats; s; 136 for (const rtc::SSLCertificateStats* s = &certificate_stats; s;
79 s = s->issuer.get()) { 137 s = s->issuer.get()) {
80 RTCCertificateStats* certificate_stats = new RTCCertificateStats( 138 RTCCertificateStats* certificate_stats = new RTCCertificateStats(
81 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us); 139 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us);
82 certificate_stats->fingerprint = s->fingerprint; 140 certificate_stats->fingerprint = s->fingerprint;
83 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; 141 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 } 235 }
178 236
179 void RTCStatsCollector::ClearCachedStatsReport() { 237 void RTCStatsCollector::ClearCachedStatsReport() {
180 RTC_DCHECK(signaling_thread_->IsCurrent()); 238 RTC_DCHECK(signaling_thread_->IsCurrent());
181 cached_report_ = nullptr; 239 cached_report_ = nullptr;
182 } 240 }
183 241
184 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( 242 void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
185 int64_t timestamp_us) { 243 int64_t timestamp_us) {
186 RTC_DCHECK(signaling_thread_->IsCurrent()); 244 RTC_DCHECK(signaling_thread_->IsCurrent());
187 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 245 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
246 timestamp_us);
188 247
189 SessionStats session_stats; 248 SessionStats session_stats;
190 if (pc_->session()->GetTransportStats(&session_stats)) { 249 if (pc_->session()->GetTransportStats(&session_stats)) {
191 std::map<std::string, CertificateStatsPair> transport_cert_stats = 250 std::map<std::string, CertificateStatsPair> transport_cert_stats =
192 PrepareTransportCertificateStats_s(session_stats); 251 PrepareTransportCertificateStats_s(session_stats);
193 252
194 ProduceCertificateStats_s( 253 ProduceCertificateStats_s(
195 timestamp_us, transport_cert_stats, report.get()); 254 timestamp_us, transport_cert_stats, report.get());
196 ProduceIceCandidateAndPairStats_s( 255 ProduceIceCandidateAndPairStats_s(
197 timestamp_us, session_stats, report.get()); 256 timestamp_us, session_stats, report.get());
257 ProduceRTPStreamStats_s(
258 timestamp_us, session_stats, report.get());
198 ProduceTransportStats_s( 259 ProduceTransportStats_s(
199 timestamp_us, session_stats, transport_cert_stats, report.get()); 260 timestamp_us, session_stats, transport_cert_stats, report.get());
200 } 261 }
201 ProduceDataChannelStats_s(timestamp_us, report.get()); 262 ProduceDataChannelStats_s(timestamp_us, report.get());
202 ProducePeerConnectionStats_s(timestamp_us, report.get()); 263 ProducePeerConnectionStats_s(timestamp_us, report.get());
203 264
204 AddPartialResults(report); 265 AddPartialResults(report);
205 } 266 }
206 267
207 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( 268 void RTCStatsCollector::ProducePartialResultsOnWorkerThread(
208 int64_t timestamp_us) { 269 int64_t timestamp_us) {
209 RTC_DCHECK(worker_thread_->IsCurrent()); 270 RTC_DCHECK(worker_thread_->IsCurrent());
210 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 271 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
272 timestamp_us);
211 273
212 // TODO(hbos): Gather stats on worker thread. 274 // TODO(hbos): Gather stats on worker thread.
275 // pc_->session()'s channels are owned by the signaling thread but there are
276 // some stats that are gathered on the worker thread. Instead of a synchronous
277 // invoke on "s->w" we could to the "w" work here asynchronously if it wasn't
278 // for the ownership issue. Synchronous invokes in other places makes it
279 // difficult to introduce locks without introducing deadlocks and the channels
280 // are not reference counted.
213 281
214 AddPartialResults(report); 282 AddPartialResults(report);
215 } 283 }
216 284
217 void RTCStatsCollector::ProducePartialResultsOnNetworkThread( 285 void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
218 int64_t timestamp_us) { 286 int64_t timestamp_us) {
219 RTC_DCHECK(network_thread_->IsCurrent()); 287 RTC_DCHECK(network_thread_->IsCurrent());
220 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 288 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
289 timestamp_us);
221 290
222 // TODO(hbos): Gather stats on network thread. 291 // TODO(hbos): Gather stats on network thread.
292 // pc_->session()'s channels are owned by the signaling thread but there are
293 // some stats that are gathered on the network thread. Instead of a
294 // synchronous invoke on "s->n" we could to the "n" work here asynchronously
295 // if it wasn't for the ownership issue. Synchronous invokes in other places
296 // makes it difficult to introduce locks without introducing deadlocks and the
297 // channels are not reference counted.
223 298
224 AddPartialResults(report); 299 AddPartialResults(report);
225 } 300 }
226 301
227 void RTCStatsCollector::AddPartialResults( 302 void RTCStatsCollector::AddPartialResults(
228 const rtc::scoped_refptr<RTCStatsReport>& partial_report) { 303 const rtc::scoped_refptr<RTCStatsReport>& partial_report) {
229 if (!signaling_thread_->IsCurrent()) { 304 if (!signaling_thread_->IsCurrent()) {
230 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_, 305 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_,
231 rtc::Bind(&RTCStatsCollector::AddPartialResults_s, 306 rtc::Bind(&RTCStatsCollector::AddPartialResults_s,
232 rtc::scoped_refptr<RTCStatsCollector>(this), 307 rtc::scoped_refptr<RTCStatsCollector>(this),
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // crbug.com/633550 405 // crbug.com/633550
331 candidate_pair_stats->writable = info.writable; 406 candidate_pair_stats->writable = info.writable;
332 candidate_pair_stats->bytes_sent = 407 candidate_pair_stats->bytes_sent =
333 static_cast<uint64_t>(info.sent_total_bytes); 408 static_cast<uint64_t>(info.sent_total_bytes);
334 candidate_pair_stats->bytes_received = 409 candidate_pair_stats->bytes_received =
335 static_cast<uint64_t>(info.recv_total_bytes); 410 static_cast<uint64_t>(info.recv_total_bytes);
336 // TODO(hbos): The |info.rtt| measurement is smoothed. It shouldn't be 411 // TODO(hbos): The |info.rtt| measurement is smoothed. It shouldn't be
337 // smoothed according to the spec. crbug.com/633550. See 412 // smoothed according to the spec. crbug.com/633550. See
338 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-curr entrtt 413 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-curr entrtt
339 candidate_pair_stats->current_rtt = 414 candidate_pair_stats->current_rtt =
340 static_cast<double>(info.rtt) / 1000.0; 415 static_cast<double>(info.rtt) / rtc::kNumMillisecsPerSec;
341 candidate_pair_stats->requests_sent = 416 candidate_pair_stats->requests_sent =
342 static_cast<uint64_t>(info.sent_ping_requests_total); 417 static_cast<uint64_t>(info.sent_ping_requests_total);
343 candidate_pair_stats->responses_received = 418 candidate_pair_stats->responses_received =
344 static_cast<uint64_t>(info.recv_ping_responses); 419 static_cast<uint64_t>(info.recv_ping_responses);
345 candidate_pair_stats->responses_sent = 420 candidate_pair_stats->responses_sent =
346 static_cast<uint64_t>(info.sent_ping_responses); 421 static_cast<uint64_t>(info.sent_ping_responses);
347 422
348 report->AddStats(std::move(candidate_pair_stats)); 423 report->AddStats(std::move(candidate_pair_stats));
349 } 424 }
350 } 425 }
(...skipping 16 matching lines...) Expand all
367 // There is always just one |RTCPeerConnectionStats| so its |id| can be a 442 // There is always just one |RTCPeerConnectionStats| so its |id| can be a
368 // constant. 443 // constant.
369 std::unique_ptr<RTCPeerConnectionStats> stats( 444 std::unique_ptr<RTCPeerConnectionStats> stats(
370 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); 445 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us));
371 stats->data_channels_opened = data_channels_opened; 446 stats->data_channels_opened = data_channels_opened;
372 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - 447 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) -
373 data_channels_opened; 448 data_channels_opened;
374 report->AddStats(std::move(stats)); 449 report->AddStats(std::move(stats));
375 } 450 }
376 451
452 void RTCStatsCollector::ProduceRTPStreamStats_s(
453 int64_t timestamp_us, const SessionStats& session_stats,
454 RTCStatsReport* report) const {
455 RTC_DCHECK(signaling_thread_->IsCurrent());
456
457 // Audio
458 if (pc_->session()->voice_channel()) {
459 cricket::VoiceMediaInfo voice_media_info;
460 if (pc_->session()->voice_channel()->GetStats(&voice_media_info)) {
461 std::string transport_id = RTCTransportStatsIDFromBaseChannel(
462 session_stats.proxy_to_transport, *pc_->session()->voice_channel());
463 for (const cricket::VoiceSenderInfo& voice_sender_info :
464 voice_media_info.senders) {
465 // TODO(nisse): SSRC == 0 currently means none. Delete check when that
466 // is fixed.
467 if (voice_sender_info.ssrc() == 0)
468 continue;
469 std::unique_ptr<RTCOutboundRTPStreamStats> outbound_audio(
470 new RTCOutboundRTPStreamStats(
471 RTCOutboundRTPStreamStatsIDFromSSRC(
472 true, voice_sender_info.ssrc()),
473 timestamp_us));
474 SetOutboundRTPStreamStatsFromVoiceSenderInfo(
475 voice_sender_info, outbound_audio.get());
476 if (!transport_id.empty())
477 outbound_audio->transport_id = transport_id;
478 report->AddStats(std::move(outbound_audio));
479 }
480 }
481 }
482 // Video
483 if (pc_->session()->video_channel()) {
484 cricket::VideoMediaInfo video_media_info;
485 if (pc_->session()->video_channel()->GetStats(&video_media_info)) {
486 std::string transport_id = RTCTransportStatsIDFromBaseChannel(
487 session_stats.proxy_to_transport, *pc_->session()->video_channel());
488 for (const cricket::VideoSenderInfo& video_sender_info :
489 video_media_info.senders) {
490 // TODO(nisse): SSRC == 0 currently means none. Delete check when that
491 // is fixed.
492 if (video_sender_info.ssrc() == 0)
493 continue;
494 std::unique_ptr<RTCOutboundRTPStreamStats> outbound_video(
495 new RTCOutboundRTPStreamStats(
496 RTCOutboundRTPStreamStatsIDFromSSRC(
497 false, video_sender_info.ssrc()),
498 timestamp_us));
499 SetOutboundRTPStreamStatsFromVideoSenderInfo(
500 video_sender_info, outbound_video.get());
501 if (!transport_id.empty())
502 outbound_video->transport_id = transport_id;
503 report->AddStats(std::move(outbound_video));
504 }
505 }
506 }
507 }
508
377 void RTCStatsCollector::ProduceTransportStats_s( 509 void RTCStatsCollector::ProduceTransportStats_s(
378 int64_t timestamp_us, const SessionStats& session_stats, 510 int64_t timestamp_us, const SessionStats& session_stats,
379 const std::map<std::string, CertificateStatsPair>& transport_cert_stats, 511 const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
380 RTCStatsReport* report) const { 512 RTCStatsReport* report) const {
381 RTC_DCHECK(signaling_thread_->IsCurrent()); 513 RTC_DCHECK(signaling_thread_->IsCurrent());
382 for (const auto& transport : session_stats.transport_stats) { 514 for (const auto& transport : session_stats.transport_stats) {
383 // Get reference to RTCP channel, if it exists. 515 // Get reference to RTCP channel, if it exists.
384 std::string rtcp_transport_stats_id; 516 std::string rtcp_transport_stats_id;
385 for (const auto& channel_stats : transport.second.channel_stats) { 517 for (const auto& channel_stats : transport.second.channel_stats) {
386 if (channel_stats.component == 518 if (channel_stats.component ==
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 const std::string& type) { 602 const std::string& type) {
471 return CandidateTypeToRTCIceCandidateType(type); 603 return CandidateTypeToRTCIceCandidateType(type);
472 } 604 }
473 605
474 const char* DataStateToRTCDataChannelStateForTesting( 606 const char* DataStateToRTCDataChannelStateForTesting(
475 DataChannelInterface::DataState state) { 607 DataChannelInterface::DataState state) {
476 return DataStateToRTCDataChannelState(state); 608 return DataStateToRTCDataChannelState(state);
477 } 609 }
478 610
479 } // namespace webrtc 611 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/rtcstatscollector.h ('k') | webrtc/api/rtcstatscollector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698