Revert "Update RTCStatsCollector to work with RtpTransceivers"
This reverts commit 56bae8ded39c3fab2635b7d2d1d17a87d5d2818b.
Reason for revert: Speculative revert. This CL is suspect of making Chrome trybots fail the following test, preventing rolls:
external/wpt/webrtc/RTCPeerConnection-track-stats.https.html
Some failed roll attempts:
https://chromium-review.googlesource.com/c/chromium/src/+/921421
https://chromium-review.googlesource.com/c/chromium/src/+/921422
https://chromium-review.googlesource.com/c/chromium/src/+/921781
Some failed bot runs:
https://ci.chromium.org/buildbot/tryserver.chromium.linux/linux_chromium_rel_ng/647669
https://ci.chromium.org/buildbot/tryserver.chromium.win/win7_chromium_rel_ng/103786
Original change's description:
> Update RTCStatsCollector to work with RtpTransceivers
>
> Bug: webrtc:8764
> Change-Id: I8b442345869eb6d8b65fd12241ed7cb6e7d7ce3d
> Reviewed-on: https://webrtc-review.googlesource.com/49580
> Commit-Queue: Steve Anton <steveanton@webrtc.org>
> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22026}
TBR=steveanton@webrtc.org,deadbeef@webrtc.org,hbos@webrtc.org,pthatcher@webrtc.org
Change-Id: I21ce2109087d7b2d9470471ee9a6757f904296d2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:8764
Reviewed-on: https://webrtc-review.googlesource.com/54000
Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
Commit-Queue: Guido Urdaneta <guidou@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22036}
diff --git a/pc/rtcstatscollector.cc b/pc/rtcstatscollector.cc
index e2be5ff..77dde95 100644
--- a/pc/rtcstatscollector.cc
+++ b/pc/rtcstatscollector.cc
@@ -24,7 +24,6 @@
#include "p2p/base/port.h"
#include "pc/peerconnection.h"
#include "rtc_base/checks.h"
-#include "rtc_base/ptr_util.h"
#include "rtc_base/stringutils.h"
#include "rtc_base/timeutils.h"
#include "rtc_base/trace_event.h"
@@ -37,11 +36,19 @@
return "RTCCertificate_" + fingerprint;
}
-std::string RTCCodecStatsIDFromMidDirectionAndPayload(const std::string& mid,
- bool inbound,
- uint32_t payload_type) {
- return "RTCCodec_" + mid + "_" + (inbound ? "Inbound" : "Outbound") + "_" +
- rtc::ToString<>(payload_type);
+std::string RTCCodecStatsIDFromDirectionMediaAndPayload(
+ bool inbound, bool audio, uint32_t payload_type) {
+ // TODO(hbos): The present codec ID assignment is not sufficient to support
+ // Unified Plan or unbundled connections in all cases. When we are able to
+ // handle multiple m= lines of the same media type (and multiple BaseChannels
+ // for the same type is possible?) this needs to be updated to differentiate
+ // the transport being used, and stats need to be collected for all of them.
+ if (inbound) {
+ return audio ? "RTCCodec_InboundAudio_" + rtc::ToString<>(payload_type)
+ : "RTCCodec_InboundVideo_" + rtc::ToString<>(payload_type);
+ }
+ return audio ? "RTCCodec_OutboundAudio_" + rtc::ToString<>(payload_type)
+ : "RTCCodec_OutboundVideo_" + rtc::ToString<>(payload_type);
}
std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
@@ -168,16 +175,14 @@
}
std::unique_ptr<RTCCodecStats> CodecStatsFromRtpCodecParameters(
- uint64_t timestamp_us,
- const std::string& mid,
- bool inbound,
+ uint64_t timestamp_us, bool inbound, bool audio,
const RtpCodecParameters& codec_params) {
RTC_DCHECK_GE(codec_params.payload_type, 0);
RTC_DCHECK_LE(codec_params.payload_type, 127);
RTC_DCHECK(codec_params.clock_rate);
uint32_t payload_type = static_cast<uint32_t>(codec_params.payload_type);
std::unique_ptr<RTCCodecStats> codec_stats(new RTCCodecStats(
- RTCCodecStatsIDFromMidDirectionAndPayload(mid, inbound, payload_type),
+ RTCCodecStatsIDFromDirectionMediaAndPayload(inbound, audio, payload_type),
timestamp_us));
codec_stats->payload_type = payload_type;
codec_stats->mime_type = codec_params.mime_type();
@@ -213,15 +218,15 @@
}
void SetInboundRTPStreamStatsFromVoiceReceiverInfo(
- const std::string& mid,
const cricket::VoiceReceiverInfo& voice_receiver_info,
RTCInboundRTPStreamStats* inbound_audio) {
SetInboundRTPStreamStatsFromMediaReceiverInfo(
voice_receiver_info, inbound_audio);
inbound_audio->media_type = "audio";
if (voice_receiver_info.codec_payload_type) {
- inbound_audio->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
- mid, true, *voice_receiver_info.codec_payload_type);
+ inbound_audio->codec_id =
+ RTCCodecStatsIDFromDirectionMediaAndPayload(
+ true, true, *voice_receiver_info.codec_payload_type);
}
inbound_audio->jitter =
static_cast<double>(voice_receiver_info.jitter_ms) /
@@ -231,15 +236,15 @@
}
void SetInboundRTPStreamStatsFromVideoReceiverInfo(
- const std::string& mid,
const cricket::VideoReceiverInfo& video_receiver_info,
RTCInboundRTPStreamStats* inbound_video) {
SetInboundRTPStreamStatsFromMediaReceiverInfo(
video_receiver_info, inbound_video);
inbound_video->media_type = "video";
if (video_receiver_info.codec_payload_type) {
- inbound_video->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
- mid, true, *video_receiver_info.codec_payload_type);
+ inbound_video->codec_id =
+ RTCCodecStatsIDFromDirectionMediaAndPayload(
+ true, false, *video_receiver_info.codec_payload_type);
}
inbound_video->fir_count =
static_cast<uint32_t>(video_receiver_info.firs_sent);
@@ -267,30 +272,30 @@
}
void SetOutboundRTPStreamStatsFromVoiceSenderInfo(
- const std::string& mid,
const cricket::VoiceSenderInfo& voice_sender_info,
RTCOutboundRTPStreamStats* outbound_audio) {
SetOutboundRTPStreamStatsFromMediaSenderInfo(
voice_sender_info, outbound_audio);
outbound_audio->media_type = "audio";
if (voice_sender_info.codec_payload_type) {
- outbound_audio->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
- mid, false, *voice_sender_info.codec_payload_type);
+ outbound_audio->codec_id =
+ RTCCodecStatsIDFromDirectionMediaAndPayload(
+ false, true, *voice_sender_info.codec_payload_type);
}
// |fir_count|, |pli_count| and |sli_count| are only valid for video and are
// purposefully left undefined for audio.
}
void SetOutboundRTPStreamStatsFromVideoSenderInfo(
- const std::string& mid,
const cricket::VideoSenderInfo& video_sender_info,
RTCOutboundRTPStreamStats* outbound_video) {
SetOutboundRTPStreamStatsFromMediaSenderInfo(
video_sender_info, outbound_video);
outbound_video->media_type = "video";
if (video_sender_info.codec_payload_type) {
- outbound_video->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
- mid, false, *video_sender_info.codec_payload_type);
+ outbound_video->codec_id =
+ RTCCodecStatsIDFromDirectionMediaAndPayload(
+ false, false, *video_sender_info.codec_payload_type);
}
outbound_video->fir_count =
static_cast<uint32_t>(video_sender_info.firs_rcvd);
@@ -497,14 +502,14 @@
void ProduceSenderMediaTrackStats(
int64_t timestamp_us,
const TrackMediaInfoMap& track_media_info_map,
- std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders,
+ std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders,
RTCStatsReport* report) {
// This function iterates over the senders to generate outgoing track stats.
// TODO(hbos): Return stats of detached tracks. We have to perform stats
// gathering at the time of detachment to get accurate stats and timestamps.
// https://crbug.com/659137
- for (auto sender : senders) {
+ for (auto const sender : senders) {
if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
AudioTrackInterface* track =
static_cast<AudioTrackInterface*>(sender->track().get());
@@ -515,11 +520,11 @@
// TODO(hta): Checking on ssrc is not proper. There should be a way
// to see from a sender whether it's connected or not.
// Related to https://crbug.com/8694 (using ssrc 0 to indicate "none")
- if (sender->ssrc() != 0) {
+ if (sender->ssrc()) {
// When pc.close is called, sender info is discarded, so
// we generate zeroes instead. Bug: It should be retained.
// https://crbug.com/807174
- const cricket::VoiceSenderInfo* sender_info =
+ auto sender_info =
track_media_info_map.GetVoiceSenderInfoBySsrc(sender->ssrc());
if (sender_info) {
voice_sender_info = sender_info;
@@ -543,11 +548,11 @@
// TODO(hta): Check on state not ssrc when state is available
// Related to https://bugs.webrtc.org/8694 (using ssrc 0 to indicate
// "none")
- if (sender->ssrc() != 0) {
+ if (sender->ssrc()) {
// When pc.close is called, sender info is discarded, so
// we generate zeroes instead. Bug: It should be retained.
// https://crbug.com/807174
- const cricket::VideoSenderInfo* sender_info =
+ auto sender_info =
track_media_info_map.GetVideoSenderInfoBySsrc(sender->ssrc());
if (sender_info) {
video_sender_info = sender_info;
@@ -569,10 +574,10 @@
void ProduceReceiverMediaTrackStats(
int64_t timestamp_us,
const TrackMediaInfoMap& track_media_info_map,
- std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers,
+ std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers,
RTCStatsReport* report) {
// This function iterates over the receivers to find the remote tracks.
- for (auto receiver : receivers) {
+ for (auto const receiver : receivers) {
if (receiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
AudioTrackInterface* track =
static_cast<AudioTrackInterface*>(receiver->track().get());
@@ -605,6 +610,38 @@
}
}
+void ProduceMediaStreamStats(
+ int64_t timestamp_us,
+ const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
+ const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers,
+ RTCStatsReport* report) {
+ std::map<std::string, std::vector<std::string>> track_ids;
+
+ for (auto& sender : rtp_senders) {
+ std::string track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kSender, sender->AttachmentId());
+ for (auto& stream_id : sender->stream_ids()) {
+ track_ids[stream_id].push_back(track_id);
+ }
+ }
+ for (auto& receiver : rtp_receivers) {
+ std::string track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kReceiver, receiver->AttachmentId());
+ for (auto& stream : receiver->streams()) {
+ track_ids[stream->label()].push_back(track_id);
+ }
+ }
+
+ // Build stats for each stream ID known.
+ for (auto& it : track_ids) {
+ std::unique_ptr<RTCMediaStreamStats> stream_stats(
+ new RTCMediaStreamStats("RTCMediaStream_" + it.first, timestamp_us));
+ stream_stats->stream_identifier = it.first;
+ stream_stats->track_ids = it.second;
+ report->AddStats(std::move(stream_stats));
+ }
+}
+
} // namespace
rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create(
@@ -662,10 +699,27 @@
num_pending_partial_reports_ = 2;
partial_report_timestamp_us_ = cache_now_us;
- // Prepare |transceiver_stats_infos_| for use in
+ // Prepare |transport_name_by_mid_| for use in
+ // |ProducePartialResultsOnNetworkThread|.
+ transport_names_by_mid_ = pc_->GetTransportNamesByMid();
+ // Prepare |track_media_info_map_| for use in
// |ProducePartialResultsOnNetworkThread| and
// |ProducePartialResultsOnSignalingThread|.
- transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s();
+ track_media_info_map_.reset(PrepareTrackMediaInfoMap_s().release());
+ // Prepare |track_to_id_| for use in |ProducePartialResultsOnNetworkThread|.
+ // This avoids a possible deadlock if |MediaStreamTrackInterface::id| is
+ // implemented to invoke on the signaling thread.
+ track_to_id_ = PrepareTrackToID_s();
+
+ voice_mid_.reset();
+ if (pc_->voice_channel()) {
+ voice_mid_ = pc_->voice_channel()->content_name();
+ }
+
+ video_mid_.reset();
+ if (pc_->video_channel()) {
+ video_mid_ = pc_->video_channel()->content_name();
+ }
// Prepare |call_stats_| here since GetCallStats() will hop to the worker
// thread.
@@ -704,8 +758,7 @@
timestamp_us);
ProduceDataChannelStats_s(timestamp_us, report.get());
- ProduceMediaStreamStats_s(timestamp_us, report.get());
- ProduceMediaStreamTrackStats_s(timestamp_us, report.get());
+ ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get());
ProducePeerConnectionStats_s(timestamp_us, report.get());
AddPartialResults(report);
@@ -718,8 +771,8 @@
timestamp_us);
std::set<std::string> transport_names;
- for (const auto& stats : transceiver_stats_infos_) {
- transport_names.insert(stats.transport_name);
+ for (const auto& entry : transport_names_by_mid_) {
+ transport_names.insert(entry.second);
}
std::map<std::string, cricket::TransportStats> transport_stats_by_name =
pc_->GetTransportStatsByNames(transport_names);
@@ -728,10 +781,12 @@
PrepareTransportCertificateStats_n(transport_stats_by_name);
ProduceCertificateStats_n(timestamp_us, transport_cert_stats, report.get());
- ProduceCodecStats_n(timestamp_us, transceiver_stats_infos_, report.get());
+ ProduceCodecStats_n(timestamp_us, *track_media_info_map_, report.get());
ProduceIceCandidateAndPairStats_n(timestamp_us, transport_stats_by_name,
+ track_media_info_map_->video_media_info(),
call_stats_, report.get());
- ProduceRTPStreamStats_n(timestamp_us, transceiver_stats_infos_, report.get());
+ ProduceRTPStreamStats_n(timestamp_us, transport_names_by_mid_,
+ *track_media_info_map_, report.get());
ProduceTransportStats_n(timestamp_us, transport_stats_by_name,
transport_cert_stats, report.get());
@@ -763,7 +818,9 @@
cache_timestamp_us_ = partial_report_timestamp_us_;
cached_report_ = partial_report_;
partial_report_ = nullptr;
- transceiver_stats_infos_.clear();
+ transport_names_by_mid_.clear();
+ track_media_info_map_.reset();
+ track_to_id_.clear();
// Trace WebRTC Stats when getStats is called on Javascript.
// This allows access to WebRTC stats from trace logs. To enable them,
// select the "webrtc_stats" category when recording traces.
@@ -802,40 +859,37 @@
}
void RTCStatsCollector::ProduceCodecStats_n(
- int64_t timestamp_us,
- const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+ int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const {
RTC_DCHECK(network_thread_->IsCurrent());
- for (const auto& stats : transceiver_stats_infos) {
- const cricket::VoiceMediaInfo* voice_media_info =
- stats.track_media_info_map->voice_media_info();
- const cricket::VideoMediaInfo* video_media_info =
- stats.track_media_info_map->video_media_info();
- // Audio
- if (voice_media_info) {
- // Inbound
- for (const auto& pair : voice_media_info->receive_codecs) {
- report->AddStats(CodecStatsFromRtpCodecParameters(
- timestamp_us, stats.mid, true, pair.second));
- }
- // Outbound
- for (const auto& pair : voice_media_info->send_codecs) {
- report->AddStats(CodecStatsFromRtpCodecParameters(
- timestamp_us, stats.mid, false, pair.second));
- }
+ // Audio
+ if (track_media_info_map.voice_media_info()) {
+ // Inbound
+ for (const auto& pair :
+ track_media_info_map.voice_media_info()->receive_codecs) {
+ report->AddStats(CodecStatsFromRtpCodecParameters(
+ timestamp_us, true, true, pair.second));
}
- // Video
- if (video_media_info) {
- // Inbound
- for (const auto& pair : video_media_info->receive_codecs) {
- report->AddStats(CodecStatsFromRtpCodecParameters(
- timestamp_us, stats.mid, true, pair.second));
- }
- // Outbound
- for (const auto& pair : video_media_info->send_codecs) {
- report->AddStats(CodecStatsFromRtpCodecParameters(
- timestamp_us, stats.mid, false, pair.second));
- }
+ // Outbound
+ for (const auto& pair :
+ track_media_info_map.voice_media_info()->send_codecs) {
+ report->AddStats(CodecStatsFromRtpCodecParameters(
+ timestamp_us, false, true, pair.second));
+ }
+ }
+ // Video
+ if (track_media_info_map.video_media_info()) {
+ // Inbound
+ for (const auto& pair :
+ track_media_info_map.video_media_info()->receive_codecs) {
+ report->AddStats(CodecStatsFromRtpCodecParameters(
+ timestamp_us, true, false, pair.second));
+ }
+ // Outbound
+ for (const auto& pair :
+ track_media_info_map.video_media_info()->send_codecs) {
+ report->AddStats(CodecStatsFromRtpCodecParameters(
+ timestamp_us, false, false, pair.second));
}
}
}
@@ -866,6 +920,7 @@
int64_t timestamp_us,
const std::map<std::string, cricket::TransportStats>&
transport_stats_by_name,
+ const cricket::VideoMediaInfo* video_media_info,
const Call::Stats& call_stats,
RTCStatsReport* report) const {
RTC_DCHECK(network_thread_->IsCurrent());
@@ -945,61 +1000,16 @@
}
}
-void RTCStatsCollector::ProduceMediaStreamStats_s(
- int64_t timestamp_us,
- RTCStatsReport* report) const {
+void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s(
+ int64_t timestamp_us, RTCStatsReport* report) const {
RTC_DCHECK(signaling_thread_->IsCurrent());
-
- std::map<std::string, std::vector<std::string>> track_ids;
-
- for (const auto& stats : transceiver_stats_infos_) {
- for (auto sender : stats.transceiver->senders()) {
- std::string track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kSender, sender->internal()->AttachmentId());
- for (auto& stream_id : sender->stream_ids()) {
- track_ids[stream_id].push_back(track_id);
- }
- }
- for (auto receiver : stats.transceiver->receivers()) {
- std::string track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kReceiver, receiver->internal()->AttachmentId());
- for (auto& stream : receiver->streams()) {
- track_ids[stream->label()].push_back(track_id);
- }
- }
- }
-
- // Build stats for each stream ID known.
- for (auto& it : track_ids) {
- std::unique_ptr<RTCMediaStreamStats> stream_stats(
- new RTCMediaStreamStats("RTCMediaStream_" + it.first, timestamp_us));
- stream_stats->stream_identifier = it.first;
- stream_stats->track_ids = it.second;
- report->AddStats(std::move(stream_stats));
- }
-}
-
-void RTCStatsCollector::ProduceMediaStreamTrackStats_s(
- int64_t timestamp_us,
- RTCStatsReport* report) const {
- RTC_DCHECK(signaling_thread_->IsCurrent());
- for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos_) {
- std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders;
- for (auto sender : stats.transceiver->senders()) {
- senders.push_back(sender->internal());
- }
- ProduceSenderMediaTrackStats(timestamp_us, *stats.track_media_info_map,
- senders, report);
-
- std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers;
- for (auto receiver : stats.transceiver->receivers()) {
- receivers.push_back(receiver->internal());
- }
- ProduceReceiverMediaTrackStats(timestamp_us, *stats.track_media_info_map,
- receivers, report);
- }
+ RTC_DCHECK(track_media_info_map_);
+ ProduceMediaStreamStats(timestamp_us, pc_->GetSenders(), pc_->GetReceivers(),
+ report);
+ ProduceSenderMediaTrackStats(timestamp_us, *track_media_info_map_,
+ pc_->GetSenders(), report);
+ ProduceReceiverMediaTrackStats(timestamp_us, *track_media_info_map_,
+ pc_->GetReceivers(), report);
}
void RTCStatsCollector::ProducePeerConnectionStats_s(
@@ -1014,125 +1024,122 @@
void RTCStatsCollector::ProduceRTPStreamStats_n(
int64_t timestamp_us,
- const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+ const std::map<std::string, std::string>& transport_names_by_mid,
+ const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const {
RTC_DCHECK(network_thread_->IsCurrent());
- for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos) {
- if (stats.media_type == cricket::MEDIA_TYPE_AUDIO) {
- ProduceAudioRTPStreamStats_n(timestamp_us, stats, report);
- } else if (stats.media_type == cricket::MEDIA_TYPE_VIDEO) {
- ProduceVideoRTPStreamStats_n(timestamp_us, stats, report);
- } else {
- RTC_NOTREACHED();
- }
- }
-}
+ // Audio
+ if (track_media_info_map.voice_media_info()) {
+ RTC_DCHECK(voice_mid_);
+ const std::string& transport_name = transport_names_by_mid.at(*voice_mid_);
+ std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+ transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
+ // Inbound
+ for (const cricket::VoiceReceiverInfo& voice_receiver_info :
+ track_media_info_map.voice_media_info()->receivers) {
+ if (!voice_receiver_info.connected())
+ continue;
-void RTCStatsCollector::ProduceAudioRTPStreamStats_n(
- int64_t timestamp_us,
- const RtpTransceiverStatsInfo& stats,
- RTCStatsReport* report) const {
- RTC_DCHECK(stats.track_media_info_map);
- const TrackMediaInfoMap& track_media_info_map = *stats.track_media_info_map;
- RTC_DCHECK(track_media_info_map.voice_media_info());
- std::string transport_id = RTCTransportStatsIDFromTransportChannel(
- stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
- // Inbound
- for (const cricket::VoiceReceiverInfo& voice_receiver_info :
- track_media_info_map.voice_media_info()->receivers) {
- if (!voice_receiver_info.connected())
- continue;
- auto inbound_audio = rtc::MakeUnique<RTCInboundRTPStreamStats>(
- RTCInboundRTPStreamStatsIDFromSSRC(true, voice_receiver_info.ssrc()),
- timestamp_us);
- SetInboundRTPStreamStatsFromVoiceReceiverInfo(
- stats.mid, voice_receiver_info, inbound_audio.get());
- // TODO(hta): This lookup should look for the sender, not the track.
- rtc::scoped_refptr<AudioTrackInterface> audio_track =
- track_media_info_map.GetAudioTrack(voice_receiver_info);
- if (audio_track) {
- inbound_audio->track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kReceiver,
- track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+ std::unique_ptr<RTCInboundRTPStreamStats> inbound_audio(
+ new RTCInboundRTPStreamStats(RTCInboundRTPStreamStatsIDFromSSRC(
+ true, voice_receiver_info.ssrc()),
+ timestamp_us));
+ SetInboundRTPStreamStatsFromVoiceReceiverInfo(voice_receiver_info,
+ inbound_audio.get());
+ // TODO(hta): This lookup should look for the sender, not the track.
+ rtc::scoped_refptr<AudioTrackInterface> audio_track =
+ track_media_info_map_->GetAudioTrack(voice_receiver_info);
+ if (audio_track) {
+ RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
+ inbound_audio
+ ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kReceiver,
+ track_media_info_map_->GetAttachmentIdByTrack(audio_track).value());
+ }
+ inbound_audio->transport_id = transport_id;
+ report->AddStats(std::move(inbound_audio));
}
- inbound_audio->transport_id = transport_id;
- report->AddStats(std::move(inbound_audio));
+ // Outbound
+ for (const cricket::VoiceSenderInfo& voice_sender_info :
+ track_media_info_map.voice_media_info()->senders) {
+ if (!voice_sender_info.connected())
+ continue;
+ std::unique_ptr<RTCOutboundRTPStreamStats> outbound_audio(
+ new RTCOutboundRTPStreamStats(
+ RTCOutboundRTPStreamStatsIDFromSSRC(
+ true, voice_sender_info.ssrc()),
+ timestamp_us));
+ SetOutboundRTPStreamStatsFromVoiceSenderInfo(
+ voice_sender_info, outbound_audio.get());
+ rtc::scoped_refptr<AudioTrackInterface> audio_track =
+ track_media_info_map_->GetAudioTrack(voice_sender_info);
+ if (audio_track) {
+ RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
+ outbound_audio
+ ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kSender,
+ track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+ }
+ outbound_audio->transport_id = transport_id;
+ report->AddStats(std::move(outbound_audio));
+ }
}
- // Outbound
- for (const cricket::VoiceSenderInfo& voice_sender_info :
- track_media_info_map.voice_media_info()->senders) {
- if (!voice_sender_info.connected())
- continue;
- auto outbound_audio = rtc::MakeUnique<RTCOutboundRTPStreamStats>(
- RTCOutboundRTPStreamStatsIDFromSSRC(true, voice_sender_info.ssrc()),
- timestamp_us);
- SetOutboundRTPStreamStatsFromVoiceSenderInfo(stats.mid, voice_sender_info,
- outbound_audio.get());
- rtc::scoped_refptr<AudioTrackInterface> audio_track =
- track_media_info_map.GetAudioTrack(voice_sender_info);
- if (audio_track) {
- outbound_audio->track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kSender,
- track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+ // Video
+ if (track_media_info_map.video_media_info()) {
+ RTC_DCHECK(video_mid_);
+ const std::string& transport_name = transport_names_by_mid.at(*video_mid_);
+ std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+ transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
+ // Inbound
+ for (const cricket::VideoReceiverInfo& video_receiver_info :
+ track_media_info_map.video_media_info()->receivers) {
+ // TODO(nisse): SSRC == 0 currently means none. Delete check when that
+ // is fixed.
+ if (!video_receiver_info.connected())
+ continue;
+ std::unique_ptr<RTCInboundRTPStreamStats> inbound_video(
+ new RTCInboundRTPStreamStats(
+ RTCInboundRTPStreamStatsIDFromSSRC(
+ false, video_receiver_info.ssrc()),
+ timestamp_us));
+ SetInboundRTPStreamStatsFromVideoReceiverInfo(
+ video_receiver_info, inbound_video.get());
+ rtc::scoped_refptr<VideoTrackInterface> video_track =
+ track_media_info_map_->GetVideoTrack(video_receiver_info);
+ if (video_track) {
+ RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
+ inbound_video
+ ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kReceiver,
+ track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
+ }
+ inbound_video->transport_id = transport_id;
+ report->AddStats(std::move(inbound_video));
}
- outbound_audio->transport_id = transport_id;
- report->AddStats(std::move(outbound_audio));
- }
-}
-
-void RTCStatsCollector::ProduceVideoRTPStreamStats_n(
- int64_t timestamp_us,
- const RtpTransceiverStatsInfo& stats,
- RTCStatsReport* report) const {
- RTC_DCHECK(stats.track_media_info_map);
- const TrackMediaInfoMap& track_media_info_map = *stats.track_media_info_map;
- RTC_DCHECK(track_media_info_map.video_media_info());
- std::string transport_id = RTCTransportStatsIDFromTransportChannel(
- stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
- // Inbound
- for (const cricket::VideoReceiverInfo& video_receiver_info :
- track_media_info_map.video_media_info()->receivers) {
- if (!video_receiver_info.connected())
- continue;
- auto inbound_video = rtc::MakeUnique<RTCInboundRTPStreamStats>(
- RTCInboundRTPStreamStatsIDFromSSRC(false, video_receiver_info.ssrc()),
- timestamp_us);
- SetInboundRTPStreamStatsFromVideoReceiverInfo(
- stats.mid, video_receiver_info, inbound_video.get());
- rtc::scoped_refptr<VideoTrackInterface> video_track =
- track_media_info_map.GetVideoTrack(video_receiver_info);
- if (video_track) {
- inbound_video->track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kReceiver,
- track_media_info_map.GetAttachmentIdByTrack(video_track).value());
+ // Outbound
+ for (const cricket::VideoSenderInfo& video_sender_info :
+ track_media_info_map.video_media_info()->senders) {
+ if (!video_sender_info.connected())
+ continue;
+ std::unique_ptr<RTCOutboundRTPStreamStats> outbound_video(
+ new RTCOutboundRTPStreamStats(RTCOutboundRTPStreamStatsIDFromSSRC(
+ false, video_sender_info.ssrc()),
+ timestamp_us));
+ SetOutboundRTPStreamStatsFromVideoSenderInfo(
+ video_sender_info, outbound_video.get());
+ rtc::scoped_refptr<VideoTrackInterface> video_track =
+ track_media_info_map_->GetVideoTrack(video_sender_info);
+ if (video_track) {
+ RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
+ outbound_video
+ ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+ kSender,
+ track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
+ }
+ outbound_video->transport_id = transport_id;
+ report->AddStats(std::move(outbound_video));
}
- inbound_video->transport_id = transport_id;
- report->AddStats(std::move(inbound_video));
- }
- // Outbound
- for (const cricket::VideoSenderInfo& video_sender_info :
- track_media_info_map.video_media_info()->senders) {
- if (!video_sender_info.connected())
- continue;
- auto outbound_video = rtc::MakeUnique<RTCOutboundRTPStreamStats>(
- RTCOutboundRTPStreamStatsIDFromSSRC(false, video_sender_info.ssrc()),
- timestamp_us);
- SetOutboundRTPStreamStatsFromVideoSenderInfo(stats.mid, video_sender_info,
- outbound_video.get());
- rtc::scoped_refptr<VideoTrackInterface> video_track =
- track_media_info_map.GetVideoTrack(video_sender_info);
- if (video_track) {
- outbound_video->track_id =
- RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
- kSender,
- track_media_info_map.GetAttachmentIdByTrack(video_track).value());
- }
- outbound_video->transport_id = transport_id;
- report->AddStats(std::move(outbound_video));
}
}
@@ -1236,100 +1243,47 @@
return transport_cert_stats;
}
-std::vector<RTCStatsCollector::RtpTransceiverStatsInfo>
-RTCStatsCollector::PrepareTransceiverStatsInfos_s() const {
- std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos;
-
- // These are used to invoke GetStats for all the media channels together in
- // one worker thread hop.
- std::map<cricket::VoiceMediaChannel*,
- std::unique_ptr<cricket::VoiceMediaInfo>>
- voice_stats;
- std::map<cricket::VideoMediaChannel*,
- std::unique_ptr<cricket::VideoMediaInfo>>
- video_stats;
-
- for (auto transceiver : pc_->GetTransceiversInternal()) {
- cricket::MediaType media_type = transceiver->internal()->media_type();
- cricket::BaseChannel* channel = transceiver->internal()->channel();
- if (!channel) {
- // No BaseChannel, no stats to collect.
- continue;
- }
-
- // Prepare stats entry. The TrackMediaInfoMap will be filled in after the
- // stats have been fetched on the worker thread.
- transceiver_stats_infos.emplace_back();
- RtpTransceiverStatsInfo& stats = transceiver_stats_infos.back();
- stats.transceiver = transceiver->internal();
- stats.media_type = media_type;
- stats.mid = channel->content_name();
- stats.transport_name = channel->transport_name();
-
- if (media_type == cricket::MEDIA_TYPE_AUDIO) {
- auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel);
- RTC_DCHECK(voice_stats.find(voice_channel->media_channel()) ==
- voice_stats.end());
- voice_stats[voice_channel->media_channel()] =
- rtc::MakeUnique<cricket::VoiceMediaInfo>();
- } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
- auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
- RTC_DCHECK(video_stats.find(video_channel->media_channel()) ==
- video_stats.end());
- video_stats[video_channel->media_channel()] =
- rtc::MakeUnique<cricket::VideoMediaInfo>();
- } else {
- RTC_NOTREACHED();
+std::unique_ptr<TrackMediaInfoMap>
+RTCStatsCollector::PrepareTrackMediaInfoMap_s() const {
+ RTC_DCHECK(signaling_thread_->IsCurrent());
+ std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
+ if (pc_->voice_channel()) {
+ voice_media_info.reset(new cricket::VoiceMediaInfo());
+ if (!pc_->voice_channel()->GetStats(voice_media_info.get())) {
+ voice_media_info.reset();
}
}
-
- // Call GetStats for all media channels together on the worker thread in one
- // hop.
- worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
- for (const auto& entry : voice_stats) {
- if (!entry.first->GetStats(entry.second.get())) {
- RTC_LOG(LS_WARNING) << "Failed to get voice stats.";
- }
+ std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
+ if (pc_->video_channel()) {
+ video_media_info.reset(new cricket::VideoMediaInfo());
+ if (!pc_->video_channel()->GetStats(video_media_info.get())) {
+ video_media_info.reset();
}
- for (const auto& entry : video_stats) {
- if (!entry.first->GetStats(entry.second.get())) {
- RTC_LOG(LS_WARNING) << "Failed to get video stats.";
- }
- }
- });
-
- // Create the TrackMediaInfoMap for each transceiver stats object.
- for (auto& stats : transceiver_stats_infos) {
- auto transceiver = stats.transceiver;
- RTC_DCHECK(transceiver->channel());
- std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
- std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
- cricket::MediaType media_type = transceiver->media_type();
- if (media_type == cricket::MEDIA_TYPE_AUDIO) {
- auto* voice_channel =
- static_cast<cricket::VoiceChannel*>(transceiver->channel());
- RTC_DCHECK(voice_stats[voice_channel->media_channel()]);
- voice_media_info = std::move(voice_stats[voice_channel->media_channel()]);
- } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
- auto* video_channel =
- static_cast<cricket::VideoChannel*>(transceiver->channel());
- RTC_DCHECK(video_stats[video_channel->media_channel()]);
- video_media_info = std::move(video_stats[video_channel->media_channel()]);
- }
- std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders;
- for (auto sender : transceiver->senders()) {
- senders.push_back(sender->internal());
- }
- std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers;
- for (auto receiver : transceiver->receivers()) {
- receivers.push_back(receiver->internal());
- }
- stats.track_media_info_map = rtc::MakeUnique<TrackMediaInfoMap>(
- std::move(voice_media_info), std::move(video_media_info), senders,
- receivers);
}
+ std::unique_ptr<TrackMediaInfoMap> track_media_info_map(new TrackMediaInfoMap(
+ std::move(voice_media_info), std::move(video_media_info),
+ pc_->GetSenders(), pc_->GetReceivers()));
+ return track_media_info_map;
+}
- return transceiver_stats_infos;
+std::map<MediaStreamTrackInterface*, std::string>
+RTCStatsCollector::PrepareTrackToID_s() const {
+ // TODO(hta): Remove this method, and vector its callers via
+ // senders / receivers instead.
+ // It ignores tracks that are multiply connected to the PC.
+ RTC_DCHECK(signaling_thread_->IsCurrent());
+ std::map<MediaStreamTrackInterface*, std::string> track_to_id;
+ for (auto sender : pc_->GetSenders()) {
+ auto track = sender->track();
+ if (track)
+ track_to_id[track.get()] = track->id();
+ }
+ for (auto receiver : pc_->GetReceivers()) {
+ auto track = receiver->track();
+ if (track)
+ track_to_id[track.get()] = track->id();
+ }
+ return track_to_id;
}
void RTCStatsCollector::OnDataChannelCreated(DataChannel* channel) {