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

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

Issue 1713043002: Late initialize MediaController, for less resource i.e. ProcessThread, usage by PeerConnection. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: some comments Created 4 years, 10 months 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
« webrtc/api/peerconnection.cc ('K') | « webrtc/api/statscollector.h ('k') | no next file » | 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 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2012 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
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 return ""; 351 return "";
352 } 352 }
353 } 353 }
354 354
355 StatsCollector::StatsCollector(PeerConnection* pc) 355 StatsCollector::StatsCollector(PeerConnection* pc)
356 : pc_(pc), stats_gathering_started_(0) { 356 : pc_(pc), stats_gathering_started_(0) {
357 RTC_DCHECK(pc_); 357 RTC_DCHECK(pc_);
358 } 358 }
359 359
360 StatsCollector::~StatsCollector() { 360 StatsCollector::~StatsCollector() {
361 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 361 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
362 } 362 }
363 363
364 double StatsCollector::GetTimeNow() { 364 double StatsCollector::GetTimeNow() {
365 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
365 return rtc::Timing::WallTimeNow() * rtc::kNumMillisecsPerSec; 366 return rtc::Timing::WallTimeNow() * rtc::kNumMillisecsPerSec;
366 } 367 }
367 368
368 // Adds a MediaStream with tracks that can be used as a |selector| in a call 369 // Adds a MediaStream with tracks that can be used as a |selector| in a call
369 // to GetStats. 370 // to GetStats.
370 void StatsCollector::AddStream(MediaStreamInterface* stream) { 371 void StatsCollector::AddStream(MediaStreamInterface* stream) {
371 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 372 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
372 RTC_DCHECK(stream != NULL); 373 RTC_DCHECK(stream != NULL);
373 374
374 CreateTrackReports<AudioTrackVector>(stream->GetAudioTracks(), 375 CreateTrackReports<AudioTrackVector>(stream->GetAudioTracks(),
375 &reports_, track_ids_); 376 &reports_, track_ids_);
376 CreateTrackReports<VideoTrackVector>(stream->GetVideoTracks(), 377 CreateTrackReports<VideoTrackVector>(stream->GetVideoTracks(),
377 &reports_, track_ids_); 378 &reports_, track_ids_);
378 } 379 }
379 380
380 void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track, 381 void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track,
381 uint32_t ssrc) { 382 uint32_t ssrc) {
382 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 383 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
383 RTC_DCHECK(audio_track != NULL); 384 RTC_DCHECK(audio_track != NULL);
384 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 385 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
385 for (const auto& track : local_audio_tracks_) 386 for (const auto& track : local_audio_tracks_)
386 RTC_DCHECK(track.first != audio_track || track.second != ssrc); 387 RTC_DCHECK(track.first != audio_track || track.second != ssrc);
387 #endif 388 #endif
388 389
389 local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc)); 390 local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc));
390 391
391 // Create the kStatsReportTypeTrack report for the new track if there is no 392 // Create the kStatsReportTypeTrack report for the new track if there is no
392 // report yet. 393 // report yet.
393 StatsReport::Id id(StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack, 394 StatsReport::Id id(StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack,
394 audio_track->id())); 395 audio_track->id()));
395 StatsReport* report = reports_.Find(id); 396 StatsReport* report = reports_.Find(id);
396 if (!report) { 397 if (!report) {
397 report = reports_.InsertNew(id); 398 report = reports_.InsertNew(id);
398 report->AddString(StatsReport::kStatsValueNameTrackId, audio_track->id()); 399 report->AddString(StatsReport::kStatsValueNameTrackId, audio_track->id());
399 } 400 }
400 } 401 }
401 402
402 void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track, 403 void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track,
403 uint32_t ssrc) { 404 uint32_t ssrc) {
405 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
404 RTC_DCHECK(audio_track != NULL); 406 RTC_DCHECK(audio_track != NULL);
405 local_audio_tracks_.erase(std::remove_if(local_audio_tracks_.begin(), 407 local_audio_tracks_.erase(std::remove_if(local_audio_tracks_.begin(),
406 local_audio_tracks_.end(), 408 local_audio_tracks_.end(),
407 [audio_track, ssrc](const LocalAudioTrackVector::value_type& track) { 409 [audio_track, ssrc](const LocalAudioTrackVector::value_type& track) {
408 return track.first == audio_track && track.second == ssrc; 410 return track.first == audio_track && track.second == ssrc;
409 })); 411 }));
410 } 412 }
411 413
412 void StatsCollector::GetStats(MediaStreamTrackInterface* track, 414 void StatsCollector::GetStats(MediaStreamTrackInterface* track,
413 StatsReports* reports) { 415 StatsReports* reports) {
414 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 416 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
415 RTC_DCHECK(reports != NULL); 417 RTC_DCHECK(reports != NULL);
416 RTC_DCHECK(reports->empty()); 418 RTC_DCHECK(reports->empty());
417 419
418 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; 420 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
419 421
420 if (!track) { 422 if (!track) {
421 reports->reserve(reports_.size()); 423 reports->reserve(reports_.size());
422 for (auto* r : reports_) 424 for (auto* r : reports_)
423 reports->push_back(r); 425 reports->push_back(r);
424 return; 426 return;
425 } 427 }
426 428
429 // TODO(solenberg): Need to pull out session id so we have that even when
430 // there is no session.
427 StatsReport* report = reports_.Find(StatsReport::NewTypedId( 431 StatsReport* report = reports_.Find(StatsReport::NewTypedId(
428 StatsReport::kStatsReportTypeSession, pc_->session()->id())); 432 StatsReport::kStatsReportTypeSession, pc_->session()->id()));
429 if (report) 433 if (report)
430 reports->push_back(report); 434 reports->push_back(report);
431 435
432 report = reports_.Find(StatsReport::NewTypedId( 436 report = reports_.Find(StatsReport::NewTypedId(
433 StatsReport::kStatsReportTypeTrack, track->id())); 437 StatsReport::kStatsReportTypeTrack, track->id()));
434 438
435 if (!report) 439 if (!report)
436 return; 440 return;
437 441
438 reports->push_back(report); 442 reports->push_back(report);
439 443
440 std::string track_id; 444 std::string track_id;
441 for (const auto* r : reports_) { 445 for (const auto* r : reports_) {
442 if (r->type() != StatsReport::kStatsReportTypeSsrc) 446 if (r->type() != StatsReport::kStatsReportTypeSsrc)
443 continue; 447 continue;
444 448
445 const StatsReport::Value* v = 449 const StatsReport::Value* v =
446 r->FindValue(StatsReport::kStatsValueNameTrackId); 450 r->FindValue(StatsReport::kStatsValueNameTrackId);
447 if (v && v->string_val() == track->id()) 451 if (v && v->string_val() == track->id())
448 reports->push_back(r); 452 reports->push_back(r);
449 } 453 }
450 } 454 }
451 455
452 void 456 void
453 StatsCollector::UpdateStats(PeerConnectionInterface::StatsOutputLevel level) { 457 StatsCollector::UpdateStats(PeerConnectionInterface::StatsOutputLevel level) {
454 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 458 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
455 double time_now = GetTimeNow(); 459 double time_now = GetTimeNow();
456 // Calls to UpdateStats() that occur less than kMinGatherStatsPeriod number of 460 // Calls to UpdateStats() that occur less than kMinGatherStatsPeriod number of
457 // ms apart will be ignored. 461 // ms apart will be ignored.
458 const double kMinGatherStatsPeriod = 50; 462 const double kMinGatherStatsPeriod = 50;
459 if (stats_gathering_started_ != 0 && 463 if (stats_gathering_started_ != 0 &&
460 stats_gathering_started_ + kMinGatherStatsPeriod > time_now) { 464 stats_gathering_started_ + kMinGatherStatsPeriod > time_now) {
461 return; 465 return;
462 } 466 }
463 stats_gathering_started_ = time_now; 467 stats_gathering_started_ = time_now;
464 468
469 // TODO(solenberg): Need to use a call which won't auto-create the session!
470 // Likely, this condition needs to go (PC always used to have a WebRtcSession)
471 // and some of the info at the beginning of ExtractSessionInfo is added even
472 // when there isn't a session.
pthatcher1 2016/02/26 21:51:20 I think we can just make this: TODO(pthatcher): M
the sun 2016/02/29 15:58:22 Done.
465 if (pc_->session()) { 473 if (pc_->session()) {
466 // TODO(tommi): All of these hop over to the worker thread to fetch 474 // TODO(tommi): All of these hop over to the worker thread to fetch
467 // information. We could use an AsyncInvoker to run all of these and post 475 // information. We could use an AsyncInvoker to run all of these and post
468 // the information back to the signaling thread where we can create and 476 // the information back to the signaling thread where we can create and
469 // update stats reports. That would also clean up the threading story a bit 477 // update stats reports. That would also clean up the threading story a bit
470 // since we'd be creating/updating the stats report objects consistently on 478 // since we'd be creating/updating the stats report objects consistently on
471 // the same thread (this class has no locks right now). 479 // the same thread (this class has no locks right now).
472 ExtractSessionInfo(); 480 ExtractSessionInfo();
473 ExtractVoiceInfo(); 481 ExtractVoiceInfo();
474 ExtractVideoInfo(level); 482 ExtractVideoInfo(level);
475 ExtractDataInfo(); 483 ExtractDataInfo();
476 UpdateTrackReports(); 484 UpdateTrackReports();
477 } 485 }
478 } 486 }
479 487
480 StatsReport* StatsCollector::PrepareReport( 488 StatsReport* StatsCollector::PrepareReport(
481 bool local, 489 bool local,
482 uint32_t ssrc, 490 uint32_t ssrc,
483 const StatsReport::Id& transport_id, 491 const StatsReport::Id& transport_id,
484 StatsReport::Direction direction) { 492 StatsReport::Direction direction) {
485 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 493 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
486 StatsReport::Id id(StatsReport::NewIdWithDirection( 494 StatsReport::Id id(StatsReport::NewIdWithDirection(
487 local ? StatsReport::kStatsReportTypeSsrc 495 local ? StatsReport::kStatsReportTypeSsrc
488 : StatsReport::kStatsReportTypeRemoteSsrc, 496 : StatsReport::kStatsReportTypeRemoteSsrc,
489 rtc::ToString<uint32_t>(ssrc), direction)); 497 rtc::ToString<uint32_t>(ssrc), direction));
490 StatsReport* report = reports_.Find(id); 498 StatsReport* report = reports_.Find(id);
491 499
492 // Use the ID of the track that is currently mapped to the SSRC, if any. 500 // Use the ID of the track that is currently mapped to the SSRC, if any.
493 std::string track_id; 501 std::string track_id;
494 if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { 502 if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) {
495 if (!report) { 503 if (!report) {
(...skipping 18 matching lines...) Expand all
514 522
515 report->AddInt64(StatsReport::kStatsValueNameSsrc, ssrc); 523 report->AddInt64(StatsReport::kStatsValueNameSsrc, ssrc);
516 report->AddString(StatsReport::kStatsValueNameTrackId, track_id); 524 report->AddString(StatsReport::kStatsValueNameTrackId, track_id);
517 // Add the mapping of SSRC to transport. 525 // Add the mapping of SSRC to transport.
518 report->AddId(StatsReport::kStatsValueNameTransportId, transport_id); 526 report->AddId(StatsReport::kStatsValueNameTransportId, transport_id);
519 return report; 527 return report;
520 } 528 }
521 529
522 StatsReport* StatsCollector::AddOneCertificateReport( 530 StatsReport* StatsCollector::AddOneCertificateReport(
523 const rtc::SSLCertificate* cert, const StatsReport* issuer) { 531 const rtc::SSLCertificate* cert, const StatsReport* issuer) {
524 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 532 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
525 533
526 // TODO(bemasc): Move this computation to a helper class that caches these 534 // TODO(bemasc): Move this computation to a helper class that caches these
527 // values to reduce CPU use in GetStats. This will require adding a fast 535 // values to reduce CPU use in GetStats. This will require adding a fast
528 // SSLCertificate::Equals() method to detect certificate changes. 536 // SSLCertificate::Equals() method to detect certificate changes.
529 537
530 std::string digest_algorithm; 538 std::string digest_algorithm;
531 if (!cert->GetSignatureDigestAlgorithm(&digest_algorithm)) 539 if (!cert->GetSignatureDigestAlgorithm(&digest_algorithm))
532 return nullptr; 540 return nullptr;
533 541
534 rtc::scoped_ptr<rtc::SSLFingerprint> ssl_fingerprint( 542 rtc::scoped_ptr<rtc::SSLFingerprint> ssl_fingerprint(
(...skipping 22 matching lines...) Expand all
557 report->AddString(StatsReport::kStatsValueNameFingerprintAlgorithm, 565 report->AddString(StatsReport::kStatsValueNameFingerprintAlgorithm,
558 digest_algorithm); 566 digest_algorithm);
559 report->AddString(StatsReport::kStatsValueNameDer, der_base64); 567 report->AddString(StatsReport::kStatsValueNameDer, der_base64);
560 if (issuer) 568 if (issuer)
561 report->AddId(StatsReport::kStatsValueNameIssuerId, issuer->id()); 569 report->AddId(StatsReport::kStatsValueNameIssuerId, issuer->id());
562 return report; 570 return report;
563 } 571 }
564 572
565 StatsReport* StatsCollector::AddCertificateReports( 573 StatsReport* StatsCollector::AddCertificateReports(
566 const rtc::SSLCertificate* cert) { 574 const rtc::SSLCertificate* cert) {
567 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 575 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
568 // Produces a chain of StatsReports representing this certificate and the rest 576 // Produces a chain of StatsReports representing this certificate and the rest
569 // of its chain, and adds those reports to |reports_|. The return value is 577 // of its chain, and adds those reports to |reports_|. The return value is
570 // the id of the leaf report. The provided cert must be non-null, so at least 578 // the id of the leaf report. The provided cert must be non-null, so at least
571 // one report will always be provided and the returned string will never be 579 // one report will always be provided and the returned string will never be
572 // empty. 580 // empty.
573 RTC_DCHECK(cert != NULL); 581 RTC_DCHECK(cert != NULL);
574 582
575 StatsReport* issuer = nullptr; 583 StatsReport* issuer = nullptr;
576 rtc::scoped_ptr<rtc::SSLCertChain> chain; 584 rtc::scoped_ptr<rtc::SSLCertChain> chain;
577 if (cert->GetChain(chain.accept())) { 585 if (cert->GetChain(chain.accept())) {
578 // This loop runs in reverse, i.e. from root to leaf, so that each 586 // This loop runs in reverse, i.e. from root to leaf, so that each
579 // certificate's issuer's report ID is known before the child certificate's 587 // certificate's issuer's report ID is known before the child certificate's
580 // report is generated. The root certificate does not have an issuer ID 588 // report is generated. The root certificate does not have an issuer ID
581 // value. 589 // value.
582 for (ptrdiff_t i = chain->GetSize() - 1; i >= 0; --i) { 590 for (ptrdiff_t i = chain->GetSize() - 1; i >= 0; --i) {
583 const rtc::SSLCertificate& cert_i = chain->Get(i); 591 const rtc::SSLCertificate& cert_i = chain->Get(i);
584 issuer = AddOneCertificateReport(&cert_i, issuer); 592 issuer = AddOneCertificateReport(&cert_i, issuer);
585 } 593 }
586 } 594 }
587 // Add the leaf certificate. 595 // Add the leaf certificate.
588 return AddOneCertificateReport(cert, issuer); 596 return AddOneCertificateReport(cert, issuer);
589 } 597 }
590 598
591 StatsReport* StatsCollector::AddConnectionInfoReport( 599 StatsReport* StatsCollector::AddConnectionInfoReport(
592 const std::string& content_name, int component, int connection_id, 600 const std::string& content_name, int component, int connection_id,
593 const StatsReport::Id& channel_report_id, 601 const StatsReport::Id& channel_report_id,
594 const cricket::ConnectionInfo& info) { 602 const cricket::ConnectionInfo& info) {
603 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
595 StatsReport::Id id(StatsReport::NewCandidatePairId(content_name, component, 604 StatsReport::Id id(StatsReport::NewCandidatePairId(content_name, component,
596 connection_id)); 605 connection_id));
597 StatsReport* report = reports_.ReplaceOrAddNew(id); 606 StatsReport* report = reports_.ReplaceOrAddNew(id);
598 report->set_timestamp(stats_gathering_started_); 607 report->set_timestamp(stats_gathering_started_);
599 608
600 const BoolForAdd bools[] = { 609 const BoolForAdd bools[] = {
601 {StatsReport::kStatsValueNameActiveConnection, info.best_connection}, 610 {StatsReport::kStatsValueNameActiveConnection, info.best_connection},
602 {StatsReport::kStatsValueNameReceiving, info.receiving}, 611 {StatsReport::kStatsValueNameReceiving, info.receiving},
603 {StatsReport::kStatsValueNameWritable, info.writable}, 612 {StatsReport::kStatsValueNameWritable, info.writable},
604 }; 613 };
(...skipping 27 matching lines...) Expand all
632 info.remote_candidate.type()); 641 info.remote_candidate.type());
633 report->AddString(StatsReport::kStatsValueNameTransportType, 642 report->AddString(StatsReport::kStatsValueNameTransportType,
634 info.local_candidate.protocol()); 643 info.local_candidate.protocol());
635 644
636 return report; 645 return report;
637 } 646 }
638 647
639 StatsReport* StatsCollector::AddCandidateReport( 648 StatsReport* StatsCollector::AddCandidateReport(
640 const cricket::Candidate& candidate, 649 const cricket::Candidate& candidate,
641 bool local) { 650 bool local) {
651 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
642 StatsReport::Id id(StatsReport::NewCandidateId(local, candidate.id())); 652 StatsReport::Id id(StatsReport::NewCandidateId(local, candidate.id()));
643 StatsReport* report = reports_.Find(id); 653 StatsReport* report = reports_.Find(id);
644 if (!report) { 654 if (!report) {
645 report = reports_.InsertNew(id); 655 report = reports_.InsertNew(id);
646 report->set_timestamp(stats_gathering_started_); 656 report->set_timestamp(stats_gathering_started_);
647 if (local) { 657 if (local) {
648 report->AddString(StatsReport::kStatsValueNameCandidateNetworkType, 658 report->AddString(StatsReport::kStatsValueNameCandidateNetworkType,
649 AdapterTypeToStatsType(candidate.network_type())); 659 AdapterTypeToStatsType(candidate.network_type()));
650 } 660 }
651 report->AddString(StatsReport::kStatsValueNameCandidateIPAddress, 661 report->AddString(StatsReport::kStatsValueNameCandidateIPAddress,
652 candidate.address().ipaddr().ToString()); 662 candidate.address().ipaddr().ToString());
653 report->AddString(StatsReport::kStatsValueNameCandidatePortNumber, 663 report->AddString(StatsReport::kStatsValueNameCandidatePortNumber,
654 candidate.address().PortAsString()); 664 candidate.address().PortAsString());
655 report->AddInt(StatsReport::kStatsValueNameCandidatePriority, 665 report->AddInt(StatsReport::kStatsValueNameCandidatePriority,
656 candidate.priority()); 666 candidate.priority());
657 report->AddString(StatsReport::kStatsValueNameCandidateType, 667 report->AddString(StatsReport::kStatsValueNameCandidateType,
658 IceCandidateTypeToStatsType(candidate.type())); 668 IceCandidateTypeToStatsType(candidate.type()));
659 report->AddString(StatsReport::kStatsValueNameCandidateTransportType, 669 report->AddString(StatsReport::kStatsValueNameCandidateTransportType,
660 candidate.protocol()); 670 candidate.protocol());
661 } 671 }
662 672
663 return report; 673 return report;
664 } 674 }
665 675
666 void StatsCollector::ExtractSessionInfo() { 676 void StatsCollector::ExtractSessionInfo() {
667 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 677 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
668 678
669 // Extract information from the base session. 679 // Extract information from the base session.
670 StatsReport::Id id(StatsReport::NewTypedId( 680 StatsReport::Id id(StatsReport::NewTypedId(
671 StatsReport::kStatsReportTypeSession, pc_->session()->id())); 681 StatsReport::kStatsReportTypeSession, pc_->session()->id()));
672 StatsReport* report = reports_.ReplaceOrAddNew(id); 682 StatsReport* report = reports_.ReplaceOrAddNew(id);
673 report->set_timestamp(stats_gathering_started_); 683 report->set_timestamp(stats_gathering_started_);
674 report->AddBoolean(StatsReport::kStatsValueNameInitiator, 684 report->AddBoolean(StatsReport::kStatsValueNameInitiator,
675 pc_->session()->initial_offerer()); 685 pc_->session()->initial_offerer());
676 686
677 SessionStats stats; 687 SessionStats stats;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 channel_report->AddId( 760 channel_report->AddId(
751 StatsReport::kStatsValueNameSelectedCandidatePairId, 761 StatsReport::kStatsValueNameSelectedCandidatePairId,
752 connection_report->id()); 762 connection_report->id());
753 } 763 }
754 } 764 }
755 } 765 }
756 } 766 }
757 } 767 }
758 768
759 void StatsCollector::ExtractVoiceInfo() { 769 void StatsCollector::ExtractVoiceInfo() {
760 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 770 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
761 771
762 if (!pc_->session()->voice_channel()) { 772 if (!pc_->session()->voice_channel()) {
763 return; 773 return;
764 } 774 }
765 cricket::VoiceMediaInfo voice_info; 775 cricket::VoiceMediaInfo voice_info;
766 if (!pc_->session()->voice_channel()->GetStats(&voice_info)) { 776 if (!pc_->session()->voice_channel()->GetStats(&voice_info)) {
767 LOG(LS_ERROR) << "Failed to get voice channel stats."; 777 LOG(LS_ERROR) << "Failed to get voice channel stats.";
768 return; 778 return;
769 } 779 }
770 780
(...skipping 12 matching lines...) Expand all
783 ExtractStatsFromList(voice_info.receivers, transport_id, this, 793 ExtractStatsFromList(voice_info.receivers, transport_id, this,
784 StatsReport::kReceive); 794 StatsReport::kReceive);
785 ExtractStatsFromList(voice_info.senders, transport_id, this, 795 ExtractStatsFromList(voice_info.senders, transport_id, this,
786 StatsReport::kSend); 796 StatsReport::kSend);
787 797
788 UpdateStatsFromExistingLocalAudioTracks(); 798 UpdateStatsFromExistingLocalAudioTracks();
789 } 799 }
790 800
791 void StatsCollector::ExtractVideoInfo( 801 void StatsCollector::ExtractVideoInfo(
792 PeerConnectionInterface::StatsOutputLevel level) { 802 PeerConnectionInterface::StatsOutputLevel level) {
793 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 803 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
794 804
795 if (!pc_->session()->video_channel()) 805 if (!pc_->session()->video_channel())
796 return; 806 return;
797 807
798 cricket::VideoMediaInfo video_info; 808 cricket::VideoMediaInfo video_info;
799 if (!pc_->session()->video_channel()->GetStats(&video_info)) { 809 if (!pc_->session()->video_channel()->GetStats(&video_info)) {
800 LOG(LS_ERROR) << "Failed to get video channel stats."; 810 LOG(LS_ERROR) << "Failed to get video channel stats.";
801 return; 811 return;
802 } 812 }
803 813
(...skipping 16 matching lines...) Expand all
820 LOG(LS_ERROR) << "BWEs count: " << video_info.bw_estimations.size(); 830 LOG(LS_ERROR) << "BWEs count: " << video_info.bw_estimations.size();
821 } else { 831 } else {
822 StatsReport::Id report_id(StatsReport::NewBandwidthEstimationId()); 832 StatsReport::Id report_id(StatsReport::NewBandwidthEstimationId());
823 StatsReport* report = reports_.FindOrAddNew(report_id); 833 StatsReport* report = reports_.FindOrAddNew(report_id);
824 ExtractStats( 834 ExtractStats(
825 video_info.bw_estimations[0], stats_gathering_started_, level, report); 835 video_info.bw_estimations[0], stats_gathering_started_, level, report);
826 } 836 }
827 } 837 }
828 838
829 void StatsCollector::ExtractDataInfo() { 839 void StatsCollector::ExtractDataInfo() {
830 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 840 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
831 841
832 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; 842 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
833 843
834 for (const auto& dc : pc_->sctp_data_channels()) { 844 for (const auto& dc : pc_->sctp_data_channels()) {
835 StatsReport::Id id(StatsReport::NewTypedIntId( 845 StatsReport::Id id(StatsReport::NewTypedIntId(
836 StatsReport::kStatsReportTypeDataChannel, dc->id())); 846 StatsReport::kStatsReportTypeDataChannel, dc->id()));
837 StatsReport* report = reports_.ReplaceOrAddNew(id); 847 StatsReport* report = reports_.ReplaceOrAddNew(id);
838 report->set_timestamp(stats_gathering_started_); 848 report->set_timestamp(stats_gathering_started_);
839 report->AddString(StatsReport::kStatsValueNameLabel, dc->label()); 849 report->AddString(StatsReport::kStatsValueNameLabel, dc->label());
840 report->AddInt(StatsReport::kStatsValueNameDataChannelId, dc->id()); 850 report->AddInt(StatsReport::kStatsValueNameDataChannelId, dc->id());
841 report->AddString(StatsReport::kStatsValueNameProtocol, dc->protocol()); 851 report->AddString(StatsReport::kStatsValueNameProtocol, dc->protocol());
842 report->AddString(StatsReport::kStatsValueNameState, 852 report->AddString(StatsReport::kStatsValueNameState,
843 DataChannelInterface::DataStateString(dc->state())); 853 DataChannelInterface::DataStateString(dc->state()));
844 } 854 }
845 } 855 }
846 856
847 StatsReport* StatsCollector::GetReport(const StatsReport::StatsType& type, 857 StatsReport* StatsCollector::GetReport(const StatsReport::StatsType& type,
848 const std::string& id, 858 const std::string& id,
849 StatsReport::Direction direction) { 859 StatsReport::Direction direction) {
850 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 860 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
851 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc || 861 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc ||
852 type == StatsReport::kStatsReportTypeRemoteSsrc); 862 type == StatsReport::kStatsReportTypeRemoteSsrc);
853 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction)); 863 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction));
854 } 864 }
855 865
856 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() { 866 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() {
857 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 867 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
858 // Loop through the existing local audio tracks. 868 // Loop through the existing local audio tracks.
859 for (const auto& it : local_audio_tracks_) { 869 for (const auto& it : local_audio_tracks_) {
860 AudioTrackInterface* track = it.first; 870 AudioTrackInterface* track = it.first;
861 uint32_t ssrc = it.second; 871 uint32_t ssrc = it.second;
862 StatsReport* report = 872 StatsReport* report =
863 GetReport(StatsReport::kStatsReportTypeSsrc, 873 GetReport(StatsReport::kStatsReportTypeSsrc,
864 rtc::ToString<uint32_t>(ssrc), StatsReport::kSend); 874 rtc::ToString<uint32_t>(ssrc), StatsReport::kSend);
865 if (report == NULL) { 875 if (report == NULL) {
866 // This can happen if a local audio track is added to a stream on the 876 // This can happen if a local audio track is added to a stream on the
867 // fly and the report has not been set up yet. Do nothing in this case. 877 // fly and the report has not been set up yet. Do nothing in this case.
868 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc; 878 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc;
869 continue; 879 continue;
870 } 880 }
871 881
872 // The same ssrc can be used by both local and remote audio tracks. 882 // The same ssrc can be used by both local and remote audio tracks.
873 const StatsReport::Value* v = 883 const StatsReport::Value* v =
874 report->FindValue(StatsReport::kStatsValueNameTrackId); 884 report->FindValue(StatsReport::kStatsValueNameTrackId);
875 if (!v || v->string_val() != track->id()) 885 if (!v || v->string_val() != track->id())
876 continue; 886 continue;
877 887
878 report->set_timestamp(stats_gathering_started_); 888 report->set_timestamp(stats_gathering_started_);
879 UpdateReportFromAudioTrack(track, report); 889 UpdateReportFromAudioTrack(track, report);
880 } 890 }
881 } 891 }
882 892
883 void StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track, 893 void StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track,
884 StatsReport* report) { 894 StatsReport* report) {
885 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 895 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
886 RTC_DCHECK(track != NULL); 896 RTC_DCHECK(track != NULL);
887 897
888 // Don't overwrite report values if they're not available. 898 // Don't overwrite report values if they're not available.
889 int signal_level; 899 int signal_level;
890 if (track->GetSignalLevel(&signal_level)) { 900 if (track->GetSignalLevel(&signal_level)) {
891 RTC_DCHECK_GE(signal_level, 0); 901 RTC_DCHECK_GE(signal_level, 0);
892 report->AddInt(StatsReport::kStatsValueNameAudioInputLevel, signal_level); 902 report->AddInt(StatsReport::kStatsValueNameAudioInputLevel, signal_level);
893 } 903 }
894 904
895 auto audio_processor(track->GetAudioProcessor()); 905 auto audio_processor(track->GetAudioProcessor());
896 906
897 if (audio_processor.get()) { 907 if (audio_processor.get()) {
898 AudioProcessorInterface::AudioProcessorStats stats; 908 AudioProcessorInterface::AudioProcessorStats stats;
899 audio_processor->GetStats(&stats); 909 audio_processor->GetStats(&stats);
900 910
901 SetAudioProcessingStats( 911 SetAudioProcessingStats(
902 report, stats.typing_noise_detected, stats.echo_return_loss, 912 report, stats.typing_noise_detected, stats.echo_return_loss,
903 stats.echo_return_loss_enhancement, stats.echo_delay_median_ms, 913 stats.echo_return_loss_enhancement, stats.echo_delay_median_ms,
904 stats.aec_quality_min, stats.echo_delay_std_ms); 914 stats.aec_quality_min, stats.echo_delay_std_ms);
905 } 915 }
906 } 916 }
907 917
908 bool StatsCollector::GetTrackIdBySsrc(uint32_t ssrc, 918 bool StatsCollector::GetTrackIdBySsrc(uint32_t ssrc,
909 std::string* track_id, 919 std::string* track_id,
910 StatsReport::Direction direction) { 920 StatsReport::Direction direction) {
911 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 921 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
912 if (direction == StatsReport::kSend) { 922 if (direction == StatsReport::kSend) {
913 if (!pc_->session()->GetLocalTrackIdBySsrc(ssrc, track_id)) { 923 if (!pc_->session()->GetLocalTrackIdBySsrc(ssrc, track_id)) {
914 LOG(LS_WARNING) << "The SSRC " << ssrc 924 LOG(LS_WARNING) << "The SSRC " << ssrc
915 << " is not associated with a sending track"; 925 << " is not associated with a sending track";
916 return false; 926 return false;
917 } 927 }
918 } else { 928 } else {
919 RTC_DCHECK(direction == StatsReport::kReceive); 929 RTC_DCHECK(direction == StatsReport::kReceive);
920 if (!pc_->session()->GetRemoteTrackIdBySsrc(ssrc, track_id)) { 930 if (!pc_->session()->GetRemoteTrackIdBySsrc(ssrc, track_id)) {
921 LOG(LS_WARNING) << "The SSRC " << ssrc 931 LOG(LS_WARNING) << "The SSRC " << ssrc
922 << " is not associated with a receiving track"; 932 << " is not associated with a receiving track";
923 return false; 933 return false;
924 } 934 }
925 } 935 }
926 936
927 return true; 937 return true;
928 } 938 }
929 939
930 void StatsCollector::UpdateTrackReports() { 940 void StatsCollector::UpdateTrackReports() {
931 RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent()); 941 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
932 942
933 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; 943 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
934 944
935 for (const auto& entry : track_ids_) { 945 for (const auto& entry : track_ids_) {
936 StatsReport* report = entry.second; 946 StatsReport* report = entry.second;
937 report->set_timestamp(stats_gathering_started_); 947 report->set_timestamp(stats_gathering_started_);
938 } 948 }
939 } 949 }
940 950
941 void StatsCollector::ClearUpdateStatsCacheForTest() { 951 void StatsCollector::ClearUpdateStatsCacheForTest() {
952 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
942 stats_gathering_started_ = 0; 953 stats_gathering_started_ = 0;
943 } 954 }
944 955
945 } // namespace webrtc 956 } // namespace webrtc
OLDNEW
« webrtc/api/peerconnection.cc ('K') | « webrtc/api/statscollector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698