| 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/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" | |
| 22 #include "webrtc/p2p/base/candidate.h" | 20 #include "webrtc/p2p/base/candidate.h" |
| 23 #include "webrtc/p2p/base/p2pconstants.h" | 21 #include "webrtc/p2p/base/p2pconstants.h" |
| 24 #include "webrtc/p2p/base/port.h" | 22 #include "webrtc/p2p/base/port.h" |
| 25 | 23 |
| 26 namespace webrtc { | 24 namespace webrtc { |
| 27 | 25 |
| 28 namespace { | 26 namespace { |
| 29 | 27 |
| 30 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { | 28 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { |
| 31 return "RTCCertificate_" + fingerprint; | 29 return "RTCCertificate_" + fingerprint; |
| 32 } | 30 } |
| 33 | 31 |
| 34 std::string RTCIceCandidatePairStatsIDFromConnectionInfo( | 32 std::string RTCIceCandidatePairStatsIDFromConnectionInfo( |
| 35 const cricket::ConnectionInfo& info) { | 33 const cricket::ConnectionInfo& info) { |
| 36 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + | 34 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + |
| 37 info.remote_candidate.id(); | 35 info.remote_candidate.id(); |
| 38 } | 36 } |
| 39 | 37 |
| 40 std::string RTCTransportStatsIDFromTransportChannel( | 38 std::string RTCTransportStatsIDFromTransportChannel( |
| 41 const std::string& transport_name, int channel_component) { | 39 const std::string& transport_name, int channel_component) { |
| 42 return "RTCTransport_" + transport_name + "_" + | 40 return "RTCTransport_" + transport_name + "_" + |
| 43 rtc::ToString<>(channel_component); | 41 rtc::ToString<>(channel_component); |
| 44 } | 42 } |
| 45 | 43 |
| 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 | |
| 61 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { | 44 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { |
| 62 if (type == cricket::LOCAL_PORT_TYPE) | 45 if (type == cricket::LOCAL_PORT_TYPE) |
| 63 return RTCIceCandidateType::kHost; | 46 return RTCIceCandidateType::kHost; |
| 64 if (type == cricket::STUN_PORT_TYPE) | 47 if (type == cricket::STUN_PORT_TYPE) |
| 65 return RTCIceCandidateType::kSrflx; | 48 return RTCIceCandidateType::kSrflx; |
| 66 if (type == cricket::PRFLX_PORT_TYPE) | 49 if (type == cricket::PRFLX_PORT_TYPE) |
| 67 return RTCIceCandidateType::kPrflx; | 50 return RTCIceCandidateType::kPrflx; |
| 68 if (type == cricket::RELAY_PORT_TYPE) | 51 if (type == cricket::RELAY_PORT_TYPE) |
| 69 return RTCIceCandidateType::kRelay; | 52 return RTCIceCandidateType::kRelay; |
| 70 RTC_NOTREACHED(); | 53 RTC_NOTREACHED(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 81 case DataChannelInterface::kClosing: | 64 case DataChannelInterface::kClosing: |
| 82 return RTCDataChannelState::kClosing; | 65 return RTCDataChannelState::kClosing; |
| 83 case DataChannelInterface::kClosed: | 66 case DataChannelInterface::kClosed: |
| 84 return RTCDataChannelState::kClosed; | 67 return RTCDataChannelState::kClosed; |
| 85 default: | 68 default: |
| 86 RTC_NOTREACHED(); | 69 RTC_NOTREACHED(); |
| 87 return nullptr; | 70 return nullptr; |
| 88 } | 71 } |
| 89 } | 72 } |
| 90 | 73 |
| 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 | |
| 132 void ProduceCertificateStatsFromSSLCertificateStats( | 74 void ProduceCertificateStatsFromSSLCertificateStats( |
| 133 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, | 75 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, |
| 134 RTCStatsReport* report) { | 76 RTCStatsReport* report) { |
| 135 RTCCertificateStats* prev_certificate_stats = nullptr; | 77 RTCCertificateStats* prev_certificate_stats = nullptr; |
| 136 for (const rtc::SSLCertificateStats* s = &certificate_stats; s; | 78 for (const rtc::SSLCertificateStats* s = &certificate_stats; s; |
| 137 s = s->issuer.get()) { | 79 s = s->issuer.get()) { |
| 138 RTCCertificateStats* certificate_stats = new RTCCertificateStats( | 80 RTCCertificateStats* certificate_stats = new RTCCertificateStats( |
| 139 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us); | 81 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us); |
| 140 certificate_stats->fingerprint = s->fingerprint; | 82 certificate_stats->fingerprint = s->fingerprint; |
| 141 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; | 83 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 } | 177 } |
| 236 | 178 |
| 237 void RTCStatsCollector::ClearCachedStatsReport() { | 179 void RTCStatsCollector::ClearCachedStatsReport() { |
| 238 RTC_DCHECK(signaling_thread_->IsCurrent()); | 180 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 239 cached_report_ = nullptr; | 181 cached_report_ = nullptr; |
| 240 } | 182 } |
| 241 | 183 |
| 242 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( | 184 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( |
| 243 int64_t timestamp_us) { | 185 int64_t timestamp_us) { |
| 244 RTC_DCHECK(signaling_thread_->IsCurrent()); | 186 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 245 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( | 187 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
| 246 timestamp_us); | |
| 247 | 188 |
| 248 SessionStats session_stats; | 189 SessionStats session_stats; |
| 249 if (pc_->session()->GetTransportStats(&session_stats)) { | 190 if (pc_->session()->GetTransportStats(&session_stats)) { |
| 250 std::map<std::string, CertificateStatsPair> transport_cert_stats = | 191 std::map<std::string, CertificateStatsPair> transport_cert_stats = |
| 251 PrepareTransportCertificateStats_s(session_stats); | 192 PrepareTransportCertificateStats_s(session_stats); |
| 252 | 193 |
| 253 ProduceCertificateStats_s( | 194 ProduceCertificateStats_s( |
| 254 timestamp_us, transport_cert_stats, report.get()); | 195 timestamp_us, transport_cert_stats, report.get()); |
| 255 ProduceIceCandidateAndPairStats_s( | 196 ProduceIceCandidateAndPairStats_s( |
| 256 timestamp_us, session_stats, report.get()); | 197 timestamp_us, session_stats, report.get()); |
| 257 ProduceRTPStreamStats_s( | |
| 258 timestamp_us, session_stats, report.get()); | |
| 259 ProduceTransportStats_s( | 198 ProduceTransportStats_s( |
| 260 timestamp_us, session_stats, transport_cert_stats, report.get()); | 199 timestamp_us, session_stats, transport_cert_stats, report.get()); |
| 261 } | 200 } |
| 262 ProduceDataChannelStats_s(timestamp_us, report.get()); | 201 ProduceDataChannelStats_s(timestamp_us, report.get()); |
| 263 ProducePeerConnectionStats_s(timestamp_us, report.get()); | 202 ProducePeerConnectionStats_s(timestamp_us, report.get()); |
| 264 | 203 |
| 265 AddPartialResults(report); | 204 AddPartialResults(report); |
| 266 } | 205 } |
| 267 | 206 |
| 268 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( | 207 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( |
| 269 int64_t timestamp_us) { | 208 int64_t timestamp_us) { |
| 270 RTC_DCHECK(worker_thread_->IsCurrent()); | 209 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 271 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( | 210 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
| 272 timestamp_us); | |
| 273 | 211 |
| 274 // TODO(hbos): Gather stats on worker thread. | 212 // 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. | |
| 281 | 213 |
| 282 AddPartialResults(report); | 214 AddPartialResults(report); |
| 283 } | 215 } |
| 284 | 216 |
| 285 void RTCStatsCollector::ProducePartialResultsOnNetworkThread( | 217 void RTCStatsCollector::ProducePartialResultsOnNetworkThread( |
| 286 int64_t timestamp_us) { | 218 int64_t timestamp_us) { |
| 287 RTC_DCHECK(network_thread_->IsCurrent()); | 219 RTC_DCHECK(network_thread_->IsCurrent()); |
| 288 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create( | 220 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
| 289 timestamp_us); | |
| 290 | 221 |
| 291 // TODO(hbos): Gather stats on network thread. | 222 // 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. | |
| 298 | 223 |
| 299 AddPartialResults(report); | 224 AddPartialResults(report); |
| 300 } | 225 } |
| 301 | 226 |
| 302 void RTCStatsCollector::AddPartialResults( | 227 void RTCStatsCollector::AddPartialResults( |
| 303 const rtc::scoped_refptr<RTCStatsReport>& partial_report) { | 228 const rtc::scoped_refptr<RTCStatsReport>& partial_report) { |
| 304 if (!signaling_thread_->IsCurrent()) { | 229 if (!signaling_thread_->IsCurrent()) { |
| 305 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_, | 230 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_, |
| 306 rtc::Bind(&RTCStatsCollector::AddPartialResults_s, | 231 rtc::Bind(&RTCStatsCollector::AddPartialResults_s, |
| 307 rtc::scoped_refptr<RTCStatsCollector>(this), | 232 rtc::scoped_refptr<RTCStatsCollector>(this), |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 // crbug.com/633550 | 330 // crbug.com/633550 |
| 406 candidate_pair_stats->writable = info.writable; | 331 candidate_pair_stats->writable = info.writable; |
| 407 candidate_pair_stats->bytes_sent = | 332 candidate_pair_stats->bytes_sent = |
| 408 static_cast<uint64_t>(info.sent_total_bytes); | 333 static_cast<uint64_t>(info.sent_total_bytes); |
| 409 candidate_pair_stats->bytes_received = | 334 candidate_pair_stats->bytes_received = |
| 410 static_cast<uint64_t>(info.recv_total_bytes); | 335 static_cast<uint64_t>(info.recv_total_bytes); |
| 411 // TODO(hbos): The |info.rtt| measurement is smoothed. It shouldn't be | 336 // TODO(hbos): The |info.rtt| measurement is smoothed. It shouldn't be |
| 412 // smoothed according to the spec. crbug.com/633550. See | 337 // smoothed according to the spec. crbug.com/633550. See |
| 413 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-curr
entrtt | 338 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-curr
entrtt |
| 414 candidate_pair_stats->current_rtt = | 339 candidate_pair_stats->current_rtt = |
| 415 static_cast<double>(info.rtt) / rtc::kNumMillisecsPerSec; | 340 static_cast<double>(info.rtt) / 1000.0; |
| 416 candidate_pair_stats->requests_sent = | 341 candidate_pair_stats->requests_sent = |
| 417 static_cast<uint64_t>(info.sent_ping_requests_total); | 342 static_cast<uint64_t>(info.sent_ping_requests_total); |
| 418 candidate_pair_stats->responses_received = | 343 candidate_pair_stats->responses_received = |
| 419 static_cast<uint64_t>(info.recv_ping_responses); | 344 static_cast<uint64_t>(info.recv_ping_responses); |
| 420 candidate_pair_stats->responses_sent = | 345 candidate_pair_stats->responses_sent = |
| 421 static_cast<uint64_t>(info.sent_ping_responses); | 346 static_cast<uint64_t>(info.sent_ping_responses); |
| 422 | 347 |
| 423 report->AddStats(std::move(candidate_pair_stats)); | 348 report->AddStats(std::move(candidate_pair_stats)); |
| 424 } | 349 } |
| 425 } | 350 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 442 // There is always just one |RTCPeerConnectionStats| so its |id| can be a | 367 // There is always just one |RTCPeerConnectionStats| so its |id| can be a |
| 443 // constant. | 368 // constant. |
| 444 std::unique_ptr<RTCPeerConnectionStats> stats( | 369 std::unique_ptr<RTCPeerConnectionStats> stats( |
| 445 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); | 370 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); |
| 446 stats->data_channels_opened = data_channels_opened; | 371 stats->data_channels_opened = data_channels_opened; |
| 447 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - | 372 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - |
| 448 data_channels_opened; | 373 data_channels_opened; |
| 449 report->AddStats(std::move(stats)); | 374 report->AddStats(std::move(stats)); |
| 450 } | 375 } |
| 451 | 376 |
| 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 | |
| 509 void RTCStatsCollector::ProduceTransportStats_s( | 377 void RTCStatsCollector::ProduceTransportStats_s( |
| 510 int64_t timestamp_us, const SessionStats& session_stats, | 378 int64_t timestamp_us, const SessionStats& session_stats, |
| 511 const std::map<std::string, CertificateStatsPair>& transport_cert_stats, | 379 const std::map<std::string, CertificateStatsPair>& transport_cert_stats, |
| 512 RTCStatsReport* report) const { | 380 RTCStatsReport* report) const { |
| 513 RTC_DCHECK(signaling_thread_->IsCurrent()); | 381 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 514 for (const auto& transport : session_stats.transport_stats) { | 382 for (const auto& transport : session_stats.transport_stats) { |
| 515 // Get reference to RTCP channel, if it exists. | 383 // Get reference to RTCP channel, if it exists. |
| 516 std::string rtcp_transport_stats_id; | 384 std::string rtcp_transport_stats_id; |
| 517 for (const auto& channel_stats : transport.second.channel_stats) { | 385 for (const auto& channel_stats : transport.second.channel_stats) { |
| 518 if (channel_stats.component == | 386 if (channel_stats.component == |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 const std::string& type) { | 470 const std::string& type) { |
| 603 return CandidateTypeToRTCIceCandidateType(type); | 471 return CandidateTypeToRTCIceCandidateType(type); |
| 604 } | 472 } |
| 605 | 473 |
| 606 const char* DataStateToRTCDataChannelStateForTesting( | 474 const char* DataStateToRTCDataChannelStateForTesting( |
| 607 DataChannelInterface::DataState state) { | 475 DataChannelInterface::DataState state) { |
| 608 return DataStateToRTCDataChannelState(state); | 476 return DataStateToRTCDataChannelState(state); |
| 609 } | 477 } |
| 610 | 478 |
| 611 } // namespace webrtc | 479 } // namespace webrtc |
| OLD | NEW |