blob: 881aa7c1586ce6645c794d7ac36b959d33a301cd [file] [log] [blame]
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "video/send_statistics_proxy.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000012
13#include <map>
kwiberg27f982b2016-03-01 11:52:33 -080014#include <memory>
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000015#include <string>
16#include <vector>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "system_wrappers/include/metrics.h"
19#include "system_wrappers/include/metrics_default.h"
asapersson8d75ac72017-09-15 06:41:15 -070020#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "test/gtest.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000022
23namespace webrtc {
asapersson5265fed2016-04-18 02:58:47 -070024namespace {
25const uint32_t kFirstSsrc = 17;
26const uint32_t kSecondSsrc = 42;
27const uint32_t kFirstRtxSsrc = 18;
28const uint32_t kSecondRtxSsrc = 43;
asaperssona6a699a2016-11-25 03:52:46 -080029const uint32_t kFlexFecSsrc = 55;
asapersson320e45a2016-11-29 01:40:35 -080030const int kFpsPeriodicIntervalMs = 2000;
31const int kWidth = 640;
32const int kHeight = 480;
asapersson5265fed2016-04-18 02:58:47 -070033const int kQpIdx0 = 21;
34const int kQpIdx1 = 39;
kthelgason0cd27ba2016-12-19 06:32:16 -080035const CodecSpecificInfo kDefaultCodecInfo = []() {
36 CodecSpecificInfo codec_info;
37 codec_info.codecType = kVideoCodecVP8;
38 codec_info.codecSpecific.VP8.simulcastIdx = 0;
39 return codec_info;
40}();
asapersson5265fed2016-04-18 02:58:47 -070041} // namespace
sprang07fb9be2016-02-24 07:55:00 -080042
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000043class SendStatisticsProxyTest : public ::testing::Test {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000044 public:
asapersson8d75ac72017-09-15 06:41:15 -070045 SendStatisticsProxyTest() : SendStatisticsProxyTest("") {}
46 explicit SendStatisticsProxyTest(const std::string& field_trials)
47 : override_field_trials_(field_trials),
48 fake_clock_(1234),
49 config_(GetTestConfig()),
50 avg_delay_ms_(0),
solenberg4fbae2b2015-08-28 04:07:10 -070051 max_delay_ms_(0) {}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000052 virtual ~SendStatisticsProxyTest() {}
53
54 protected:
55 virtual void SetUp() {
asapersson01d70a32016-05-20 06:29:46 -070056 metrics::Reset();
sprangb4a1ae52015-12-03 08:10:08 -080057 statistics_proxy_.reset(new SendStatisticsProxy(
58 &fake_clock_, GetTestConfig(),
59 VideoEncoderConfig::ContentType::kRealtimeVideo));
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000060 expected_ = VideoSendStream::Stats();
asapersson2e5cfcd2016-08-11 08:41:18 -070061 for (const auto& ssrc : config_.rtp.ssrcs)
62 expected_.substreams[ssrc].is_rtx = false;
63 for (const auto& ssrc : config_.rtp.rtx.ssrcs)
64 expected_.substreams[ssrc].is_rtx = true;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000065 }
66
67 VideoSendStream::Config GetTestConfig() {
solenberg4fbae2b2015-08-28 04:07:10 -070068 VideoSendStream::Config config(nullptr);
sprang07fb9be2016-02-24 07:55:00 -080069 config.rtp.ssrcs.push_back(kFirstSsrc);
70 config.rtp.ssrcs.push_back(kSecondSsrc);
71 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
72 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
brandtrb5f2c3f2016-10-04 23:28:39 -070073 config.rtp.ulpfec.red_payload_type = 17;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000074 return config;
75 }
76
asaperssona6a699a2016-11-25 03:52:46 -080077 VideoSendStream::Config GetTestConfigWithFlexFec() {
78 VideoSendStream::Config config(nullptr);
79 config.rtp.ssrcs.push_back(kFirstSsrc);
80 config.rtp.ssrcs.push_back(kSecondSsrc);
81 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
82 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
brandtr3d200bd2017-01-16 06:59:19 -080083 config.rtp.flexfec.payload_type = 50;
84 config.rtp.flexfec.ssrc = kFlexFecSsrc;
asaperssona6a699a2016-11-25 03:52:46 -080085 return config;
86 }
87
88 VideoSendStream::StreamStats GetStreamStats(uint32_t ssrc) {
89 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
90 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
91 stats.substreams.find(ssrc);
92 EXPECT_NE(it, stats.substreams.end());
93 return it->second;
94 }
95
asapersson66d4b372016-12-19 06:50:53 -080096 void UpdateDataCounters(uint32_t ssrc) {
97 StreamDataCountersCallback* proxy =
98 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
99 StreamDataCounters counters;
100 proxy->DataCountersUpdated(counters, ssrc);
101 }
102
sprang@webrtc.org09315702014-02-07 12:06:29 +0000103 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
sprang@webrtc.org09315702014-02-07 12:06:29 +0000104 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
105 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000106 EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);
Pera48ddb72016-09-29 11:48:50 +0200107 EXPECT_EQ(one.preferred_media_bitrate_bps,
108 other.preferred_media_bitrate_bps);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000109 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000110
111 EXPECT_EQ(one.substreams.size(), other.substreams.size());
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000112 for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
sprang@webrtc.org09315702014-02-07 12:06:29 +0000113 one.substreams.begin();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000114 it != one.substreams.end(); ++it) {
115 std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
116 corresponding_it = other.substreams.find(it->first);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000117 ASSERT_TRUE(corresponding_it != other.substreams.end());
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000118 const VideoSendStream::StreamStats& a = it->second;
119 const VideoSendStream::StreamStats& b = corresponding_it->second;
sprang@webrtc.org09315702014-02-07 12:06:29 +0000120
asapersson2e5cfcd2016-08-11 08:41:18 -0700121 EXPECT_EQ(a.is_rtx, b.is_rtx);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000122 EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
123 EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000124 EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000125 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
126 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000127
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000128 EXPECT_EQ(a.rtp_stats.transmitted.payload_bytes,
129 b.rtp_stats.transmitted.payload_bytes);
130 EXPECT_EQ(a.rtp_stats.transmitted.header_bytes,
131 b.rtp_stats.transmitted.header_bytes);
132 EXPECT_EQ(a.rtp_stats.transmitted.padding_bytes,
133 b.rtp_stats.transmitted.padding_bytes);
134 EXPECT_EQ(a.rtp_stats.transmitted.packets,
135 b.rtp_stats.transmitted.packets);
136 EXPECT_EQ(a.rtp_stats.retransmitted.packets,
137 b.rtp_stats.retransmitted.packets);
138 EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000139
140 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700141 EXPECT_EQ(a.rtcp_stats.packets_lost, b.rtcp_stats.packets_lost);
142 EXPECT_EQ(a.rtcp_stats.extended_highest_sequence_number,
143 b.rtcp_stats.extended_highest_sequence_number);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000144 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
145 }
146 }
147
asapersson8d75ac72017-09-15 06:41:15 -0700148 test::ScopedFieldTrials override_field_trials_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000149 SimulatedClock fake_clock_;
kwiberg27f982b2016-03-01 11:52:33 -0800150 std::unique_ptr<SendStatisticsProxy> statistics_proxy_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000151 VideoSendStream::Config config_;
152 int avg_delay_ms_;
153 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000154 VideoSendStream::Stats expected_;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000155 typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
156 StreamIterator;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000157};
158
159TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
160 RtcpStatisticsCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700161 for (const auto& ssrc : config_.rtp.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000162 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000163
164 // Add statistics with some arbitrary, but unique, numbers.
165 uint32_t offset = ssrc * sizeof(RtcpStatistics);
srte186d9c32017-08-04 05:03:53 -0700166 ssrc_stats.rtcp_stats.packets_lost = offset;
167 ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000168 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
169 ssrc_stats.rtcp_stats.jitter = offset + 3;
170 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
171 }
asapersson35151f32016-05-02 23:44:01 -0700172 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000173 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000174
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000175 // Add statistics with some arbitrary, but unique, numbers.
176 uint32_t offset = ssrc * sizeof(RtcpStatistics);
srte186d9c32017-08-04 05:03:53 -0700177 ssrc_stats.rtcp_stats.packets_lost = offset;
178 ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000179 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
180 ssrc_stats.rtcp_stats.jitter = offset + 3;
181 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
182 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000183 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000184 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000185}
186
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000187TEST_F(SendStatisticsProxyTest, Suspended) {
188 // Verify that the value is false by default.
189 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
190
191 // Verify that we can set it to true.
Peter Boström7083e112015-09-22 16:28:51 +0200192 statistics_proxy_->OnSuspendChange(true);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000193 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
194
195 // Verify that we can set it back to false again.
Peter Boström7083e112015-09-22 16:28:51 +0200196 statistics_proxy_->OnSuspendChange(false);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000197 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
198}
199
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000200TEST_F(SendStatisticsProxyTest, FrameCounts) {
201 FrameCountObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700202 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000203 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000204 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
205 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000206 FrameCounts frame_counts;
207 frame_counts.key_frames = offset;
208 frame_counts.delta_frames = offset + 1;
209 stats.frame_counts = frame_counts;
210 observer->FrameCountUpdated(frame_counts, ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000211 }
asapersson35151f32016-05-02 23:44:01 -0700212 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000213 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000214 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
215 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000216 FrameCounts frame_counts;
217 frame_counts.key_frames = offset;
218 frame_counts.delta_frames = offset + 1;
219 stats.frame_counts = frame_counts;
220 observer->FrameCountUpdated(frame_counts, ssrc);
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000221 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000222
223 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000224 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000225}
226
227TEST_F(SendStatisticsProxyTest, DataCounters) {
228 StreamDataCountersCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700229 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000230 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
231 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000232 size_t offset = ssrc * sizeof(StreamDataCounters);
233 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000234 counters.transmitted.payload_bytes = offset;
235 counters.transmitted.header_bytes = offset + 1;
236 counters.fec.packets = offset_uint32 + 2;
237 counters.transmitted.padding_bytes = offset + 3;
238 counters.retransmitted.packets = offset_uint32 + 4;
239 counters.transmitted.packets = offset_uint32 + 5;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000240 callback->DataCountersUpdated(counters, ssrc);
241 }
asapersson35151f32016-05-02 23:44:01 -0700242 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000243 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
244 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000245 size_t offset = ssrc * sizeof(StreamDataCounters);
246 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000247 counters.transmitted.payload_bytes = offset;
248 counters.transmitted.header_bytes = offset + 1;
249 counters.fec.packets = offset_uint32 + 2;
250 counters.transmitted.padding_bytes = offset + 3;
251 counters.retransmitted.packets = offset_uint32 + 4;
252 counters.transmitted.packets = offset_uint32 + 5;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000253 callback->DataCountersUpdated(counters, ssrc);
254 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000255
256 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000257 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000258}
259
260TEST_F(SendStatisticsProxyTest, Bitrate) {
261 BitrateStatisticsObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700262 for (const auto& ssrc : config_.rtp.ssrcs) {
sprangcd349d92016-07-13 09:11:28 -0700263 uint32_t total;
264 uint32_t retransmit;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000265 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 09:11:28 -0700266 total = ssrc;
267 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000268 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 09:11:28 -0700269 expected_.substreams[ssrc].total_bitrate_bps = total;
270 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000271 }
asapersson35151f32016-05-02 23:44:01 -0700272 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
sprangcd349d92016-07-13 09:11:28 -0700273 uint32_t total;
274 uint32_t retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000275 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 09:11:28 -0700276 total = ssrc;
277 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000278 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 09:11:28 -0700279 expected_.substreams[ssrc].total_bitrate_bps = total;
280 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000281 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000282
283 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000284 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000285}
286
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000287TEST_F(SendStatisticsProxyTest, SendSideDelay) {
288 SendSideDelayObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700289 for (const auto& ssrc : config_.rtp.ssrcs) {
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000290 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
291 // stream.
292 int avg_delay_ms = ssrc;
293 int max_delay_ms = ssrc + 1;
294 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
295 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
296 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
297 }
asapersson35151f32016-05-02 23:44:01 -0700298 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000299 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
300 // stream.
301 int avg_delay_ms = ssrc;
302 int max_delay_ms = ssrc + 1;
303 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
304 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
305 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
306 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000307 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000308 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000309}
310
Peter Boströme4499152016-02-05 11:13:28 +0100311TEST_F(SendStatisticsProxyTest, OnEncodedFrameTimeMeasured) {
asapersson1aa420b2015-12-07 03:12:22 -0800312 const int kEncodeTimeMs = 11;
Peter Boströme4499152016-02-05 11:13:28 +0100313 CpuOveruseMetrics metrics;
314 metrics.encode_usage_percent = 80;
315 statistics_proxy_->OnEncodedFrameTimeMeasured(kEncodeTimeMs, metrics);
asapersson1aa420b2015-12-07 03:12:22 -0800316
317 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
318 EXPECT_EQ(kEncodeTimeMs, stats.avg_encode_time_ms);
Peter Boströme4499152016-02-05 11:13:28 +0100319 EXPECT_EQ(metrics.encode_usage_percent, stats.encode_usage_percent);
asapersson1aa420b2015-12-07 03:12:22 -0800320}
321
Pera48ddb72016-09-29 11:48:50 +0200322TEST_F(SendStatisticsProxyTest, OnEncoderReconfiguredChangePreferredBitrate) {
323 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
324 EXPECT_EQ(0, stats.preferred_media_bitrate_bps);
325 const int kPreferredMediaBitrateBps = 50;
326
327 VideoEncoderConfig config;
328 statistics_proxy_->OnEncoderReconfigured(config, kPreferredMediaBitrateBps);
329 stats = statistics_proxy_->GetStats();
330 EXPECT_EQ(kPreferredMediaBitrateBps, stats.preferred_media_bitrate_bps);
331}
332
sakal43536c32016-10-24 01:46:43 -0700333TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesFramesEncoded) {
334 EncodedImage encoded_image;
335 CodecSpecificInfo codec_info;
336 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_encoded);
337 for (uint32_t i = 1; i <= 3; ++i) {
338 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
339 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded);
340 }
341}
342
sakal87da4042016-10-31 06:53:47 -0700343TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesQpSum) {
344 EncodedImage encoded_image;
345 CodecSpecificInfo codec_info;
346 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
347 encoded_image.qp_ = 3;
348 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
349 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
350 encoded_image.qp_ = 127;
351 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
352 EXPECT_EQ(rtc::Optional<uint64_t>(130u),
353 statistics_proxy_->GetStats().qp_sum);
354}
355
356TEST_F(SendStatisticsProxyTest, OnSendEncodedImageWithoutQpQpSumWontExist) {
357 EncodedImage encoded_image;
358 CodecSpecificInfo codec_info;
359 encoded_image.qp_ = -1;
360 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
361 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
362 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
363}
364
asapersson09f05612017-05-15 23:40:18 -0700365TEST_F(SendStatisticsProxyTest, GetCpuAdaptationStats) {
mflodmancc3d4422017-08-03 08:27:51 -0700366 VideoStreamEncoder::AdaptCounts cpu_counts;
367 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700368 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson36e9eb42017-03-31 05:29:12 -0700369 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700370 cpu_counts.fps = 1;
371 cpu_counts.resolution = 0;
372 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
373 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson36e9eb42017-03-31 05:29:12 -0700374 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700375 cpu_counts.fps = 0;
376 cpu_counts.resolution = 1;
377 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
378 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson6eca98b2017-04-04 23:40:50 -0700379 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700380 cpu_counts.fps = 1;
381 cpu_counts.resolution = -1;
382 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
383 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700384 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700385 cpu_counts.fps = -1;
386 cpu_counts.resolution = -1;
387 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
388 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
389 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
390}
391
392TEST_F(SendStatisticsProxyTest, GetQualityAdaptationStats) {
mflodmancc3d4422017-08-03 08:27:51 -0700393 VideoStreamEncoder::AdaptCounts cpu_counts;
394 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700395 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
396 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
397 quality_counts.fps = 1;
398 quality_counts.resolution = 0;
399 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
400 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
401 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
402 quality_counts.fps = 0;
403 quality_counts.resolution = 1;
404 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
405 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
406 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
407 quality_counts.fps = 1;
408 quality_counts.resolution = -1;
409 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
410 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
411 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
412 quality_counts.fps = -1;
413 quality_counts.resolution = -1;
414 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
415 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
416 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
417}
418
419TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
mflodmancc3d4422017-08-03 08:27:51 -0700420 VideoStreamEncoder::AdaptCounts cpu_counts;
421 VideoStreamEncoder::AdaptCounts quality_counts;
asaperssonfab67072017-04-04 05:51:49 -0700422 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
423
asapersson09f05612017-05-15 23:40:18 -0700424 cpu_counts.resolution = 1;
425 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
426 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700427 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
428 EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
429
asapersson09f05612017-05-15 23:40:18 -0700430 cpu_counts.resolution = 2;
431 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
432 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
433 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
asaperssonfab67072017-04-04 05:51:49 -0700434 EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
asapersson09f05612017-05-15 23:40:18 -0700435 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
asaperssonfab67072017-04-04 05:51:49 -0700436}
437
asapersson09f05612017-05-15 23:40:18 -0700438TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
mflodmancc3d4422017-08-03 08:27:51 -0700439 VideoStreamEncoder::AdaptCounts cpu_counts;
440 VideoStreamEncoder::AdaptCounts quality_counts;
asaperssonfab67072017-04-04 05:51:49 -0700441 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
442
asapersson09f05612017-05-15 23:40:18 -0700443 quality_counts.fps = 1;
444 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
445 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
446 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
asaperssonfab67072017-04-04 05:51:49 -0700447 EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
448
asapersson09f05612017-05-15 23:40:18 -0700449 quality_counts.fps = 0;
450 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
451 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700452 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700453 EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
454 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
asaperssonfab67072017-04-04 05:51:49 -0700455}
456
asapersson09f05612017-05-15 23:40:18 -0700457TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_AdaptationNotEnabled) {
asapersson0944a802017-04-07 00:57:58 -0700458 // First RTP packet sent.
459 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700460 // Min runtime has passed.
461 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
462 statistics_proxy_.reset();
463 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
464 EXPECT_EQ(0,
465 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
466}
467
468TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_MinRuntimeNotPassed) {
asapersson0944a802017-04-07 00:57:58 -0700469 // First RTP packet sent.
470 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700471 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700472 VideoStreamEncoder::AdaptCounts cpu_counts;
473 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700474 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700475 // Min runtime has not passed.
476 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
477 statistics_proxy_.reset();
478 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
479 EXPECT_EQ(0,
480 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
481}
482
asapersson09f05612017-05-15 23:40:18 -0700483TEST_F(SendStatisticsProxyTest, ZeroAdaptChangesReported) {
asapersson0944a802017-04-07 00:57:58 -0700484 // First RTP packet sent.
485 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700486 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700487 VideoStreamEncoder::AdaptCounts cpu_counts;
488 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700489 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700490 // Min runtime has passed.
491 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
492 statistics_proxy_.reset();
493 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
494 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 0));
asapersson6eca98b2017-04-04 23:40:50 -0700495 EXPECT_EQ(1,
496 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
497 EXPECT_EQ(
498 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 0));
499}
500
501TEST_F(SendStatisticsProxyTest, CpuAdaptChangesReported) {
asapersson0944a802017-04-07 00:57:58 -0700502 // First RTP packet sent.
503 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700504 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700505 VideoStreamEncoder::AdaptCounts cpu_counts;
506 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700507 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700508 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
asapersson09f05612017-05-15 23:40:18 -0700509 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700510 fake_clock_.AdvanceTimeMilliseconds(10000);
511 statistics_proxy_.reset();
512 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
513 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
514}
515
516TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
asapersson0944a802017-04-07 00:57:58 -0700517 // First RTP packet sent.
518 UpdateDataCounters(kFirstSsrc);
519
asapersson09f05612017-05-15 23:40:18 -0700520 // Disable quality adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700521 VideoStreamEncoder::AdaptCounts cpu_counts;
522 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700523 quality_counts.fps = -1;
524 quality_counts.resolution = -1;
525 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700526 fake_clock_.AdvanceTimeMilliseconds(10000);
527
asapersson09f05612017-05-15 23:40:18 -0700528 // Enable quality adaptation.
asapersson0944a802017-04-07 00:57:58 -0700529 // Adapt changes: 2, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700530 quality_counts.fps = 0;
531 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700532 fake_clock_.AdvanceTimeMilliseconds(5000);
asapersson09f05612017-05-15 23:40:18 -0700533 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700534 fake_clock_.AdvanceTimeMilliseconds(9000);
asapersson09f05612017-05-15 23:40:18 -0700535 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700536 fake_clock_.AdvanceTimeMilliseconds(6000);
asapersson09f05612017-05-15 23:40:18 -0700537 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700538
asapersson09f05612017-05-15 23:40:18 -0700539 // Disable quality adaptation.
540 quality_counts.fps = -1;
541 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700542 fake_clock_.AdvanceTimeMilliseconds(30000);
543
asapersson09f05612017-05-15 23:40:18 -0700544 // Enable quality adaptation.
asapersson0944a802017-04-07 00:57:58 -0700545 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700546 quality_counts.resolution = 0;
547 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
548 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700549 fake_clock_.AdvanceTimeMilliseconds(10000);
550
asapersson09f05612017-05-15 23:40:18 -0700551 // Disable quality adaptation.
552 quality_counts.resolution = -1;
553 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700554 fake_clock_.AdvanceTimeMilliseconds(5000);
asapersson09f05612017-05-15 23:40:18 -0700555 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700556 fake_clock_.AdvanceTimeMilliseconds(20000);
557
asapersson0944a802017-04-07 00:57:58 -0700558 // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700559 statistics_proxy_.reset();
560 EXPECT_EQ(1,
561 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
562 EXPECT_EQ(
563 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
564}
565
asapersson0944a802017-04-07 00:57:58 -0700566TEST_F(SendStatisticsProxyTest,
567 AdaptChangesNotReported_ScalingNotEnabledVideoResumed) {
568 // First RTP packet sent.
569 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700570
asapersson0944a802017-04-07 00:57:58 -0700571 // Suspend and resume video.
572 statistics_proxy_->OnSuspendChange(true);
573 fake_clock_.AdvanceTimeMilliseconds(5000);
574 statistics_proxy_->OnSuspendChange(false);
575
576 // Min runtime has passed but scaling not enabled.
577 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
578 statistics_proxy_.reset();
579 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
580 EXPECT_EQ(0,
581 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
582}
583
584TEST_F(SendStatisticsProxyTest, QualityAdaptChangesStatsExcludesSuspendedTime) {
585 // First RTP packet sent.
586 UpdateDataCounters(kFirstSsrc);
587
asapersson09f05612017-05-15 23:40:18 -0700588 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700589 VideoStreamEncoder::AdaptCounts cpu_counts;
590 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson0944a802017-04-07 00:57:58 -0700591 // Adapt changes: 2, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700592 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700593 fake_clock_.AdvanceTimeMilliseconds(20000);
asapersson09f05612017-05-15 23:40:18 -0700594 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
595 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700596
597 // Suspend and resume video.
598 statistics_proxy_->OnSuspendChange(true);
599 fake_clock_.AdvanceTimeMilliseconds(30000);
600 statistics_proxy_->OnSuspendChange(false);
601
602 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700603 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700604 fake_clock_.AdvanceTimeMilliseconds(10000);
605
606 // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
607 statistics_proxy_.reset();
608 EXPECT_EQ(1,
609 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
610 EXPECT_EQ(
611 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
612}
613
614TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
615 // First RTP packet sent.
616 UpdateDataCounters(kFirstSsrc);
617
618 // Video not suspended.
619 statistics_proxy_->OnSuspendChange(false);
620 fake_clock_.AdvanceTimeMilliseconds(30000);
621
asapersson09f05612017-05-15 23:40:18 -0700622 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700623 VideoStreamEncoder::AdaptCounts cpu_counts;
624 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson0944a802017-04-07 00:57:58 -0700625 // Adapt changes: 1, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700626 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700627 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700628 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700629
630 // Video not suspended, stats time already started.
631 statistics_proxy_->OnSuspendChange(false);
632 fake_clock_.AdvanceTimeMilliseconds(10000);
633
asapersson09f05612017-05-15 23:40:18 -0700634 // Disable adaptation.
635 cpu_counts.fps = -1;
636 cpu_counts.resolution = -1;
637 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700638 fake_clock_.AdvanceTimeMilliseconds(30000);
639
640 // Suspend and resume video, stats time not started when scaling not enabled.
641 statistics_proxy_->OnSuspendChange(true);
642 fake_clock_.AdvanceTimeMilliseconds(30000);
643 statistics_proxy_->OnSuspendChange(false);
644 fake_clock_.AdvanceTimeMilliseconds(30000);
645
asapersson09f05612017-05-15 23:40:18 -0700646 // Enable adaptation.
asapersson0944a802017-04-07 00:57:58 -0700647 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700648 cpu_counts.fps = 0;
649 cpu_counts.resolution = 0;
650 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700651 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700652 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700653
654 // Adapt changes: 2, elapsed time: 30 sec => 4 per minute.
655 statistics_proxy_.reset();
656 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
657 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 4));
658}
659
660TEST_F(SendStatisticsProxyTest, AdaptChangesStatsNotStartedIfVideoSuspended) {
661 // First RTP packet sent.
662 UpdateDataCounters(kFirstSsrc);
663
664 // Video suspended.
665 statistics_proxy_->OnSuspendChange(true);
666
asapersson09f05612017-05-15 23:40:18 -0700667 // Enable adaptation, stats time not started when suspended.
mflodmancc3d4422017-08-03 08:27:51 -0700668 VideoStreamEncoder::AdaptCounts cpu_counts;
669 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700670 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700671 fake_clock_.AdvanceTimeMilliseconds(10000);
672
673 // Resume video, stats time started.
674 // Adapt changes: 1, elapsed time: 10 sec.
675 statistics_proxy_->OnSuspendChange(false);
676 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700677 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700678
679 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
680 statistics_proxy_.reset();
681 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
682 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
683}
684
685TEST_F(SendStatisticsProxyTest, AdaptChangesStatsRestartsOnFirstSentPacket) {
asapersson09f05612017-05-15 23:40:18 -0700686 // Send first packet, adaptation enabled.
asapersson6eca98b2017-04-04 23:40:50 -0700687 // Elapsed time before first packet is sent should be excluded.
mflodmancc3d4422017-08-03 08:27:51 -0700688 VideoStreamEncoder::AdaptCounts cpu_counts;
689 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700690 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700691 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson0944a802017-04-07 00:57:58 -0700692 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700693
asapersson0944a802017-04-07 00:57:58 -0700694 // Adapt changes: 1, elapsed time: 10 sec.
asapersson6eca98b2017-04-04 23:40:50 -0700695 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700696 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700697 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700698
asapersson0944a802017-04-07 00:57:58 -0700699 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700700 statistics_proxy_.reset();
701 EXPECT_EQ(1,
702 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
703 EXPECT_EQ(
704 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
705}
706
707TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
asapersson09f05612017-05-15 23:40:18 -0700708 // Enable and disable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700709 VideoStreamEncoder::AdaptCounts cpu_counts;
710 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700711 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700712 fake_clock_.AdvanceTimeMilliseconds(60000);
asapersson09f05612017-05-15 23:40:18 -0700713 cpu_counts.fps = -1;
714 cpu_counts.resolution = -1;
715 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700716
717 // Send first packet, scaling disabled.
718 // Elapsed time before first packet is sent should be excluded.
asapersson0944a802017-04-07 00:57:58 -0700719 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700720 fake_clock_.AdvanceTimeMilliseconds(60000);
721
asapersson09f05612017-05-15 23:40:18 -0700722 // Enable adaptation.
723 cpu_counts.resolution = 0;
724 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700725 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson0944a802017-04-07 00:57:58 -0700726 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700727
asapersson0944a802017-04-07 00:57:58 -0700728 // Adapt changes: 1, elapsed time: 20 sec.
asapersson6eca98b2017-04-04 23:40:50 -0700729 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700730 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700731
asapersson0944a802017-04-07 00:57:58 -0700732 // Adapt changes: 1, elapsed time: 20 sec => 3 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700733 statistics_proxy_.reset();
734 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
735 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 3));
736}
737
738TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
asapersson09f05612017-05-15 23:40:18 -0700739 // First RTP packet sent, cpu adaptation enabled.
asapersson0944a802017-04-07 00:57:58 -0700740 UpdateDataCounters(kFirstSsrc);
mflodmancc3d4422017-08-03 08:27:51 -0700741 VideoStreamEncoder::AdaptCounts cpu_counts;
742 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700743 quality_counts.fps = -1;
744 quality_counts.resolution = -1;
745 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700746
asapersson0944a802017-04-07 00:57:58 -0700747 // Adapt changes: 2, elapsed time: 15 sec => 8 per minute.
asapersson09f05612017-05-15 23:40:18 -0700748 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700749 fake_clock_.AdvanceTimeMilliseconds(6000);
asapersson09f05612017-05-15 23:40:18 -0700750 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700751 fake_clock_.AdvanceTimeMilliseconds(9000);
752
753 // Switch content type, real-time stats should be updated.
754 VideoEncoderConfig config;
755 config.content_type = VideoEncoderConfig::ContentType::kScreen;
756 statistics_proxy_->OnEncoderReconfigured(config, 50);
757 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
758 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 8));
759 EXPECT_EQ(0,
760 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
761
asapersson0944a802017-04-07 00:57:58 -0700762 // First RTP packet sent, scaling enabled.
763 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700764 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700765
asapersson0944a802017-04-07 00:57:58 -0700766 // Adapt changes: 4, elapsed time: 120 sec => 2 per minute.
asapersson09f05612017-05-15 23:40:18 -0700767 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
768 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
769 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
770 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700771 fake_clock_.AdvanceTimeMilliseconds(120000);
772
773 statistics_proxy_.reset();
774 EXPECT_EQ(1, metrics::NumSamples(
775 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu"));
776 EXPECT_EQ(1, metrics::NumEvents(
777 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu", 2));
778 EXPECT_EQ(0, metrics::NumSamples(
779 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Quality"));
780}
781
asapersson59bac1a2016-01-07 23:36:00 -0800782TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
perkj803d97f2016-11-01 11:45:46 -0700783 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson59bac1a2016-01-07 23:36:00 -0800784 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
785
Pera48ddb72016-09-29 11:48:50 +0200786 // No switch, stats should not be updated.
787 VideoEncoderConfig config;
788 config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
789 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 06:29:46 -0700790 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-07 23:36:00 -0800791
792 // Switch to screenshare, real-time stats should be updated.
Pera48ddb72016-09-29 11:48:50 +0200793 config.content_type = VideoEncoderConfig::ContentType::kScreen;
794 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 06:29:46 -0700795 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-07 23:36:00 -0800796}
797
asapersson320e45a2016-11-29 01:40:35 -0800798TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) {
799 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
800 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
perkj803d97f2016-11-01 11:45:46 -0700801
asapersson320e45a2016-11-29 01:40:35 -0800802 statistics_proxy_.reset();
803 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
804 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputWidthInPixels", kWidth));
805 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputHeightInPixels"));
806 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputHeightInPixels", kHeight));
807}
808
809TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) {
Åsa Persson0122e842017-10-16 12:19:23 +0200810 const int64_t kMaxEncodedFrameWindowMs = 800;
811 const int kFps = 20;
812 const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
813 const int kMinSamples = // Sample added when removed from EncodedFrameMap.
814 SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
asapersson320e45a2016-11-29 01:40:35 -0800815 EncodedImage encoded_image;
Åsa Persson0122e842017-10-16 12:19:23 +0200816
817 // Not enough samples, stats should not be updated.
818 for (int i = 0; i < kMinSamples - 1; ++i) {
819 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
820 ++encoded_image._timeStamp;
asapersson320e45a2016-11-29 01:40:35 -0800821 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
822 }
Åsa Persson0122e842017-10-16 12:19:23 +0200823 SetUp(); // Reset stats proxy also causes histograms to be reported.
824 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
825 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
826
827 // Enough samples, max resolution per frame should be reported.
828 encoded_image._timeStamp = 0xfffffff0; // Will wrap.
829 for (int i = 0; i < kMinSamples; ++i) {
830 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
831 ++encoded_image._timeStamp;
832 encoded_image._encodedWidth = kWidth;
833 encoded_image._encodedHeight = kHeight;
834 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
835 encoded_image._encodedWidth = kWidth / 2;
836 encoded_image._encodedHeight = kHeight / 2;
837 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
838 }
839
asapersson320e45a2016-11-29 01:40:35 -0800840 statistics_proxy_.reset();
841 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
842 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentWidthInPixels", kWidth));
843 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
844 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentHeightInPixels", kHeight));
845}
846
847TEST_F(SendStatisticsProxyTest, InputFpsHistogramIsUpdated) {
848 const int kFps = 20;
849 const int kMinPeriodicSamples = 6;
850 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
851 for (int i = 0; i <= frames; ++i) {
852 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
853 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
854 }
855 statistics_proxy_.reset();
856 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
857 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
858}
859
860TEST_F(SendStatisticsProxyTest, SentFpsHistogramIsUpdated) {
861 EncodedImage encoded_image;
862 const int kFps = 20;
863 const int kMinPeriodicSamples = 6;
864 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000 + 1;
Åsa Persson0122e842017-10-16 12:19:23 +0200865 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800866 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
Åsa Persson0122e842017-10-16 12:19:23 +0200867 ++encoded_image._timeStamp;
868 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
869 // Frame with same timestamp should not be counted.
asapersson320e45a2016-11-29 01:40:35 -0800870 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
871 }
872 statistics_proxy_.reset();
873 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
874 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
875}
876
877TEST_F(SendStatisticsProxyTest, InputFpsHistogramExcludesSuspendedTime) {
878 const int kFps = 20;
879 const int kSuspendTimeMs = 10000;
880 const int kMinPeriodicSamples = 6;
881 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
882 for (int i = 0; i < frames; ++i) {
883 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
884 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
885 }
886 // Suspend.
887 statistics_proxy_->OnSuspendChange(true);
888 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
889
890 for (int i = 0; i < frames; ++i) {
891 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
892 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
893 }
894 // Suspended time interval should not affect the framerate.
895 statistics_proxy_.reset();
896 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
897 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
898}
899
900TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
901 EncodedImage encoded_image;
902 const int kFps = 20;
903 const int kSuspendTimeMs = 10000;
904 const int kMinPeriodicSamples = 6;
905 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
Åsa Persson0122e842017-10-16 12:19:23 +0200906 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800907 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
908 encoded_image._timeStamp = i + 1;
909 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
910 }
911 // Suspend.
912 statistics_proxy_->OnSuspendChange(true);
913 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
914
Åsa Persson0122e842017-10-16 12:19:23 +0200915 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800916 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
917 encoded_image._timeStamp = i + 1;
918 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
919 }
920 // Suspended time interval should not affect the framerate.
921 statistics_proxy_.reset();
922 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
923 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
924}
925
asaperssonf4e44af2017-04-19 02:01:06 -0700926TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramNotUpdatedWhenDisabled) {
mflodmancc3d4422017-08-03 08:27:51 -0700927 VideoStreamEncoder::AdaptCounts cpu_counts;
928 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700929 cpu_counts.resolution = -1;
930 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asaperssonf4e44af2017-04-19 02:01:06 -0700931
932 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
933 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
934
935 statistics_proxy_.reset();
936 EXPECT_EQ(0,
937 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
938}
939
940TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramUpdated) {
mflodmancc3d4422017-08-03 08:27:51 -0700941 VideoStreamEncoder::AdaptCounts cpu_counts;
942 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700943 cpu_counts.resolution = 0;
944 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asaperssonf4e44af2017-04-19 02:01:06 -0700945
perkj803d97f2016-11-01 11:45:46 -0700946 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
947 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
948
asapersson09f05612017-05-15 23:40:18 -0700949 cpu_counts.resolution = 1;
950 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
perkj803d97f2016-11-01 11:45:46 -0700951
952 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
953 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
954
955 statistics_proxy_.reset();
956 EXPECT_EQ(1,
957 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
958 EXPECT_EQ(
959 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
960}
961
asapersson4374a092016-07-27 00:39:09 -0700962TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) {
963 const int64_t kTimeSec = 3;
964 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
965 statistics_proxy_.reset();
966 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds"));
967 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds",
968 kTimeSec));
969}
970
971TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) {
972 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
973 statistics_proxy_.reset();
974 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType"));
975}
976
asapersson66d4b372016-12-19 06:50:53 -0800977TEST_F(SendStatisticsProxyTest, PauseEventHistogramIsUpdated) {
978 // First RTP packet sent.
979 UpdateDataCounters(kFirstSsrc);
980
981 // Min runtime has passed.
982 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
983 statistics_proxy_.reset();
984 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
985 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
986}
987
988TEST_F(SendStatisticsProxyTest,
989 PauseEventHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
990 // First RTP packet sent.
991 UpdateDataCounters(kFirstSsrc);
992
993 // Min runtime has not passed.
994 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
995 statistics_proxy_.reset();
996 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
997 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
998}
999
1000TEST_F(SendStatisticsProxyTest,
1001 PauseEventHistogramIsNotUpdatedIfNoMediaIsSent) {
1002 // First RTP packet not sent.
1003 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1004 statistics_proxy_.reset();
1005 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1006}
1007
1008TEST_F(SendStatisticsProxyTest, NoPauseEvent) {
1009 // First RTP packet sent and min runtime passed.
1010 UpdateDataCounters(kFirstSsrc);
1011
1012 // No change. Video: 10000 ms, paused: 0 ms (0%).
1013 statistics_proxy_->OnSetEncoderTargetRate(50000);
1014 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1015 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1016
1017 statistics_proxy_.reset();
1018 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1019 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
1020 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1021 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 0));
1022}
1023
1024TEST_F(SendStatisticsProxyTest, OnePauseEvent) {
1025 // First RTP packet sent and min runtime passed.
1026 UpdateDataCounters(kFirstSsrc);
1027
1028 // One change. Video: 7000 ms, paused: 3000 ms (30%).
1029 statistics_proxy_->OnSetEncoderTargetRate(50000);
1030 fake_clock_.AdvanceTimeMilliseconds(7000);
1031 statistics_proxy_->OnSetEncoderTargetRate(0);
1032 fake_clock_.AdvanceTimeMilliseconds(3000);
1033 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1034
1035 statistics_proxy_.reset();
1036 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1037 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 1));
1038 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1039 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 30));
1040}
1041
1042TEST_F(SendStatisticsProxyTest, TwoPauseEvents) {
1043 // First RTP packet sent.
1044 UpdateDataCounters(kFirstSsrc);
1045
1046 // Two changes. Video: 19000 ms, paused: 1000 ms (5%).
1047 statistics_proxy_->OnSetEncoderTargetRate(0);
1048 fake_clock_.AdvanceTimeMilliseconds(1000);
1049 statistics_proxy_->OnSetEncoderTargetRate(50000); // Starts on bitrate > 0.
1050 fake_clock_.AdvanceTimeMilliseconds(7000);
1051 statistics_proxy_->OnSetEncoderTargetRate(60000);
1052 fake_clock_.AdvanceTimeMilliseconds(3000);
1053 statistics_proxy_->OnSetEncoderTargetRate(0);
1054 fake_clock_.AdvanceTimeMilliseconds(250);
1055 statistics_proxy_->OnSetEncoderTargetRate(0);
1056 fake_clock_.AdvanceTimeMilliseconds(750);
1057 statistics_proxy_->OnSetEncoderTargetRate(60000);
1058 fake_clock_.AdvanceTimeMilliseconds(5000);
1059 statistics_proxy_->OnSetEncoderTargetRate(50000);
1060 fake_clock_.AdvanceTimeMilliseconds(4000);
1061 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1062
1063 statistics_proxy_.reset();
1064 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1065 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 2));
1066 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1067 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 5));
1068}
1069
1070TEST_F(SendStatisticsProxyTest,
1071 PausedTimeHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
1072 // First RTP packet sent.
1073 UpdateDataCounters(kFirstSsrc);
1074 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1075
1076 // Min runtime has not passed.
1077 statistics_proxy_->OnSetEncoderTargetRate(50000);
1078 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
1079 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1080
1081 statistics_proxy_.reset();
1082 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1083}
1084
asapersson118ef002016-03-31 00:00:19 -07001085TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
asapersson118ef002016-03-31 00:00:19 -07001086 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001087 CodecSpecificInfo codec_info;
1088 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 00:00:19 -07001089
perkj803d97f2016-11-01 11:45:46 -07001090 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 05:05:54 -07001091 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 00:00:19 -07001092 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001093 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1094 codec_info.codecSpecific.VP8.simulcastIdx = 1;
asapersson118ef002016-03-31 00:00:19 -07001095 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 05:05:54 -07001096 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 00:00:19 -07001097 }
1098 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001099 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
1100 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0));
1101 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1"));
1102 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1));
asapersson118ef002016-03-31 00:00:19 -07001103}
1104
1105TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
1106 VideoSendStream::Config config(nullptr);
1107 config.rtp.ssrcs.push_back(kFirstSsrc);
1108 statistics_proxy_.reset(new SendStatisticsProxy(
1109 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1110
asapersson118ef002016-03-31 00:00:19 -07001111 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001112 CodecSpecificInfo codec_info;
1113 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 00:00:19 -07001114
perkj803d97f2016-11-01 11:45:46 -07001115 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 05:05:54 -07001116 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 00:00:19 -07001117 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001118 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 00:00:19 -07001119 }
1120 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001121 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8"));
1122 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0));
asapersson118ef002016-03-31 00:00:19 -07001123}
1124
asapersson5265fed2016-04-18 02:58:47 -07001125TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
asapersson5265fed2016-04-18 02:58:47 -07001126 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001127 CodecSpecificInfo codec_info;
1128 codec_info.codecType = kVideoCodecVP9;
1129 codec_info.codecSpecific.VP9.num_spatial_layers = 2;
asapersson5265fed2016-04-18 02:58:47 -07001130
perkj803d97f2016-11-01 11:45:46 -07001131 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 02:58:47 -07001132 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001133 codec_info.codecSpecific.VP9.spatial_idx = 0;
1134 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001135 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 05:05:54 -07001136 codec_info.codecSpecific.VP9.spatial_idx = 1;
1137 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001138 }
1139 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001140 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
1141 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0));
1142 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1"));
1143 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1));
asapersson5265fed2016-04-18 02:58:47 -07001144}
1145
1146TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
1147 VideoSendStream::Config config(nullptr);
1148 config.rtp.ssrcs.push_back(kFirstSsrc);
1149 statistics_proxy_.reset(new SendStatisticsProxy(
1150 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1151
asapersson5265fed2016-04-18 02:58:47 -07001152 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001153 CodecSpecificInfo codec_info;
1154 codec_info.codecType = kVideoCodecVP9;
1155 codec_info.codecSpecific.VP9.num_spatial_layers = 1;
asapersson5265fed2016-04-18 02:58:47 -07001156
perkj803d97f2016-11-01 11:45:46 -07001157 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 02:58:47 -07001158 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001159 codec_info.codecSpecific.VP9.spatial_idx = 0;
1160 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001161 }
1162 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001163 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9"));
1164 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0));
asapersson5265fed2016-04-18 02:58:47 -07001165}
1166
asapersson827cab32016-11-02 09:08:47 -07001167TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_H264) {
1168 EncodedImage encoded_image;
1169 CodecSpecificInfo codec_info;
1170 codec_info.codecType = kVideoCodecH264;
1171
1172 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1173 encoded_image.qp_ = kQpIdx0;
1174 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1175 }
1176 statistics_proxy_.reset();
1177 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.H264"));
1178 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.H264", kQpIdx0));
1179}
1180
asapersson4ee70462016-10-31 04:05:12 -07001181TEST_F(SendStatisticsProxyTest,
1182 BandwidthLimitedHistogramsNotUpdatedWhenDisabled) {
1183 EncodedImage encoded_image;
1184 // encoded_image.adapt_reason_.bw_resolutions_disabled by default: -1
perkj803d97f2016-11-01 11:45:46 -07001185 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001186 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1187
1188 // Histograms are updated when the statistics_proxy_ is deleted.
1189 statistics_proxy_.reset();
1190 EXPECT_EQ(0, metrics::NumSamples(
1191 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1192 EXPECT_EQ(0, metrics::NumSamples(
1193 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1194}
1195
1196TEST_F(SendStatisticsProxyTest,
1197 BandwidthLimitedHistogramsUpdatedWhenEnabled_NoResolutionDisabled) {
1198 const int kResolutionsDisabled = 0;
1199 EncodedImage encoded_image;
1200 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 11:45:46 -07001201 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001202 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1203
1204 // Histograms are updated when the statistics_proxy_ is deleted.
1205 statistics_proxy_.reset();
1206 EXPECT_EQ(1, metrics::NumSamples(
1207 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1208 EXPECT_EQ(1, metrics::NumEvents(
1209 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 0));
1210 // No resolution disabled.
1211 EXPECT_EQ(0, metrics::NumSamples(
1212 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1213}
1214
1215TEST_F(SendStatisticsProxyTest,
1216 BandwidthLimitedHistogramsUpdatedWhenEnabled_OneResolutionDisabled) {
1217 const int kResolutionsDisabled = 1;
1218 EncodedImage encoded_image;
1219 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 11:45:46 -07001220 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001221 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1222
1223 // Histograms are updated when the statistics_proxy_ is deleted.
1224 statistics_proxy_.reset();
1225 EXPECT_EQ(1, metrics::NumSamples(
1226 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1227 EXPECT_EQ(1, metrics::NumEvents(
1228 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 100));
1229 // Resolutions disabled.
1230 EXPECT_EQ(1, metrics::NumSamples(
1231 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1232 EXPECT_EQ(
1233 1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionsDisabled",
1234 kResolutionsDisabled));
1235}
1236
1237TEST_F(SendStatisticsProxyTest,
1238 QualityLimitedHistogramsNotUpdatedWhenDisabled) {
mflodmancc3d4422017-08-03 08:27:51 -07001239 VideoStreamEncoder::AdaptCounts cpu_counts;
1240 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001241 quality_counts.resolution = -1;
1242 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001243 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001244 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001245 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001246
1247 // Histograms are updated when the statistics_proxy_ is deleted.
1248 statistics_proxy_.reset();
1249 EXPECT_EQ(
1250 0, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1251 EXPECT_EQ(0, metrics::NumSamples(
1252 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1253}
1254
1255TEST_F(SendStatisticsProxyTest,
1256 QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale) {
mflodmancc3d4422017-08-03 08:27:51 -07001257 VideoStreamEncoder::AdaptCounts cpu_counts;
1258 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001259 quality_counts.resolution = 0;
1260 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001261 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001262 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001263 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001264
1265 // Histograms are updated when the statistics_proxy_ is deleted.
1266 statistics_proxy_.reset();
1267 EXPECT_EQ(
1268 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1269 EXPECT_EQ(1, metrics::NumEvents(
1270 "WebRTC.Video.QualityLimitedResolutionInPercent", 0));
1271 // No resolution downscale.
1272 EXPECT_EQ(0, metrics::NumSamples(
1273 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1274}
1275
1276TEST_F(SendStatisticsProxyTest,
1277 QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales) {
1278 const int kDownscales = 2;
mflodmancc3d4422017-08-03 08:27:51 -07001279 VideoStreamEncoder::AdaptCounts cpu_counts;
1280 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001281 quality_counts.resolution = kDownscales;
1282 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001283 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001284 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001285 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001286 // Histograms are updated when the statistics_proxy_ is deleted.
1287 statistics_proxy_.reset();
1288 EXPECT_EQ(
1289 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1290 EXPECT_EQ(1, metrics::NumEvents(
1291 "WebRTC.Video.QualityLimitedResolutionInPercent", 100));
1292 // Resolution downscales.
1293 EXPECT_EQ(1, metrics::NumSamples(
1294 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1295 EXPECT_EQ(
1296 1, metrics::NumEvents("WebRTC.Video.QualityLimitedResolutionDownscales",
1297 kDownscales));
1298}
1299
1300TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
1301 // Initially false.
1302 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1303 // No resolution scale by default.
1304 EncodedImage encoded_image;
1305 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1306 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
kthelgason0cd27ba2016-12-19 06:32:16 -08001307
1308 // Simulcast disabled resolutions
1309 encoded_image.adapt_reason_.bw_resolutions_disabled = 1;
1310 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1311 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
1312
asapersson4ee70462016-10-31 04:05:12 -07001313 encoded_image.adapt_reason_.bw_resolutions_disabled = 0;
asapersson4ee70462016-10-31 04:05:12 -07001314 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1315 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
kthelgason0cd27ba2016-12-19 06:32:16 -08001316
1317 // Resolution scaled due to quality.
mflodmancc3d4422017-08-03 08:27:51 -07001318 VideoStreamEncoder::AdaptCounts cpu_counts;
1319 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001320 quality_counts.resolution = 1;
1321 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001322 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1323 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
1324}
1325
asapersson66d4b372016-12-19 06:50:53 -08001326TEST_F(SendStatisticsProxyTest, GetStatsReportsTargetMediaBitrate) {
1327 // Initially zero.
1328 EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
1329
1330 const int kBitrate = 100000;
1331 statistics_proxy_->OnSetEncoderTargetRate(kBitrate);
1332 EXPECT_EQ(kBitrate, statistics_proxy_->GetStats().target_media_bitrate_bps);
1333
1334 statistics_proxy_->OnSetEncoderTargetRate(0);
1335 EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
1336}
1337
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001338TEST_F(SendStatisticsProxyTest, NoSubstreams) {
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001339 uint32_t excluded_ssrc =
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001340 std::max(
1341 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()),
1342 *std::max_element(config_.rtp.rtx.ssrcs.begin(),
1343 config_.rtp.rtx.ssrcs.end())) +
1344 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001345 // From RtcpStatisticsCallback.
1346 RtcpStatistics rtcp_stats;
1347 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001348 rtcp_callback->StatisticsUpdated(rtcp_stats, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001349
1350 // From BitrateStatisticsObserver.
sprangcd349d92016-07-13 09:11:28 -07001351 uint32_t total = 0;
1352 uint32_t retransmit = 0;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001353 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001354 bitrate_observer->Notify(total, retransmit, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001355
1356 // From FrameCountObserver.
1357 FrameCountObserver* fps_observer = statistics_proxy_.get();
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00001358 FrameCounts frame_counts;
1359 frame_counts.key_frames = 1;
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001360 fps_observer->FrameCountUpdated(frame_counts, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001361
1362 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
1363 EXPECT_TRUE(stats.substreams.empty());
1364}
1365
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001366TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
1367 static const int kEncodedWidth = 123;
1368 static const int kEncodedHeight = 81;
1369 EncodedImage encoded_image;
1370 encoded_image._encodedWidth = kEncodedWidth;
1371 encoded_image._encodedHeight = kEncodedHeight;
1372
kjellander02b3d272016-04-20 05:05:54 -07001373 CodecSpecificInfo codec_info;
1374 codec_info.codecType = kVideoCodecVP8;
1375 codec_info.codecSpecific.VP8.simulcastIdx = 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001376
kjellander02b3d272016-04-20 05:05:54 -07001377 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1378 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1379 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001380
1381 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001382 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1383 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
1384 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
1385 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001386
1387 // Forward almost to timeout, this should not have removed stats.
1388 fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
1389 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001390 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1391 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001392
1393 // Update the first SSRC with bogus RTCP stats to make sure that encoded
1394 // resolution still times out (no global timeout for all stats).
1395 RtcpStatistics rtcp_statistics;
1396 RtcpStatisticsCallback* rtcp_stats = statistics_proxy_.get();
1397 rtcp_stats->StatisticsUpdated(rtcp_statistics, config_.rtp.ssrcs[0]);
1398
1399 // Report stats for second SSRC to make sure it's not outdated along with the
1400 // first SSRC.
kjellander02b3d272016-04-20 05:05:54 -07001401 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1402 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001403
1404 // Forward 1 ms, reach timeout, substream 0 should have no resolution
1405 // reported, but substream 1 should.
1406 fake_clock_.AdvanceTimeMilliseconds(1);
1407 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001408 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].width);
1409 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].height);
1410 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
1411 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001412}
1413
Peter Boström20f3f942015-05-15 11:33:39 +02001414TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
1415 static const int kEncodedWidth = 123;
1416 static const int kEncodedHeight = 81;
1417 EncodedImage encoded_image;
1418 encoded_image._encodedWidth = kEncodedWidth;
1419 encoded_image._encodedHeight = kEncodedHeight;
1420
kjellander02b3d272016-04-20 05:05:54 -07001421 CodecSpecificInfo codec_info;
1422 codec_info.codecType = kVideoCodecVP8;
1423 codec_info.codecSpecific.VP8.simulcastIdx = 0;
Peter Boström20f3f942015-05-15 11:33:39 +02001424
kjellander02b3d272016-04-20 05:05:54 -07001425 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1426 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1427 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
Peter Boström20f3f942015-05-15 11:33:39 +02001428
1429 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
1430 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
1431 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1432 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
1433 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].width);
1434 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].height);
1435}
1436
1437TEST_F(SendStatisticsProxyTest, ClearsBitratesFromInactiveSsrcs) {
sprangcd349d92016-07-13 09:11:28 -07001438 uint32_t bitrate = 42;
Peter Boström20f3f942015-05-15 11:33:39 +02001439 BitrateStatisticsObserver* observer = statistics_proxy_.get();
1440 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[0]);
1441 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[1]);
1442
1443 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
1444
1445 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprangcd349d92016-07-13 09:11:28 -07001446 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 11:33:39 +02001447 stats.substreams[config_.rtp.ssrcs[0]].total_bitrate_bps);
sprangcd349d92016-07-13 09:11:28 -07001448 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 11:33:39 +02001449 stats.substreams[config_.rtp.ssrcs[0]].retransmit_bitrate_bps);
1450 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].total_bitrate_bps);
1451 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].retransmit_bitrate_bps);
1452}
1453
sprang07fb9be2016-02-24 07:55:00 -08001454TEST_F(SendStatisticsProxyTest, ResetsRtcpCountersOnContentChange) {
1455 RtcpPacketTypeCounterObserver* proxy =
1456 static_cast<RtcpPacketTypeCounterObserver*>(statistics_proxy_.get());
1457 RtcpPacketTypeCounter counters;
1458 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
1459 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1460 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1461
1462 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1463
1464 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
1465 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
1466 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
1467 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
1468 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
1469
1470 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1471 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1472
1473 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 11:48:50 +02001474 VideoEncoderConfig config;
1475 config.content_type = VideoEncoderConfig::ContentType::kScreen;
1476 statistics_proxy_->OnEncoderReconfigured(config, 50);
sprang07fb9be2016-02-24 07:55:00 -08001477
asapersson01d70a32016-05-20 06:29:46 -07001478 EXPECT_EQ(1,
1479 metrics::NumSamples("WebRTC.Video.NackPacketsReceivedPerMinute"));
1480 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsReceivedPerMinute"));
1481 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsReceivedPerMinute"));
1482 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001483 "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
1484
1485 const int kRate = 60 * 2; // Packets per minute with two streams.
1486
asapersson01d70a32016-05-20 06:29:46 -07001487 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NackPacketsReceivedPerMinute",
1488 1 * kRate));
1489 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FirPacketsReceivedPerMinute",
1490 2 * kRate));
1491 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PliPacketsReceivedPerMinute",
1492 3 * kRate));
1493 EXPECT_EQ(
1494 1, metrics::NumEvents("WebRTC.Video.UniqueNackRequestsReceivedInPercent",
1495 4 * 100 / 5));
sprang07fb9be2016-02-24 07:55:00 -08001496
1497 // New start time but same counter values.
1498 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1499 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1500
1501 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1502
1503 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
1504 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
1505 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
1506 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
1507 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
1508
1509 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1510 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1511
1512 SetUp(); // Reset stats proxy also causes histograms to be reported.
1513
asapersson01d70a32016-05-20 06:29:46 -07001514 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001515 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 06:29:46 -07001516 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001517 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 06:29:46 -07001518 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001519 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute"));
1520 EXPECT_EQ(
asapersson01d70a32016-05-20 06:29:46 -07001521 1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001522 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent"));
1523
asapersson01d70a32016-05-20 06:29:46 -07001524 EXPECT_EQ(1, metrics::NumEvents(
1525 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute",
1526 1 * kRate));
1527 EXPECT_EQ(1, metrics::NumEvents(
1528 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute",
1529 2 * kRate));
1530 EXPECT_EQ(1, metrics::NumEvents(
1531 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute",
1532 3 * kRate));
1533 EXPECT_EQ(1,
1534 metrics::NumEvents(
1535 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent",
1536 4 * 100 / 5));
sprang07fb9be2016-02-24 07:55:00 -08001537}
1538
asaperssona6a699a2016-11-25 03:52:46 -08001539TEST_F(SendStatisticsProxyTest, GetStatsReportsIsFlexFec) {
1540 statistics_proxy_.reset(
1541 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
1542 VideoEncoderConfig::ContentType::kRealtimeVideo));
1543
1544 StreamDataCountersCallback* proxy =
1545 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1546 StreamDataCounters counters;
1547 proxy->DataCountersUpdated(counters, kFirstSsrc);
1548 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
1549
1550 EXPECT_FALSE(GetStreamStats(kFirstSsrc).is_flexfec);
1551 EXPECT_TRUE(GetStreamStats(kFlexFecSsrc).is_flexfec);
1552}
1553
1554TEST_F(SendStatisticsProxyTest, SendBitratesAreReportedWithFlexFecEnabled) {
1555 statistics_proxy_.reset(
1556 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
1557 VideoEncoderConfig::ContentType::kRealtimeVideo));
1558
1559 StreamDataCountersCallback* proxy =
1560 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
asaperssona6a699a2016-11-25 03:52:46 -08001561 StreamDataCounters counters;
1562 StreamDataCounters rtx_counters;
asaperssona6a699a2016-11-25 03:52:46 -08001563
asapersson93e1e232017-02-06 05:18:35 -08001564 const int kMinRequiredPeriodSamples = 8;
1565 const int kPeriodIntervalMs = 2000;
1566 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1567 counters.transmitted.packets += 20;
1568 counters.transmitted.header_bytes += 500;
1569 counters.transmitted.padding_bytes += 1000;
1570 counters.transmitted.payload_bytes += 2000;
1571 counters.retransmitted.packets += 2;
1572 counters.retransmitted.header_bytes += 25;
1573 counters.retransmitted.padding_bytes += 100;
1574 counters.retransmitted.payload_bytes += 250;
1575 counters.fec = counters.retransmitted;
1576 rtx_counters.transmitted = counters.transmitted;
1577 // Advance one interval and update counters.
1578 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1579 proxy->DataCountersUpdated(counters, kFirstSsrc);
1580 proxy->DataCountersUpdated(counters, kSecondSsrc);
1581 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1582 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1583 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
1584 }
asaperssona6a699a2016-11-25 03:52:46 -08001585
asaperssona6a699a2016-11-25 03:52:46 -08001586 statistics_proxy_.reset();
asapersson93e1e232017-02-06 05:18:35 -08001587 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001588 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001589 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
1590 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1591 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1592 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
1593 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001594 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001595 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
1596 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001597 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001598 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
1599 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1600 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1601 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
1602 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001603 EXPECT_EQ(1,
1604 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
asaperssona6a699a2016-11-25 03:52:46 -08001605 EXPECT_EQ(
asapersson93e1e232017-02-06 05:18:35 -08001606 1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
asaperssona6a699a2016-11-25 03:52:46 -08001607}
1608
Erik Språng22c2b482016-03-01 09:40:42 +01001609TEST_F(SendStatisticsProxyTest, ResetsRtpCountersOnContentChange) {
1610 StreamDataCountersCallback* proxy =
1611 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1612 StreamDataCounters counters;
1613 StreamDataCounters rtx_counters;
1614 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
Erik Språng22c2b482016-03-01 09:40:42 +01001615
asapersson93e1e232017-02-06 05:18:35 -08001616 const int kMinRequiredPeriodSamples = 8;
1617 const int kPeriodIntervalMs = 2000;
1618 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1619 counters.transmitted.packets += 20;
1620 counters.transmitted.header_bytes += 500;
1621 counters.transmitted.padding_bytes += 1000;
1622 counters.transmitted.payload_bytes += 2000;
1623 counters.retransmitted.packets += 2;
1624 counters.retransmitted.header_bytes += 25;
1625 counters.retransmitted.padding_bytes += 100;
1626 counters.retransmitted.payload_bytes += 250;
1627 counters.fec = counters.retransmitted;
1628 rtx_counters.transmitted = counters.transmitted;
1629 // Advance one interval and update counters.
1630 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1631 proxy->DataCountersUpdated(counters, kFirstSsrc);
1632 proxy->DataCountersUpdated(counters, kSecondSsrc);
1633 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1634 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1635 }
Erik Språng22c2b482016-03-01 09:40:42 +01001636
1637 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 11:48:50 +02001638 VideoEncoderConfig config;
1639 config.content_type = VideoEncoderConfig::ContentType::kScreen;
asapersson93e1e232017-02-06 05:18:35 -08001640 statistics_proxy_->OnEncoderReconfigured(config, 50000);
Erik Språng22c2b482016-03-01 09:40:42 +01001641
asapersson93e1e232017-02-06 05:18:35 -08001642 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asapersson01d70a32016-05-20 06:29:46 -07001643 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001644 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
1645 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1646 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1647 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
1648 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asapersson01d70a32016-05-20 06:29:46 -07001649 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001650 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
1651 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asapersson01d70a32016-05-20 06:29:46 -07001652 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001653 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
1654 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1655 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1656 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
1657 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
Erik Språng22c2b482016-03-01 09:40:42 +01001658 EXPECT_EQ(1,
asapersson01d70a32016-05-20 06:29:46 -07001659 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 09:40:42 +01001660 EXPECT_EQ(
asapersson93e1e232017-02-06 05:18:35 -08001661 1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
Erik Språng22c2b482016-03-01 09:40:42 +01001662
asapersson93e1e232017-02-06 05:18:35 -08001663 // New metric counters but same data counters.
Erik Språng22c2b482016-03-01 09:40:42 +01001664 // Double counter values, this should result in the same counts as before but
1665 // with new histogram names.
asapersson93e1e232017-02-06 05:18:35 -08001666 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1667 counters.transmitted.packets += 20;
1668 counters.transmitted.header_bytes += 500;
1669 counters.transmitted.padding_bytes += 1000;
1670 counters.transmitted.payload_bytes += 2000;
1671 counters.retransmitted.packets += 2;
1672 counters.retransmitted.header_bytes += 25;
1673 counters.retransmitted.padding_bytes += 100;
1674 counters.retransmitted.payload_bytes += 250;
1675 counters.fec = counters.retransmitted;
1676 rtx_counters.transmitted = counters.transmitted;
1677 // Advance one interval and update counters.
1678 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1679 proxy->DataCountersUpdated(counters, kFirstSsrc);
1680 proxy->DataCountersUpdated(counters, kSecondSsrc);
1681 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1682 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1683 }
Erik Språng22c2b482016-03-01 09:40:42 +01001684
asapersson93e1e232017-02-06 05:18:35 -08001685 // Reset stats proxy also causes histograms to be reported.
1686 statistics_proxy_.reset();
Erik Språng22c2b482016-03-01 09:40:42 +01001687
asapersson93e1e232017-02-06 05:18:35 -08001688 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asapersson01d70a32016-05-20 06:29:46 -07001689 EXPECT_EQ(1,
1690 metrics::NumSamples("WebRTC.Video.Screenshare.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001691 EXPECT_EQ(
1692 1, metrics::NumEvents("WebRTC.Video.Screenshare.BitrateSentInKbps", 56));
1693 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1694 EXPECT_EQ(
1695 1, metrics::NumSamples("WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
1696 EXPECT_EQ(1, metrics::NumEvents(
1697 "WebRTC.Video.Screenshare.RtxBitrateSentInKbps", 28));
1698 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asapersson01d70a32016-05-20 06:29:46 -07001699 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001700 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
asapersson01d70a32016-05-20 06:29:46 -07001701 EXPECT_EQ(1, metrics::NumEvents(
asapersson93e1e232017-02-06 05:18:35 -08001702 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps", 12));
1703 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asapersson01d70a32016-05-20 06:29:46 -07001704 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001705 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001706 EXPECT_EQ(1, metrics::NumEvents(
1707 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps", 16));
1708 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1709 EXPECT_EQ(
1710 1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
1711 EXPECT_EQ(1, metrics::NumEvents(
1712 "WebRTC.Video.Screenshare.FecBitrateSentInKbps", 3));
1713 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
asapersson01d70a32016-05-20 06:29:46 -07001714 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001715 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
asapersson01d70a32016-05-20 06:29:46 -07001716 EXPECT_EQ(1,
1717 metrics::NumEvents(
asapersson93e1e232017-02-06 05:18:35 -08001718 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps", 3));
1719}
Erik Språng22c2b482016-03-01 09:40:42 +01001720
asapersson93e1e232017-02-06 05:18:35 -08001721TEST_F(SendStatisticsProxyTest, RtxBitrateIsZeroWhenEnabledAndNoRtxDataIsSent) {
1722 StreamDataCountersCallback* proxy =
1723 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1724 StreamDataCounters counters;
1725 StreamDataCounters rtx_counters;
Erik Språng22c2b482016-03-01 09:40:42 +01001726
asapersson93e1e232017-02-06 05:18:35 -08001727 const int kMinRequiredPeriodSamples = 8;
1728 const int kPeriodIntervalMs = 2000;
1729 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1730 counters.transmitted.packets += 20;
1731 counters.transmitted.header_bytes += 500;
1732 counters.transmitted.payload_bytes += 2000;
1733 counters.fec = counters.retransmitted;
1734 // Advance one interval and update counters.
1735 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1736 proxy->DataCountersUpdated(counters, kFirstSsrc);
1737 }
1738
1739 // RTX enabled. No data sent over RTX.
1740 statistics_proxy_.reset();
1741 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1742 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 0));
1743}
1744
1745TEST_F(SendStatisticsProxyTest, RtxBitrateNotReportedWhenNotEnabled) {
1746 VideoSendStream::Config config(nullptr);
1747 config.rtp.ssrcs.push_back(kFirstSsrc); // RTX not configured.
1748 statistics_proxy_.reset(new SendStatisticsProxy(
1749 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1750
1751 StreamDataCountersCallback* proxy =
1752 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1753 StreamDataCounters counters;
1754
1755 const int kMinRequiredPeriodSamples = 8;
1756 const int kPeriodIntervalMs = 2000;
1757 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1758 counters.transmitted.packets += 20;
1759 counters.transmitted.header_bytes += 500;
1760 counters.transmitted.payload_bytes += 2000;
1761 counters.fec = counters.retransmitted;
1762 // Advance one interval and update counters.
1763 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1764 proxy->DataCountersUpdated(counters, kFirstSsrc);
1765 }
1766
1767 // RTX not enabled.
1768 statistics_proxy_.reset();
1769 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1770}
1771
1772TEST_F(SendStatisticsProxyTest, FecBitrateIsZeroWhenEnabledAndNoFecDataIsSent) {
1773 StreamDataCountersCallback* proxy =
1774 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1775 StreamDataCounters counters;
1776 StreamDataCounters rtx_counters;
1777
1778 const int kMinRequiredPeriodSamples = 8;
1779 const int kPeriodIntervalMs = 2000;
1780 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1781 counters.transmitted.packets += 20;
1782 counters.transmitted.header_bytes += 500;
1783 counters.transmitted.payload_bytes += 2000;
1784 // Advance one interval and update counters.
1785 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1786 proxy->DataCountersUpdated(counters, kFirstSsrc);
1787 }
1788
1789 // FEC enabled. No FEC data sent.
1790 statistics_proxy_.reset();
1791 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1792 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 0));
1793}
1794
1795TEST_F(SendStatisticsProxyTest, FecBitrateNotReportedWhenNotEnabled) {
1796 VideoSendStream::Config config(nullptr);
1797 config.rtp.ssrcs.push_back(kFirstSsrc); // FEC not configured.
1798 statistics_proxy_.reset(new SendStatisticsProxy(
1799 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1800
1801 StreamDataCountersCallback* proxy =
1802 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1803 StreamDataCounters counters;
1804
1805 const int kMinRequiredPeriodSamples = 8;
1806 const int kPeriodIntervalMs = 2000;
1807 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1808 counters.transmitted.packets += 20;
1809 counters.transmitted.header_bytes += 500;
1810 counters.transmitted.payload_bytes += 2000;
1811 counters.fec = counters.retransmitted;
1812 // Advance one interval and update counters.
1813 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1814 proxy->DataCountersUpdated(counters, kFirstSsrc);
1815 }
1816
1817 // FEC not enabled.
1818 statistics_proxy_.reset();
1819 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 09:40:42 +01001820}
1821
asapersson8d75ac72017-09-15 06:41:15 -07001822TEST_F(SendStatisticsProxyTest, GetStatsReportsEncoderImplementationName) {
1823 const char* kName = "encoderName";
1824 EncodedImage encoded_image;
1825 CodecSpecificInfo codec_info;
1826 codec_info.codec_name = kName;
1827 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1828 EXPECT_STREQ(
1829 kName, statistics_proxy_->GetStats().encoder_implementation_name.c_str());
1830}
1831
1832class ForcedFallbackTest : public SendStatisticsProxyTest {
1833 public:
1834 explicit ForcedFallbackTest(const std::string& field_trials)
1835 : SendStatisticsProxyTest(field_trials) {
1836 codec_info_.codecType = kVideoCodecVP8;
1837 codec_info_.codecSpecific.VP8.simulcastIdx = 0;
1838 codec_info_.codecSpecific.VP8.temporalIdx = 0;
1839 codec_info_.codec_name = "fake_codec";
Åsa Persson45bbc8a2017-11-13 10:16:47 +01001840 encoded_image_._encodedWidth = kWidth;
1841 encoded_image_._encodedHeight = kHeight;
asapersson8d75ac72017-09-15 06:41:15 -07001842 }
1843
1844 ~ForcedFallbackTest() override {}
1845
1846 protected:
1847 void InsertEncodedFrames(int num_frames, int interval_ms) {
1848 // First frame is not updating stats, insert initial frame.
1849 if (statistics_proxy_->GetStats().frames_encoded == 0) {
1850 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1851 }
1852 for (int i = 0; i < num_frames; ++i) {
1853 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1854 fake_clock_.AdvanceTimeMilliseconds(interval_ms);
1855 }
1856 // Add frame to include last time interval.
1857 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1858 }
1859
1860 EncodedImage encoded_image_;
1861 CodecSpecificInfo codec_info_;
1862 const std::string kPrefix = "WebRTC.Video.Encoder.ForcedSw";
1863 const int kFrameIntervalMs = 1000;
1864 const int kMinFrames = 20; // Min run time 20 sec.
1865};
1866
1867class ForcedFallbackDisabled : public ForcedFallbackTest {
1868 public:
1869 ForcedFallbackDisabled()
Åsa Persson45bbc8a2017-11-13 10:16:47 +01001870 : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder-v2/Disabled/") {}
asapersson8d75ac72017-09-15 06:41:15 -07001871};
1872
1873class ForcedFallbackEnabled : public ForcedFallbackTest {
1874 public:
1875 ForcedFallbackEnabled()
Åsa Persson45bbc8a2017-11-13 10:16:47 +01001876 : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1," +
1877 std::to_string(kWidth * kHeight) + ",3/") {}
asapersson8d75ac72017-09-15 06:41:15 -07001878};
1879
1880TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfMinRunTimeHasNotPassed) {
1881 InsertEncodedFrames(kMinFrames, kFrameIntervalMs - 1);
1882 statistics_proxy_.reset();
1883 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1884 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1885}
1886
1887TEST_F(ForcedFallbackEnabled, StatsUpdated) {
1888 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1889 statistics_proxy_.reset();
1890 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1891 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 0));
1892 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1893 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 0));
1894}
1895
1896TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfNotVp8) {
1897 codec_info_.codecType = kVideoCodecVP9;
1898 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1899 statistics_proxy_.reset();
1900 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1901 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1902}
1903
1904TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForTemporalLayers) {
1905 codec_info_.codecSpecific.VP8.temporalIdx = 1;
1906 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1907 statistics_proxy_.reset();
1908 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1909 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1910}
1911
1912TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForSimulcast) {
1913 codec_info_.codecSpecific.VP8.simulcastIdx = 1;
1914 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1915 statistics_proxy_.reset();
1916 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1917 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1918}
1919
1920TEST_F(ForcedFallbackDisabled, StatsNotUpdatedIfNoFieldTrial) {
1921 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1922 statistics_proxy_.reset();
1923 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1924 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1925}
1926
1927TEST_F(ForcedFallbackEnabled, OneFallbackEvent) {
1928 // One change. Video: 20000 ms, fallback: 5000 ms (25%).
1929 InsertEncodedFrames(15, 1000);
1930 codec_info_.codec_name = "libvpx";
1931 InsertEncodedFrames(5, 1000);
1932
1933 statistics_proxy_.reset();
1934 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1935 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25));
1936 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1937 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3));
1938}
1939
1940TEST_F(ForcedFallbackEnabled, ThreeFallbackEvents) {
1941 codec_info_.codecSpecific.VP8.temporalIdx = kNoTemporalIdx; // Should work.
1942 const int kMaxFrameDiffMs = 2000;
1943
1944 // Three changes. Video: 60000 ms, fallback: 15000 ms (25%).
1945 InsertEncodedFrames(10, 1000);
1946 codec_info_.codec_name = "libvpx";
1947 InsertEncodedFrames(15, 500);
1948 codec_info_.codec_name = "notlibvpx";
1949 InsertEncodedFrames(20, 1000);
1950 InsertEncodedFrames(3, kMaxFrameDiffMs); // Should not be included.
1951 InsertEncodedFrames(10, 1000);
1952 codec_info_.codec_name = "notlibvpx2";
1953 InsertEncodedFrames(10, 500);
1954 codec_info_.codec_name = "libvpx";
1955 InsertEncodedFrames(15, 500);
1956
1957 statistics_proxy_.reset();
1958 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1959 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25));
1960 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1961 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3));
1962}
1963
Åsa Persson45bbc8a2017-11-13 10:16:47 +01001964TEST_F(ForcedFallbackEnabled, NoFallbackIfAboveMaxPixels) {
1965 encoded_image_._encodedWidth = kWidth + 1;
asapersson8d75ac72017-09-15 06:41:15 -07001966 codec_info_.codec_name = "libvpx";
1967 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1968
1969 statistics_proxy_.reset();
1970 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1971 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1972}
1973
Åsa Persson45bbc8a2017-11-13 10:16:47 +01001974TEST_F(ForcedFallbackEnabled, FallbackIfAtMaxPixels) {
1975 encoded_image_._encodedWidth = kWidth;
asapersson8d75ac72017-09-15 06:41:15 -07001976 codec_info_.codec_name = "libvpx";
1977 InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
1978
1979 statistics_proxy_.reset();
1980 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
1981 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
1982}
1983
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001984} // namespace webrtc