Chromium Code Reviews| Index: webrtc/api/rtcstatscollector.cc |
| diff --git a/webrtc/api/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc |
| index b14b39670e61ce8d08bd71118c7b296ca3c5d7e7..5be5a8028a2819706190280faa3deabf6c80d16b 100644 |
| --- a/webrtc/api/rtcstatscollector.cc |
| +++ b/webrtc/api/rtcstatscollector.cc |
| @@ -15,6 +15,8 @@ |
| #include <vector> |
| #include "webrtc/api/peerconnection.h" |
| +#include "webrtc/api/peerconnectioninterface.h" |
| +#include "webrtc/api/mediastreaminterface.h" |
| #include "webrtc/api/webrtcsession.h" |
| #include "webrtc/base/checks.h" |
| #include "webrtc/base/timeutils.h" |
| @@ -37,6 +39,11 @@ std::string RTCIceCandidatePairStatsIDFromConnectionInfo( |
| info.remote_candidate.id(); |
| } |
| +std::string RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
| + const MediaStreamTrackInterface& track) { |
| + return "RTCMediaStreamTrack_" + track.id(); |
| +} |
| + |
| std::string RTCTransportStatsIDFromTransportChannel( |
| const std::string& transport_name, int channel_component) { |
| return "RTCTransport_" + transport_name + "_" + |
| @@ -93,6 +100,13 @@ const char* DataStateToRTCDataChannelState( |
| } |
| } |
| +void SetMediaStreamTrackStatsFromMediaStreamTrackInterface( |
| + const MediaStreamTrackInterface& track, |
| + RTCMediaStreamTrackStats* track_stats) { |
| + track_stats->track_identifier = track.id(); |
| + track_stats->ended = (track.state() == MediaStreamTrackInterface::kEnded); |
| +} |
| + |
| void SetInboundRTPStreamStatsFromMediaReceiverInfo( |
| const cricket::MediaReceiverInfo& media_receiver_info, |
| RTCInboundRTPStreamStats* inbound_stats) { |
| @@ -214,6 +228,95 @@ const std::string& ProduceIceCandidateStats( |
| return stats->id(); |
| } |
| +void ProduceMediaStreamAndTrackStats( |
| + int64_t timestamp_us, |
| + rtc::scoped_refptr<StreamCollectionInterface> streams, |
| + bool is_local, |
| + RTCStatsReport* report) { |
| + // TODO(hbos): When "AddTrack" is implemented we should iterate tracks to |
| + // find which streams exist, not iterate streams to find tracks. |
| + // crbug.com/659137 |
| + // TODO(hbos): As soon as a track is added it should appear in the stats, and |
| + // a track that is removed should continue to appear as a detached track |
| + // stats, taken at the moment of detachment. This means we have to either keep |
| + // the track as-is after detachment or perform stats collection upon |
| + // detachment. crbug.com/659137 |
|
hta-webrtc
2016/11/08 09:50:22
Since data can be passed between the time of the l
hbos
2016/11/08 13:43:37
Done.
|
| + if (!streams) |
| + return; |
| + for (size_t i = 0; i < streams->count(); ++i) { |
| + MediaStreamInterface* stream = streams->at(i); |
| + |
| + std::unique_ptr<RTCMediaStreamStats> stream_stats( |
| + new RTCMediaStreamStats("RTCMediaStream_" + stream->label(), |
| + timestamp_us)); |
| + stream_stats->stream_identifier = stream->label(); |
| + stream_stats->track_ids = std::vector<std::string>(); |
| + // Audio Tracks |
| + for (rtc::scoped_refptr<AudioTrackInterface> audio_track : |
| + stream->GetAudioTracks()) { |
| + std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
| + *audio_track.get()); |
| + if (report->Get(id)) { |
| + // Skip track, stats already exist for it. |
| + continue; |
| + } |
| + std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats( |
| + new RTCMediaStreamTrackStats(id, timestamp_us)); |
| + stream_stats->track_ids->push_back(audio_track_stats->id()); |
| + SetMediaStreamTrackStatsFromMediaStreamTrackInterface( |
| + *audio_track.get(), |
| + audio_track_stats.get()); |
| + audio_track_stats->remote_source = !is_local; |
| + audio_track_stats->detached = false; |
| + int signal_level; |
| + if (audio_track->GetSignalLevel(&signal_level)) { |
| + // Convert signal level from [0,32767] int to [0,1] double. |
| + RTC_DCHECK_GE(signal_level, 0); |
| + RTC_DCHECK_LE(signal_level, 32767); |
| + audio_track_stats->audio_level = signal_level / 32767.0; |
| + } |
| + if (audio_track->GetAudioProcessor()) { |
| + AudioProcessorInterface::AudioProcessorStats audio_processor_stats; |
| + audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats); |
| + audio_track_stats->echo_return_loss = static_cast<double>( |
| + audio_processor_stats.echo_return_loss); |
| + audio_track_stats->echo_return_loss_enhancement = static_cast<double>( |
| + audio_processor_stats.echo_return_loss_enhancement); |
| + } |
| + report->AddStats(std::move(audio_track_stats)); |
| + } |
| + // Video Tracks |
| + for (rtc::scoped_refptr<VideoTrackInterface> video_track : |
| + stream->GetVideoTracks()) { |
| + std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
| + *video_track.get()); |
| + if (report->Get(id)) { |
| + // Skip track, stats already exist for it. |
| + continue; |
| + } |
| + std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats( |
| + new RTCMediaStreamTrackStats(id, timestamp_us)); |
| + stream_stats->track_ids->push_back(video_track_stats->id()); |
| + SetMediaStreamTrackStatsFromMediaStreamTrackInterface( |
| + *video_track.get(), |
| + video_track_stats.get()); |
| + video_track_stats->remote_source = !is_local; |
| + video_track_stats->detached = false; |
| + if (video_track->GetSource()) { |
| + VideoTrackSourceInterface::Stats video_track_source_stats; |
| + if (video_track->GetSource()->GetStats(&video_track_source_stats)) { |
| + video_track_stats->frame_width = static_cast<uint32_t>( |
| + video_track_source_stats.input_width); |
| + video_track_stats->frame_height = static_cast<uint32_t>( |
| + video_track_source_stats.input_height); |
| + } |
| + } |
| + report->AddStats(std::move(video_track_stats)); |
| + } |
| + report->AddStats(std::move(stream_stats)); |
| + } |
| +} |
| + |
| } // namespace |
| rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( |
| @@ -301,6 +404,7 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThread( |
| timestamp_us, session_stats, transport_cert_stats, report.get()); |
| } |
| ProduceDataChannelStats_s(timestamp_us, report.get()); |
| + ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get()); |
| ProducePeerConnectionStats_s(timestamp_us, report.get()); |
| AddPartialResults(report); |
| @@ -467,6 +571,15 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( |
| } |
| } |
| +void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s( |
| + int64_t timestamp_us, RTCStatsReport* report) const { |
| + RTC_DCHECK(signaling_thread_->IsCurrent()); |
| + ProduceMediaStreamAndTrackStats( |
| + timestamp_us, pc_->local_streams(), true, report); |
| + ProduceMediaStreamAndTrackStats( |
| + timestamp_us, pc_->remote_streams(), false, report); |
| +} |
| + |
| void RTCStatsCollector::ProducePeerConnectionStats_s( |
| int64_t timestamp_us, RTCStatsReport* report) const { |
| RTC_DCHECK(signaling_thread_->IsCurrent()); |