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

Unified Diff: webrtc/api/rtcstatscollector.cc

Issue 2605033002: RTCMediaStreamTrackStats.ssrcIds collected by RTCStatsCollector. (Closed)
Patch Set: Rebase with master (reupload from other machine to create dependent patchset) Created 4 years 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/api/rtcstatscollector.cc
diff --git a/webrtc/api/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc
index cf97057c1b6884595618b3083beeacad5727f93d..c54619ef5d189e77723c0f540c79a73977668bd3 100644
--- a/webrtc/api/rtcstatscollector.cc
+++ b/webrtc/api/rtcstatscollector.cc
@@ -29,6 +29,11 @@ namespace webrtc {
namespace {
+// If the track is associated with multiple SSRCs, the |uint32_t| is the first
+// one in the group, used as an identifier for that group. The SSRCs are listed
+// in ||Voice/Video][Sender/Receiver]Info::ssrcs()|.
+typedef std::map<MediaStreamTrackInterface*, uint32_t> TracksToSsrcs;
pthatcher1 2017/01/03 19:29:00 I'd prefer you just use std::map<MediaStreamTrackI
+
std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) {
return "RTCCertificate_" + fingerprint;
}
@@ -54,8 +59,9 @@ std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
}
std::string RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface(
- const MediaStreamTrackInterface& track) {
- return "RTCMediaStreamTrack_" + track.id();
+ const MediaStreamTrackInterface& track, bool is_local) {
+ return (is_local ? "RTCMediaStreamTrack_local_" :
+ "RTCMediaStreamTrack_remote_") + track.id();
}
std::string RTCTransportStatsIDFromTransportChannel(
@@ -280,10 +286,73 @@ const std::string& ProduceIceCandidateStats(
return stats->id();
}
+TracksToSsrcs GetTracksToSsrcs(
+ const std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders) {
+ TracksToSsrcs tracks_to_ssrcs;
pthatcher1 2017/01/03 19:28:59 I think a better name would be "track_to_ssrc".
+ for (const rtc::scoped_refptr<RtpSenderInterface>& sender : senders) {
+ if (!sender->track())
+ continue;
pthatcher1 2017/01/03 19:28:59 {}s please
+ if (sender->ssrc() != 0) {
pthatcher1 2017/01/03 19:28:59 Why not do another early continue? if (!sender->s
+ // TODO(hbos): What if multiple |RtpSenderInterface| have the same track
+ // attached yielding multiple SSRCs groups? Only one of them would
+ // currently be used. crbug.com/659137
hta-webrtc 2017/01/02 15:29:46 This is supposed to be allowed, and the track is t
+ // TODO(hbos): What if |GetParameters().encodings.size() > 1| yields
+ // multiple SSRC groups per sender? crbug.com/659137
+ tracks_to_ssrcs[sender->track().get()] = sender->ssrc();
hta-webrtc 2017/01/02 15:29:46 If you DCHECK(!tracks_to_ssrcs.is_member(sender->t
+ }
+ }
+ return tracks_to_ssrcs;
+}
+// TODO(hbos,deadbeef): With template argument |T| for both |RtpSenderInterface|
+// and |RtpReceiverInterface| this function should be able to cover both sender
+// and receiver cases. But the |RtpSenderInterface| needs to be updated first,
+// when this comment was written it could have an |ssrc()| and still not a value
+// for |GetParameters().encodings[0].ssrc|.
+TracksToSsrcs GetTracksToSsrcs(
+ const std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers) {
+ TracksToSsrcs tracks_to_ssrcs;
+ for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver : receivers) {
+ if (!receiver->track())
Taylor Brandstetter 2017/01/04 00:36:56 A receiver should always have a track; you can DCH
+ continue;
pthatcher1 2017/01/03 19:29:00 {}s please
+ RTC_DCHECK(
+ tracks_to_ssrcs.find(receiver->track().get()) == tracks_to_ssrcs.end());
+ RtpParameters parameters = receiver->GetParameters();
+ if (parameters.encodings.empty())
+ continue;
pthatcher1 2017/01/03 19:28:59 {}s please
+ RTC_DCHECK_EQ(1u, parameters.encodings.size());
pthatcher1 2017/01/03 19:29:00 This is going to explode as soon as we implement G
Taylor Brandstetter 2017/01/04 00:36:56 In that case the DCHECK would be redundant since "
+ rtc::Optional<uint32_t> ssrc = parameters.encodings[0].ssrc;
+ if (ssrc)
+ tracks_to_ssrcs[receiver->track().get()] = *ssrc;
pthatcher1 2017/01/03 19:28:59 {}s please
+ }
+ return tracks_to_ssrcs;
+}
+
+// |T| can be any |MediaSenderInfo| or |MediaReceiverInfo|.
+template<typename T>
+const T* GetMediaInfoFromSsrc(const std::vector<T>& infos, uint32_t ssrc) {
pthatcher1 2017/01/03 19:28:59 Sounds more like "BySsrc" than "FromSsrc" Or why
+ for (const T& info : infos) {
+ if (info.ssrc() == ssrc)
+ return &info;
pthatcher1 2017/01/03 19:28:59 {}s please
+ }
+ return nullptr;
+}
+
+std::vector<std::string> StringSsrcsFromSsrcs(
+ const std::vector<uint32_t>& ssrcs) {
pthatcher1 2017/01/03 19:28:59 Why not just call this ToStrings? You could even
+ std::vector<std::string> string_ssrcs;
+ for (uint32_t ssrc : ssrcs) {
+ string_ssrcs.push_back(rtc::ToString<>(ssrc));
+ }
+ return string_ssrcs;
+}
+
void ProduceMediaStreamAndTrackStats(
int64_t timestamp_us,
rtc::scoped_refptr<StreamCollectionInterface> streams,
bool is_local,
+ const TracksToSsrcs& tracks_to_ssrcs,
+ const rtc::Optional<cricket::VoiceMediaInfo>& voice_info,
+ const rtc::Optional<cricket::VideoMediaInfo>& video_info,
RTCStatsReport* report) {
// TODO(hbos): When "AddTrack" is implemented we should iterate tracks to
// find which streams exist, not iterate streams to find tracks.
@@ -306,17 +375,33 @@ void ProduceMediaStreamAndTrackStats(
for (const 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;
- }
pthatcher1 2017/01/03 19:29:00 So why don't we skip this any more?
+ *audio_track.get(), is_local);
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());
+ TracksToSsrcs::const_iterator it = tracks_to_ssrcs.find(
+ audio_track.get());
+ if (it != tracks_to_ssrcs.end() && voice_info) {
+ uint32_t ssrc = it->second;
+ if (is_local) {
+ const cricket::VoiceSenderInfo* sender_info =
+ GetMediaInfoFromSsrc(voice_info->senders, ssrc);
+ if (sender_info) {
+ audio_track_stats->ssrc_ids = StringSsrcsFromSsrcs(
+ sender_info->ssrcs());
+ }
+ } else {
+ const cricket::VoiceReceiverInfo* receiver_info =
+ GetMediaInfoFromSsrc(voice_info->receivers, ssrc);
+ if (receiver_info) {
+ audio_track_stats->ssrc_ids = StringSsrcsFromSsrcs(
+ receiver_info->ssrcs());
+ }
+ }
+ }
audio_track_stats->remote_source = !is_local;
audio_track_stats->detached = false;
int signal_level;
@@ -344,17 +429,33 @@ void ProduceMediaStreamAndTrackStats(
for (const 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;
- }
+ *video_track.get(), is_local);
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());
+ TracksToSsrcs::const_iterator it = tracks_to_ssrcs.find(
+ video_track.get());
+ if (it != tracks_to_ssrcs.end() && video_info) {
+ uint32_t ssrc = it->second;
+ if (is_local) {
+ const cricket::VideoSenderInfo* sender_info =
+ GetMediaInfoFromSsrc(video_info->senders, ssrc);
+ if (sender_info) {
+ video_track_stats->ssrc_ids = StringSsrcsFromSsrcs(
+ sender_info->ssrcs());
+ }
+ } else {
+ const cricket::VideoReceiverInfo* receiver_info =
+ GetMediaInfoFromSsrc(video_info->receivers, ssrc);
+ if (receiver_info) {
+ video_track_stats->ssrc_ids = StringSsrcsFromSsrcs(
+ receiver_info->ssrcs());
+ }
+ }
+ }
video_track_stats->remote_source = !is_local;
video_track_stats->detached = false;
if (video_track->GetSource()) {
@@ -427,9 +528,6 @@ void RTCStatsCollector::GetStatsReport(
num_pending_partial_reports_ = 3;
partial_report_timestamp_us_ = cache_now_us;
- invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_,
- rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnSignalingThread,
- rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
// TODO(hbos): No stats are gathered by
// |ProducePartialResultsOnWorkerThread|, remove it.
@@ -437,8 +535,9 @@ void RTCStatsCollector::GetStatsReport(
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnWorkerThread,
rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
- // Prepare |channel_names_| and |media_info_| for use in
- // |ProducePartialResultsOnNetworkThread|.
+ // Prepare |channel_names_| and |media_info_|. These are read in
hta-webrtc 2017/01/02 15:29:46 Do you mean channel_name_pairs_?
+ // |ProducePartialResultsOnNetworkThread|, and |media_info_| is also used in
+ // |ProducePartialResultsOnSignalingThread|.
channel_name_pairs_.reset(new ChannelNamePairs());
if (pc_->session()->voice_channel()) {
channel_name_pairs_->voice = rtc::Optional<ChannelNamePair>(
@@ -459,6 +558,7 @@ void RTCStatsCollector::GetStatsReport(
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, network_thread_,
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnNetworkThread,
rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
+ ProducePartialResultsOnSignalingThread(timestamp_us);
pthatcher1 2017/01/03 19:28:59 Should you DCHECK that you're on the signaling thr
Taylor Brandstetter 2017/01/04 00:36:56 ProducePartialResultsOnSignalingThread does this.
}
}
@@ -702,9 +802,21 @@ void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s(
int64_t timestamp_us, RTCStatsReport* report) const {
RTC_DCHECK(signaling_thread_->IsCurrent());
ProduceMediaStreamAndTrackStats(
- timestamp_us, pc_->local_streams(), true, report);
+ timestamp_us,
+ pc_->local_streams(),
+ true,
+ GetTracksToSsrcs(pc_->GetSenders()),
+ media_info_->voice,
+ media_info_->video,
+ report);
ProduceMediaStreamAndTrackStats(
- timestamp_us, pc_->remote_streams(), false, report);
+ timestamp_us,
+ pc_->remote_streams(),
+ false,
+ GetTracksToSsrcs(pc_->GetReceivers()),
+ media_info_->voice,
+ media_info_->video,
+ report);
}
void RTCStatsCollector::ProducePeerConnectionStats_s(

Powered by Google App Engine
This is Rietveld 408576698