OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 const char* STATSREPORT_ADAPTER_TYPE_LOOPBACK = "loopback"; | 59 const char* STATSREPORT_ADAPTER_TYPE_LOOPBACK = "loopback"; |
60 | 60 |
61 template<typename ValueType> | 61 template<typename ValueType> |
62 struct TypeForAdd { | 62 struct TypeForAdd { |
63 const StatsReport::StatsValueName name; | 63 const StatsReport::StatsValueName name; |
64 const ValueType& value; | 64 const ValueType& value; |
65 }; | 65 }; |
66 | 66 |
67 typedef TypeForAdd<bool> BoolForAdd; | 67 typedef TypeForAdd<bool> BoolForAdd; |
68 typedef TypeForAdd<float> FloatForAdd; | 68 typedef TypeForAdd<float> FloatForAdd; |
69 typedef TypeForAdd<int64> Int64ForAdd; | 69 typedef TypeForAdd<int64_t> Int64ForAdd; |
70 typedef TypeForAdd<int> IntForAdd; | 70 typedef TypeForAdd<int> IntForAdd; |
71 | 71 |
72 StatsReport::Id GetTransportIdFromProxy(const cricket::ProxyTransportMap& map, | 72 StatsReport::Id GetTransportIdFromProxy(const cricket::ProxyTransportMap& map, |
73 const std::string& proxy) { | 73 const std::string& proxy) { |
74 RTC_DCHECK(!proxy.empty()); | 74 RTC_DCHECK(!proxy.empty()); |
75 cricket::ProxyTransportMap::const_iterator found = map.find(proxy); | 75 cricket::ProxyTransportMap::const_iterator found = map.find(proxy); |
76 if (found == map.end()) | 76 if (found == map.end()) |
77 return StatsReport::Id(); | 77 return StatsReport::Id(); |
78 | 78 |
79 return StatsReport::NewComponentId( | 79 return StatsReport::NewComponentId( |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 // Template to extract stats from a data vector. | 294 // Template to extract stats from a data vector. |
295 // In order to use the template, the functions that are called from it, | 295 // In order to use the template, the functions that are called from it, |
296 // ExtractStats and ExtractRemoteStats, must be defined and overloaded | 296 // ExtractStats and ExtractRemoteStats, must be defined and overloaded |
297 // for each type. | 297 // for each type. |
298 template<typename T> | 298 template<typename T> |
299 void ExtractStatsFromList(const std::vector<T>& data, | 299 void ExtractStatsFromList(const std::vector<T>& data, |
300 const StatsReport::Id& transport_id, | 300 const StatsReport::Id& transport_id, |
301 StatsCollector* collector, | 301 StatsCollector* collector, |
302 StatsReport::Direction direction) { | 302 StatsReport::Direction direction) { |
303 for (const auto& d : data) { | 303 for (const auto& d : data) { |
304 uint32 ssrc = d.ssrc(); | 304 uint32_t ssrc = d.ssrc(); |
305 // Each track can have stats for both local and remote objects. | 305 // Each track can have stats for both local and remote objects. |
306 // TODO(hta): Handle the case of multiple SSRCs per object. | 306 // TODO(hta): Handle the case of multiple SSRCs per object. |
307 StatsReport* report = collector->PrepareReport(true, ssrc, transport_id, | 307 StatsReport* report = collector->PrepareReport(true, ssrc, transport_id, |
308 direction); | 308 direction); |
309 if (report) | 309 if (report) |
310 ExtractStats(d, report); | 310 ExtractStats(d, report); |
311 | 311 |
312 if (!d.remote_stats.empty()) { | 312 if (!d.remote_stats.empty()) { |
313 report = collector->PrepareReport(false, ssrc, transport_id, direction); | 313 report = collector->PrepareReport(false, ssrc, transport_id, direction); |
314 if (report) | 314 if (report) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 376 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
377 RTC_DCHECK(stream != NULL); | 377 RTC_DCHECK(stream != NULL); |
378 | 378 |
379 CreateTrackReports<AudioTrackVector>(stream->GetAudioTracks(), | 379 CreateTrackReports<AudioTrackVector>(stream->GetAudioTracks(), |
380 &reports_, track_ids_); | 380 &reports_, track_ids_); |
381 CreateTrackReports<VideoTrackVector>(stream->GetVideoTracks(), | 381 CreateTrackReports<VideoTrackVector>(stream->GetVideoTracks(), |
382 &reports_, track_ids_); | 382 &reports_, track_ids_); |
383 } | 383 } |
384 | 384 |
385 void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track, | 385 void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track, |
386 uint32 ssrc) { | 386 uint32_t ssrc) { |
387 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 387 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
388 RTC_DCHECK(audio_track != NULL); | 388 RTC_DCHECK(audio_track != NULL); |
389 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) | 389 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) |
390 for (const auto& track : local_audio_tracks_) | 390 for (const auto& track : local_audio_tracks_) |
391 RTC_DCHECK(track.first != audio_track || track.second != ssrc); | 391 RTC_DCHECK(track.first != audio_track || track.second != ssrc); |
392 #endif | 392 #endif |
393 | 393 |
394 local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc)); | 394 local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc)); |
395 | 395 |
396 // Create the kStatsReportTypeTrack report for the new track if there is no | 396 // Create the kStatsReportTypeTrack report for the new track if there is no |
397 // report yet. | 397 // report yet. |
398 StatsReport::Id id(StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack, | 398 StatsReport::Id id(StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack, |
399 audio_track->id())); | 399 audio_track->id())); |
400 StatsReport* report = reports_.Find(id); | 400 StatsReport* report = reports_.Find(id); |
401 if (!report) { | 401 if (!report) { |
402 report = reports_.InsertNew(id); | 402 report = reports_.InsertNew(id); |
403 report->AddString(StatsReport::kStatsValueNameTrackId, audio_track->id()); | 403 report->AddString(StatsReport::kStatsValueNameTrackId, audio_track->id()); |
404 } | 404 } |
405 } | 405 } |
406 | 406 |
407 void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track, | 407 void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track, |
408 uint32 ssrc) { | 408 uint32_t ssrc) { |
409 RTC_DCHECK(audio_track != NULL); | 409 RTC_DCHECK(audio_track != NULL); |
410 local_audio_tracks_.erase(std::remove_if(local_audio_tracks_.begin(), | 410 local_audio_tracks_.erase(std::remove_if(local_audio_tracks_.begin(), |
411 local_audio_tracks_.end(), | 411 local_audio_tracks_.end(), |
412 [audio_track, ssrc](const LocalAudioTrackVector::value_type& track) { | 412 [audio_track, ssrc](const LocalAudioTrackVector::value_type& track) { |
413 return track.first == audio_track && track.second == ssrc; | 413 return track.first == audio_track && track.second == ssrc; |
414 })); | 414 })); |
415 } | 415 } |
416 | 416 |
417 void StatsCollector::GetStats(MediaStreamTrackInterface* track, | 417 void StatsCollector::GetStats(MediaStreamTrackInterface* track, |
418 StatsReports* reports) { | 418 StatsReports* reports) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 // since we'd be creating/updating the stats report objects consistently on | 475 // since we'd be creating/updating the stats report objects consistently on |
476 // the same thread (this class has no locks right now). | 476 // the same thread (this class has no locks right now). |
477 ExtractSessionInfo(); | 477 ExtractSessionInfo(); |
478 ExtractVoiceInfo(); | 478 ExtractVoiceInfo(); |
479 ExtractVideoInfo(level); | 479 ExtractVideoInfo(level); |
480 ExtractDataInfo(); | 480 ExtractDataInfo(); |
481 UpdateTrackReports(); | 481 UpdateTrackReports(); |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 StatsReport* StatsCollector::PrepareReport( | 485 StatsReport* StatsCollector::PrepareReport(bool local, |
486 bool local, | 486 uint32_t ssrc, |
487 uint32 ssrc, | 487 const StatsReport::Id& transport_id, |
488 const StatsReport::Id& transport_id, | 488 StatsReport::Direction direction) { |
489 StatsReport::Direction direction) { | |
490 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 489 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
491 StatsReport::Id id(StatsReport::NewIdWithDirection( | 490 StatsReport::Id id(StatsReport::NewIdWithDirection( |
492 local ? StatsReport::kStatsReportTypeSsrc : | 491 local ? StatsReport::kStatsReportTypeSsrc |
493 StatsReport::kStatsReportTypeRemoteSsrc, | 492 : StatsReport::kStatsReportTypeRemoteSsrc, |
494 rtc::ToString<uint32>(ssrc), direction)); | 493 rtc::ToString<uint32_t>(ssrc), direction)); |
495 StatsReport* report = reports_.Find(id); | 494 StatsReport* report = reports_.Find(id); |
496 | 495 |
497 // Use the ID of the track that is currently mapped to the SSRC, if any. | 496 // Use the ID of the track that is currently mapped to the SSRC, if any. |
498 std::string track_id; | 497 std::string track_id; |
499 if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { | 498 if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { |
500 if (!report) { | 499 if (!report) { |
501 // The ssrc is not used by any track or existing report, return NULL | 500 // The ssrc is not used by any track or existing report, return NULL |
502 // in such case to indicate no report is prepared for the ssrc. | 501 // in such case to indicate no report is prepared for the ssrc. |
503 return NULL; | 502 return NULL; |
504 } | 503 } |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc || | 853 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc || |
855 type == StatsReport::kStatsReportTypeRemoteSsrc); | 854 type == StatsReport::kStatsReportTypeRemoteSsrc); |
856 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction)); | 855 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction)); |
857 } | 856 } |
858 | 857 |
859 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() { | 858 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() { |
860 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 859 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
861 // Loop through the existing local audio tracks. | 860 // Loop through the existing local audio tracks. |
862 for (const auto& it : local_audio_tracks_) { | 861 for (const auto& it : local_audio_tracks_) { |
863 AudioTrackInterface* track = it.first; | 862 AudioTrackInterface* track = it.first; |
864 uint32 ssrc = it.second; | 863 uint32_t ssrc = it.second; |
865 StatsReport* report = GetReport(StatsReport::kStatsReportTypeSsrc, | 864 StatsReport* report = |
866 rtc::ToString<uint32>(ssrc), | 865 GetReport(StatsReport::kStatsReportTypeSsrc, |
867 StatsReport::kSend); | 866 rtc::ToString<uint32_t>(ssrc), StatsReport::kSend); |
868 if (report == NULL) { | 867 if (report == NULL) { |
869 // This can happen if a local audio track is added to a stream on the | 868 // This can happen if a local audio track is added to a stream on the |
870 // fly and the report has not been set up yet. Do nothing in this case. | 869 // fly and the report has not been set up yet. Do nothing in this case. |
871 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc; | 870 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc; |
872 continue; | 871 continue; |
873 } | 872 } |
874 | 873 |
875 // The same ssrc can be used by both local and remote audio tracks. | 874 // The same ssrc can be used by both local and remote audio tracks. |
876 const StatsReport::Value* v = | 875 const StatsReport::Value* v = |
877 report->FindValue(StatsReport::kStatsValueNameTrackId); | 876 report->FindValue(StatsReport::kStatsValueNameTrackId); |
(...skipping 20 matching lines...) Expand all Loading... |
898 AudioProcessorInterface::AudioProcessorStats stats; | 897 AudioProcessorInterface::AudioProcessorStats stats; |
899 if (audio_processor.get()) | 898 if (audio_processor.get()) |
900 audio_processor->GetStats(&stats); | 899 audio_processor->GetStats(&stats); |
901 | 900 |
902 SetAudioProcessingStats(report, signal_level, stats.typing_noise_detected, | 901 SetAudioProcessingStats(report, signal_level, stats.typing_noise_detected, |
903 stats.echo_return_loss, stats.echo_return_loss_enhancement, | 902 stats.echo_return_loss, stats.echo_return_loss_enhancement, |
904 stats.echo_delay_median_ms, stats.aec_quality_min, | 903 stats.echo_delay_median_ms, stats.aec_quality_min, |
905 stats.echo_delay_std_ms); | 904 stats.echo_delay_std_ms); |
906 } | 905 } |
907 | 906 |
908 bool StatsCollector::GetTrackIdBySsrc(uint32 ssrc, std::string* track_id, | 907 bool StatsCollector::GetTrackIdBySsrc(uint32_t ssrc, |
| 908 std::string* track_id, |
909 StatsReport::Direction direction) { | 909 StatsReport::Direction direction) { |
910 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 910 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
911 if (direction == StatsReport::kSend) { | 911 if (direction == StatsReport::kSend) { |
912 if (!session_->GetLocalTrackIdBySsrc(ssrc, track_id)) { | 912 if (!session_->GetLocalTrackIdBySsrc(ssrc, track_id)) { |
913 LOG(LS_WARNING) << "The SSRC " << ssrc | 913 LOG(LS_WARNING) << "The SSRC " << ssrc |
914 << " is not associated with a sending track"; | 914 << " is not associated with a sending track"; |
915 return false; | 915 return false; |
916 } | 916 } |
917 } else { | 917 } else { |
918 RTC_DCHECK(direction == StatsReport::kReceive); | 918 RTC_DCHECK(direction == StatsReport::kReceive); |
(...skipping 16 matching lines...) Expand all Loading... |
935 StatsReport* report = entry.second; | 935 StatsReport* report = entry.second; |
936 report->set_timestamp(stats_gathering_started_); | 936 report->set_timestamp(stats_gathering_started_); |
937 } | 937 } |
938 } | 938 } |
939 | 939 |
940 void StatsCollector::ClearUpdateStatsCacheForTest() { | 940 void StatsCollector::ClearUpdateStatsCacheForTest() { |
941 stats_gathering_started_ = 0; | 941 stats_gathering_started_ = 0; |
942 } | 942 } |
943 | 943 |
944 } // namespace webrtc | 944 } // namespace webrtc |
OLD | NEW |