diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index d891733367..deb7e18449 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -1057,9 +1057,8 @@ void ProduceSenderMediaTrackStats( 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 + // TODO(https://crbug.com/webrtc/14175): Stop collecting "track" stats, + // they're deprecated. for (const auto& sender : senders) { if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) { AudioTrackInterface* track = @@ -1549,32 +1548,32 @@ void RTCStatsCollector::ProduceCodecStats_n( std::string transport_id = RTCTransportStatsIDFromTransportChannel( *stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); - 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) { + if (stats.track_media_info_map.voice_media_info().has_value()) { // Inbound - for (const auto& pair : voice_media_info->receive_codecs) { + for (const auto& pair : + stats.track_media_info_map.voice_media_info()->receive_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( timestamp_us, *stats.mid, transport_id, true, pair.second)); } // Outbound - for (const auto& pair : voice_media_info->send_codecs) { + for (const auto& pair : + stats.track_media_info_map.voice_media_info()->send_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( timestamp_us, *stats.mid, transport_id, false, pair.second)); } } // Video - if (video_media_info) { + if (stats.track_media_info_map.video_media_info().has_value()) { // Inbound - for (const auto& pair : video_media_info->receive_codecs) { + for (const auto& pair : + stats.track_media_info_map.video_media_info()->receive_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( timestamp_us, *stats.mid, transport_id, true, pair.second)); } // Outbound - for (const auto& pair : video_media_info->send_codecs) { + for (const auto& pair : + stats.track_media_info_map.video_media_info()->send_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( timestamp_us, *stats.mid, transport_id, false, pair.second)); } @@ -1758,7 +1757,7 @@ void RTCStatsCollector::ProduceMediaStreamTrackStats_s( senders.push_back( rtc::scoped_refptr(sender->internal())); } - ProduceSenderMediaTrackStats(timestamp_us, *stats.track_media_info_map, + ProduceSenderMediaTrackStats(timestamp_us, stats.track_media_info_map, senders, report); std::vector> receivers; @@ -1766,7 +1765,7 @@ void RTCStatsCollector::ProduceMediaStreamTrackStats_s( receivers.push_back( rtc::scoped_refptr(receiver->internal())); } - ProduceReceiverMediaTrackStats(timestamp_us, *stats.track_media_info_map, + ProduceReceiverMediaTrackStats(timestamp_us, stats.track_media_info_map, receivers, report); } } @@ -1808,7 +1807,7 @@ void RTCStatsCollector::ProduceMediaSourceStats_s( // value indicating no SSRC. if (sender_internal->ssrc() != 0) { auto* voice_sender_info = - track_media_info_map->GetVoiceSenderInfoBySsrc( + track_media_info_map.GetVoiceSenderInfoBySsrc( sender_internal->ssrc()); if (voice_sender_info) { audio_source_stats->audio_level = DoubleAudioLevelFromIntAudioLevel( @@ -1853,7 +1852,7 @@ void RTCStatsCollector::ProduceMediaSourceStats_s( // value indicating no SSRC. if (sender_internal->ssrc() != 0) { auto* video_sender_info = - track_media_info_map->GetVideoSenderInfoBySsrc( + track_media_info_map.GetVideoSenderInfoBySsrc( sender_internal->ssrc()); if (video_sender_info) { video_source_stats->frames_per_second = @@ -1911,9 +1910,7 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( if (!stats.mid || !stats.transport_name) { return; } - 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()); + RTC_DCHECK(stats.track_media_info_map.voice_media_info().has_value()); std::string mid = *stats.mid; std::string transport_id = RTCTransportStatsIDFromTransportChannel( *stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); @@ -1921,7 +1918,7 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( // The remote-outbound stats are based on RTCP sender reports sent from the // remote endpoint providing metrics about the remote outbound streams. for (const cricket::VoiceReceiverInfo& voice_receiver_info : - track_media_info_map.voice_media_info()->receivers) { + stats.track_media_info_map.voice_media_info()->receivers) { if (!voice_receiver_info.connected()) continue; // Inbound. @@ -1929,13 +1926,13 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( CreateInboundAudioStreamStats(voice_receiver_info, mid, timestamp_us); // TODO(hta): This lookup should look for the sender, not the track. rtc::scoped_refptr audio_track = - track_media_info_map.GetAudioTrack(voice_receiver_info); + stats.track_media_info_map.GetAudioTrack(voice_receiver_info); if (audio_track) { inbound_audio->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment( - kReceiver, - track_media_info_map.GetAttachmentIdByTrack(audio_track.get()) - .value()); + kReceiver, stats.track_media_info_map + .GetAttachmentIdByTrack(audio_track.get()) + .value()); inbound_audio->track_identifier = audio_track->id(); } inbound_audio->transport_id = transport_id; @@ -1954,7 +1951,7 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( // Outbound. std::map audio_outbound_rtps; for (const cricket::VoiceSenderInfo& voice_sender_info : - track_media_info_map.voice_media_info()->senders) { + stats.track_media_info_map.voice_media_info()->senders) { if (!voice_sender_info.connected()) continue; auto outbound_audio = std::make_unique( @@ -1964,10 +1961,10 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( SetOutboundRTPStreamStatsFromVoiceSenderInfo(mid, voice_sender_info, outbound_audio.get()); rtc::scoped_refptr audio_track = - track_media_info_map.GetAudioTrack(voice_sender_info); + stats.track_media_info_map.GetAudioTrack(voice_sender_info); if (audio_track) { int attachment_id = - track_media_info_map.GetAttachmentIdByTrack(audio_track.get()) + stats.track_media_info_map.GetAttachmentIdByTrack(audio_track.get()) .value(); outbound_audio->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(kSender, @@ -1987,7 +1984,7 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( // that RTCOutboundRtpStreamStats, RTCCodecStats and RTCTransport have already // been added to the report. for (const cricket::VoiceSenderInfo& voice_sender_info : - track_media_info_map.voice_media_info()->senders) { + stats.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, audio_outbound_rtps, @@ -2006,15 +2003,13 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( if (!stats.mid || !stats.transport_name) { return; } - 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()); + RTC_DCHECK(stats.track_media_info_map.video_media_info().has_value()); std::string mid = *stats.mid; 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) { + stats.track_media_info_map.video_media_info()->receivers) { if (!video_receiver_info.connected()) continue; auto inbound_video = std::make_unique( @@ -2024,13 +2019,13 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( SetInboundRTPStreamStatsFromVideoReceiverInfo(mid, video_receiver_info, inbound_video.get()); rtc::scoped_refptr video_track = - track_media_info_map.GetVideoTrack(video_receiver_info); + stats.track_media_info_map.GetVideoTrack(video_receiver_info); if (video_track) { inbound_video->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment( - kReceiver, - track_media_info_map.GetAttachmentIdByTrack(video_track.get()) - .value()); + kReceiver, stats.track_media_info_map + .GetAttachmentIdByTrack(video_track.get()) + .value()); inbound_video->track_identifier = video_track->id(); } inbound_video->transport_id = transport_id; @@ -2039,7 +2034,7 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( // Outbound std::map video_outbound_rtps; for (const cricket::VideoSenderInfo& video_sender_info : - track_media_info_map.video_media_info()->senders) { + stats.track_media_info_map.video_media_info()->senders) { if (!video_sender_info.connected()) continue; auto outbound_video = std::make_unique( @@ -2049,10 +2044,10 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( SetOutboundRTPStreamStatsFromVideoSenderInfo(mid, video_sender_info, outbound_video.get()); rtc::scoped_refptr video_track = - track_media_info_map.GetVideoTrack(video_sender_info); + stats.track_media_info_map.GetVideoTrack(video_sender_info); if (video_track) { int attachment_id = - track_media_info_map.GetAttachmentIdByTrack(video_track.get()) + stats.track_media_info_map.GetAttachmentIdByTrack(video_track.get()) .value(); outbound_video->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(kSender, @@ -2072,7 +2067,7 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( // that RTCOutboundRtpStreamStats, RTCCodecStats and RTCTransport have already // been added to the report. for (const cricket::VideoSenderInfo& video_sender_info : - track_media_info_map.video_media_info()->senders) { + stats.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, video_outbound_rtps, @@ -2231,10 +2226,8 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { transceiver_stats_infos_.clear(); // These are used to invoke GetStats for all the media channels together in // one worker thread hop. - std::map> - voice_stats; - std::map> - video_stats; + std::map voice_stats; + std::map video_stats; auto transceivers = pc_->GetTransceiversInternal(); @@ -2265,15 +2258,17 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { stats.transport_name = std::string(channel->transport_name()); if (media_type == cricket::MEDIA_TYPE_AUDIO) { - RTC_DCHECK(voice_stats.find(channel->media_channel()) == - voice_stats.end()); - voice_stats[channel->media_channel()] = - std::make_unique(); + cricket::VoiceMediaChannel* voice_channel = + static_cast(channel->media_channel()); + RTC_DCHECK(voice_stats.find(voice_channel) == voice_stats.end()); + voice_stats.insert( + std::make_pair(voice_channel, cricket::VoiceMediaInfo())); } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - RTC_DCHECK(video_stats.find(channel->media_channel()) == - video_stats.end()); - video_stats[channel->media_channel()] = - std::make_unique(); + cricket::VideoMediaChannel* video_channel = + static_cast(channel->media_channel()); + RTC_DCHECK(video_stats.find(video_channel) == video_stats.end()); + video_stats.insert( + std::make_pair(video_channel, cricket::VideoMediaInfo())); } else { RTC_DCHECK_NOTREACHED(); } @@ -2287,16 +2282,14 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { worker_thread_->Invoke(RTC_FROM_HERE, [&] { rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; - for (const auto& entry : voice_stats) { - if (!static_cast(entry.first) - ->GetStats(entry.second.get(), - /*get_and_clear_legacy_stats=*/false)) { + for (auto& pair : voice_stats) { + if (!pair.first->GetStats(&pair.second, + /*get_and_clear_legacy_stats=*/false)) { RTC_LOG(LS_WARNING) << "Failed to get voice stats."; } } - for (const auto& entry : video_stats) { - if (!static_cast(entry.first) - ->GetStats(entry.second.get())) { + for (auto& pair : video_stats) { + if (!pair.first->GetStats(&pair.second)) { RTC_LOG(LS_WARNING) << "Failed to get video stats."; } } @@ -2304,17 +2297,23 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { // Create the TrackMediaInfoMap for each transceiver stats object. for (auto& stats : transceiver_stats_infos_) { auto transceiver = stats.transceiver; - std::unique_ptr voice_media_info; - std::unique_ptr video_media_info; + absl::optional voice_media_info; + absl::optional video_media_info; auto channel = transceiver->channel(); if (channel) { cricket::MediaType media_type = transceiver->media_type(); if (media_type == cricket::MEDIA_TYPE_AUDIO) { - RTC_DCHECK(voice_stats[channel->media_channel()]); - voice_media_info = std::move(voice_stats[channel->media_channel()]); + cricket::VoiceMediaChannel* voice_channel = + static_cast( + channel->media_channel()); + RTC_DCHECK(voice_stats.find(voice_channel) != voice_stats.end()); + voice_media_info = std::move(voice_stats[voice_channel]); } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - RTC_DCHECK(video_stats[channel->media_channel()]); - video_media_info = std::move(video_stats[channel->media_channel()]); + cricket::VideoMediaChannel* video_channel = + static_cast( + channel->media_channel()); + RTC_DCHECK(video_stats.find(video_channel) != video_stats.end()); + video_media_info = std::move(video_stats[video_channel]); } } std::vector> senders; @@ -2327,9 +2326,9 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { receivers.push_back( rtc::scoped_refptr(receiver->internal())); } - stats.track_media_info_map = std::make_unique( - std::move(voice_media_info), std::move(video_media_info), senders, - receivers); + stats.track_media_info_map.Initialize(std::move(voice_media_info), + std::move(video_media_info), + senders, receivers); } call_stats_ = pc_->GetCallStats(); diff --git a/pc/rtc_stats_collector.h b/pc/rtc_stats_collector.h index e6d9d184fe..b1909cb4c4 100644 --- a/pc/rtc_stats_collector.h +++ b/pc/rtc_stats_collector.h @@ -162,7 +162,7 @@ class RTCStatsCollector : public rtc::RefCountInterface, cricket::MediaType media_type; absl::optional mid; absl::optional transport_name; - std::unique_ptr track_media_info_map; + TrackMediaInfoMap track_media_info_map; }; void DeliverCachedReport( diff --git a/pc/track_media_info_map.cc b/pc/track_media_info_map.cc index bf3ec0f2bc..914bb5b5cc 100644 --- a/pc/track_media_info_map.cc +++ b/pc/track_media_info_map.cc @@ -104,14 +104,18 @@ void GetAudioAndVideoTrackBySsrc( } // namespace -TrackMediaInfoMap::TrackMediaInfoMap( - std::unique_ptr voice_media_info, - std::unique_ptr video_media_info, +TrackMediaInfoMap::TrackMediaInfoMap() = default; + +void TrackMediaInfoMap::Initialize( + absl::optional voice_media_info, + absl::optional video_media_info, const std::vector>& rtp_senders, - const std::vector>& rtp_receivers) - : voice_media_info_(std::move(voice_media_info)), - video_media_info_(std::move(video_media_info)) { + const std::vector>& rtp_receivers) { rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; + RTC_DCHECK(!is_initialized_); + is_initialized_ = true; + voice_media_info_ = std::move(voice_media_info); + video_media_info_ = std::move(video_media_info); std::map local_audio_track_by_ssrc; std::map local_video_track_by_ssrc; @@ -132,7 +136,7 @@ TrackMediaInfoMap::TrackMediaInfoMap( attachment_id_by_track_[receiver->track().get()] = receiver->AttachmentId(); } - if (voice_media_info_) { + if (voice_media_info_.has_value()) { for (auto& sender_info : voice_media_info_->senders) { AudioTrackInterface* associated_track = FindValueOrNull(local_audio_track_by_ssrc, sender_info.ssrc()); @@ -167,7 +171,7 @@ TrackMediaInfoMap::TrackMediaInfoMap( voice_info_by_receiver_ssrc_[receiver_info.ssrc()] = &receiver_info; } } - if (video_media_info_) { + if (video_media_info_.has_value()) { for (auto& sender_info : video_media_info_->senders) { std::set ssrcs; ssrcs.insert(sender_info.ssrc()); @@ -224,66 +228,79 @@ TrackMediaInfoMap::TrackMediaInfoMap( const std::vector* TrackMediaInfoMap::GetVoiceSenderInfos( const AudioTrackInterface& local_audio_track) const { + RTC_DCHECK(is_initialized_); return FindAddressOrNull(voice_infos_by_local_track_, &local_audio_track); } const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfo( const AudioTrackInterface& remote_audio_track) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(voice_info_by_remote_track_, &remote_audio_track); } const std::vector* TrackMediaInfoMap::GetVideoSenderInfos( const VideoTrackInterface& local_video_track) const { + RTC_DCHECK(is_initialized_); return FindAddressOrNull(video_infos_by_local_track_, &local_video_track); } const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfo( const VideoTrackInterface& remote_video_track) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(video_info_by_remote_track_, &remote_video_track); } const cricket::VoiceSenderInfo* TrackMediaInfoMap::GetVoiceSenderInfoBySsrc( uint32_t ssrc) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(voice_info_by_sender_ssrc_, ssrc); } const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfoBySsrc( uint32_t ssrc) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(voice_info_by_receiver_ssrc_, ssrc); } const cricket::VideoSenderInfo* TrackMediaInfoMap::GetVideoSenderInfoBySsrc( uint32_t ssrc) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(video_info_by_sender_ssrc_, ssrc); } const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfoBySsrc( uint32_t ssrc) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(video_info_by_receiver_ssrc_, ssrc); } rtc::scoped_refptr TrackMediaInfoMap::GetAudioTrack( const cricket::VoiceSenderInfo& voice_sender_info) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(audio_track_by_sender_info_, &voice_sender_info); } rtc::scoped_refptr TrackMediaInfoMap::GetAudioTrack( const cricket::VoiceReceiverInfo& voice_receiver_info) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(audio_track_by_receiver_info_, &voice_receiver_info); } rtc::scoped_refptr TrackMediaInfoMap::GetVideoTrack( const cricket::VideoSenderInfo& video_sender_info) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(video_track_by_sender_info_, &video_sender_info); } rtc::scoped_refptr TrackMediaInfoMap::GetVideoTrack( const cricket::VideoReceiverInfo& video_receiver_info) const { + RTC_DCHECK(is_initialized_); return FindValueOrNull(video_track_by_receiver_info_, &video_receiver_info); } absl::optional TrackMediaInfoMap::GetAttachmentIdByTrack( const MediaStreamTrackInterface* track) const { + RTC_DCHECK(is_initialized_); auto it = attachment_id_by_track_.find(track); return it != attachment_id_by_track_.end() ? absl::optional(it->second) : absl::nullopt; diff --git a/pc/track_media_info_map.h b/pc/track_media_info_map.h index c8c6da2701..b0d9e16588 100644 --- a/pc/track_media_info_map.h +++ b/pc/track_media_info_map.h @@ -38,20 +38,32 @@ namespace webrtc { // |[Voice/Video][Sender/Receiver]Info| has statistical information for a set of // SSRCs. Looking at the RTP senders and receivers uncovers the track <-> info // relationships, which this class does. +// +// In the spec, "track" attachment stats have been made obsolete, and in Unified +// Plan there is just one sender and one receiver per transceiver, so we may be +// able to simplify/delete this class. +// TODO(https://crbug.com/webrtc/14175): Simplify or delete this class when +// "track" stats have been deleted. +// TODO(https://crbug.com/webrtc/13528): Simplify or delete this class when +// Plan B is gone from the native library (already gone for Chrome). class TrackMediaInfoMap { public: - TrackMediaInfoMap( - std::unique_ptr voice_media_info, - std::unique_ptr video_media_info, + TrackMediaInfoMap(); + + void Initialize( + absl::optional voice_media_info, + absl::optional video_media_info, const std::vector>& rtp_senders, const std::vector>& rtp_receivers); - const cricket::VoiceMediaInfo* voice_media_info() const { - return voice_media_info_.get(); + const absl::optional& voice_media_info() const { + RTC_DCHECK(is_initialized_); + return voice_media_info_; } - const cricket::VideoMediaInfo* video_media_info() const { - return video_media_info_.get(); + const absl::optional& video_media_info() const { + RTC_DCHECK(is_initialized_); + return video_media_info_; } const std::vector* GetVoiceSenderInfos( @@ -87,10 +99,9 @@ class TrackMediaInfoMap { const MediaStreamTrackInterface* track) const; private: - absl::optional voice_mid_; - absl::optional video_mid_; - std::unique_ptr voice_media_info_; - std::unique_ptr video_media_info_; + bool is_initialized_ = false; + absl::optional voice_media_info_; + absl::optional video_media_info_; // These maps map tracks (identified by a pointer) to their corresponding info // object of the correct kind. One track can map to multiple info objects. std::map> diff --git a/pc/track_media_info_map_unittest.cc b/pc/track_media_info_map_unittest.cc index 0adfbf30c4..affb3630f5 100644 --- a/pc/track_media_info_map_unittest.cc +++ b/pc/track_media_info_map_unittest.cc @@ -33,6 +33,8 @@ #include "test/gmock.h" #include "test/gtest.h" +using ::testing::ElementsAre; + namespace webrtc { namespace { @@ -104,9 +106,7 @@ class TrackMediaInfoMapTest : public ::testing::Test { TrackMediaInfoMapTest() : TrackMediaInfoMapTest(true) {} explicit TrackMediaInfoMapTest(bool use_real_video_track) - : voice_media_info_(new cricket::VoiceMediaInfo()), - video_media_info_(new cricket::VideoMediaInfo()), - local_audio_track_(AudioTrack::Create("LocalAudioTrack", nullptr)), + : local_audio_track_(AudioTrack::Create("LocalAudioTrack", nullptr)), remote_audio_track_(AudioTrack::Create("RemoteAudioTrack", nullptr)), local_video_track_(use_real_video_track ? CreateVideoTrack("LocalVideoTrack") @@ -115,15 +115,6 @@ class TrackMediaInfoMapTest : public ::testing::Test { ? CreateVideoTrack("RemoteVideoTrack") : CreateMockVideoTrack("LocalVideoTrack")) {} - ~TrackMediaInfoMapTest() { - // If we have a map the ownership has been passed to the map, only delete if - // `CreateMap` has not been called. - if (!map_) { - delete voice_media_info_; - delete video_media_info_; - } - } - void AddRtpSenderWithSsrcs(std::initializer_list ssrcs, MediaStreamTrackInterface* local_track) { rtc::scoped_refptr rtp_sender = CreateMockRtpSender( @@ -140,7 +131,7 @@ class TrackMediaInfoMapTest : public ::testing::Test { voice_sender_info.local_stats.push_back(cricket::SsrcSenderInfo()); voice_sender_info.local_stats[i++].ssrc = ssrc; } - voice_media_info_->senders.push_back(voice_sender_info); + voice_media_info_.senders.push_back(voice_sender_info); } else { cricket::VideoSenderInfo video_sender_info; size_t i = 0; @@ -148,8 +139,8 @@ class TrackMediaInfoMapTest : public ::testing::Test { video_sender_info.local_stats.push_back(cricket::SsrcSenderInfo()); video_sender_info.local_stats[i++].ssrc = ssrc; } - video_media_info_->senders.push_back(video_sender_info); - video_media_info_->aggregated_senders.push_back(video_sender_info); + video_media_info_.senders.push_back(video_sender_info); + video_media_info_.aggregated_senders.push_back(video_sender_info); } } @@ -169,7 +160,7 @@ class TrackMediaInfoMapTest : public ::testing::Test { voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo()); voice_receiver_info.local_stats[i++].ssrc = ssrc; } - voice_media_info_->receivers.push_back(voice_receiver_info); + voice_media_info_.receivers.push_back(voice_receiver_info); } else { cricket::VideoReceiverInfo video_receiver_info; size_t i = 0; @@ -177,25 +168,26 @@ class TrackMediaInfoMapTest : public ::testing::Test { video_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo()); video_receiver_info.local_stats[i++].ssrc = ssrc; } - video_media_info_->receivers.push_back(video_receiver_info); + video_media_info_.receivers.push_back(video_receiver_info); } } - void CreateMap() { - RTC_DCHECK(!map_); - map_.reset(new TrackMediaInfoMap( - std::unique_ptr(voice_media_info_), - std::unique_ptr(video_media_info_), - rtp_senders_, rtp_receivers_)); + // Copies the current state of `voice_media_info_` and `video_media_info_` + // into the map. + void InitializeMap() { + map_.Initialize(voice_media_info_, video_media_info_, rtp_senders_, + rtp_receivers_); } - protected: + private: rtc::AutoThread main_thread_; - cricket::VoiceMediaInfo* voice_media_info_; - cricket::VideoMediaInfo* video_media_info_; + cricket::VoiceMediaInfo voice_media_info_; + cricket::VideoMediaInfo video_media_info_; + + protected: std::vector> rtp_senders_; std::vector> rtp_receivers_; - std::unique_ptr map_; + TrackMediaInfoMap map_; rtc::scoped_refptr local_audio_track_; rtc::scoped_refptr remote_audio_track_; rtc::scoped_refptr local_video_track_; @@ -209,34 +201,32 @@ TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithOneSsrc) { AddRtpReceiverWithSsrcs({2}, remote_audio_track_.get()); AddRtpSenderWithSsrcs({3}, local_video_track_.get()); AddRtpReceiverWithSsrcs({4}, remote_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio sender - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector({&voice_media_info_->senders[0]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); // Remote audio track <-> RTP audio receiver - EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_), - &voice_media_info_->receivers[0]); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVoiceReceiverInfo(*remote_audio_track_), + &map_.voice_media_info()->receivers[0]); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->receivers[0]), remote_audio_track_.get()); // Local video track <-> RTP video sender - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector({&video_media_info_->senders[0]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); // Remote video track <-> RTP video receiver - EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_), - &video_media_info_->receivers[0]); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVideoReceiverInfo(*remote_video_track_), + &map_.video_media_info()->receivers[0]); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->receivers[0]), remote_video_track_.get()); } @@ -245,12 +235,12 @@ TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithMissingSsrc) { AddRtpSenderWithSsrcs({}, local_video_track_.get()); AddRtpReceiverWithSsrcs({}, remote_audio_track_.get()); AddRtpReceiverWithSsrcs({}, remote_video_track_.get()); - CreateMap(); + InitializeMap(); - EXPECT_FALSE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_FALSE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_FALSE(map_->GetVoiceReceiverInfo(*remote_audio_track_)); - EXPECT_FALSE(map_->GetVideoReceiverInfo(*remote_video_track_)); + EXPECT_FALSE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_FALSE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_FALSE(map_.GetVoiceReceiverInfo(*remote_audio_track_)); + EXPECT_FALSE(map_.GetVideoReceiverInfo(*remote_video_track_)); } TEST_F(TrackMediaInfoMapTest, @@ -259,56 +249,52 @@ TEST_F(TrackMediaInfoMapTest, AddRtpReceiverWithSsrcs({2}, remote_audio_track_.get()); AddRtpSenderWithSsrcs({1}, local_video_track_.get()); AddRtpReceiverWithSsrcs({2}, remote_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio sender - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector({&voice_media_info_->senders[0]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); // Remote audio track <-> RTP audio receiver - EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_), - &voice_media_info_->receivers[0]); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVoiceReceiverInfo(*remote_audio_track_), + &map_.voice_media_info()->receivers[0]); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->receivers[0]), remote_audio_track_.get()); // Local video track <-> RTP video sender - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector({&video_media_info_->senders[0]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); // Remote video track <-> RTP video receiver - EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_), - &video_media_info_->receivers[0]); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVideoReceiverInfo(*remote_video_track_), + &map_.video_media_info()->receivers[0]); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->receivers[0]), remote_video_track_.get()); } TEST_F(TrackMediaInfoMapTest, SingleMultiSsrcSenderPerTrack) { AddRtpSenderWithSsrcs({1, 2}, local_audio_track_.get()); AddRtpSenderWithSsrcs({3, 4}, local_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio senders - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector({&voice_media_info_->senders[0]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); // Local video track <-> RTP video senders - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector({&video_media_info_->senders[0]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); } @@ -317,28 +303,26 @@ TEST_F(TrackMediaInfoMapTest, MultipleOneSsrcSendersPerTrack) { AddRtpSenderWithSsrcs({2}, local_audio_track_.get()); AddRtpSenderWithSsrcs({3}, local_video_track_.get()); AddRtpSenderWithSsrcs({4}, local_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio senders - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector( - {&voice_media_info_->senders[0], &voice_media_info_->senders[1]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0], + &map_.voice_media_info()->senders[1])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]), + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[1]), local_audio_track_.get()); // Local video track <-> RTP video senders - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector( - {&video_media_info_->senders[0], &video_media_info_->senders[1]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0], + &map_.video_media_info()->senders[1])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]), + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[1]), local_video_track_.get()); } @@ -347,28 +331,26 @@ TEST_F(TrackMediaInfoMapTest, MultipleMultiSsrcSendersPerTrack) { AddRtpSenderWithSsrcs({3, 4}, local_audio_track_.get()); AddRtpSenderWithSsrcs({5, 6}, local_video_track_.get()); AddRtpSenderWithSsrcs({7, 8}, local_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio senders - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector( - {&voice_media_info_->senders[0], &voice_media_info_->senders[1]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0], + &map_.voice_media_info()->senders[1])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]), + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[1]), local_audio_track_.get()); // Local video track <-> RTP video senders - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector( - {&video_media_info_->senders[0], &video_media_info_->senders[1]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0], + &map_.video_media_info()->senders[1])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]), + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[1]), local_video_track_.get()); } @@ -378,34 +360,32 @@ TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithSsrcNotUnique) { AddRtpReceiverWithSsrcs({1}, remote_audio_track_.get()); AddRtpSenderWithSsrcs({2}, local_video_track_.get()); AddRtpReceiverWithSsrcs({2}, remote_video_track_.get()); - CreateMap(); + InitializeMap(); // Local audio track <-> RTP audio senders - ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); - EXPECT_EQ( - *map_->GetVoiceSenderInfos(*local_audio_track_), - std::vector({&voice_media_info_->senders[0]})); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVoiceSenderInfos(*local_audio_track_)); + EXPECT_THAT(*map_.GetVoiceSenderInfos(*local_audio_track_), + ElementsAre(&map_.voice_media_info()->senders[0])); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->senders[0]), local_audio_track_.get()); // Remote audio track <-> RTP audio receiver - EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_), - &voice_media_info_->receivers[0]); - EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVoiceReceiverInfo(*remote_audio_track_), + &map_.voice_media_info()->receivers[0]); + EXPECT_EQ(map_.GetAudioTrack(map_.voice_media_info()->receivers[0]), remote_audio_track_.get()); // Local video track <-> RTP video senders - ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); - EXPECT_EQ( - *map_->GetVideoSenderInfos(*local_video_track_), - std::vector({&video_media_info_->senders[0]})); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), + ASSERT_TRUE(map_.GetVideoSenderInfos(*local_video_track_)); + EXPECT_THAT(*map_.GetVideoSenderInfos(*local_video_track_), + ElementsAre(&map_.video_media_info()->senders[0])); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->senders[0]), local_video_track_.get()); // Remote video track <-> RTP video receiver - EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_), - &video_media_info_->receivers[0]); - EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]), + EXPECT_EQ(map_.GetVideoReceiverInfo(*remote_video_track_), + &map_.video_media_info()->receivers[0]); + EXPECT_EQ(map_.GetVideoTrack(map_.video_media_info()->receivers[0]), remote_video_track_.get()); } @@ -414,22 +394,22 @@ TEST_F(TrackMediaInfoMapTest, SsrcLookupFunction) { AddRtpReceiverWithSsrcs({2}, remote_audio_track_.get()); AddRtpSenderWithSsrcs({3}, local_video_track_.get()); AddRtpReceiverWithSsrcs({4}, remote_video_track_.get()); - CreateMap(); - EXPECT_TRUE(map_->GetVoiceSenderInfoBySsrc(1)); - EXPECT_TRUE(map_->GetVoiceReceiverInfoBySsrc(2)); - EXPECT_TRUE(map_->GetVideoSenderInfoBySsrc(3)); - EXPECT_TRUE(map_->GetVideoReceiverInfoBySsrc(4)); - EXPECT_FALSE(map_->GetVoiceSenderInfoBySsrc(2)); - EXPECT_FALSE(map_->GetVoiceSenderInfoBySsrc(1024)); + InitializeMap(); + EXPECT_TRUE(map_.GetVoiceSenderInfoBySsrc(1)); + EXPECT_TRUE(map_.GetVoiceReceiverInfoBySsrc(2)); + EXPECT_TRUE(map_.GetVideoSenderInfoBySsrc(3)); + EXPECT_TRUE(map_.GetVideoReceiverInfoBySsrc(4)); + EXPECT_FALSE(map_.GetVoiceSenderInfoBySsrc(2)); + EXPECT_FALSE(map_.GetVoiceSenderInfoBySsrc(1024)); } TEST_F(TrackMediaInfoMapTest, GetAttachmentIdByTrack) { AddRtpSenderWithSsrcs({1}, local_audio_track_.get()); - CreateMap(); + InitializeMap(); EXPECT_EQ(rtp_senders_[0]->AttachmentId(), - map_->GetAttachmentIdByTrack(local_audio_track_.get())); + map_.GetAttachmentIdByTrack(local_audio_track_.get())); EXPECT_EQ(absl::nullopt, - map_->GetAttachmentIdByTrack(local_video_track_.get())); + map_.GetAttachmentIdByTrack(local_video_track_.get())); } // Death tests. @@ -447,7 +427,7 @@ TEST_F(TrackMediaInfoMapDeathTest, MultipleOneSsrcReceiversPerTrack) { AddRtpReceiverWithSsrcs({2}, remote_audio_track_.get()); AddRtpReceiverWithSsrcs({3}, remote_video_track_.get()); AddRtpReceiverWithSsrcs({4}, remote_video_track_.get()); - EXPECT_DEATH(CreateMap(), ""); + EXPECT_DEATH(InitializeMap(), ""); } TEST_F(TrackMediaInfoMapDeathTest, MultipleMultiSsrcReceiversPerTrack) { @@ -455,7 +435,7 @@ TEST_F(TrackMediaInfoMapDeathTest, MultipleMultiSsrcReceiversPerTrack) { AddRtpReceiverWithSsrcs({3, 4}, remote_audio_track_.get()); AddRtpReceiverWithSsrcs({5, 6}, remote_video_track_.get()); AddRtpReceiverWithSsrcs({7, 8}, remote_video_track_.get()); - EXPECT_DEATH(CreateMap(), ""); + EXPECT_DEATH(InitializeMap(), ""); } #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)