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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc || | 857 RTC_DCHECK(type == StatsReport::kStatsReportTypeSsrc || |
859 type == StatsReport::kStatsReportTypeRemoteSsrc); | 858 type == StatsReport::kStatsReportTypeRemoteSsrc); |
860 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction)); | 859 return reports_.Find(StatsReport::NewIdWithDirection(type, id, direction)); |
861 } | 860 } |
862 | 861 |
863 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() { | 862 void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() { |
864 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 863 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
865 // Loop through the existing local audio tracks. | 864 // Loop through the existing local audio tracks. |
866 for (const auto& it : local_audio_tracks_) { | 865 for (const auto& it : local_audio_tracks_) { |
867 AudioTrackInterface* track = it.first; | 866 AudioTrackInterface* track = it.first; |
868 uint32 ssrc = it.second; | 867 uint32_t ssrc = it.second; |
869 StatsReport* report = GetReport(StatsReport::kStatsReportTypeSsrc, | 868 StatsReport* report = |
870 rtc::ToString<uint32>(ssrc), | 869 GetReport(StatsReport::kStatsReportTypeSsrc, |
871 StatsReport::kSend); | 870 rtc::ToString<uint32_t>(ssrc), StatsReport::kSend); |
872 if (report == NULL) { | 871 if (report == NULL) { |
873 // This can happen if a local audio track is added to a stream on the | 872 // This can happen if a local audio track is added to a stream on the |
874 // fly and the report has not been set up yet. Do nothing in this case. | 873 // fly and the report has not been set up yet. Do nothing in this case. |
875 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc; | 874 LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc; |
876 continue; | 875 continue; |
877 } | 876 } |
878 | 877 |
879 // The same ssrc can be used by both local and remote audio tracks. | 878 // The same ssrc can be used by both local and remote audio tracks. |
880 const StatsReport::Value* v = | 879 const StatsReport::Value* v = |
881 report->FindValue(StatsReport::kStatsValueNameTrackId); | 880 report->FindValue(StatsReport::kStatsValueNameTrackId); |
(...skipping 20 matching lines...) Expand all Loading... |
902 AudioProcessorInterface::AudioProcessorStats stats; | 901 AudioProcessorInterface::AudioProcessorStats stats; |
903 if (audio_processor.get()) | 902 if (audio_processor.get()) |
904 audio_processor->GetStats(&stats); | 903 audio_processor->GetStats(&stats); |
905 | 904 |
906 SetAudioProcessingStats(report, signal_level, stats.typing_noise_detected, | 905 SetAudioProcessingStats(report, signal_level, stats.typing_noise_detected, |
907 stats.echo_return_loss, stats.echo_return_loss_enhancement, | 906 stats.echo_return_loss, stats.echo_return_loss_enhancement, |
908 stats.echo_delay_median_ms, stats.aec_quality_min, | 907 stats.echo_delay_median_ms, stats.aec_quality_min, |
909 stats.echo_delay_std_ms); | 908 stats.echo_delay_std_ms); |
910 } | 909 } |
911 | 910 |
912 bool StatsCollector::GetTrackIdBySsrc(uint32 ssrc, std::string* track_id, | 911 bool StatsCollector::GetTrackIdBySsrc(uint32_t ssrc, |
| 912 std::string* track_id, |
913 StatsReport::Direction direction) { | 913 StatsReport::Direction direction) { |
914 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); | 914 RTC_DCHECK(session_->signaling_thread()->IsCurrent()); |
915 if (direction == StatsReport::kSend) { | 915 if (direction == StatsReport::kSend) { |
916 if (!session_->GetLocalTrackIdBySsrc(ssrc, track_id)) { | 916 if (!session_->GetLocalTrackIdBySsrc(ssrc, track_id)) { |
917 LOG(LS_WARNING) << "The SSRC " << ssrc | 917 LOG(LS_WARNING) << "The SSRC " << ssrc |
918 << " is not associated with a sending track"; | 918 << " is not associated with a sending track"; |
919 return false; | 919 return false; |
920 } | 920 } |
921 } else { | 921 } else { |
922 RTC_DCHECK(direction == StatsReport::kReceive); | 922 RTC_DCHECK(direction == StatsReport::kReceive); |
(...skipping 17 matching lines...) Expand all Loading... |
940 report->set_timestamp(stats_gathering_started_); | 940 report->set_timestamp(stats_gathering_started_); |
941 } | 941 } |
942 | 942 |
943 } | 943 } |
944 | 944 |
945 void StatsCollector::ClearUpdateStatsCacheForTest() { | 945 void StatsCollector::ClearUpdateStatsCacheForTest() { |
946 stats_gathering_started_ = 0; | 946 stats_gathering_started_ = 0; |
947 } | 947 } |
948 | 948 |
949 } // namespace webrtc | 949 } // namespace webrtc |
OLD | NEW |