Index: webrtc/api/rtcstatscollector.cc |
diff --git a/webrtc/api/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc |
index b14b39670e61ce8d08bd71118c7b296ca3c5d7e7..c7e9a969cbcf219654909b548f11d4f6f920ae7e 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,91 @@ 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): This gets the current stream/track stats. The spec says that |
+ // stream/track stats should appear in the stats as soon as they have been |
+ // attached. This means we need to invalidate the collector's cache upon |
+ // attaching or in some other way make sure that the new streams/tracks are |
+ // accounted for. crbug.com/659137 |
+ // TODO(hbos): Also return detached tracks' stats (no longer present when |
+ // iterating). The spec says the state should be a snapshot of the track 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 |
hbos
2016/11/02 11:54:44
Is it not the case that a stream can be detached a
hta-webrtc
2016/11/03 14:34:21
The spec has strongly deemphasized streams. In fac
hbos
2016/11/03 18:10:30
Acknowledged.
|
+ 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::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats( |
+ new RTCMediaStreamTrackStats( |
+ RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
+ *audio_track.get()), |
+ timestamp_us)); |
+ stream_stats->track_ids->push_back(audio_track_stats->id()); |
hta-webrtc
2016/11/03 14:34:21
Consider what happens here if a track is a member
hbos
2016/11/03 18:10:30
Done. Skipping if already exists.
|
+ 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; |
hta-webrtc
2016/11/03 14:34:21
Check this one with Niklas. Audio levels are awful
hbos
2016/11/03 18:10:30
+niklase: Is this the correct way to get the audio
|
+ } |
+ 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::unique_ptr<RTCMediaStreamTrackStats> video_track_stats( |
+ new RTCMediaStreamTrackStats( |
+ RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface( |
+ *video_track.get()), |
+ 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); |
hbos
2016/11/02 11:44:55
I wonder if this is the right value. What if the s
hbos
2016/11/02 11:48:41
And there are similar stats to the spec in Video[S
hta-webrtc
2016/11/03 14:34:21
Yes. More work needed both for getSettings and for
hta-webrtc
2016/11/03 14:34:21
It should be the downscaled value. I have a TODO t
hbos
2016/11/03 18:10:30
What are you referring to when you say "getSetting
hta-webrtc
2016/11/04 16:30:01
https://w3c.github.io/mediacapture-main/getusermed
|
+ } |
+ } |
+ report->AddStats(std::move(video_track_stats)); |
+ } |
+ report->AddStats(std::move(stream_stats)); |
+ } |
+} |
+ |
} // namespace |
rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create( |
@@ -301,6 +400,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 +567,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()); |