diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index 383939a3b5..68e0dd07e0 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -187,8 +187,11 @@ absl::optional FakeVoiceMediaChannel::GetBaseMinimumPlayoutDelayMs( } return absl::nullopt; } -bool FakeVoiceMediaChannel::GetStats(VoiceMediaInfo* info, - bool get_and_clear_legacy_stats) { +bool FakeVoiceMediaChannel::GetSendStats(VoiceMediaSendInfo* info) { + return false; +} +bool FakeVoiceMediaChannel::GetReceiveStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) { return false; } void FakeVoiceMediaChannel::SetRawAudioSink( @@ -367,7 +370,10 @@ bool FakeVideoMediaChannel::RemoveRecvStream(uint32_t ssrc) { } void FakeVideoMediaChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) { } -bool FakeVideoMediaChannel::GetStats(VideoMediaInfo* info) { +bool FakeVideoMediaChannel::GetSendStats(VideoMediaSendInfo* info) { + return false; +} +bool FakeVideoMediaChannel::GetReceiveStats(VideoMediaReceiveInfo* info) { return false; } std::vector FakeVideoMediaChannel::GetSources( diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index a03a8a6646..ef7701400e 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -381,7 +381,9 @@ class FakeVoiceMediaChannel : public RtpHelper { absl::optional GetBaseMinimumPlayoutDelayMs( uint32_t ssrc) const override; - bool GetStats(VoiceMediaInfo* info, bool get_and_clear_legacy_stats) override; + bool GetSendStats(VoiceMediaSendInfo* info) override; + bool GetReceiveStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) override; void SetRawAudioSink( uint32_t ssrc, @@ -473,7 +475,8 @@ class FakeVideoMediaChannel : public RtpHelper { bool RemoveRecvStream(uint32_t ssrc) override; void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override; - bool GetStats(VideoMediaInfo* info) override; + bool GetSendStats(VideoMediaSendInfo* info) override; + bool GetReceiveStats(VideoMediaReceiveInfo* info) override; std::vector GetSources(uint32_t ssrc) const override; diff --git a/media/base/media_channel.h b/media/base/media_channel.h index 233f1185dc..9dced9485e 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -676,8 +676,41 @@ struct BandwidthEstimationInfo { // Maps from payload type to `RtpCodecParameters`. typedef std::map RtpCodecParametersMap; +// Stats returned from VoiceMediaSendChannel.GetStats() +struct VoiceMediaSendInfo { + VoiceMediaSendInfo(); + ~VoiceMediaSendInfo(); + void Clear() { + senders.clear(); + send_codecs.clear(); + } + std::vector senders; + RtpCodecParametersMap send_codecs; +}; + +// Stats returned from VoiceMediaReceiveChannel.GetStats() +struct VoiceMediaReceiveInfo { + VoiceMediaReceiveInfo(); + ~VoiceMediaReceiveInfo(); + void Clear() { + receivers.clear(); + receive_codecs.clear(); + } + std::vector receivers; + RtpCodecParametersMap receive_codecs; + int32_t device_underrun_count = 0; +}; + +// Combined VoiceMediaSendInfo and VoiceMediaReceiveInfo +// Returned from Transceiver.getStats() struct VoiceMediaInfo { VoiceMediaInfo(); + VoiceMediaInfo(VoiceMediaSendInfo&& send, VoiceMediaReceiveInfo&& receive) + : senders(std::move(send.senders)), + receivers(std::move(receive.receivers)), + send_codecs(std::move(send.send_codecs)), + receive_codecs(std::move(receive.receive_codecs)), + device_underrun_count(receive.device_underrun_count) {} ~VoiceMediaInfo(); void Clear() { senders.clear(); @@ -692,8 +725,49 @@ struct VoiceMediaInfo { int32_t device_underrun_count = 0; }; +// Stats for a VideoMediaSendChannel +struct VideoMediaSendInfo { + VideoMediaSendInfo(); + ~VideoMediaSendInfo(); + void Clear() { + senders.clear(); + aggregated_senders.clear(); + send_codecs.clear(); + } + // Each sender info represents one "outbound-rtp" stream.In non - simulcast, + // this means one info per RtpSender but if simulcast is used this means + // one info per simulcast layer. + std::vector senders; + // Used for legacy getStats() API's "ssrc" stats and modern getStats() API's + // "track" stats. If simulcast is used, instead of having one sender info per + // simulcast layer, the metrics of all layers of an RtpSender are aggregated + // into a single sender info per RtpSender. + std::vector aggregated_senders; + RtpCodecParametersMap send_codecs; +}; + +// Stats for a VideoMediaReceiveChannel +struct VideoMediaReceiveInfo { + VideoMediaReceiveInfo(); + ~VideoMediaReceiveInfo(); + void Clear() { + receivers.clear(); + receive_codecs.clear(); + } + std::vector receivers; + RtpCodecParametersMap receive_codecs; +}; + +// Combined VideoMediaSenderInfo and VideoMediaReceiverInfo. +// Returned from channel.GetStats() struct VideoMediaInfo { VideoMediaInfo(); + VideoMediaInfo(VideoMediaSendInfo&& send, VideoMediaReceiveInfo&& receive) + : senders(std::move(send.senders)), + aggregated_senders(std::move(send.aggregated_senders)), + receivers(std::move(receive.receivers)), + send_codecs(std::move(send.send_codecs)), + receive_codecs(std::move(receive.receive_codecs)) {} ~VideoMediaInfo(); void Clear() { senders.clear(); @@ -801,6 +875,7 @@ class VoiceMediaSendChannelInterface : public MediaSendChannelInterface { // The valid value for the `event` are 0 to 15 which corresponding to // DTMF event 0-9, *, #, A-D. virtual bool InsertDtmf(uint32_t ssrc, int event, int duration) = 0; + virtual bool GetStats(VoiceMediaSendInfo* stats) = 0; }; class VoiceMediaReceiveChannelInterface : public MediaReceiveChannelInterface { @@ -824,6 +899,7 @@ class VoiceMediaReceiveChannelInterface : public MediaReceiveChannelInterface { std::unique_ptr sink) = 0; virtual void SetDefaultRawAudioSink( std::unique_ptr sink) = 0; + virtual bool GetStats(VoiceMediaReceiveInfo* stats, bool reset_legacy) = 0; }; // TODO(deadbeef): Rename to VideoSenderParameters, since they're intended to @@ -865,6 +941,8 @@ class VideoMediaSendChannelInterface : public MediaSendChannelInterface { const std::vector& rids) = 0; // Enable network condition based codec switching. virtual void SetVideoCodecSwitchingEnabled(bool enabled) = 0; + virtual bool GetStats(VideoMediaSendInfo* stats) = 0; + virtual void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) = 0; }; class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface { @@ -893,6 +971,7 @@ class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface { std::function callback) = 0; // Clear recordable encoded frame callback for `ssrc` virtual void ClearRecordableEncodedFrameCallback(uint32_t ssrc) = 0; + virtual bool GetStats(VideoMediaReceiveInfo* stats) = 0; }; // Info about data received in DataMediaChannel. For use in diff --git a/media/base/media_channel_impl.cc b/media/base/media_channel_impl.cc index eeefea0bab..a72b97413d 100644 --- a/media/base/media_channel_impl.cc +++ b/media/base/media_channel_impl.cc @@ -265,6 +265,18 @@ VoiceMediaInfo::~VoiceMediaInfo() = default; VideoMediaInfo::VideoMediaInfo() = default; VideoMediaInfo::~VideoMediaInfo() = default; +VideoMediaSendInfo::VideoMediaSendInfo() = default; +VideoMediaSendInfo::~VideoMediaSendInfo() = default; + +VoiceMediaSendInfo::VoiceMediaSendInfo() = default; +VoiceMediaSendInfo::~VoiceMediaSendInfo() = default; + +VideoMediaReceiveInfo::VideoMediaReceiveInfo() = default; +VideoMediaReceiveInfo::~VideoMediaReceiveInfo() = default; + +VoiceMediaReceiveInfo::VoiceMediaReceiveInfo() = default; +VoiceMediaReceiveInfo::~VoiceMediaReceiveInfo() = default; + AudioSendParameters::AudioSendParameters() = default; AudioSendParameters::~AudioSendParameters() = default; diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h index 190477a63e..b4263f4a86 100644 --- a/media/base/media_channel_impl.h +++ b/media/base/media_channel_impl.h @@ -221,11 +221,23 @@ class VideoMediaChannel : public MediaChannel, // need access to bitrates of the streams, or change the (RTC)StatsCollector // so that it's getting the send stream stats separately by calling // GetStats(), and merges with BandwidthEstimationInfo by itself. - virtual void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) = 0; + void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override = 0; // Gets quality stats for the channel. - virtual bool GetStats(VideoMediaInfo* info) = 0; + virtual bool GetSendStats(VideoMediaSendInfo* info) = 0; + virtual bool GetReceiveStats(VideoMediaReceiveInfo* info) = 0; // Enable network condition based codec switching. void SetVideoCodecSwitchingEnabled(bool enabled) override; + + private: + // Functions not implemented on this interface + bool GetStats(VideoMediaSendInfo* info) override { + RTC_CHECK_NOTREACHED(); + return false; + } + bool GetStats(VideoMediaReceiveInfo* info) override { + RTC_CHECK_NOTREACHED(); + return false; + } }; // Base class for implementation classes @@ -261,8 +273,21 @@ class VoiceMediaChannel : public MediaChannel, } // Gets quality stats for the channel. - virtual bool GetStats(VoiceMediaInfo* info, - bool get_and_clear_legacy_stats) = 0; + virtual bool GetSendStats(VoiceMediaSendInfo* info) = 0; + virtual bool GetReceiveStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) = 0; + + private: + // Functions not implemented on this interface + bool GetStats(VoiceMediaSendInfo* info) override { + RTC_CHECK_NOTREACHED(); + return false; + } + bool GetStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) override { + RTC_CHECK_NOTREACHED(); + return false; + } }; // The externally exposed objects that support the Send and Receive interfaces. @@ -345,6 +370,9 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface { bool InsertDtmf(uint32_t ssrc, int event, int duration) override { return impl()->InsertDtmf(ssrc, event, duration); } + bool GetStats(VoiceMediaSendInfo* info) override { + return impl_->GetSendStats(info); + } private: VoiceMediaSendChannelInterface* impl() { return impl_; } @@ -438,6 +466,9 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { std::unique_ptr sink) override { return impl()->SetDefaultRawAudioSink(std::move(sink)); } + bool GetStats(VoiceMediaReceiveInfo* info, bool reset_legacy) override { + return impl_->GetReceiveStats(info, reset_legacy); + } private: VoiceMediaReceiveChannelInterface* impl() { return impl_; } @@ -456,7 +487,7 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { } // Implementation of MediaBaseChannelInterface - cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; } + cricket::MediaType media_type() const override { return MEDIA_TYPE_VIDEO; } void OnPacketReceived(rtc::CopyOnWriteBuffer packet, int64_t packet_time_us) override { impl()->OnPacketReceived(packet, packet_time_us); @@ -528,6 +559,12 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { void SetVideoCodecSwitchingEnabled(bool enabled) override { return impl()->SetVideoCodecSwitchingEnabled(enabled); } + bool GetStats(VideoMediaSendInfo* info) override { + return impl_->GetSendStats(info); + } + void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override { + return impl_->FillBitrateInfo(bwe_info); + } private: VideoMediaSendChannelInterface* impl() { return impl_; } @@ -539,7 +576,7 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { public: explicit VideoMediaReceiveChannel(VideoMediaChannel* impl) : impl_(impl) {} // Implementation of MediaBaseChannelInterface - cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; } + cricket::MediaType media_type() const override { return MEDIA_TYPE_VIDEO; } void OnPacketReceived(rtc::CopyOnWriteBuffer packet, int64_t packet_time_us) override { impl()->OnPacketReceived(packet, packet_time_us); @@ -565,6 +602,9 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { return impl()->GetBaseMinimumPlayoutDelayMs(ssrc); } // Implementation of MediaReceiveChannelInterface + VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { + return this; + } bool AddRecvStream(const StreamParams& sp) override { return impl()->AddRecvStream(sp); } @@ -626,6 +666,9 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { void ClearRecordableEncodedFrameCallback(uint32_t ssrc) override { impl()->ClearRecordableEncodedFrameCallback(ssrc); } + bool GetStats(VideoMediaReceiveInfo* info) override { + return impl_->GetReceiveStats(info); + } private: VideoMediaReceiveChannelInterface* impl() { return impl_; } diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index adeaab0c12..d023f21da2 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1600,9 +1600,9 @@ void WebRtcVideoChannel::SetDefaultSink( default_unsignalled_ssrc_handler_.SetDefaultSink(this, sink); } -bool WebRtcVideoChannel::GetStats(VideoMediaInfo* info) { +bool WebRtcVideoChannel::GetSendStats(VideoMediaSendInfo* info) { RTC_DCHECK_RUN_ON(&thread_checker_); - TRACE_EVENT0("webrtc", "WebRtcVideoChannel::GetStats"); + TRACE_EVENT0("webrtc", "WebRtcVideoChannel::GetSendStats"); // Log stats periodically. bool log_stats = false; @@ -1615,8 +1615,7 @@ bool WebRtcVideoChannel::GetStats(VideoMediaInfo* info) { info->Clear(); FillSenderStats(info, log_stats); - FillReceiverStats(info, log_stats); - FillSendAndReceiveCodecStats(info); + FillSendCodecStats(info); // TODO(holmer): We should either have rtt available as a metric on // VideoSend/ReceiveStreams, or we should remove rtt from VideoSenderInfo. webrtc::Call::Stats stats = call_->GetStats(); @@ -1634,8 +1633,27 @@ bool WebRtcVideoChannel::GetStats(VideoMediaInfo* info) { return true; } +bool WebRtcVideoChannel::GetReceiveStats(VideoMediaReceiveInfo* info) { + RTC_DCHECK_RUN_ON(&thread_checker_); + TRACE_EVENT0("webrtc", "WebRtcVideoChannel::GetReceiveStats"); -void WebRtcVideoChannel::FillSenderStats(VideoMediaInfo* video_media_info, + // Log stats periodically. + bool log_stats = false; + int64_t now_ms = rtc::TimeMillis(); + if (last_stats_log_ms_ == -1 || + now_ms - last_stats_log_ms_ > kStatsLogIntervalMs) { + last_stats_log_ms_ = now_ms; + log_stats = true; + } + + info->Clear(); + FillReceiverStats(info, log_stats); + FillReceiveCodecStats(info); + + return true; +} + +void WebRtcVideoChannel::FillSenderStats(VideoMediaSendInfo* video_media_info, bool log_stats) { for (std::map::iterator it = send_streams_.begin(); @@ -1651,8 +1669,9 @@ void WebRtcVideoChannel::FillSenderStats(VideoMediaInfo* video_media_info, } } -void WebRtcVideoChannel::FillReceiverStats(VideoMediaInfo* video_media_info, - bool log_stats) { +void WebRtcVideoChannel::FillReceiverStats( + VideoMediaReceiveInfo* video_media_info, + bool log_stats) { for (std::map::iterator it = receive_streams_.begin(); it != receive_streams_.end(); ++it) { @@ -1670,13 +1689,18 @@ void WebRtcVideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) { } } -void WebRtcVideoChannel::FillSendAndReceiveCodecStats( - VideoMediaInfo* video_media_info) { +void WebRtcVideoChannel::FillSendCodecStats( + VideoMediaSendInfo* video_media_info) { for (const VideoCodec& codec : send_params_.codecs) { webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); video_media_info->send_codecs.insert( std::make_pair(codec_params.payload_type, std::move(codec_params))); } +} + +void WebRtcVideoChannel::FillReceiveCodecStats( + VideoMediaReceiveInfo* video_media_info) { + // TODO(bugs.webrtc.org/14808): Don't copy codec info around - reference it. for (const VideoCodec& codec : recv_params_.codecs) { webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); video_media_info->receive_codecs.insert( diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index e59640ddc8..8b7e4561bd 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -172,7 +172,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, void SetDefaultSink( rtc::VideoSinkInterface* sink) override; void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override; - bool GetStats(VideoMediaInfo* info) override; + bool GetSendStats(VideoMediaSendInfo* info) override; + bool GetReceiveStats(VideoMediaReceiveInfo* info) override; void OnPacketReceived(rtc::CopyOnWriteBuffer packet, int64_t packet_time_us) override; @@ -574,14 +575,16 @@ class WebRtcVideoChannel : public VideoMediaChannel, std::vector before, std::vector after); - void FillSenderStats(VideoMediaInfo* info, bool log_stats) + void FillSenderStats(VideoMediaSendInfo* info, bool log_stats) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); - void FillReceiverStats(VideoMediaInfo* info, bool log_stats) + void FillReceiverStats(VideoMediaReceiveInfo* info, bool log_stats) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); void FillBandwidthEstimationStats(const webrtc::Call::Stats& stats, VideoMediaInfo* info) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); - void FillSendAndReceiveCodecStats(VideoMediaInfo* video_media_info) + void FillSendCodecStats(VideoMediaSendInfo* video_media_info) + RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); + void FillReceiveCodecStats(VideoMediaReceiveInfo* video_media_info) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); webrtc::TaskQueueBase* const worker_thread_; diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 7653fea293..0dcf08b20a 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -563,8 +563,10 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) { auto send_channel = std::make_unique(channel.get()); EXPECT_TRUE(send_channel->AddSendStream(StreamParams::CreateLegacy(123))); - VideoMediaInfo info; - channel->GetStats(&info); + VideoMediaSendInfo send_info; + VideoMediaReceiveInfo receive_info; + channel->GetSendStats(&send_info); + channel->GetReceiveStats(&receive_info); } TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) { @@ -1727,14 +1729,14 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { } cricket::VideoSenderInfo GetSenderStats(size_t i) { - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); - return info.senders[i]; + VideoMediaSendInfo send_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + return send_info.senders[i]; } cricket::VideoReceiverInfo GetReceiverStats(size_t i) { - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaReceiveInfo info; + EXPECT_TRUE(channel_->GetReceiveStats(&info)); return info.receivers[i]; } @@ -1827,54 +1829,57 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStats) { const int kFps = 10; SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps); - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - ASSERT_EQ(1U, info.senders.size()); + ASSERT_EQ(1U, send_info.senders.size()); // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload? // For webrtc, bytes_sent does not include the RTP header length. - EXPECT_EQ(info.senders[0].payload_bytes_sent, + EXPECT_EQ(send_info.senders[0].payload_bytes_sent, NumRtpBytes() - kRtpHeaderSize * NumRtpPackets()); - EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent); - EXPECT_EQ(0.0, info.senders[0].fraction_lost); - ASSERT_TRUE(info.senders[0].codec_payload_type); - EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type); - EXPECT_EQ(0, info.senders[0].firs_rcvd); - EXPECT_EQ(0, info.senders[0].plis_rcvd); - EXPECT_EQ(0u, info.senders[0].nacks_rcvd); - EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width); - EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height); - EXPECT_GT(info.senders[0].framerate_input, 0); - EXPECT_GT(info.senders[0].framerate_sent, 0); + EXPECT_EQ(NumRtpPackets(), send_info.senders[0].packets_sent); + EXPECT_EQ(0.0, send_info.senders[0].fraction_lost); + ASSERT_TRUE(send_info.senders[0].codec_payload_type); + EXPECT_EQ(DefaultCodec().id, *send_info.senders[0].codec_payload_type); + EXPECT_EQ(0, send_info.senders[0].firs_rcvd); + EXPECT_EQ(0, send_info.senders[0].plis_rcvd); + EXPECT_EQ(0u, send_info.senders[0].nacks_rcvd); + EXPECT_EQ(kVideoWidth, send_info.senders[0].send_frame_width); + EXPECT_EQ(kVideoHeight, send_info.senders[0].send_frame_height); + EXPECT_GT(send_info.senders[0].framerate_input, 0); + EXPECT_GT(send_info.senders[0].framerate_sent, 0); - EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id)); + EXPECT_EQ(1U, send_info.send_codecs.count(DefaultCodec().id)); EXPECT_EQ(DefaultCodec().ToCodecParameters(), - info.send_codecs[DefaultCodec().id]); + send_info.send_codecs[DefaultCodec().id]); - ASSERT_EQ(1U, info.receivers.size()); - EXPECT_EQ(1U, info.senders[0].ssrcs().size()); - EXPECT_EQ(1U, info.receivers[0].ssrcs().size()); - EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]); - ASSERT_TRUE(info.receivers[0].codec_payload_type); - EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type); + ASSERT_EQ(1U, receive_info.receivers.size()); + EXPECT_EQ(1U, send_info.senders[0].ssrcs().size()); + EXPECT_EQ(1U, receive_info.receivers[0].ssrcs().size()); + EXPECT_EQ(send_info.senders[0].ssrcs()[0], + receive_info.receivers[0].ssrcs()[0]); + ASSERT_TRUE(receive_info.receivers[0].codec_payload_type); + EXPECT_EQ(DefaultCodec().id, *receive_info.receivers[0].codec_payload_type); EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), - info.receivers[0].payload_bytes_rcvd); - EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd); - EXPECT_EQ(0, info.receivers[0].packets_lost); + receive_info.receivers[0].payload_bytes_rcvd); + EXPECT_EQ(NumRtpPackets(), receive_info.receivers[0].packets_rcvd); + EXPECT_EQ(0, receive_info.receivers[0].packets_lost); // TODO(asapersson): Not set for webrtc. Handle missing stats. - // EXPECT_EQ(0, info.receivers[0].packets_concealed); - EXPECT_EQ(0, info.receivers[0].firs_sent); - EXPECT_EQ(0, info.receivers[0].plis_sent); - EXPECT_EQ(0U, info.receivers[0].nacks_sent); - EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width); - EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height); - EXPECT_GT(info.receivers[0].framerate_rcvd, 0); - EXPECT_GT(info.receivers[0].framerate_decoded, 0); - EXPECT_GT(info.receivers[0].framerate_output, 0); + // EXPECT_EQ(0, receive_info.receivers[0].packets_concealed); + EXPECT_EQ(0, receive_info.receivers[0].firs_sent); + EXPECT_EQ(0, receive_info.receivers[0].plis_sent); + EXPECT_EQ(0U, receive_info.receivers[0].nacks_sent); + EXPECT_EQ(kVideoWidth, receive_info.receivers[0].frame_width); + EXPECT_EQ(kVideoHeight, receive_info.receivers[0].frame_height); + EXPECT_GT(receive_info.receivers[0].framerate_rcvd, 0); + EXPECT_GT(receive_info.receivers[0].framerate_decoded, 0); + EXPECT_GT(receive_info.receivers[0].framerate_output, 0); - EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id)); + EXPECT_EQ(1U, receive_info.receive_codecs.count(DefaultCodec().id)); EXPECT_EQ(DefaultCodec().ToCodecParameters(), - info.receive_codecs[DefaultCodec().id]); + receive_info.receive_codecs[DefaultCodec().id]); } // Test that stats work properly for a conf call with multiple recv streams. @@ -1906,9 +1911,12 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { EXPECT_TRUE(channel_->SetSend(false)); - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1U, info.senders.size()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1U, send_info.senders.size()); // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload? // For webrtc, bytes_sent does not include the RTP header length. EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), @@ -1917,8 +1925,8 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width); EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height); - ASSERT_EQ(2U, info.receivers.size()); - for (size_t i = 0; i < info.receivers.size(); ++i) { + ASSERT_EQ(2U, receive_info.receivers.size()); + for (size_t i = 0; i < receive_info.receivers.size(); ++i) { EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size()); EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]); EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), @@ -1966,29 +1974,30 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) { // Get stats, and make sure they are correct for two senders. We wait until // the number of expected packets have been sent to avoid races where we // check stats before it has been updated. - cricket::VideoMediaInfo info; + cricket::VideoMediaSendInfo send_info; for (uint32_t i = 0; i < kTimeout; ++i) { rtc::Thread::Current()->ProcessMessages(1); - EXPECT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(2U, info.senders.size()); - if (info.senders[0].packets_sent + info.senders[1].packets_sent == + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + + ASSERT_EQ(2U, send_info.senders.size()); + if (send_info.senders[0].packets_sent + send_info.senders[1].packets_sent == NumRtpPackets()) { // Stats have been updated for both sent frames, expectations can be // checked now. break; } } - EXPECT_EQ(NumRtpPackets(), - info.senders[0].packets_sent + info.senders[1].packets_sent) + EXPECT_EQ(NumRtpPackets(), send_info.senders[0].packets_sent + + send_info.senders[1].packets_sent) << "Timed out while waiting for packet counts for all sent packets."; - EXPECT_EQ(1U, info.senders[0].ssrcs().size()); - EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]); - EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width); - EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height); - EXPECT_EQ(1U, info.senders[1].ssrcs().size()); - EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]); - EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width); - EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height); + EXPECT_EQ(1U, send_info.senders[0].ssrcs().size()); + EXPECT_EQ(1234U, send_info.senders[0].ssrcs()[0]); + EXPECT_EQ(kVideoWidth, send_info.senders[0].send_frame_width); + EXPECT_EQ(kVideoHeight, send_info.senders[0].send_frame_height); + EXPECT_EQ(1U, send_info.senders[1].ssrcs().size()); + EXPECT_EQ(5678U, send_info.senders[1].ssrcs()[0]); + EXPECT_EQ(kTestWidth, send_info.senders[1].send_frame_width); + EXPECT_EQ(kTestHeight, send_info.senders[1].send_frame_height); // The capturer must be unregistered here as it runs out of it's scope next. channel_->SetVideoSend(5678, nullptr, nullptr); } @@ -4049,10 +4058,14 @@ TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) { EXPECT_EQ(2, renderer.num_rendered_frames()); // Verify that NTP time has been correctly deduced. - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1u, info.receivers.size()); - EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1u, receive_info.receivers.size()); + EXPECT_EQ(kInitialNtpTimeMs, + receive_info.receivers[0].capture_start_ntp_time_ms); } TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) { @@ -5436,9 +5449,12 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) { AddSendStream(); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ("VP8", info.senders[0].codec_name); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ("VP8", send_info.senders[0].codec_name); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) { @@ -5447,10 +5463,13 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) { stats.encoder_implementation_name = "encoder_implementation_name"; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + EXPECT_EQ(stats.encoder_implementation_name, - info.senders[0].encoder_implementation_name); + send_info.senders[0].encoder_implementation_name); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsPowerEfficientEncoder) { @@ -5459,9 +5478,12 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsPowerEfficientEncoder) { stats.power_efficient_encoder = true; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_TRUE(info.senders[0].power_efficient_encoder); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_TRUE(send_info.senders[0].power_efficient_encoder); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) { @@ -5471,10 +5493,14 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) { stats.encode_usage_percent = 42; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms); - EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(stats.avg_encode_time_ms, send_info.senders[0].avg_encode_ms); + EXPECT_EQ(stats.encode_usage_percent, + send_info.senders[0].encode_usage_percent); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) { @@ -5483,9 +5509,12 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) { stats.frames_encoded = 13; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(stats.frames_encoded, send_info.senders[0].frames_encoded); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) { @@ -5495,12 +5524,15 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) { stats.substreams[456].frame_counts.key_frames = 87; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(info.senders.size(), 2u); - EXPECT_EQ(10u, info.senders[0].key_frames_encoded); - EXPECT_EQ(87u, info.senders[1].key_frames_encoded); - EXPECT_EQ(97u, info.aggregated_senders[0].key_frames_encoded); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(send_info.senders.size(), 2u); + EXPECT_EQ(10u, send_info.senders[0].key_frames_encoded); + EXPECT_EQ(87u, send_info.senders[1].key_frames_encoded); + EXPECT_EQ(97u, send_info.aggregated_senders[0].key_frames_encoded); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsPerLayerQpSum) { @@ -5510,12 +5542,15 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsPerLayerQpSum) { stats.substreams[456].qp_sum = 11; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(info.senders.size(), 2u); - EXPECT_EQ(stats.substreams[123].qp_sum, info.senders[0].qp_sum); - EXPECT_EQ(stats.substreams[456].qp_sum, info.senders[1].qp_sum); - EXPECT_EQ(*info.aggregated_senders[0].qp_sum, 26u); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(send_info.senders.size(), 2u); + EXPECT_EQ(stats.substreams[123].qp_sum, send_info.senders[0].qp_sum); + EXPECT_EQ(stats.substreams[456].qp_sum, send_info.senders[1].qp_sum); + EXPECT_EQ(*send_info.aggregated_senders[0].qp_sum, 26u); } webrtc::VideoSendStream::Stats GetInitialisedStats() { @@ -5559,10 +5594,13 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportWithoutSubStreams) { FakeVideoSendStream* stream = AddSendStream(); auto stats = GetInitialisedStats(); stream->SetStats(stats); - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u); - auto& sender = video_media_info.aggregated_senders[0]; + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(send_info.aggregated_senders.size(), 1u); + auto& sender = send_info.aggregated_senders[0]; // MediaSenderInfo @@ -5669,10 +5707,13 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { stream->SetStats(stats); - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u); - auto& sender = video_media_info.aggregated_senders[0]; + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(send_info.aggregated_senders.size(), 1u); + auto& sender = send_info.aggregated_senders[0]; // MediaSenderInfo @@ -5792,10 +5833,13 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { stream->SetStats(stats); - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - EXPECT_EQ(video_media_info.senders.size(), 2u); - auto& sender = video_media_info.senders[0]; + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ(send_info.senders.size(), 2u); + auto& sender = send_info.senders[0]; // MediaSenderInfo @@ -5896,13 +5940,16 @@ TEST_F(WebRtcVideoChannelTest, stream->SetStats(stats); // GetStats() and ensure `active` matches `encodings` for each SSRC. - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - ASSERT_EQ(video_media_info.senders.size(), 2u); - ASSERT_TRUE(video_media_info.senders[0].active.has_value()); - EXPECT_FALSE(video_media_info.senders[0].active.value()); - ASSERT_TRUE(video_media_info.senders[1].active.has_value()); - EXPECT_TRUE(video_media_info.senders[1].active.value()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(send_info.senders.size(), 2u); + ASSERT_TRUE(send_info.senders[0].active.has_value()); + EXPECT_FALSE(send_info.senders[0].active.value()); + ASSERT_TRUE(send_info.senders[1].active.has_value()); + EXPECT_TRUE(send_info.senders[1].active.value()); } TEST_F(WebRtcVideoChannelTest, OutboundRtpIsActiveComesFromAnyEncodingInSvc) { @@ -5939,12 +5986,15 @@ TEST_F(WebRtcVideoChannelTest, OutboundRtpIsActiveComesFromAnyEncodingInSvc) { stream->SetStats(stats); // GetStats() and ensure `active` is true if ANY encoding is active. - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - ASSERT_EQ(video_media_info.senders.size(), 1u); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(send_info.senders.size(), 1u); // Middle layer is active. - ASSERT_TRUE(video_media_info.senders[0].active.has_value()); - EXPECT_TRUE(video_media_info.senders[0].active.value()); + ASSERT_TRUE(send_info.senders[0].active.has_value()); + EXPECT_TRUE(send_info.senders[0].active.value()); parameters = send_channel_->GetRtpSendParameters(kSsrc1); ASSERT_EQ(3u, parameters.encodings.size()); @@ -5952,11 +6002,13 @@ TEST_F(WebRtcVideoChannelTest, OutboundRtpIsActiveComesFromAnyEncodingInSvc) { parameters.encodings[1].active = false; parameters.encodings[2].active = false; send_channel_->SetRtpSendParameters(kSsrc1, parameters); - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - ASSERT_EQ(video_media_info.senders.size(), 1u); + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(send_info.senders.size(), 1u); // No layer is active. - ASSERT_TRUE(video_media_info.senders[0].active.has_value()); - EXPECT_FALSE(video_media_info.senders[0].active.value()); + ASSERT_TRUE(send_info.senders[0].active.has_value()); + EXPECT_FALSE(send_info.senders[0].active.value()); } TEST_F(WebRtcVideoChannelTest, MediaSubstreamMissingProducesEmpyStats) { @@ -5975,9 +6027,12 @@ TEST_F(WebRtcVideoChannelTest, MediaSubstreamMissingProducesEmpyStats) { substream.referenced_media_ssrc = kMissingMediaSsrc; stream->SetStats(stats); - cricket::VideoMediaInfo video_media_info; - ASSERT_TRUE(channel_->GetStats(&video_media_info)); - EXPECT_TRUE(video_media_info.senders.empty()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_TRUE(send_info.senders.empty()); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) { @@ -5991,18 +6046,21 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) { stats.substreams[11].height = 90; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1u, info.aggregated_senders.size()); - ASSERT_EQ(3u, info.senders.size()); - EXPECT_EQ(123, info.senders[1].send_frame_width); - EXPECT_EQ(40, info.senders[1].send_frame_height); - EXPECT_EQ(80, info.senders[2].send_frame_width); - EXPECT_EQ(31, info.senders[2].send_frame_height); - EXPECT_EQ(20, info.senders[0].send_frame_width); - EXPECT_EQ(90, info.senders[0].send_frame_height); - EXPECT_EQ(123, info.aggregated_senders[0].send_frame_width); - EXPECT_EQ(90, info.aggregated_senders[0].send_frame_height); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1u, send_info.aggregated_senders.size()); + ASSERT_EQ(3u, send_info.senders.size()); + EXPECT_EQ(123, send_info.senders[1].send_frame_width); + EXPECT_EQ(40, send_info.senders[1].send_frame_height); + EXPECT_EQ(80, send_info.senders[2].send_frame_width); + EXPECT_EQ(31, send_info.senders[2].send_frame_height); + EXPECT_EQ(20, send_info.senders[0].send_frame_width); + EXPECT_EQ(90, send_info.senders[0].send_frame_height); + EXPECT_EQ(123, send_info.aggregated_senders[0].send_frame_width); + EXPECT_EQ(90, send_info.aggregated_senders[0].send_frame_height); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) { @@ -6012,11 +6070,16 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) { stats.cpu_limited_resolution = true; stream->SetStats(stats); - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1U, info.senders.size()); - EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason); - EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1U, send_info.senders.size()); + EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, + send_info.senders[0].adapt_reason); + EXPECT_EQ(stats.number_of_cpu_adapt_changes, + send_info.senders[0].adapt_changes); } TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) { @@ -6027,13 +6090,17 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) { stats.bw_limited_resolution = true; stream->SetStats(stats); - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1U, info.senders.size()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1U, send_info.senders.size()); EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU | WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, - info.senders[0].adapt_reason); - EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes); + send_info.senders[0].adapt_reason); + EXPECT_EQ(stats.number_of_cpu_adapt_changes, + send_info.senders[0].adapt_changes); } TEST(WebRtcVideoChannelHelperTest, MergeInfoAboutOutboundRtpSubstreams) { @@ -6198,20 +6265,23 @@ TEST_F(WebRtcVideoChannelTest, stats.substreams[301].referenced_media_ssrc = 201; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(info.senders.size(), 2u); - EXPECT_EQ(15u, info.senders[0].header_and_padding_bytes_sent); - EXPECT_EQ(30u, info.senders[0].payload_bytes_sent); - EXPECT_EQ(4, info.senders[0].packets_sent); - EXPECT_EQ(10u, info.senders[0].retransmitted_bytes_sent); - EXPECT_EQ(1u, info.senders[0].retransmitted_packets_sent); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - EXPECT_EQ(45u, info.senders[1].header_and_padding_bytes_sent); - EXPECT_EQ(77u, info.senders[1].payload_bytes_sent); - EXPECT_EQ(16, info.senders[1].packets_sent); - EXPECT_EQ(20u, info.senders[1].retransmitted_bytes_sent); - EXPECT_EQ(4u, info.senders[1].retransmitted_packets_sent); + EXPECT_EQ(send_info.senders.size(), 2u); + EXPECT_EQ(15u, send_info.senders[0].header_and_padding_bytes_sent); + EXPECT_EQ(30u, send_info.senders[0].payload_bytes_sent); + EXPECT_EQ(4, send_info.senders[0].packets_sent); + EXPECT_EQ(10u, send_info.senders[0].retransmitted_bytes_sent); + EXPECT_EQ(1u, send_info.senders[0].retransmitted_packets_sent); + + EXPECT_EQ(45u, send_info.senders[1].header_and_padding_bytes_sent); + EXPECT_EQ(77u, send_info.senders[1].payload_bytes_sent); + EXPECT_EQ(16, send_info.senders[1].packets_sent); + EXPECT_EQ(20u, send_info.senders[1].retransmitted_bytes_sent); + EXPECT_EQ(4u, send_info.senders[1].retransmitted_packets_sent); } TEST_F(WebRtcVideoChannelTest, @@ -6221,11 +6291,14 @@ TEST_F(WebRtcVideoChannelTest, stats.bw_limited_resolution = true; stream->SetStats(stats); - cricket::VideoMediaInfo info; - EXPECT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(1U, info.senders.size()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(1U, send_info.senders.size()); EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, - info.senders[0].adapt_reason); + send_info.senders[0].adapt_reason); } TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) { @@ -6241,19 +6314,22 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) { stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(2, info.senders[0].firs_rcvd); - EXPECT_EQ(3u, info.senders[0].nacks_rcvd); - EXPECT_EQ(4, info.senders[0].plis_rcvd); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - EXPECT_EQ(5, info.senders[1].firs_rcvd); - EXPECT_EQ(7u, info.senders[1].nacks_rcvd); - EXPECT_EQ(9, info.senders[1].plis_rcvd); + EXPECT_EQ(2, send_info.senders[0].firs_rcvd); + EXPECT_EQ(3u, send_info.senders[0].nacks_rcvd); + EXPECT_EQ(4, send_info.senders[0].plis_rcvd); - EXPECT_EQ(7, info.aggregated_senders[0].firs_rcvd); - EXPECT_EQ(10u, info.aggregated_senders[0].nacks_rcvd); - EXPECT_EQ(13, info.aggregated_senders[0].plis_rcvd); + EXPECT_EQ(5, send_info.senders[1].firs_rcvd); + EXPECT_EQ(7u, send_info.senders[1].nacks_rcvd); + EXPECT_EQ(9, send_info.senders[1].plis_rcvd); + + EXPECT_EQ(7, send_info.aggregated_senders[0].firs_rcvd); + EXPECT_EQ(10u, send_info.aggregated_senders[0].nacks_rcvd); + EXPECT_EQ(13, send_info.aggregated_senders[0].plis_rcvd); } TEST_F(WebRtcVideoChannelTest, @@ -6265,14 +6341,19 @@ TEST_F(WebRtcVideoChannelTest, stats.rtcp_packet_type_counts.pli_packets = 4; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets, - rtc::checked_cast(info.receivers[0].firs_sent)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ( + stats.rtcp_packet_type_counts.fir_packets, + rtc::checked_cast(receive_info.receivers[0].firs_sent)); EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets, - info.receivers[0].nacks_sent); - EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets, - rtc::checked_cast(info.receivers[0].plis_sent)); + receive_info.receivers[0].nacks_sent); + EXPECT_EQ( + stats.rtcp_packet_type_counts.pli_packets, + rtc::checked_cast(receive_info.receivers[0].plis_sent)); } TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) { @@ -6301,36 +6382,42 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) { stats.power_efficient_decoder = true; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + EXPECT_EQ(stats.decoder_implementation_name, - info.receivers[0].decoder_implementation_name); - EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms); - EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms); - EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms); - EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms); - EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms); + receive_info.receivers[0].decoder_implementation_name); + EXPECT_EQ(stats.decode_ms, receive_info.receivers[0].decode_ms); + EXPECT_EQ(stats.max_decode_ms, receive_info.receivers[0].max_decode_ms); + EXPECT_EQ(stats.current_delay_ms, receive_info.receivers[0].current_delay_ms); + EXPECT_EQ(stats.target_delay_ms, receive_info.receivers[0].target_delay_ms); + EXPECT_EQ(stats.jitter_buffer_ms, receive_info.receivers[0].jitter_buffer_ms); EXPECT_EQ(stats.jitter_buffer_delay_seconds, - info.receivers[0].jitter_buffer_delay_seconds); + receive_info.receivers[0].jitter_buffer_delay_seconds); EXPECT_EQ(stats.jitter_buffer_emitted_count, - info.receivers[0].jitter_buffer_emitted_count); - EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms); - EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms); - EXPECT_EQ(stats.width, info.receivers[0].frame_width); - EXPECT_EQ(stats.height, info.receivers[0].frame_height); + receive_info.receivers[0].jitter_buffer_emitted_count); + EXPECT_EQ(stats.min_playout_delay_ms, + receive_info.receivers[0].min_playout_delay_ms); + EXPECT_EQ(stats.render_delay_ms, receive_info.receivers[0].render_delay_ms); + EXPECT_EQ(stats.width, receive_info.receivers[0].frame_width); + EXPECT_EQ(stats.height, receive_info.receivers[0].frame_height); EXPECT_EQ(rtc::checked_cast(stats.frame_counts.key_frames + stats.frame_counts.delta_frames), - info.receivers[0].frames_received); - EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered); - EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded); + receive_info.receivers[0].frames_received); + EXPECT_EQ(stats.frames_rendered, receive_info.receivers[0].frames_rendered); + EXPECT_EQ(stats.frames_decoded, receive_info.receivers[0].frames_decoded); EXPECT_EQ(rtc::checked_cast(stats.frame_counts.key_frames), - info.receivers[0].key_frames_decoded); - EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum); - EXPECT_EQ(stats.total_decode_time, info.receivers[0].total_decode_time); - EXPECT_EQ(stats.total_assembly_time, info.receivers[0].total_assembly_time); + receive_info.receivers[0].key_frames_decoded); + EXPECT_EQ(stats.qp_sum, receive_info.receivers[0].qp_sum); + EXPECT_EQ(stats.total_decode_time, + receive_info.receivers[0].total_decode_time); + EXPECT_EQ(stats.total_assembly_time, + receive_info.receivers[0].total_assembly_time); EXPECT_EQ(stats.frames_assembled_from_multiple_packets, - info.receivers[0].frames_assembled_from_multiple_packets); - EXPECT_TRUE(info.receivers[0].power_efficient_decoder); + receive_info.receivers[0].frames_assembled_from_multiple_packets); + EXPECT_TRUE(receive_info.receivers[0].power_efficient_decoder); } TEST_F(WebRtcVideoChannelTest, @@ -6341,12 +6428,15 @@ TEST_F(WebRtcVideoChannelTest, stats.total_squared_inter_frame_delay = 0.00456; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + EXPECT_EQ(stats.total_inter_frame_delay, - info.receivers[0].total_inter_frame_delay); + receive_info.receivers[0].total_inter_frame_delay); EXPECT_EQ(stats.total_squared_inter_frame_delay, - info.receivers[0].total_squared_inter_frame_delay); + receive_info.receivers[0].total_squared_inter_frame_delay); } TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) { @@ -6359,13 +6449,19 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) { stats.rtp_stats.packets_lost = 6; stream->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes, - rtc::checked_cast(info.receivers[0].payload_bytes_rcvd)); - EXPECT_EQ(stats.rtp_stats.packet_counter.packets, - rtc::checked_cast(info.receivers[0].packets_rcvd)); - EXPECT_EQ(stats.rtp_stats.packets_lost, info.receivers[0].packets_lost); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_EQ( + stats.rtp_stats.packet_counter.payload_bytes, + rtc::checked_cast(receive_info.receivers[0].payload_bytes_rcvd)); + EXPECT_EQ( + stats.rtp_stats.packet_counter.packets, + rtc::checked_cast(receive_info.receivers[0].packets_rcvd)); + EXPECT_EQ(stats.rtp_stats.packets_lost, + receive_info.receivers[0].packets_lost); } TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) { @@ -6375,11 +6471,14 @@ TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) { stats.rtt_ms = 123; fake_call_->SetStats(stats); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(2u, info.senders.size()); - EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms); - EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(2u, send_info.senders.size()); + EXPECT_EQ(stats.rtt_ms, send_info.senders[0].rtt_ms); + EXPECT_EQ(stats.rtt_ms, send_info.senders[1].rtt_ms); } TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) { @@ -6403,18 +6502,21 @@ TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) { stats2.substreams[21].retransmit_bitrate_bps = 8; stream2->SetStats(stats2); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); - ASSERT_EQ(2u, info.aggregated_senders.size()); - ASSERT_EQ(4u, info.senders.size()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + ASSERT_EQ(2u, send_info.aggregated_senders.size()); + ASSERT_EQ(4u, send_info.senders.size()); BandwidthEstimationInfo bwe_info; channel_->FillBitrateInfo(&bwe_info); // Assuming stream and stream2 corresponds to senders[0] and [1] respectively // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs. EXPECT_EQ(stats.media_bitrate_bps, - info.aggregated_senders[0].nominal_bitrate); + send_info.aggregated_senders[0].nominal_bitrate); EXPECT_EQ(stats2.media_bitrate_bps, - info.aggregated_senders[1].nominal_bitrate); + send_info.aggregated_senders[1].nominal_bitrate); EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps, bwe_info.target_enc_bitrate); EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps, @@ -6540,38 +6642,47 @@ TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) { "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs)); EXPECT_TRUE(receive_channel_->AddRecvStream(receiver_sp)); - cricket::VideoMediaInfo info; - ASSERT_TRUE(channel_->GetStats(&info)); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - ASSERT_EQ(1u, info.senders.size()); - ASSERT_EQ(1u, info.receivers.size()); + ASSERT_EQ(1u, send_info.senders.size()); + ASSERT_EQ(1u, receive_info.receivers.size()); EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups); - EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups); - EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups); + EXPECT_EQ(sender_sp.ssrc_groups, send_info.senders[0].ssrc_groups); + EXPECT_EQ(receiver_sp.ssrc_groups, receive_info.receivers[0].ssrc_groups); } TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) { FakeVideoReceiveStream* stream = AddRecvStream(); webrtc::VideoReceiveStreamInterface::Stats stats; - cricket::VideoMediaInfo info; // Report no codec name before receiving. stream->SetStats(stats); - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_STREQ("", receive_info.receivers[0].codec_name.c_str()); // Report VP8 if we're receiving it. stats.current_payload_type = GetEngineCodec("VP8").id; stream->SetStats(stats); - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str()); + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_STREQ(kVp8CodecName, receive_info.receivers[0].codec_name.c_str()); // Report no codec name for unknown playload types. stats.current_payload_type = 3; stream->SetStats(stats); - ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); + + EXPECT_STREQ("", receive_info.receivers[0].codec_name.c_str()); } // Tests that when we add a stream without SSRCs, but contains a stream_id diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 31fa7959cc..c87eca5fdf 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -2262,9 +2262,8 @@ void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); } -bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info, - bool get_and_clear_legacy_stats) { - TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetStats"); +bool WebRtcVoiceMediaChannel::GetSendStats(VoiceMediaSendInfo* info) { + TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetSendStats"); RTC_DCHECK_RUN_ON(worker_thread_); RTC_DCHECK(info); @@ -2304,6 +2303,21 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info, info->senders.push_back(sinfo); } + // Get codec info + for (const AudioCodec& codec : send_codecs_) { + webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); + info->send_codecs.insert( + std::make_pair(codec_params.payload_type, std::move(codec_params))); + } + + return true; +} +bool WebRtcVoiceMediaChannel::GetReceiveStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) { + TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetReceiveStats"); + RTC_DCHECK_RUN_ON(worker_thread_); + RTC_DCHECK(info); + // Get SSRC and stats for each receiver. RTC_DCHECK_EQ(info->receivers.size(), 0U); for (const auto& stream : recv_streams_) { @@ -2403,11 +2417,6 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info, } // Get codec info - for (const AudioCodec& codec : send_codecs_) { - webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); - info->send_codecs.insert( - std::make_pair(codec_params.payload_type, std::move(codec_params))); - } for (const AudioCodec& codec : recv_codecs_) { webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); info->receive_codecs.insert( diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index e4017568ff..35dad9f679 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -207,7 +207,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, void OnNetworkRouteChanged(absl::string_view transport_name, const rtc::NetworkRoute& network_route) override; void OnReadyToSend(bool ready) override; - bool GetStats(VoiceMediaInfo* info, bool get_and_clear_legacy_stats) override; + bool GetSendStats(VoiceMediaSendInfo* info) override; + bool GetReceiveStats(VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) override; // Set the audio sink for an existing stream. void SetRawAudioSink( diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index 0012be37bc..422906f3b1 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -753,17 +753,20 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output); EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms); } - void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const { - EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size()); + void VerifyVoiceSendRecvCodecs( + const cricket::VoiceMediaSendInfo& send_info, + const cricket::VoiceMediaReceiveInfo& receive_info) const { + EXPECT_EQ(send_parameters_.codecs.size(), send_info.send_codecs.size()); for (const cricket::AudioCodec& codec : send_parameters_.codecs) { - ASSERT_EQ(info.send_codecs.count(codec.id), 1U); - EXPECT_EQ(info.send_codecs.find(codec.id)->second, + ASSERT_EQ(send_info.send_codecs.count(codec.id), 1U); + EXPECT_EQ(send_info.send_codecs.find(codec.id)->second, codec.ToCodecParameters()); } - EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size()); + EXPECT_EQ(recv_parameters_.codecs.size(), + receive_info.receive_codecs.size()); for (const cricket::AudioCodec& codec : recv_parameters_.codecs) { - ASSERT_EQ(info.receive_codecs.count(codec.id), 1U); - EXPECT_EQ(info.receive_codecs.find(codec.id)->second, + ASSERT_EQ(receive_info.receive_codecs.count(codec.id), 1U); + EXPECT_EQ(receive_info.receive_codecs.find(codec.id)->second, codec.ToCodecParameters()); } } @@ -2321,46 +2324,55 @@ TEST_P(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) { // Check stats for the added streams. { EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - cricket::VoiceMediaInfo info; - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); // We have added 4 send streams. We should see empty stats for all. - EXPECT_EQ(static_cast(arraysize(kSsrcs4)), info.senders.size()); - for (const auto& sender : info.senders) { + EXPECT_EQ(static_cast(arraysize(kSsrcs4)), + send_info.senders.size()); + for (const auto& sender : send_info.senders) { VerifyVoiceSenderInfo(sender, false); } - VerifyVoiceSendRecvCodecs(info); + VerifyVoiceSendRecvCodecs(send_info, receive_info); // We have added one receive stream. We should see empty stats. - EXPECT_EQ(info.receivers.size(), 1u); - EXPECT_EQ(info.receivers[0].ssrc(), 0u); + EXPECT_EQ(receive_info.receivers.size(), 1u); + EXPECT_EQ(receive_info.receivers[0].ssrc(), 0u); } // Remove the kSsrcY stream. No receiver stats. { - cricket::VoiceMediaInfo info; + cricket::VoiceMediaReceiveInfo receive_info; + cricket::VoiceMediaSendInfo send_info; EXPECT_TRUE(receive_channel_->RemoveRecvStream(kSsrcY)); EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); - EXPECT_EQ(static_cast(arraysize(kSsrcs4)), info.senders.size()); - EXPECT_EQ(0u, info.receivers.size()); + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); + EXPECT_EQ(static_cast(arraysize(kSsrcs4)), + send_info.senders.size()); + EXPECT_EQ(0u, receive_info.receivers.size()); } // Deliver a new packet - a default receive stream should be created and we // should see stats again. { - cricket::VoiceMediaInfo info; + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); SetAudioReceiveStreamStats(); EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); - EXPECT_EQ(static_cast(arraysize(kSsrcs4)), info.senders.size()); - EXPECT_EQ(1u, info.receivers.size()); - VerifyVoiceReceiverInfo(info.receivers[0]); - VerifyVoiceSendRecvCodecs(info); + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); + EXPECT_EQ(static_cast(arraysize(kSsrcs4)), + send_info.senders.size()); + EXPECT_EQ(1u, receive_info.receivers.size()); + VerifyVoiceReceiverInfo(receive_info.receivers[0]); + VerifyVoiceSendRecvCodecs(send_info, receive_info); } } @@ -2466,53 +2478,61 @@ TEST_P(WebRtcVoiceEngineTestFake, GetStats) { // Check stats for the added streams. { EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - cricket::VoiceMediaInfo info; - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); // We have added one send stream. We should see the stats we've set. - EXPECT_EQ(1u, info.senders.size()); - VerifyVoiceSenderInfo(info.senders[0], false); + EXPECT_EQ(1u, send_info.senders.size()); + VerifyVoiceSenderInfo(send_info.senders[0], false); // We have added one receive stream. We should see empty stats. - EXPECT_EQ(info.receivers.size(), 1u); - EXPECT_EQ(info.receivers[0].ssrc(), 0u); + EXPECT_EQ(receive_info.receivers.size(), 1u); + EXPECT_EQ(receive_info.receivers[0].ssrc(), 0u); } // Start sending - this affects some reported stats. { - cricket::VoiceMediaInfo info; SetSend(true); EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); - VerifyVoiceSenderInfo(info.senders[0], true); - VerifyVoiceSendRecvCodecs(info); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); + VerifyVoiceSenderInfo(send_info.senders[0], true); + VerifyVoiceSendRecvCodecs(send_info, receive_info); } // Remove the kSsrcY stream. No receiver stats. { - cricket::VoiceMediaInfo info; EXPECT_TRUE(receive_channel_->RemoveRecvStream(kSsrcY)); EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); - EXPECT_EQ(1u, info.senders.size()); - EXPECT_EQ(0u, info.receivers.size()); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); + EXPECT_EQ(1u, send_info.senders.size()); + EXPECT_EQ(0u, receive_info.receivers.size()); } // Deliver a new packet - a default receive stream should be created and we // should see stats again. { - cricket::VoiceMediaInfo info; DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); SetAudioReceiveStreamStats(); EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0)); - EXPECT_EQ(true, - channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true)); - EXPECT_EQ(1u, info.senders.size()); - EXPECT_EQ(1u, info.receivers.size()); - VerifyVoiceReceiverInfo(info.receivers[0]); - VerifyVoiceSendRecvCodecs(info); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + EXPECT_EQ(true, channel_->GetSendStats(&send_info)); + EXPECT_EQ(true, channel_->GetReceiveStats( + &receive_info, /*get_and_clear_legacy_stats=*/true)); + EXPECT_EQ(1u, send_info.senders.size()); + EXPECT_EQ(1u, receive_info.receivers.size()); + VerifyVoiceReceiverInfo(receive_info.receivers[0]); + VerifyVoiceSendRecvCodecs(send_info, receive_info); } } diff --git a/pc/channel.h b/pc/channel.h index f25866ddb0..b3020e377c 100644 --- a/pc/channel.h +++ b/pc/channel.h @@ -65,6 +65,8 @@ namespace cricket { // and methods with _s suffix on signaling thread. // Network and worker threads may be the same thread. // +class VideoChannel; +class VoiceChannel; class BaseChannel : public ChannelInterface, // TODO(tommi): Remove has_slots inheritance. @@ -375,6 +377,12 @@ class VoiceChannel : public BaseChannel { rtc::UniqueRandomIdGenerator* ssrc_generator); ~VoiceChannel(); + VideoChannel* AsVideoChannel() override { + RTC_CHECK_NOTREACHED(); + return nullptr; + } + VoiceChannel* AsVoiceChannel() override { return this; } + VoiceMediaSendChannelInterface* media_send_channel() override { return &send_channel_; } @@ -430,22 +438,26 @@ class VideoChannel : public BaseChannel { rtc::UniqueRandomIdGenerator* ssrc_generator); ~VideoChannel(); - // downcasts a MediaChannel + VideoChannel* AsVideoChannel() override { return this; } + VoiceChannel* AsVoiceChannel() override { + RTC_CHECK_NOTREACHED(); + return nullptr; + } + VideoMediaSendChannelInterface* media_send_channel() override { - return media_channel()->AsVideoChannel()->AsVideoSendChannel(); + return &send_channel_; } VideoMediaSendChannelInterface* video_media_send_channel() override { - return media_send_channel(); + return &send_channel_; } - // downcasts a MediaChannel VideoMediaReceiveChannelInterface* media_receive_channel() override { - return media_channel()->AsVideoChannel()->AsVideoReceiveChannel(); + return &receive_channel_; } VideoMediaReceiveChannelInterface* video_media_receive_channel() override { - return media_receive_channel(); + return &receive_channel_; } cricket::MediaType media_type() const override { diff --git a/pc/channel_interface.h b/pc/channel_interface.h index c6474837fe..783755e6fe 100644 --- a/pc/channel_interface.h +++ b/pc/channel_interface.h @@ -29,6 +29,8 @@ class VideoBitrateAllocatorFactory; namespace cricket { class MediaChannel; +class VoiceChannel; +class VideoChannel; class MediaContentDescription; struct MediaConfig; @@ -48,6 +50,9 @@ class ChannelInterface { virtual ~ChannelInterface() = default; virtual cricket::MediaType media_type() const = 0; + virtual VideoChannel* AsVideoChannel() = 0; + virtual VoiceChannel* AsVoiceChannel() = 0; + // Temporary fix while MediaChannel is being reconstructed virtual MediaChannel* media_channel() = 0; virtual MediaSendChannelInterface* media_send_channel() = 0; diff --git a/pc/legacy_stats_collector.cc b/pc/legacy_stats_collector.cc index ad9f7ad007..0df1957fcb 100644 --- a/pc/legacy_stats_collector.cc +++ b/pc/legacy_stats_collector.cc @@ -38,6 +38,7 @@ #include "modules/audio_processing/include/audio_processing_statistics.h" #include "p2p/base/ice_transport_internal.h" #include "p2p/base/p2p_constants.h" +#include "pc/channel.h" #include "pc/channel_interface.h" #include "pc/data_channel_utils.h" #include "pc/rtp_receiver.h" @@ -1036,15 +1037,14 @@ void LegacyStatsCollector::ExtractBweInfo() { // Fill in target encoder bitrate, actual encoder bitrate, rtx bitrate, etc. // TODO(holmer): Also fill this in for audio. auto transceivers = pc_->GetTransceiversInternal(); - std::vector video_media_channels; + std::vector video_media_channels; for (const auto& transceiver : transceivers) { if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO) { continue; } auto* video_channel = transceiver->internal()->channel(); if (video_channel) { - video_media_channels.push_back(static_cast( - video_channel->video_media_send_channel())); + video_media_channels.push_back(video_channel->video_media_send_channel()); } } @@ -1063,9 +1063,9 @@ void LegacyStatsCollector::ExtractBweInfo() { namespace { -class MediaChannelStatsGatherer { +class ChannelStatsGatherer { public: - virtual ~MediaChannelStatsGatherer() = default; + virtual ~ChannelStatsGatherer() = default; virtual bool GetStatsOnWorkerThread() = 0; @@ -1094,17 +1094,26 @@ class MediaChannelStatsGatherer { } }; -class VoiceMediaChannelStatsGatherer final : public MediaChannelStatsGatherer { +class VoiceChannelStatsGatherer final : public ChannelStatsGatherer { public: - VoiceMediaChannelStatsGatherer( - cricket::VoiceMediaChannel* voice_media_channel) - : voice_media_channel_(voice_media_channel) { - RTC_DCHECK(voice_media_channel_); + explicit VoiceChannelStatsGatherer(cricket::VoiceChannel* voice_channel) + : voice_channel_(voice_channel) { + RTC_DCHECK(voice_channel_); } bool GetStatsOnWorkerThread() override { - return voice_media_channel_->GetStats(&voice_media_info, - /*get_and_clear_legacy_stats=*/true); + cricket::VoiceMediaSendInfo send_info; + cricket::VoiceMediaReceiveInfo receive_info; + bool success = + voice_channel_->voice_media_send_channel()->GetStats(&send_info); + success &= voice_channel_->voice_media_receive_channel()->GetStats( + &receive_info, + /*get_and_clear_legacy_stats=*/true); + if (success) { + voice_media_info = cricket::VoiceMediaInfo(std::move(send_info), + std::move(receive_info)); + } + return success; } void ExtractStats(LegacyStatsCollector* collector) const override { @@ -1123,20 +1132,29 @@ class VoiceMediaChannelStatsGatherer final : public MediaChannelStatsGatherer { } private: - cricket::VoiceMediaChannel* voice_media_channel_; + cricket::VoiceChannel* voice_channel_; cricket::VoiceMediaInfo voice_media_info; }; -class VideoMediaChannelStatsGatherer final : public MediaChannelStatsGatherer { +class VideoChannelStatsGatherer final : public ChannelStatsGatherer { public: - VideoMediaChannelStatsGatherer( - cricket::VideoMediaChannel* video_media_channel) - : video_media_channel_(video_media_channel) { - RTC_DCHECK(video_media_channel_); + explicit VideoChannelStatsGatherer(cricket::VideoChannel* video_channel) + : video_channel_(video_channel) { + RTC_DCHECK(video_channel_); } bool GetStatsOnWorkerThread() override { - return video_media_channel_->GetStats(&video_media_info); + cricket::VideoMediaSendInfo send_info; + cricket::VideoMediaReceiveInfo receive_info; + bool success = + video_channel_->video_media_send_channel()->GetStats(&send_info); + success &= + video_channel_->video_media_receive_channel()->GetStats(&receive_info); + if (success) { + video_media_info = cricket::VideoMediaInfo(std::move(send_info), + std::move(receive_info)); + } + return success; } void ExtractStats(LegacyStatsCollector* collector) const override { @@ -1147,19 +1165,19 @@ class VideoMediaChannelStatsGatherer final : public MediaChannelStatsGatherer { bool HasRemoteAudio() const override { return false; } private: - cricket::VideoMediaChannel* video_media_channel_; + cricket::VideoChannel* video_channel_; cricket::VideoMediaInfo video_media_info; }; -std::unique_ptr CreateMediaChannelStatsGatherer( - cricket::MediaChannel* channel) { +std::unique_ptr CreateChannelStatsGatherer( + cricket::ChannelInterface* channel) { RTC_DCHECK(channel); if (channel->media_type() == cricket::MEDIA_TYPE_AUDIO) { - return std::make_unique( + return std::make_unique( channel->AsVoiceChannel()); } else { RTC_DCHECK_EQ(channel->media_type(), cricket::MEDIA_TYPE_VIDEO); - return std::make_unique( + return std::make_unique( channel->AsVideoChannel()); } } @@ -1170,7 +1188,7 @@ void LegacyStatsCollector::ExtractMediaInfo( const std::map& transport_names_by_mid) { RTC_DCHECK_RUN_ON(pc_->signaling_thread()); - std::vector> gatherers; + std::vector> gatherers; auto transceivers = pc_->GetTransceiversInternal(); { @@ -1180,8 +1198,8 @@ void LegacyStatsCollector::ExtractMediaInfo( if (!channel) { continue; } - std::unique_ptr gatherer = - CreateMediaChannelStatsGatherer(channel->media_channel()); + std::unique_ptr gatherer = + CreateChannelStatsGatherer(channel); gatherer->mid = channel->mid(); gatherer->transport_name = transport_names_by_mid.at(gatherer->mid); @@ -1208,7 +1226,7 @@ void LegacyStatsCollector::ExtractMediaInfo( cricket::ChannelInterface* channel = transceiver->internal()->channel(); if (!channel) continue; - MediaChannelStatsGatherer* gatherer = gatherers[i++].get(); + ChannelStatsGatherer* gatherer = gatherers[i++].get(); RTC_DCHECK_EQ(gatherer->mid, channel->mid()); for (const auto& receiver : transceiver->internal()->receivers()) { @@ -1219,7 +1237,7 @@ void LegacyStatsCollector::ExtractMediaInfo( for (auto it = gatherers.begin(); it != gatherers.end(); /* incremented manually */) { - MediaChannelStatsGatherer* gatherer = it->get(); + ChannelStatsGatherer* gatherer = it->get(); if (!gatherer->GetStatsOnWorkerThread()) { RTC_LOG(LS_ERROR) << "Failed to get media channel stats for mid=" << gatherer->mid; diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index a9fb3b7d76..f10fd4ddc1 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -2333,15 +2333,24 @@ 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_send_stats; + std::map + video_send_stats; + std::map + voice_receive_stats; + std::map + video_receive_stats; auto transceivers = pc_->GetTransceiversInternal(); // TODO(tommi): See if we can avoid synchronously blocking the signaling // thread while we do this (or avoid the BlockingCall at all). - network_thread_->BlockingCall([this, &transceivers, &voice_stats, - &video_stats] { + network_thread_->BlockingCall([&] { rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; for (const auto& transceiver_proxy : transceivers) { @@ -2365,17 +2374,28 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { stats.transport_name = std::string(channel->transport_name()); if (media_type == cricket::MEDIA_TYPE_AUDIO) { - cricket::VoiceMediaChannel* voice_channel = - channel->media_channel()->AsVoiceChannel(); - RTC_DCHECK(voice_stats.find(voice_channel) == voice_stats.end()); - voice_stats.insert( - std::make_pair(voice_channel, cricket::VoiceMediaInfo())); + auto voice_send_channel = channel->voice_media_send_channel(); + RTC_DCHECK(voice_send_stats.find(voice_send_channel) == + voice_send_stats.end()); + voice_send_stats.insert( + std::make_pair(voice_send_channel, cricket::VoiceMediaSendInfo())); + + auto voice_receive_channel = channel->voice_media_receive_channel(); + RTC_DCHECK(voice_receive_stats.find(voice_receive_channel) == + voice_receive_stats.end()); + voice_receive_stats.insert(std::make_pair( + voice_receive_channel, cricket::VoiceMediaReceiveInfo())); } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - cricket::VideoMediaChannel* video_channel = - channel->media_channel()->AsVideoChannel(); - RTC_DCHECK(video_stats.find(video_channel) == video_stats.end()); - video_stats.insert( - std::make_pair(video_channel, cricket::VideoMediaInfo())); + auto video_send_channel = channel->video_media_send_channel(); + RTC_DCHECK(video_send_stats.find(video_send_channel) == + video_send_stats.end()); + video_send_stats.insert( + std::make_pair(video_send_channel, cricket::VideoMediaSendInfo())); + auto video_receive_channel = channel->video_media_receive_channel(); + RTC_DCHECK(video_receive_stats.find(video_receive_channel) == + video_receive_stats.end()); + video_receive_stats.insert(std::make_pair( + video_receive_channel, cricket::VideoMediaReceiveInfo())); } else { RTC_DCHECK_NOTREACHED(); } @@ -2389,15 +2409,25 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { worker_thread_->BlockingCall([&] { rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; - 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 (auto& pair : voice_send_stats) { + if (!pair.first->GetStats(&pair.second)) { + RTC_LOG(LS_WARNING) << "Failed to get voice send stats."; } } - for (auto& pair : video_stats) { + for (auto& pair : voice_receive_stats) { + if (!pair.first->GetStats(&pair.second, + /*get_and_clear_legacy_stats=*/false)) { + RTC_LOG(LS_WARNING) << "Failed to get voice receive stats."; + } + } + for (auto& pair : video_send_stats) { if (!pair.first->GetStats(&pair.second)) { - RTC_LOG(LS_WARNING) << "Failed to get video stats."; + RTC_LOG(LS_WARNING) << "Failed to get video send stats."; + } + } + for (auto& pair : video_receive_stats) { + if (!pair.first->GetStats(&pair.second)) { + RTC_LOG(LS_WARNING) << "Failed to get video receive stats."; } } @@ -2410,15 +2440,17 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { if (channel) { cricket::MediaType media_type = transceiver->media_type(); if (media_type == cricket::MEDIA_TYPE_AUDIO) { - cricket::VoiceMediaChannel* voice_channel = - channel->media_channel()->AsVoiceChannel(); - RTC_DCHECK(voice_stats.find(voice_channel) != voice_stats.end()); - voice_media_info = std::move(voice_stats[voice_channel]); + auto voice_send_channel = channel->voice_media_send_channel(); + auto voice_receive_channel = channel->voice_media_receive_channel(); + voice_media_info = cricket::VoiceMediaInfo( + std::move(voice_send_stats[voice_send_channel]), + std::move(voice_receive_stats[voice_receive_channel])); } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - cricket::VideoMediaChannel* video_channel = - channel->media_channel()->AsVideoChannel(); - RTC_DCHECK(video_stats.find(video_channel) != video_stats.end()); - video_media_info = std::move(video_stats[video_channel]); + auto video_send_channel = channel->video_media_send_channel(); + auto video_receive_channel = channel->video_media_receive_channel(); + video_media_info = cricket::VideoMediaInfo( + std::move(video_send_stats[video_send_channel]), + std::move(video_receive_stats[video_receive_channel])); } } std::vector> senders; diff --git a/pc/test/fake_peer_connection_for_stats.h b/pc/test/fake_peer_connection_for_stats.h index ca7bf0bebc..be9d3a3f53 100644 --- a/pc/test/fake_peer_connection_for_stats.h +++ b/pc/test/fake_peer_connection_for_stats.h @@ -35,21 +35,35 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { network_thread) {} void SetStats(const cricket::VoiceMediaInfo& voice_info) { - stats_ = voice_info; + send_stats_ = cricket::VoiceMediaSendInfo(); + send_stats_->senders = voice_info.senders; + send_stats_->send_codecs = voice_info.send_codecs; + receive_stats_ = cricket::VoiceMediaReceiveInfo(); + receive_stats_->receivers = voice_info.receivers; + receive_stats_->receive_codecs = voice_info.receive_codecs; + receive_stats_->device_underrun_count = voice_info.device_underrun_count; } // VoiceMediaChannel overrides. - bool GetStats(cricket::VoiceMediaInfo* info, - bool get_and_clear_legacy_stats) override { - if (stats_) { - *info = *stats_; + bool GetSendStats(cricket::VoiceMediaSendInfo* info) override { + if (send_stats_) { + *info = *send_stats_; + return true; + } + return false; + } + bool GetReceiveStats(cricket::VoiceMediaReceiveInfo* info, + bool get_and_clear_legacy_stats) override { + if (receive_stats_) { + *info = *receive_stats_; return true; } return false; } private: - absl::optional stats_; + absl::optional send_stats_; + absl::optional receive_stats_; }; // Fake VideoMediaChannel where the result of GetStats can be configured. @@ -61,20 +75,34 @@ class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel { network_thread) {} void SetStats(const cricket::VideoMediaInfo& video_info) { - stats_ = video_info; + send_stats_ = cricket::VideoMediaSendInfo(); + send_stats_->senders = video_info.senders; + send_stats_->aggregated_senders = video_info.aggregated_senders; + send_stats_->send_codecs = video_info.send_codecs; + receive_stats_ = cricket::VideoMediaReceiveInfo(); + receive_stats_->receivers = video_info.receivers; + receive_stats_->receive_codecs = video_info.receive_codecs; } // VideoMediaChannel overrides. - bool GetStats(cricket::VideoMediaInfo* info) override { - if (stats_) { - *info = *stats_; + bool GetSendStats(cricket::VideoMediaSendInfo* info) override { + if (send_stats_) { + *info = *send_stats_; + return true; + } + return false; + } + bool GetReceiveStats(cricket::VideoMediaReceiveInfo* info) override { + if (receive_stats_) { + *info = *receive_stats_; return true; } return false; } private: - absl::optional stats_; + absl::optional send_stats_; + absl::optional receive_stats_; }; constexpr bool kDefaultRtcpMuxRequired = true; diff --git a/pc/test/mock_channel_interface.h b/pc/test/mock_channel_interface.h index 229fb57a2e..41c142d5ba 100644 --- a/pc/test/mock_channel_interface.h +++ b/pc/test/mock_channel_interface.h @@ -25,6 +25,8 @@ namespace cricket { class MockChannelInterface : public cricket::ChannelInterface { public: MOCK_METHOD(cricket::MediaType, media_type, (), (const, override)); + MOCK_METHOD(VideoChannel*, AsVideoChannel, (), (override)); + MOCK_METHOD(VoiceChannel*, AsVoiceChannel, (), (override)); MOCK_METHOD(MediaChannel*, media_channel, (), (override)); MOCK_METHOD(MediaChannel*, media_send_channel, (), (override)); MOCK_METHOD(VoiceMediaChannel*, voice_media_send_channel, (), (override)); diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h index 5a9b8802dd..e89e7e7892 100644 --- a/pc/test/mock_voice_media_channel.h +++ b/pc/test/mock_voice_media_channel.h @@ -126,9 +126,10 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { InsertDtmf, (uint32_t ssrc, int event, int duration), (override)); + MOCK_METHOD(bool, GetSendStats, (VoiceMediaSendInfo * info), (override)); MOCK_METHOD(bool, - GetStats, - (VoiceMediaInfo * info, bool get_and_clear_legacy_stats), + GetReceiveStats, + (VoiceMediaReceiveInfo * info, bool get_and_clear_legacy_stats), (override)); MOCK_METHOD(void, SetRawAudioSink,