diff options
Diffstat (limited to 'pc/rtc_stats_collector.cc')
-rw-r--r-- | pc/rtc_stats_collector.cc | 310 |
1 files changed, 197 insertions, 113 deletions
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index 0e2f170ff0..5851b0680e 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -291,6 +291,24 @@ void SetInboundRTPStreamStatsFromVoiceReceiverInfo( } inbound_audio->jitter = static_cast<double>(voice_receiver_info.jitter_ms) / rtc::kNumMillisecsPerSec; + inbound_audio->jitter_buffer_delay = + voice_receiver_info.jitter_buffer_delay_seconds; + inbound_audio->jitter_buffer_emitted_count = + voice_receiver_info.jitter_buffer_emitted_count; + inbound_audio->total_samples_received = + voice_receiver_info.total_samples_received; + inbound_audio->concealed_samples = voice_receiver_info.concealed_samples; + inbound_audio->silent_concealed_samples = + voice_receiver_info.silent_concealed_samples; + inbound_audio->concealment_events = voice_receiver_info.concealment_events; + inbound_audio->inserted_samples_for_deceleration = + voice_receiver_info.inserted_samples_for_deceleration; + inbound_audio->removed_samples_for_acceleration = + voice_receiver_info.removed_samples_for_acceleration; + inbound_audio->audio_level = voice_receiver_info.audio_level; + inbound_audio->total_audio_energy = voice_receiver_info.total_output_energy; + inbound_audio->total_samples_duration = + voice_receiver_info.total_output_duration; // |fir_count|, |pli_count| and |sli_count| are only valid for video and are // purposefully left undefined for audio. if (voice_receiver_info.last_packet_received_timestamp_ms) { @@ -327,8 +345,21 @@ void SetInboundRTPStreamStatsFromVideoReceiverInfo( static_cast<uint32_t>(video_receiver_info.plis_sent); inbound_video->nack_count = static_cast<uint32_t>(video_receiver_info.nacks_sent); + inbound_video->frames_received = video_receiver_info.frames_received; inbound_video->frames_decoded = video_receiver_info.frames_decoded; + inbound_video->frames_dropped = video_receiver_info.frames_dropped; inbound_video->key_frames_decoded = video_receiver_info.key_frames_decoded; + if (video_receiver_info.frame_width > 0) { + inbound_video->frame_width = + static_cast<uint32_t>(video_receiver_info.frame_width); + } + if (video_receiver_info.frame_height > 0) { + inbound_video->frame_height = + static_cast<uint32_t>(video_receiver_info.frame_height); + } + if (video_receiver_info.framerate_rcvd > 0) { + inbound_video->frames_per_second = video_receiver_info.framerate_rcvd; + } if (video_receiver_info.qp_sum) inbound_video->qp_sum = *video_receiver_info.qp_sum; inbound_video->total_decode_time = @@ -397,7 +428,6 @@ void SetOutboundRTPStreamStatsFromVoiceSenderInfo( void SetOutboundRTPStreamStatsFromVideoSenderInfo( const std::string& mid, const cricket::VideoSenderInfo& video_sender_info, - bool enable_simulcast_stats, RTCOutboundRTPStreamStats* outbound_video) { SetOutboundRTPStreamStatsFromMediaSenderInfo(video_sender_info, outbound_video); @@ -422,21 +452,19 @@ void SetOutboundRTPStreamStatsFromVideoSenderInfo( rtc::kNumMillisecsPerSec; outbound_video->total_encoded_bytes_target = video_sender_info.total_encoded_bytes_target; - if (enable_simulcast_stats) { - if (video_sender_info.send_frame_width > 0) { - outbound_video->frame_width = - static_cast<uint32_t>(video_sender_info.send_frame_width); - } - if (video_sender_info.send_frame_height > 0) { - outbound_video->frame_height = - static_cast<uint32_t>(video_sender_info.send_frame_height); - } - if (video_sender_info.framerate_sent > 0) { - outbound_video->frames_per_second = video_sender_info.framerate_sent; - } - outbound_video->frames_sent = video_sender_info.frames_sent; - outbound_video->huge_frames_sent = video_sender_info.huge_frames_sent; + if (video_sender_info.send_frame_width > 0) { + outbound_video->frame_width = + static_cast<uint32_t>(video_sender_info.send_frame_width); } + if (video_sender_info.send_frame_height > 0) { + outbound_video->frame_height = + static_cast<uint32_t>(video_sender_info.send_frame_height); + } + if (video_sender_info.framerate_sent > 0) { + outbound_video->frames_per_second = video_sender_info.framerate_sent; + } + outbound_video->frames_sent = video_sender_info.frames_sent; + outbound_video->huge_frames_sent = video_sender_info.huge_frames_sent; outbound_video->total_packet_send_delay = static_cast<double>(video_sender_info.total_packet_send_delay_ms) / rtc::kNumMillisecsPerSec; @@ -462,7 +490,7 @@ std::unique_ptr<RTCRemoteInboundRtpStreamStats> ProduceRemoteInboundRtpStreamStatsFromReportBlockData( const ReportBlockData& report_block_data, cricket::MediaType media_type, - std::map<std::string, RTCOutboundRTPStreamStats*> outbound_rtps, + const std::map<std::string, RTCOutboundRTPStreamStats*>& outbound_rtps, const RTCStatsReport& report) { const auto& report_block = report_block_data.report_block(); // RTCStats' timestamp generally refers to when the metric was sampled, but @@ -985,9 +1013,10 @@ RTCStatsCollector::RTCStatsCollector(PeerConnectionInternal* pc, RTC_DCHECK(worker_thread_); RTC_DCHECK(network_thread_); RTC_DCHECK_GE(cache_lifetime_us_, 0); - pc_->SignalDataChannelCreated().connect( - this, &RTCStatsCollector::OnDataChannelCreated); - enable_simulcast_stats_ = pc_->GetConfiguration().enable_simulcast_stats; + pc_->SignalRtpDataChannelCreated().connect( + this, &RTCStatsCollector::OnRtpDataChannelCreated); + pc_->SignalSctpDataChannelCreated().connect( + this, &RTCStatsCollector::OnSctpDataChannelCreated); } RTCStatsCollector::~RTCStatsCollector() { @@ -1044,7 +1073,7 @@ void RTCStatsCollector::GetStatsReportInternal( // Prepare |transceiver_stats_infos_| for use in // |ProducePartialResultsOnNetworkThread| and // |ProducePartialResultsOnSignalingThread|. - transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s(); + transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s_w(); // Prepare |transport_names_| for use in // |ProducePartialResultsOnNetworkThread|. transport_names_ = PrepareTransportNames_s(); @@ -1053,6 +1082,10 @@ void RTCStatsCollector::GetStatsReportInternal( // thread. // TODO(holmer): To avoid the hop we could move BWE and BWE stats to the // network thread, where it more naturally belongs. + // TODO(https://crbug.com/webrtc/11767): In the meantime we can piggyback on + // the blocking-invoke that is already performed in + // PrepareTransceiverStatsInfos_s_w() so that we can call GetCallStats() + // without additional blocking-invokes. call_stats_ = pc_->GetCallStats(); // Don't touch |network_report_| on the signaling thread until @@ -1082,6 +1115,8 @@ void RTCStatsCollector::WaitForPendingRequest() { void RTCStatsCollector::ProducePartialResultsOnSignalingThread( int64_t timestamp_us) { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + partial_report_ = RTCStatsReport::Create(timestamp_us); ProducePartialResultsOnSignalingThreadImpl(timestamp_us, @@ -1099,6 +1134,8 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThreadImpl( int64_t timestamp_us, RTCStatsReport* partial_report) { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + ProduceDataChannelStats_s(timestamp_us, partial_report); ProduceMediaStreamStats_s(timestamp_us, partial_report); ProduceMediaStreamTrackStats_s(timestamp_us, partial_report); @@ -1109,6 +1146,8 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThreadImpl( void RTCStatsCollector::ProducePartialResultsOnNetworkThread( int64_t timestamp_us) { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + // Touching |network_report_| on this thread is safe by this method because // |network_report_event_| is reset before this method is invoked. network_report_ = RTCStatsReport::Create(timestamp_us); @@ -1136,6 +1175,8 @@ void RTCStatsCollector::ProducePartialResultsOnNetworkThreadImpl( const std::map<std::string, CertificateStatsPair>& transport_cert_stats, RTCStatsReport* partial_report) { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + ProduceCertificateStats_n(timestamp_us, transport_cert_stats, partial_report); ProduceCodecStats_n(timestamp_us, transceiver_stats_infos_, partial_report); ProduceIceCandidateAndPairStats_n(timestamp_us, transport_stats_by_name, @@ -1222,6 +1263,8 @@ void RTCStatsCollector::ProduceCertificateStats_n( const std::map<std::string, CertificateStatsPair>& transport_cert_stats, RTCStatsReport* report) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const auto& transport_cert_stats_pair : transport_cert_stats) { if (transport_cert_stats_pair.second.local) { ProduceCertificateStatsFromSSLCertificateStats( @@ -1239,6 +1282,8 @@ void RTCStatsCollector::ProduceCodecStats_n( const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos, RTCStatsReport* report) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const auto& stats : transceiver_stats_infos) { if (!stats.mid) { continue; @@ -1279,22 +1324,22 @@ void RTCStatsCollector::ProduceCodecStats_n( void RTCStatsCollector::ProduceDataChannelStats_s( int64_t timestamp_us, RTCStatsReport* report) const { - RTC_DCHECK(signaling_thread_->IsCurrent()); - for (const rtc::scoped_refptr<DataChannel>& data_channel : - pc_->sctp_data_channels()) { + RTC_DCHECK_RUN_ON(signaling_thread_); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + std::vector<DataChannelStats> data_stats = pc_->GetDataChannelStats(); + for (const auto& stats : data_stats) { std::unique_ptr<RTCDataChannelStats> data_channel_stats( new RTCDataChannelStats( - "RTCDataChannel_" + rtc::ToString(data_channel->internal_id()), + "RTCDataChannel_" + rtc::ToString(stats.internal_id), timestamp_us)); - data_channel_stats->label = data_channel->label(); - data_channel_stats->protocol = data_channel->protocol(); - data_channel_stats->datachannelid = data_channel->id(); - data_channel_stats->state = - DataStateToRTCDataChannelState(data_channel->state()); - data_channel_stats->messages_sent = data_channel->messages_sent(); - data_channel_stats->bytes_sent = data_channel->bytes_sent(); - data_channel_stats->messages_received = data_channel->messages_received(); - data_channel_stats->bytes_received = data_channel->bytes_received(); + data_channel_stats->label = std::move(stats.label); + data_channel_stats->protocol = std::move(stats.protocol); + data_channel_stats->data_channel_identifier = stats.id; + data_channel_stats->state = DataStateToRTCDataChannelState(stats.state); + data_channel_stats->messages_sent = stats.messages_sent; + data_channel_stats->bytes_sent = stats.bytes_sent; + data_channel_stats->messages_received = stats.messages_received; + data_channel_stats->bytes_received = stats.bytes_received; report->AddStats(std::move(data_channel_stats)); } } @@ -1306,6 +1351,8 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_n( const Call::Stats& call_stats, RTCStatsReport* report) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const auto& entry : transport_stats_by_name) { const std::string& transport_name = entry.first; const cricket::TransportStats& transport_stats = entry.second; @@ -1386,6 +1433,7 @@ void RTCStatsCollector::ProduceMediaStreamStats_s( int64_t timestamp_us, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; std::map<std::string, std::vector<std::string>> track_ids; @@ -1422,6 +1470,8 @@ void RTCStatsCollector::ProduceMediaStreamTrackStats_s( int64_t timestamp_us, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos_) { std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders; for (const auto& sender : stats.transceiver->senders()) { @@ -1443,6 +1493,8 @@ void RTCStatsCollector::ProduceMediaSourceStats_s( int64_t timestamp_us, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const RtpTransceiverStatsInfo& transceiver_stats_info : transceiver_stats_infos_) { const auto& track_media_info_map = @@ -1524,6 +1576,8 @@ void RTCStatsCollector::ProducePeerConnectionStats_s( int64_t timestamp_us, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + std::unique_ptr<RTCPeerConnectionStats> stats( new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); stats->data_channels_opened = internal_record_.data_channels_opened; @@ -1536,6 +1590,7 @@ void RTCStatsCollector::ProduceRTPStreamStats_n( const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos, RTCStatsReport* report) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos) { if (stats.media_type == cricket::MEDIA_TYPE_AUDIO) { @@ -1552,6 +1607,9 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( int64_t timestamp_us, const RtpTransceiverStatsInfo& stats, RTCStatsReport* report) const { + RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + if (!stats.mid || !stats.transport_name) { return; } @@ -1620,8 +1678,8 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( track_media_info_map.voice_media_info()->senders) { for (const auto& report_block_data : voice_sender_info.report_block_datas) { report->AddStats(ProduceRemoteInboundRtpStreamStatsFromReportBlockData( - report_block_data, cricket::MEDIA_TYPE_AUDIO, - std::move(audio_outbound_rtps), *report)); + report_block_data, cricket::MEDIA_TYPE_AUDIO, audio_outbound_rtps, + *report)); } } } @@ -1630,6 +1688,9 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( int64_t timestamp_us, const RtpTransceiverStatsInfo& stats, RTCStatsReport* report) const { + RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + if (!stats.mid || !stats.transport_name) { return; } @@ -1663,16 +1724,14 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( // Outbound std::map<std::string, RTCOutboundRTPStreamStats*> video_outbound_rtps; for (const cricket::VideoSenderInfo& video_sender_info : - enable_simulcast_stats_ - ? track_media_info_map.video_media_info()->senders - : track_media_info_map.video_media_info()->aggregated_senders) { + track_media_info_map.video_media_info()->senders) { if (!video_sender_info.connected()) continue; auto outbound_video = std::make_unique<RTCOutboundRTPStreamStats>( RTCOutboundRTPStreamStatsIDFromSSRC(false, video_sender_info.ssrc()), timestamp_us); - SetOutboundRTPStreamStatsFromVideoSenderInfo( - mid, video_sender_info, enable_simulcast_stats_, outbound_video.get()); + SetOutboundRTPStreamStatsFromVideoSenderInfo(mid, video_sender_info, + outbound_video.get()); rtc::scoped_refptr<VideoTrackInterface> video_track = track_media_info_map.GetVideoTrack(video_sender_info); if (video_track) { @@ -1699,8 +1758,8 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( track_media_info_map.video_media_info()->senders) { for (const auto& report_block_data : video_sender_info.report_block_datas) { report->AddStats(ProduceRemoteInboundRtpStreamStatsFromReportBlockData( - report_block_data, cricket::MEDIA_TYPE_VIDEO, - std::move(video_outbound_rtps), *report)); + report_block_data, cricket::MEDIA_TYPE_VIDEO, video_outbound_rtps, + *report)); } } } @@ -1712,6 +1771,8 @@ void RTCStatsCollector::ProduceTransportStats_n( const std::map<std::string, CertificateStatsPair>& transport_cert_stats, RTCStatsReport* report) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const auto& entry : transport_stats_by_name) { const std::string& transport_name = entry.first; const cricket::TransportStats& transport_stats = entry.second; @@ -1751,7 +1812,9 @@ void RTCStatsCollector::ProduceTransportStats_n( transport_name, channel_stats.component), timestamp_us)); transport_stats->bytes_sent = 0; + transport_stats->packets_sent = 0; transport_stats->bytes_received = 0; + transport_stats->packets_received = 0; transport_stats->dtls_state = DtlsTransportStateToRTCDtlsTransportState(channel_stats.dtls_state); transport_stats->selected_candidate_pair_changes = @@ -1759,7 +1822,10 @@ void RTCStatsCollector::ProduceTransportStats_n( for (const cricket::ConnectionInfo& info : channel_stats.ice_transport_stats.connection_infos) { *transport_stats->bytes_sent += info.sent_total_bytes; + *transport_stats->packets_sent += + info.sent_total_packets - info.sent_discarded_packets; *transport_stats->bytes_received += info.recv_total_bytes; + *transport_stats->packets_received += info.packets_received; if (info.best_connection) { transport_stats->selected_candidate_pair_id = RTCIceCandidatePairStatsIDFromConnectionInfo(info); @@ -1803,6 +1869,8 @@ RTCStatsCollector::PrepareTransportCertificateStats_n( const std::map<std::string, cricket::TransportStats>& transport_stats_by_name) const { RTC_DCHECK(network_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + std::map<std::string, CertificateStatsPair> transport_cert_stats; for (const auto& entry : transport_stats_by_name) { const std::string& transport_name = entry.first; @@ -1827,9 +1895,10 @@ RTCStatsCollector::PrepareTransportCertificateStats_n( } std::vector<RTCStatsCollector::RtpTransceiverStatsInfo> -RTCStatsCollector::PrepareTransceiverStatsInfos_s() const { - std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos; +RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const { + RTC_DCHECK(signaling_thread_->IsCurrent()); + 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*, @@ -1839,45 +1908,52 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s() const { std::unique_ptr<cricket::VideoMediaInfo>> video_stats; - for (const auto& transceiver : pc_->GetTransceiversInternal()) { - cricket::MediaType media_type = transceiver->media_type(); - - // 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; - - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (!channel) { - // The remaining fields require a BaseChannel. - continue; - } + { + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; - 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()] = - std::make_unique<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()] = - std::make_unique<cricket::VideoMediaInfo>(); - } else { - RTC_NOTREACHED(); + for (const auto& transceiver : pc_->GetTransceiversInternal()) { + cricket::MediaType media_type = transceiver->media_type(); + + // 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; + + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (!channel) { + // The remaining fields require a BaseChannel. + continue; + } + + 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()] = + std::make_unique<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()] = + std::make_unique<cricket::VideoMediaInfo>(); + } else { + RTC_NOTREACHED(); + } } } - // Call GetStats for all media channels together on the worker thread in one - // hop. + // We jump to the worker thread and call GetStats() on each media channel. At + // the same time we construct the TrackMediaInfoMaps, which also needs info + // from the worker thread. This minimizes the number of thread jumps. worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + for (const auto& entry : voice_stats) { if (!entry.first->GetStats(entry.second.get())) { RTC_LOG(LS_WARNING) << "Failed to get voice stats."; @@ -1888,46 +1964,49 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s() const { 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; - std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info; - std::unique_ptr<cricket::VideoMediaInfo> video_media_info; - if (transceiver->channel()) { - 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()]); + // Create the TrackMediaInfoMap for each transceiver stats object. + for (auto& stats : transceiver_stats_infos) { + auto transceiver = stats.transceiver; + std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info; + std::unique_ptr<cricket::VideoMediaInfo> video_media_info; + if (transceiver->channel()) { + 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 (const auto& sender : transceiver->senders()) { + senders.push_back(sender->internal()); + } + std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers; + for (const auto& receiver : transceiver->receivers()) { + receivers.push_back(receiver->internal()); + } + stats.track_media_info_map = std::make_unique<TrackMediaInfoMap>( + std::move(voice_media_info), std::move(video_media_info), senders, + receivers); } - std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders; - for (const auto& sender : transceiver->senders()) { - senders.push_back(sender->internal()); - } - std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers; - for (const auto& receiver : transceiver->receivers()) { - receivers.push_back(receiver->internal()); - } - stats.track_media_info_map = std::make_unique<TrackMediaInfoMap>( - std::move(voice_media_info), std::move(video_media_info), senders, - receivers); - } + }); return transceiver_stats_infos; } std::set<std::string> RTCStatsCollector::PrepareTransportNames_s() const { + RTC_DCHECK(signaling_thread_->IsCurrent()); + rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + std::set<std::string> transport_names; for (const auto& transceiver : pc_->GetTransceiversInternal()) { if (transceiver->internal()->channel()) { @@ -1944,12 +2023,17 @@ std::set<std::string> RTCStatsCollector::PrepareTransportNames_s() const { return transport_names; } -void RTCStatsCollector::OnDataChannelCreated(DataChannel* channel) { +void RTCStatsCollector::OnRtpDataChannelCreated(RtpDataChannel* channel) { + channel->SignalOpened.connect(this, &RTCStatsCollector::OnDataChannelOpened); + channel->SignalClosed.connect(this, &RTCStatsCollector::OnDataChannelClosed); +} + +void RTCStatsCollector::OnSctpDataChannelCreated(SctpDataChannel* channel) { channel->SignalOpened.connect(this, &RTCStatsCollector::OnDataChannelOpened); channel->SignalClosed.connect(this, &RTCStatsCollector::OnDataChannelClosed); } -void RTCStatsCollector::OnDataChannelOpened(DataChannel* channel) { +void RTCStatsCollector::OnDataChannelOpened(DataChannelInterface* channel) { RTC_DCHECK(signaling_thread_->IsCurrent()); bool result = internal_record_.opened_data_channels .insert(reinterpret_cast<uintptr_t>(channel)) @@ -1958,7 +2042,7 @@ void RTCStatsCollector::OnDataChannelOpened(DataChannel* channel) { RTC_DCHECK(result); } -void RTCStatsCollector::OnDataChannelClosed(DataChannel* channel) { +void RTCStatsCollector::OnDataChannelClosed(DataChannelInterface* channel) { RTC_DCHECK(signaling_thread_->IsCurrent()); // Only channels that have been fully opened (and have increased the // |data_channels_opened_| counter) increase the closed counter. |