Change PeerConnection stats interface to be more flexible
This removes the SessionStats object and replaces it with two methods on PeerConnection: GetTransportNamesByMid and GetTransportStatsByNames for use by the stats collectors. These methods are more flexible and can cover cases where there are more than one video/audio channel. Bug: webrtc:8764 Change-Id: Id400cc548fc43675462ff6175a7fa9c9f4fd5948 Reviewed-on: https://webrtc-review.googlesource.com/47244 Commit-Queue: Steve Anton <steveanton@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21921}
This commit is contained in:
parent
8234ead6d9
commit
5dfde18c77
@ -4760,39 +4760,48 @@ bool PeerConnection::ReadyToSendData() const {
|
||||
sctp_ready_to_send_data_;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> PeerConnection::GetSessionStats_s() {
|
||||
RTC_DCHECK(signaling_thread()->IsCurrent());
|
||||
ChannelNamePairs channel_name_pairs;
|
||||
if (voice_channel()) {
|
||||
channel_name_pairs.voice = ChannelNamePair(
|
||||
voice_channel()->content_name(), voice_channel()->transport_name());
|
||||
std::map<std::string, std::string> PeerConnection::GetTransportNamesByMid()
|
||||
const {
|
||||
std::map<std::string, std::string> transport_names_by_mid;
|
||||
for (auto transceiver : transceivers_) {
|
||||
cricket::BaseChannel* channel = transceiver->internal()->channel();
|
||||
if (channel) {
|
||||
transport_names_by_mid[channel->content_name()] =
|
||||
channel->transport_name();
|
||||
}
|
||||
}
|
||||
if (video_channel()) {
|
||||
channel_name_pairs.video = ChannelNamePair(
|
||||
video_channel()->content_name(), video_channel()->transport_name());
|
||||
}
|
||||
if (rtp_data_channel()) {
|
||||
channel_name_pairs.data =
|
||||
ChannelNamePair(rtp_data_channel()->content_name(),
|
||||
rtp_data_channel()->transport_name());
|
||||
if (rtp_data_channel_) {
|
||||
transport_names_by_mid[rtp_data_channel_->content_name()] =
|
||||
rtp_data_channel_->transport_name();
|
||||
}
|
||||
if (sctp_transport_) {
|
||||
RTC_DCHECK(sctp_content_name_);
|
||||
RTC_DCHECK(sctp_transport_name_);
|
||||
channel_name_pairs.data =
|
||||
ChannelNamePair(*sctp_content_name_, *sctp_transport_name_);
|
||||
transport_names_by_mid[*sctp_content_name_] = *sctp_transport_name_;
|
||||
}
|
||||
return GetSessionStats(channel_name_pairs);
|
||||
return transport_names_by_mid;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> PeerConnection::GetSessionStats(
|
||||
const ChannelNamePairs& channel_name_pairs) {
|
||||
if (network_thread()->IsCurrent()) {
|
||||
return GetSessionStats_n(channel_name_pairs);
|
||||
std::map<std::string, cricket::TransportStats>
|
||||
PeerConnection::GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) {
|
||||
if (!network_thread()->IsCurrent()) {
|
||||
return network_thread()
|
||||
->Invoke<std::map<std::string, cricket::TransportStats>>(
|
||||
RTC_FROM_HERE,
|
||||
[&] { return GetTransportStatsByNames(transport_names); });
|
||||
}
|
||||
return network_thread()->Invoke<std::unique_ptr<SessionStats>>(
|
||||
RTC_FROM_HERE,
|
||||
rtc::Bind(&PeerConnection::GetSessionStats_n, this, channel_name_pairs));
|
||||
std::map<std::string, cricket::TransportStats> transport_stats_by_name;
|
||||
for (const std::string& transport_name : transport_names) {
|
||||
cricket::TransportStats transport_stats;
|
||||
bool success =
|
||||
transport_controller_->GetStats(transport_name, &transport_stats);
|
||||
if (success) {
|
||||
transport_stats_by_name[transport_name] = std::move(transport_stats);
|
||||
} else {
|
||||
RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
|
||||
<< transport_name;
|
||||
}
|
||||
}
|
||||
return transport_stats_by_name;
|
||||
}
|
||||
|
||||
bool PeerConnection::GetLocalCertificate(
|
||||
@ -5270,26 +5279,6 @@ Call::Stats PeerConnection::GetCallStats() {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> PeerConnection::GetSessionStats_n(
|
||||
const ChannelNamePairs& channel_name_pairs) {
|
||||
RTC_DCHECK(network_thread()->IsCurrent());
|
||||
std::unique_ptr<SessionStats> session_stats(new SessionStats());
|
||||
for (const auto channel_name_pair :
|
||||
{&channel_name_pairs.voice, &channel_name_pairs.video,
|
||||
&channel_name_pairs.data}) {
|
||||
if (*channel_name_pair) {
|
||||
cricket::TransportStats transport_stats;
|
||||
if (!transport_controller_->GetStats((*channel_name_pair)->transport_name,
|
||||
&transport_stats)) {
|
||||
return nullptr;
|
||||
}
|
||||
session_stats->transport_stats[(*channel_name_pair)->transport_name] =
|
||||
std::move(transport_stats);
|
||||
}
|
||||
}
|
||||
return session_stats;
|
||||
}
|
||||
|
||||
bool PeerConnection::CreateSctpTransport_n(const std::string& content_name,
|
||||
const std::string& transport_name) {
|
||||
RTC_DCHECK(network_thread()->IsCurrent());
|
||||
|
||||
@ -253,9 +253,9 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
return sctp_transport_name_;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats_s() override;
|
||||
std::unique_ptr<SessionStats> GetSessionStats(
|
||||
const ChannelNamePairs& channel_name_pairs) override;
|
||||
std::map<std::string, std::string> GetTransportNamesByMid() const override;
|
||||
std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) override;
|
||||
Call::Stats GetCallStats() override;
|
||||
|
||||
bool GetLocalCertificate(
|
||||
@ -812,9 +812,6 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
bool CreateDataChannel(const std::string& mid,
|
||||
const std::string& transport_name);
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats_n(
|
||||
const ChannelNamePairs& channel_name_pairs);
|
||||
|
||||
bool CreateSctpTransport_n(const std::string& content_name,
|
||||
const std::string& transport_name);
|
||||
// For bundling.
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -22,27 +23,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Statistics for all the transports of the session.
|
||||
// TODO(pthatcher): Think of a better name for this. We already have
|
||||
// a TransportStats in transport.h. Perhaps TransportsStats?
|
||||
struct SessionStats {
|
||||
std::map<std::string, cricket::TransportStats> transport_stats;
|
||||
};
|
||||
|
||||
struct ChannelNamePair {
|
||||
ChannelNamePair(const std::string& content_name,
|
||||
const std::string& transport_name)
|
||||
: content_name(content_name), transport_name(transport_name) {}
|
||||
std::string content_name;
|
||||
std::string transport_name;
|
||||
};
|
||||
|
||||
struct ChannelNamePairs {
|
||||
rtc::Optional<ChannelNamePair> voice;
|
||||
rtc::Optional<ChannelNamePair> video;
|
||||
rtc::Optional<ChannelNamePair> data;
|
||||
};
|
||||
|
||||
// Internal interface for extra PeerConnection methods.
|
||||
class PeerConnectionInternal : public PeerConnectionInterface {
|
||||
public:
|
||||
@ -80,16 +60,13 @@ class PeerConnectionInternal : public PeerConnectionInterface {
|
||||
virtual rtc::Optional<std::string> sctp_content_name() const = 0;
|
||||
virtual rtc::Optional<std::string> sctp_transport_name() const = 0;
|
||||
|
||||
// Returns stats for all channels of all transports.
|
||||
// This avoids exposing the internal structures used to track them.
|
||||
// The parameterless version creates |ChannelNamePairs| from |voice_channel|,
|
||||
// |video_channel| and |voice_channel| if available - this requires it to be
|
||||
// called on the signaling thread - and invokes the other |GetStats|. The
|
||||
// other |GetStats| can be invoked on any thread; if not invoked on the
|
||||
// network thread a thread hop will happen.
|
||||
virtual std::unique_ptr<SessionStats> GetSessionStats_s() = 0;
|
||||
virtual std::unique_ptr<SessionStats> GetSessionStats(
|
||||
const ChannelNamePairs& channel_name_pairs) = 0;
|
||||
// Returns a map from MID to transport name for all active media sections.
|
||||
virtual std::map<std::string, std::string> GetTransportNamesByMid() const = 0;
|
||||
|
||||
// Returns a map from transport name to transport stats for all given
|
||||
// transport names.
|
||||
virtual std::map<std::string, cricket::TransportStats>
|
||||
GetTransportStatsByNames(const std::set<std::string>& transport_names) = 0;
|
||||
|
||||
virtual Call::Stats GetCallStats() = 0;
|
||||
|
||||
|
||||
@ -699,28 +699,9 @@ void RTCStatsCollector::GetStatsReport(
|
||||
num_pending_partial_reports_ = 2;
|
||||
partial_report_timestamp_us_ = cache_now_us;
|
||||
|
||||
// Prepare |channel_name_pairs_| for use in
|
||||
// Prepare |transport_name_by_mid_| for use in
|
||||
// |ProducePartialResultsOnNetworkThread|.
|
||||
channel_name_pairs_.reset(new ChannelNamePairs());
|
||||
if (pc_->voice_channel()) {
|
||||
channel_name_pairs_->voice =
|
||||
ChannelNamePair(pc_->voice_channel()->content_name(),
|
||||
pc_->voice_channel()->transport_name());
|
||||
}
|
||||
if (pc_->video_channel()) {
|
||||
channel_name_pairs_->video =
|
||||
ChannelNamePair(pc_->video_channel()->content_name(),
|
||||
pc_->video_channel()->transport_name());
|
||||
}
|
||||
if (pc_->rtp_data_channel()) {
|
||||
channel_name_pairs_->data =
|
||||
ChannelNamePair(pc_->rtp_data_channel()->content_name(),
|
||||
pc_->rtp_data_channel()->transport_name());
|
||||
}
|
||||
if (pc_->sctp_content_name()) {
|
||||
channel_name_pairs_->data = ChannelNamePair(*pc_->sctp_content_name(),
|
||||
*pc_->sctp_transport_name());
|
||||
}
|
||||
transport_names_by_mid_ = pc_->GetTransportNamesByMid();
|
||||
// Prepare |track_media_info_map_| for use in
|
||||
// |ProducePartialResultsOnNetworkThread| and
|
||||
// |ProducePartialResultsOnSignalingThread|.
|
||||
@ -730,6 +711,16 @@ void RTCStatsCollector::GetStatsReport(
|
||||
// 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.
|
||||
// TODO(holmer): To avoid the hop we could move BWE and BWE stats to the
|
||||
@ -779,24 +770,25 @@ void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
|
||||
rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
|
||||
timestamp_us);
|
||||
|
||||
std::unique_ptr<SessionStats> session_stats =
|
||||
pc_->GetSessionStats(*channel_name_pairs_);
|
||||
if (session_stats) {
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats =
|
||||
PrepareTransportCertificateStats_n(*session_stats);
|
||||
|
||||
ProduceCertificateStats_n(
|
||||
timestamp_us, transport_cert_stats, report.get());
|
||||
ProduceCodecStats_n(
|
||||
timestamp_us, *track_media_info_map_, report.get());
|
||||
ProduceIceCandidateAndPairStats_n(timestamp_us, *session_stats,
|
||||
track_media_info_map_->video_media_info(),
|
||||
call_stats_, report.get());
|
||||
ProduceRTPStreamStats_n(timestamp_us, *session_stats, *channel_name_pairs_,
|
||||
*track_media_info_map_, report.get());
|
||||
ProduceTransportStats_n(
|
||||
timestamp_us, *session_stats, transport_cert_stats, report.get());
|
||||
std::set<std::string> transport_names;
|
||||
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);
|
||||
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats =
|
||||
PrepareTransportCertificateStats_n(transport_stats_by_name);
|
||||
|
||||
ProduceCertificateStats_n(timestamp_us, transport_cert_stats, 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, transport_names_by_mid_,
|
||||
*track_media_info_map_, report.get());
|
||||
ProduceTransportStats_n(timestamp_us, transport_stats_by_name,
|
||||
transport_cert_stats, report.get());
|
||||
|
||||
AddPartialResults(report);
|
||||
}
|
||||
@ -826,7 +818,7 @@ void RTCStatsCollector::AddPartialResults_s(
|
||||
cache_timestamp_us_ = partial_report_timestamp_us_;
|
||||
cached_report_ = partial_report_;
|
||||
partial_report_ = nullptr;
|
||||
channel_name_pairs_.reset();
|
||||
transport_names_by_mid_.clear();
|
||||
track_media_info_map_.reset();
|
||||
track_to_id_.clear();
|
||||
// Trace WebRTC Stats when getStats is called on Javascript.
|
||||
@ -926,15 +918,18 @@ void RTCStatsCollector::ProduceDataChannelStats_s(
|
||||
|
||||
void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
|
||||
int64_t timestamp_us,
|
||||
const SessionStats& session_stats,
|
||||
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());
|
||||
for (const auto& transport_stats : session_stats.transport_stats) {
|
||||
for (const auto& channel_stats : transport_stats.second.channel_stats) {
|
||||
for (const auto& entry : transport_stats_by_name) {
|
||||
const std::string& transport_name = entry.first;
|
||||
const cricket::TransportStats& transport_stats = entry.second;
|
||||
for (const auto& channel_stats : transport_stats.channel_stats) {
|
||||
std::string transport_id = RTCTransportStatsIDFromTransportChannel(
|
||||
transport_stats.second.transport_name, channel_stats.component);
|
||||
transport_name, channel_stats.component);
|
||||
for (const cricket::ConnectionInfo& info :
|
||||
channel_stats.connection_infos) {
|
||||
std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
|
||||
@ -1029,17 +1024,15 @@ void RTCStatsCollector::ProducePeerConnectionStats_s(
|
||||
|
||||
void RTCStatsCollector::ProduceRTPStreamStats_n(
|
||||
int64_t timestamp_us,
|
||||
const SessionStats& session_stats,
|
||||
const ChannelNamePairs& channel_name_pairs,
|
||||
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());
|
||||
|
||||
// Audio
|
||||
if (track_media_info_map.voice_media_info()) {
|
||||
RTC_DCHECK(channel_name_pairs.voice);
|
||||
const std::string& transport_name =
|
||||
(*channel_name_pairs.voice).transport_name;
|
||||
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
|
||||
@ -1094,9 +1087,8 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
|
||||
}
|
||||
// Video
|
||||
if (track_media_info_map.video_media_info()) {
|
||||
RTC_DCHECK(channel_name_pairs.video);
|
||||
const std::string& transport_name =
|
||||
(*channel_name_pairs.video).transport_name;
|
||||
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
|
||||
@ -1152,26 +1144,32 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceTransportStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
int64_t timestamp_us,
|
||||
const std::map<std::string, cricket::TransportStats>&
|
||||
transport_stats_by_name,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
for (const auto& transport : session_stats.transport_stats) {
|
||||
for (const auto& entry : transport_stats_by_name) {
|
||||
const std::string& transport_name = entry.first;
|
||||
const cricket::TransportStats& transport_stats = entry.second;
|
||||
|
||||
// Get reference to RTCP channel, if it exists.
|
||||
std::string rtcp_transport_stats_id;
|
||||
for (const auto& channel_stats : transport.second.channel_stats) {
|
||||
for (const cricket::TransportChannelStats& channel_stats :
|
||||
transport_stats.channel_stats) {
|
||||
if (channel_stats.component ==
|
||||
cricket::ICE_CANDIDATE_COMPONENT_RTCP) {
|
||||
rtcp_transport_stats_id = RTCTransportStatsIDFromTransportChannel(
|
||||
transport.second.transport_name, channel_stats.component);
|
||||
transport_name, channel_stats.component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get reference to local and remote certificates of this transport, if they
|
||||
// exist.
|
||||
const auto& certificate_stats_it = transport_cert_stats.find(
|
||||
transport.second.transport_name);
|
||||
const auto& certificate_stats_it =
|
||||
transport_cert_stats.find(transport_name);
|
||||
RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
|
||||
std::string local_certificate_id;
|
||||
if (certificate_stats_it->second.local) {
|
||||
@ -1185,12 +1183,12 @@ void RTCStatsCollector::ProduceTransportStats_n(
|
||||
}
|
||||
|
||||
// There is one transport stats for each channel.
|
||||
for (const auto& channel_stats : transport.second.channel_stats) {
|
||||
for (const cricket::TransportChannelStats& channel_stats :
|
||||
transport_stats.channel_stats) {
|
||||
std::unique_ptr<RTCTransportStats> transport_stats(
|
||||
new RTCTransportStats(
|
||||
RTCTransportStatsIDFromTransportChannel(
|
||||
transport.second.transport_name, channel_stats.component),
|
||||
timestamp_us));
|
||||
new RTCTransportStats(RTCTransportStatsIDFromTransportChannel(
|
||||
transport_name, channel_stats.component),
|
||||
timestamp_us));
|
||||
transport_stats->bytes_sent = 0;
|
||||
transport_stats->bytes_received = 0;
|
||||
transport_stats->dtls_state = DtlsTransportStateToRTCDtlsTransportState(
|
||||
@ -1219,25 +1217,28 @@ void RTCStatsCollector::ProduceTransportStats_n(
|
||||
|
||||
std::map<std::string, RTCStatsCollector::CertificateStatsPair>
|
||||
RTCStatsCollector::PrepareTransportCertificateStats_n(
|
||||
const SessionStats& session_stats) const {
|
||||
const std::map<std::string, cricket::TransportStats>&
|
||||
transport_stats_by_name) const {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats;
|
||||
for (const auto& transport_stats : session_stats.transport_stats) {
|
||||
for (const auto& entry : transport_stats_by_name) {
|
||||
const std::string& transport_name = entry.first;
|
||||
|
||||
CertificateStatsPair certificate_stats_pair;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> local_certificate;
|
||||
if (pc_->GetLocalCertificate(transport_stats.second.transport_name,
|
||||
&local_certificate)) {
|
||||
if (pc_->GetLocalCertificate(transport_name, &local_certificate)) {
|
||||
certificate_stats_pair.local =
|
||||
local_certificate->ssl_certificate().GetStats();
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertificate> remote_certificate =
|
||||
pc_->GetRemoteSSLCertificate(transport_stats.second.transport_name);
|
||||
pc_->GetRemoteSSLCertificate(transport_name);
|
||||
if (remote_certificate) {
|
||||
certificate_stats_pair.remote = remote_certificate->GetStats();
|
||||
}
|
||||
|
||||
transport_cert_stats.insert(
|
||||
std::make_pair(transport_stats.second.transport_name,
|
||||
std::move(certificate_stats_pair)));
|
||||
std::make_pair(transport_name, std::move(certificate_stats_pair)));
|
||||
}
|
||||
return transport_cert_stats;
|
||||
}
|
||||
@ -1259,11 +1260,9 @@ RTCStatsCollector::PrepareTrackMediaInfoMap_s() const {
|
||||
video_media_info.reset();
|
||||
}
|
||||
}
|
||||
std::unique_ptr<TrackMediaInfoMap> track_media_info_map(
|
||||
new TrackMediaInfoMap(std::move(voice_media_info),
|
||||
std::move(video_media_info),
|
||||
pc_->GetSenders(),
|
||||
pc_->GetReceivers()));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +96,8 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
// Produces |RTCIceCandidatePairStats| and |RTCIceCandidateStats|.
|
||||
void ProduceIceCandidateAndPairStats_n(
|
||||
int64_t timestamp_us,
|
||||
const SessionStats& session_stats,
|
||||
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;
|
||||
@ -107,20 +108,24 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
void ProducePeerConnectionStats_s(
|
||||
int64_t timestamp_us, RTCStatsReport* report) const;
|
||||
// Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
|
||||
void ProduceRTPStreamStats_n(int64_t timestamp_us,
|
||||
const SessionStats& session_stats,
|
||||
const ChannelNamePairs& channel_name_pairs,
|
||||
const TrackMediaInfoMap& track_media_info_map,
|
||||
RTCStatsReport* report) const;
|
||||
void ProduceRTPStreamStats_n(
|
||||
int64_t timestamp_us,
|
||||
const std::map<std::string, std::string>& transport_names_by_mid,
|
||||
const TrackMediaInfoMap& track_media_info_map,
|
||||
RTCStatsReport* report) const;
|
||||
// Produces |RTCTransportStats|.
|
||||
void ProduceTransportStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
int64_t timestamp_us,
|
||||
const std::map<std::string, cricket::TransportStats>&
|
||||
transport_stats_by_name,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const;
|
||||
|
||||
// Helper function to stats-producing functions.
|
||||
std::map<std::string, CertificateStatsPair>
|
||||
PrepareTransportCertificateStats_n(const SessionStats& session_stats) const;
|
||||
PrepareTransportCertificateStats_n(
|
||||
const std::map<std::string, cricket::TransportStats>&
|
||||
transport_stats_by_name) const;
|
||||
std::unique_ptr<TrackMediaInfoMap> PrepareTrackMediaInfoMap_s() const;
|
||||
std::map<MediaStreamTrackInterface*, std::string> PrepareTrackToID_s() const;
|
||||
|
||||
@ -145,10 +150,13 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
// |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not
|
||||
// passed as arguments to avoid copies. This is thread safe - when we
|
||||
// set/reset we know there are no pending stats requests in progress.
|
||||
std::unique_ptr<ChannelNamePairs> channel_name_pairs_;
|
||||
std::map<std::string, std::string> transport_names_by_mid_;
|
||||
std::unique_ptr<TrackMediaInfoMap> track_media_info_map_;
|
||||
std::map<MediaStreamTrackInterface*, std::string> track_to_id_;
|
||||
|
||||
rtc::Optional<std::string> voice_mid_;
|
||||
rtc::Optional<std::string> video_mid_;
|
||||
|
||||
Call::Stats call_stats_;
|
||||
|
||||
// A timestamp, in microseconds, that is based on a timer that is
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "pc/statscollector.h"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -745,36 +746,41 @@ void StatsCollector::ExtractSessionInfo() {
|
||||
report->AddBoolean(StatsReport::kStatsValueNameInitiator,
|
||||
pc_->initial_offerer());
|
||||
|
||||
std::unique_ptr<SessionStats> stats = pc_->GetSessionStats_s();
|
||||
if (!stats) {
|
||||
return;
|
||||
std::set<std::string> transport_names;
|
||||
for (const auto& entry : pc_->GetTransportNamesByMid()) {
|
||||
transport_names.insert(entry.second);
|
||||
}
|
||||
|
||||
for (const auto& transport_iter : stats->transport_stats) {
|
||||
std::map<std::string, cricket::TransportStats> transport_stats_by_name =
|
||||
pc_->GetTransportStatsByNames(transport_names);
|
||||
|
||||
for (const auto& entry : transport_stats_by_name) {
|
||||
const std::string& transport_name = entry.first;
|
||||
const cricket::TransportStats& transport_stats = entry.second;
|
||||
|
||||
// Attempt to get a copy of the certificates from the transport and
|
||||
// expose them in stats reports. All channels in a transport share the
|
||||
// same local and remote certificates.
|
||||
//
|
||||
StatsReport::Id local_cert_report_id, remote_cert_report_id;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate;
|
||||
if (pc_->GetLocalCertificate(transport_iter.second.transport_name,
|
||||
&certificate)) {
|
||||
if (pc_->GetLocalCertificate(transport_name, &certificate)) {
|
||||
StatsReport* r = AddCertificateReports(&(certificate->ssl_certificate()));
|
||||
if (r)
|
||||
local_cert_report_id = r->id();
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertificate> cert =
|
||||
pc_->GetRemoteSSLCertificate(transport_iter.second.transport_name);
|
||||
pc_->GetRemoteSSLCertificate(transport_name);
|
||||
if (cert) {
|
||||
StatsReport* r = AddCertificateReports(cert.get());
|
||||
if (r)
|
||||
remote_cert_report_id = r->id();
|
||||
}
|
||||
|
||||
for (const auto& channel_iter : transport_iter.second.channel_stats) {
|
||||
StatsReport::Id id(StatsReport::NewComponentId(
|
||||
transport_iter.second.transport_name, channel_iter.component));
|
||||
for (const auto& channel_iter : transport_stats.channel_stats) {
|
||||
StatsReport::Id id(
|
||||
StatsReport::NewComponentId(transport_name, channel_iter.component));
|
||||
StatsReport* channel_report = reports_.ReplaceOrAddNew(id);
|
||||
channel_report->set_timestamp(stats_gathering_started_);
|
||||
channel_report->AddInt(StatsReport::kStatsValueNameComponent,
|
||||
@ -807,7 +813,7 @@ void StatsCollector::ExtractSessionInfo() {
|
||||
for (const cricket::ConnectionInfo& info :
|
||||
channel_iter.connection_infos) {
|
||||
StatsReport* connection_report = AddConnectionInfoReport(
|
||||
transport_iter.first, channel_iter.component, connection_id++,
|
||||
transport_name, channel_iter.component, connection_id++,
|
||||
channel_report->id(), info);
|
||||
if (info.best_connection) {
|
||||
channel_report->AddId(
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
#ifndef PC_TEST_FAKEPEERCONNECTIONBASE_H_
|
||||
#define PC_TEST_FAKEPEERCONNECTIONBASE_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -277,11 +279,13 @@ class FakePeerConnectionBase : public PeerConnectionInternal {
|
||||
return rtc::nullopt;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats_s() override { return nullptr; }
|
||||
std::map<std::string, std::string> GetTransportNamesByMid() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats(
|
||||
const ChannelNamePairs& channel_name_pairs) override {
|
||||
return nullptr;
|
||||
std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) override {
|
||||
return {};
|
||||
}
|
||||
|
||||
Call::Stats GetCallStats() override { return Call::Stats(); }
|
||||
|
||||
@ -245,30 +245,27 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
|
||||
return sctp_data_channels_;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats_s() override {
|
||||
std::set<std::string> transport_names;
|
||||
std::map<std::string, std::string> GetTransportNamesByMid() const override {
|
||||
std::map<std::string, std::string> transport_names_by_mid;
|
||||
if (voice_channel_) {
|
||||
transport_names.insert(voice_channel_->transport_name());
|
||||
transport_names_by_mid[voice_channel_->content_name()] =
|
||||
voice_channel_->transport_name();
|
||||
}
|
||||
if (video_channel_) {
|
||||
transport_names.insert(video_channel_->transport_name());
|
||||
transport_names_by_mid[video_channel_->content_name()] =
|
||||
video_channel_->transport_name();
|
||||
}
|
||||
return GetSessionStatsForTransports(transport_names);
|
||||
return transport_names_by_mid;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> GetSessionStats(
|
||||
const ChannelNamePairs& channel_name_pairs) override {
|
||||
std::set<std::string> transport_names;
|
||||
if (channel_name_pairs.voice) {
|
||||
transport_names.insert(channel_name_pairs.voice.value().transport_name);
|
||||
std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) override {
|
||||
std::map<std::string, cricket::TransportStats> transport_stats_by_name;
|
||||
for (const std::string& transport_name : transport_names) {
|
||||
transport_stats_by_name[transport_name] =
|
||||
GetTransportStatsByName(transport_name);
|
||||
}
|
||||
if (channel_name_pairs.video) {
|
||||
transport_names.insert(channel_name_pairs.video.value().transport_name);
|
||||
}
|
||||
if (channel_name_pairs.data) {
|
||||
transport_names.insert(channel_name_pairs.data.value().transport_name);
|
||||
}
|
||||
return GetSessionStatsForTransports(transport_names);
|
||||
return transport_stats_by_name;
|
||||
}
|
||||
|
||||
Call::Stats GetCallStats() override { return call_stats_; }
|
||||
@ -296,16 +293,6 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<SessionStats> GetSessionStatsForTransports(
|
||||
const std::set<std::string>& transport_names) {
|
||||
auto stats = rtc::MakeUnique<SessionStats>();
|
||||
for (const std::string& transport_name : transport_names) {
|
||||
stats->transport_stats[transport_name] =
|
||||
GetTransportStatsByName(transport_name);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
cricket::TransportStats GetTransportStatsByName(
|
||||
const std::string& transport_name) {
|
||||
auto it = transport_stats_by_name_.find(transport_name);
|
||||
|
||||
@ -68,8 +68,6 @@ class MockPeerConnection
|
||||
MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32_t, std::string*));
|
||||
MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32_t, std::string*));
|
||||
MOCK_METHOD0(GetCallStats, Call::Stats());
|
||||
MOCK_METHOD1(GetSessionStats,
|
||||
std::unique_ptr<SessionStats>(const ChannelNamePairs&));
|
||||
MOCK_METHOD2(GetLocalCertificate,
|
||||
bool(const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate));
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "pc/trackmediainfomap.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/mediastreaminterface.h"
|
||||
@ -82,6 +83,8 @@ class TrackMediaInfoMap {
|
||||
const MediaStreamTrackInterface* track) const;
|
||||
|
||||
private:
|
||||
rtc::Optional<std::string> voice_mid_;
|
||||
rtc::Optional<std::string> video_mid_;
|
||||
std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info_;
|
||||
std::unique_ptr<cricket::VideoMediaInfo> video_media_info_;
|
||||
// These maps map tracks (identified by a pointer) to their corresponding info
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user