Split stats generation for MediaChannel into sender and receiver APIs

This is in preparation for splitting MediaChannel into sender and
receiver channels, with independent objects.

Bug: webrtc:13931
Change-Id: I8e34b0c80b4d76132394efcda658a8face3ab873
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/288750
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38998}
This commit is contained in:
Harald Alvestrand 2023-01-04 12:42:56 +00:00 committed by WebRTC LUCI CQ
parent 9253240305
commit 1251c6418e
18 changed files with 811 additions and 401 deletions

View File

@ -187,8 +187,11 @@ absl::optional<int> 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<webrtc::RtpSource> FakeVideoMediaChannel::GetSources(

View File

@ -381,7 +381,9 @@ class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
absl::optional<int> 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<VideoMediaChannel> {
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<webrtc::RtpSource> GetSources(uint32_t ssrc) const override;

View File

@ -676,8 +676,41 @@ struct BandwidthEstimationInfo {
// Maps from payload type to `RtpCodecParameters`.
typedef std::map<int, webrtc::RtpCodecParameters> RtpCodecParametersMap;
// Stats returned from VoiceMediaSendChannel.GetStats()
struct VoiceMediaSendInfo {
VoiceMediaSendInfo();
~VoiceMediaSendInfo();
void Clear() {
senders.clear();
send_codecs.clear();
}
std::vector<VoiceSenderInfo> senders;
RtpCodecParametersMap send_codecs;
};
// Stats returned from VoiceMediaReceiveChannel.GetStats()
struct VoiceMediaReceiveInfo {
VoiceMediaReceiveInfo();
~VoiceMediaReceiveInfo();
void Clear() {
receivers.clear();
receive_codecs.clear();
}
std::vector<VoiceReceiverInfo> 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<VideoSenderInfo> 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<VideoSenderInfo> aggregated_senders;
RtpCodecParametersMap send_codecs;
};
// Stats for a VideoMediaReceiveChannel
struct VideoMediaReceiveInfo {
VideoMediaReceiveInfo();
~VideoMediaReceiveInfo();
void Clear() {
receivers.clear();
receive_codecs.clear();
}
std::vector<VideoReceiverInfo> 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<webrtc::AudioSinkInterface> sink) = 0;
virtual void SetDefaultRawAudioSink(
std::unique_ptr<webrtc::AudioSinkInterface> 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<std::string>& 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<void(const webrtc::RecordableEncodedFrame&)> 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

View File

@ -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;

View File

@ -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<webrtc::AudioSinkInterface> 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_; }

View File

@ -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<uint32_t, WebRtcVideoSendStream*>::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<uint32_t, WebRtcVideoReceiveStream*>::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(

View File

@ -172,7 +172,8 @@ class WebRtcVideoChannel : public VideoMediaChannel,
void SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* 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<VideoCodecSettings> before,
std::vector<VideoCodecSettings> 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_;

View File

@ -563,8 +563,10 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
auto send_channel = std::make_unique<VideoMediaSendChannel>(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<unsigned int>(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<unsigned int>(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<unsigned int>(info.receivers[0].plis_sent));
receive_info.receivers[0].nacks_sent);
EXPECT_EQ(
stats.rtcp_packet_type_counts.pli_packets,
rtc::checked_cast<unsigned int>(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<unsigned int>(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<unsigned int>(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<size_t>(info.receivers[0].payload_bytes_rcvd));
EXPECT_EQ(stats.rtp_stats.packet_counter.packets,
rtc::checked_cast<unsigned int>(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<size_t>(receive_info.receivers[0].payload_bytes_rcvd));
EXPECT_EQ(
stats.rtp_stats.packet_counter.packets,
rtc::checked_cast<unsigned int>(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

View File

@ -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(

View File

@ -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(

View File

@ -753,17 +753,20 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam<bool> {
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<size_t>(arraysize(kSsrcs4)), info.senders.size());
for (const auto& sender : info.senders) {
EXPECT_EQ(static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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);
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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<cricket::VideoMediaChannel*> video_media_channels;
std::vector<cricket::VideoMediaSendChannelInterface*> 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<cricket::VideoMediaChannel*>(
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<MediaChannelStatsGatherer> CreateMediaChannelStatsGatherer(
cricket::MediaChannel* channel) {
std::unique_ptr<ChannelStatsGatherer> CreateChannelStatsGatherer(
cricket::ChannelInterface* channel) {
RTC_DCHECK(channel);
if (channel->media_type() == cricket::MEDIA_TYPE_AUDIO) {
return std::make_unique<VoiceMediaChannelStatsGatherer>(
return std::make_unique<VoiceChannelStatsGatherer>(
channel->AsVoiceChannel());
} else {
RTC_DCHECK_EQ(channel->media_type(), cricket::MEDIA_TYPE_VIDEO);
return std::make_unique<VideoMediaChannelStatsGatherer>(
return std::make_unique<VideoChannelStatsGatherer>(
channel->AsVideoChannel());
}
}
@ -1170,7 +1188,7 @@ void LegacyStatsCollector::ExtractMediaInfo(
const std::map<std::string, std::string>& transport_names_by_mid) {
RTC_DCHECK_RUN_ON(pc_->signaling_thread());
std::vector<std::unique_ptr<MediaChannelStatsGatherer>> gatherers;
std::vector<std::unique_ptr<ChannelStatsGatherer>> gatherers;
auto transceivers = pc_->GetTransceiversInternal();
{
@ -1180,8 +1198,8 @@ void LegacyStatsCollector::ExtractMediaInfo(
if (!channel) {
continue;
}
std::unique_ptr<MediaChannelStatsGatherer> gatherer =
CreateMediaChannelStatsGatherer(channel->media_channel());
std::unique_ptr<ChannelStatsGatherer> 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;

View File

@ -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<cricket::VoiceMediaChannel*, cricket::VoiceMediaInfo> voice_stats;
std::map<cricket::VideoMediaChannel*, cricket::VideoMediaInfo> video_stats;
std::map<cricket::VoiceMediaSendChannelInterface*,
cricket::VoiceMediaSendInfo>
voice_send_stats;
std::map<cricket::VideoMediaSendChannelInterface*,
cricket::VideoMediaSendInfo>
video_send_stats;
std::map<cricket::VoiceMediaReceiveChannelInterface*,
cricket::VoiceMediaReceiveInfo>
voice_receive_stats;
std::map<cricket::VideoMediaReceiveChannelInterface*,
cricket::VideoMediaReceiveInfo>
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<rtc::scoped_refptr<RtpSenderInternal>> senders;

View File

@ -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<cricket::VoiceMediaInfo> stats_;
absl::optional<cricket::VoiceMediaSendInfo> send_stats_;
absl::optional<cricket::VoiceMediaReceiveInfo> 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<cricket::VideoMediaInfo> stats_;
absl::optional<cricket::VideoMediaSendInfo> send_stats_;
absl::optional<cricket::VideoMediaReceiveInfo> receive_stats_;
};
constexpr bool kDefaultRtcpMuxRequired = true;

View File

@ -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));

View File

@ -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,