blob: 56184b948a5ec3abe86bebdb6a1261725e2073a9 [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;
asapersson8d75ac72017-09-15 06:41:15 -070035const int kMinFirstFallbackIntervalMs = 1500;
kthelgason0cd27ba2016-12-19 06:32:16 -080036const CodecSpecificInfo kDefaultCodecInfo = []() {
37 CodecSpecificInfo codec_info;
38 codec_info.codecType = kVideoCodecVP8;
39 codec_info.codecSpecific.VP8.simulcastIdx = 0;
40 return codec_info;
41}();
asapersson5265fed2016-04-18 02:58:47 -070042} // namespace
sprang07fb9be2016-02-24 07:55:00 -080043
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000044class SendStatisticsProxyTest : public ::testing::Test {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000045 public:
asapersson8d75ac72017-09-15 06:41:15 -070046 SendStatisticsProxyTest() : SendStatisticsProxyTest("") {}
47 explicit SendStatisticsProxyTest(const std::string& field_trials)
48 : override_field_trials_(field_trials),
49 fake_clock_(1234),
50 config_(GetTestConfig()),
51 avg_delay_ms_(0),
solenberg4fbae2b2015-08-28 04:07:10 -070052 max_delay_ms_(0) {}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000053 virtual ~SendStatisticsProxyTest() {}
54
55 protected:
56 virtual void SetUp() {
asapersson01d70a32016-05-20 06:29:46 -070057 metrics::Reset();
sprangb4a1ae52015-12-03 08:10:08 -080058 statistics_proxy_.reset(new SendStatisticsProxy(
59 &fake_clock_, GetTestConfig(),
60 VideoEncoderConfig::ContentType::kRealtimeVideo));
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000061 expected_ = VideoSendStream::Stats();
asapersson2e5cfcd2016-08-11 08:41:18 -070062 for (const auto& ssrc : config_.rtp.ssrcs)
63 expected_.substreams[ssrc].is_rtx = false;
64 for (const auto& ssrc : config_.rtp.rtx.ssrcs)
65 expected_.substreams[ssrc].is_rtx = true;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000066 }
67
68 VideoSendStream::Config GetTestConfig() {
solenberg4fbae2b2015-08-28 04:07:10 -070069 VideoSendStream::Config config(nullptr);
sprang07fb9be2016-02-24 07:55:00 -080070 config.rtp.ssrcs.push_back(kFirstSsrc);
71 config.rtp.ssrcs.push_back(kSecondSsrc);
72 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
73 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
brandtrb5f2c3f2016-10-04 23:28:39 -070074 config.rtp.ulpfec.red_payload_type = 17;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000075 return config;
76 }
77
asaperssona6a699a2016-11-25 03:52:46 -080078 VideoSendStream::Config GetTestConfigWithFlexFec() {
79 VideoSendStream::Config config(nullptr);
80 config.rtp.ssrcs.push_back(kFirstSsrc);
81 config.rtp.ssrcs.push_back(kSecondSsrc);
82 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
83 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
brandtr3d200bd2017-01-16 06:59:19 -080084 config.rtp.flexfec.payload_type = 50;
85 config.rtp.flexfec.ssrc = kFlexFecSsrc;
asaperssona6a699a2016-11-25 03:52:46 -080086 return config;
87 }
88
89 VideoSendStream::StreamStats GetStreamStats(uint32_t ssrc) {
90 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
91 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
92 stats.substreams.find(ssrc);
93 EXPECT_NE(it, stats.substreams.end());
94 return it->second;
95 }
96
asapersson66d4b372016-12-19 06:50:53 -080097 void UpdateDataCounters(uint32_t ssrc) {
98 StreamDataCountersCallback* proxy =
99 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
100 StreamDataCounters counters;
101 proxy->DataCountersUpdated(counters, ssrc);
102 }
103
sprang@webrtc.org09315702014-02-07 12:06:29 +0000104 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
sprang@webrtc.org09315702014-02-07 12:06:29 +0000105 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
106 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000107 EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);
Pera48ddb72016-09-29 11:48:50 +0200108 EXPECT_EQ(one.preferred_media_bitrate_bps,
109 other.preferred_media_bitrate_bps);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000110 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000111
112 EXPECT_EQ(one.substreams.size(), other.substreams.size());
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000113 for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
sprang@webrtc.org09315702014-02-07 12:06:29 +0000114 one.substreams.begin();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000115 it != one.substreams.end(); ++it) {
116 std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
117 corresponding_it = other.substreams.find(it->first);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000118 ASSERT_TRUE(corresponding_it != other.substreams.end());
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000119 const VideoSendStream::StreamStats& a = it->second;
120 const VideoSendStream::StreamStats& b = corresponding_it->second;
sprang@webrtc.org09315702014-02-07 12:06:29 +0000121
asapersson2e5cfcd2016-08-11 08:41:18 -0700122 EXPECT_EQ(a.is_rtx, b.is_rtx);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000123 EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
124 EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000125 EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000126 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
127 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000128
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000129 EXPECT_EQ(a.rtp_stats.transmitted.payload_bytes,
130 b.rtp_stats.transmitted.payload_bytes);
131 EXPECT_EQ(a.rtp_stats.transmitted.header_bytes,
132 b.rtp_stats.transmitted.header_bytes);
133 EXPECT_EQ(a.rtp_stats.transmitted.padding_bytes,
134 b.rtp_stats.transmitted.padding_bytes);
135 EXPECT_EQ(a.rtp_stats.transmitted.packets,
136 b.rtp_stats.transmitted.packets);
137 EXPECT_EQ(a.rtp_stats.retransmitted.packets,
138 b.rtp_stats.retransmitted.packets);
139 EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000140
141 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700142 EXPECT_EQ(a.rtcp_stats.packets_lost, b.rtcp_stats.packets_lost);
143 EXPECT_EQ(a.rtcp_stats.extended_highest_sequence_number,
144 b.rtcp_stats.extended_highest_sequence_number);
sprang@webrtc.org09315702014-02-07 12:06:29 +0000145 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
146 }
147 }
148
asapersson8d75ac72017-09-15 06:41:15 -0700149 test::ScopedFieldTrials override_field_trials_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000150 SimulatedClock fake_clock_;
kwiberg27f982b2016-03-01 11:52:33 -0800151 std::unique_ptr<SendStatisticsProxy> statistics_proxy_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000152 VideoSendStream::Config config_;
153 int avg_delay_ms_;
154 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000155 VideoSendStream::Stats expected_;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000156 typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
157 StreamIterator;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000158};
159
160TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
161 RtcpStatisticsCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700162 for (const auto& ssrc : config_.rtp.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000163 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000164
165 // Add statistics with some arbitrary, but unique, numbers.
166 uint32_t offset = ssrc * sizeof(RtcpStatistics);
srte186d9c32017-08-04 05:03:53 -0700167 ssrc_stats.rtcp_stats.packets_lost = offset;
168 ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000169 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
170 ssrc_stats.rtcp_stats.jitter = offset + 3;
171 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
172 }
asapersson35151f32016-05-02 23:44:01 -0700173 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000174 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000175
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000176 // Add statistics with some arbitrary, but unique, numbers.
177 uint32_t offset = ssrc * sizeof(RtcpStatistics);
srte186d9c32017-08-04 05:03:53 -0700178 ssrc_stats.rtcp_stats.packets_lost = offset;
179 ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000180 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
181 ssrc_stats.rtcp_stats.jitter = offset + 3;
182 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
183 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000184 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000185 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000186}
187
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000188TEST_F(SendStatisticsProxyTest, Suspended) {
189 // Verify that the value is false by default.
190 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
191
192 // Verify that we can set it to true.
Peter Boström7083e112015-09-22 16:28:51 +0200193 statistics_proxy_->OnSuspendChange(true);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000194 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
195
196 // Verify that we can set it back to false again.
Peter Boström7083e112015-09-22 16:28:51 +0200197 statistics_proxy_->OnSuspendChange(false);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000198 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
199}
200
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000201TEST_F(SendStatisticsProxyTest, FrameCounts) {
202 FrameCountObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700203 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000204 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000205 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
206 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000207 FrameCounts frame_counts;
208 frame_counts.key_frames = offset;
209 frame_counts.delta_frames = offset + 1;
210 stats.frame_counts = frame_counts;
211 observer->FrameCountUpdated(frame_counts, ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000212 }
asapersson35151f32016-05-02 23:44:01 -0700213 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000214 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000215 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
216 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000217 FrameCounts frame_counts;
218 frame_counts.key_frames = offset;
219 frame_counts.delta_frames = offset + 1;
220 stats.frame_counts = frame_counts;
221 observer->FrameCountUpdated(frame_counts, ssrc);
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000222 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000223
224 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000225 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000226}
227
228TEST_F(SendStatisticsProxyTest, DataCounters) {
229 StreamDataCountersCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700230 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000231 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
232 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000233 size_t offset = ssrc * sizeof(StreamDataCounters);
234 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000235 counters.transmitted.payload_bytes = offset;
236 counters.transmitted.header_bytes = offset + 1;
237 counters.fec.packets = offset_uint32 + 2;
238 counters.transmitted.padding_bytes = offset + 3;
239 counters.retransmitted.packets = offset_uint32 + 4;
240 counters.transmitted.packets = offset_uint32 + 5;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000241 callback->DataCountersUpdated(counters, ssrc);
242 }
asapersson35151f32016-05-02 23:44:01 -0700243 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000244 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
245 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000246 size_t offset = ssrc * sizeof(StreamDataCounters);
247 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000248 counters.transmitted.payload_bytes = offset;
249 counters.transmitted.header_bytes = offset + 1;
250 counters.fec.packets = offset_uint32 + 2;
251 counters.transmitted.padding_bytes = offset + 3;
252 counters.retransmitted.packets = offset_uint32 + 4;
253 counters.transmitted.packets = offset_uint32 + 5;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000254 callback->DataCountersUpdated(counters, ssrc);
255 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000256
257 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000258 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000259}
260
261TEST_F(SendStatisticsProxyTest, Bitrate) {
262 BitrateStatisticsObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700263 for (const auto& ssrc : config_.rtp.ssrcs) {
sprangcd349d92016-07-13 09:11:28 -0700264 uint32_t total;
265 uint32_t retransmit;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000266 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 09:11:28 -0700267 total = ssrc;
268 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000269 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 09:11:28 -0700270 expected_.substreams[ssrc].total_bitrate_bps = total;
271 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000272 }
asapersson35151f32016-05-02 23:44:01 -0700273 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
sprangcd349d92016-07-13 09:11:28 -0700274 uint32_t total;
275 uint32_t retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000276 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 09:11:28 -0700277 total = ssrc;
278 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000279 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 09:11:28 -0700280 expected_.substreams[ssrc].total_bitrate_bps = total;
281 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000282 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000283
284 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000285 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000286}
287
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000288TEST_F(SendStatisticsProxyTest, SendSideDelay) {
289 SendSideDelayObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-02 23:44:01 -0700290 for (const auto& ssrc : config_.rtp.ssrcs) {
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000291 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
292 // stream.
293 int avg_delay_ms = ssrc;
294 int max_delay_ms = ssrc + 1;
295 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
296 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
297 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
298 }
asapersson35151f32016-05-02 23:44:01 -0700299 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000300 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
301 // stream.
302 int avg_delay_ms = ssrc;
303 int max_delay_ms = ssrc + 1;
304 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
305 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
306 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
307 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000308 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000309 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000310}
311
Peter Boströme4499152016-02-05 11:13:28 +0100312TEST_F(SendStatisticsProxyTest, OnEncodedFrameTimeMeasured) {
asapersson1aa420b2015-12-07 03:12:22 -0800313 const int kEncodeTimeMs = 11;
Peter Boströme4499152016-02-05 11:13:28 +0100314 CpuOveruseMetrics metrics;
315 metrics.encode_usage_percent = 80;
316 statistics_proxy_->OnEncodedFrameTimeMeasured(kEncodeTimeMs, metrics);
asapersson1aa420b2015-12-07 03:12:22 -0800317
318 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
319 EXPECT_EQ(kEncodeTimeMs, stats.avg_encode_time_ms);
Peter Boströme4499152016-02-05 11:13:28 +0100320 EXPECT_EQ(metrics.encode_usage_percent, stats.encode_usage_percent);
asapersson1aa420b2015-12-07 03:12:22 -0800321}
322
Pera48ddb72016-09-29 11:48:50 +0200323TEST_F(SendStatisticsProxyTest, OnEncoderReconfiguredChangePreferredBitrate) {
324 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
325 EXPECT_EQ(0, stats.preferred_media_bitrate_bps);
326 const int kPreferredMediaBitrateBps = 50;
327
328 VideoEncoderConfig config;
329 statistics_proxy_->OnEncoderReconfigured(config, kPreferredMediaBitrateBps);
330 stats = statistics_proxy_->GetStats();
331 EXPECT_EQ(kPreferredMediaBitrateBps, stats.preferred_media_bitrate_bps);
332}
333
sakal43536c32016-10-24 01:46:43 -0700334TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesFramesEncoded) {
335 EncodedImage encoded_image;
336 CodecSpecificInfo codec_info;
337 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_encoded);
338 for (uint32_t i = 1; i <= 3; ++i) {
339 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
340 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded);
341 }
342}
343
sakal87da4042016-10-31 06:53:47 -0700344TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesQpSum) {
345 EncodedImage encoded_image;
346 CodecSpecificInfo codec_info;
347 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
348 encoded_image.qp_ = 3;
349 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
350 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
351 encoded_image.qp_ = 127;
352 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
353 EXPECT_EQ(rtc::Optional<uint64_t>(130u),
354 statistics_proxy_->GetStats().qp_sum);
355}
356
357TEST_F(SendStatisticsProxyTest, OnSendEncodedImageWithoutQpQpSumWontExist) {
358 EncodedImage encoded_image;
359 CodecSpecificInfo codec_info;
360 encoded_image.qp_ = -1;
361 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
362 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
363 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
364}
365
asapersson09f05612017-05-15 23:40:18 -0700366TEST_F(SendStatisticsProxyTest, GetCpuAdaptationStats) {
mflodmancc3d4422017-08-03 08:27:51 -0700367 VideoStreamEncoder::AdaptCounts cpu_counts;
368 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700369 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson36e9eb42017-03-31 05:29:12 -0700370 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700371 cpu_counts.fps = 1;
372 cpu_counts.resolution = 0;
373 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
374 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson36e9eb42017-03-31 05:29:12 -0700375 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700376 cpu_counts.fps = 0;
377 cpu_counts.resolution = 1;
378 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
379 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asapersson6eca98b2017-04-04 23:40:50 -0700380 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700381 cpu_counts.fps = 1;
382 cpu_counts.resolution = -1;
383 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
384 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700385 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700386 cpu_counts.fps = -1;
387 cpu_counts.resolution = -1;
388 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
389 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
390 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
391}
392
393TEST_F(SendStatisticsProxyTest, GetQualityAdaptationStats) {
mflodmancc3d4422017-08-03 08:27:51 -0700394 VideoStreamEncoder::AdaptCounts cpu_counts;
395 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700396 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
397 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
398 quality_counts.fps = 1;
399 quality_counts.resolution = 0;
400 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
401 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
402 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
403 quality_counts.fps = 0;
404 quality_counts.resolution = 1;
405 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
406 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
407 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
408 quality_counts.fps = 1;
409 quality_counts.resolution = -1;
410 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
411 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
412 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
413 quality_counts.fps = -1;
414 quality_counts.resolution = -1;
415 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
416 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
417 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
418}
419
420TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
mflodmancc3d4422017-08-03 08:27:51 -0700421 VideoStreamEncoder::AdaptCounts cpu_counts;
422 VideoStreamEncoder::AdaptCounts quality_counts;
asaperssonfab67072017-04-04 05:51:49 -0700423 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
424
asapersson09f05612017-05-15 23:40:18 -0700425 cpu_counts.resolution = 1;
426 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
427 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700428 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
429 EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
430
asapersson09f05612017-05-15 23:40:18 -0700431 cpu_counts.resolution = 2;
432 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
433 EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
434 EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
asaperssonfab67072017-04-04 05:51:49 -0700435 EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
asapersson09f05612017-05-15 23:40:18 -0700436 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
asaperssonfab67072017-04-04 05:51:49 -0700437}
438
asapersson09f05612017-05-15 23:40:18 -0700439TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
mflodmancc3d4422017-08-03 08:27:51 -0700440 VideoStreamEncoder::AdaptCounts cpu_counts;
441 VideoStreamEncoder::AdaptCounts quality_counts;
asaperssonfab67072017-04-04 05:51:49 -0700442 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
443
asapersson09f05612017-05-15 23:40:18 -0700444 quality_counts.fps = 1;
445 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
446 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
447 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
asaperssonfab67072017-04-04 05:51:49 -0700448 EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
449
asapersson09f05612017-05-15 23:40:18 -0700450 quality_counts.fps = 0;
451 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
452 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
asaperssonfab67072017-04-04 05:51:49 -0700453 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
asapersson09f05612017-05-15 23:40:18 -0700454 EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
455 EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
asaperssonfab67072017-04-04 05:51:49 -0700456}
457
asapersson09f05612017-05-15 23:40:18 -0700458TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_AdaptationNotEnabled) {
asapersson0944a802017-04-07 00:57:58 -0700459 // First RTP packet sent.
460 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700461 // Min runtime has passed.
462 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
463 statistics_proxy_.reset();
464 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
465 EXPECT_EQ(0,
466 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
467}
468
469TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_MinRuntimeNotPassed) {
asapersson0944a802017-04-07 00:57:58 -0700470 // First RTP packet sent.
471 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700472 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700473 VideoStreamEncoder::AdaptCounts cpu_counts;
474 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700475 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700476 // Min runtime has not passed.
477 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
478 statistics_proxy_.reset();
479 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
480 EXPECT_EQ(0,
481 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
482}
483
asapersson09f05612017-05-15 23:40:18 -0700484TEST_F(SendStatisticsProxyTest, ZeroAdaptChangesReported) {
asapersson0944a802017-04-07 00:57:58 -0700485 // First RTP packet sent.
486 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700487 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700488 VideoStreamEncoder::AdaptCounts cpu_counts;
489 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700490 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700491 // Min runtime has passed.
492 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
493 statistics_proxy_.reset();
494 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
495 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 0));
asapersson6eca98b2017-04-04 23:40:50 -0700496 EXPECT_EQ(1,
497 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
498 EXPECT_EQ(
499 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 0));
500}
501
502TEST_F(SendStatisticsProxyTest, CpuAdaptChangesReported) {
asapersson0944a802017-04-07 00:57:58 -0700503 // First RTP packet sent.
504 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700505 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700506 VideoStreamEncoder::AdaptCounts cpu_counts;
507 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700508 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700509 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
asapersson09f05612017-05-15 23:40:18 -0700510 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700511 fake_clock_.AdvanceTimeMilliseconds(10000);
512 statistics_proxy_.reset();
513 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
514 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
515}
516
517TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
asapersson0944a802017-04-07 00:57:58 -0700518 // First RTP packet sent.
519 UpdateDataCounters(kFirstSsrc);
520
asapersson09f05612017-05-15 23:40:18 -0700521 // Disable quality adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700522 VideoStreamEncoder::AdaptCounts cpu_counts;
523 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700524 quality_counts.fps = -1;
525 quality_counts.resolution = -1;
526 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700527 fake_clock_.AdvanceTimeMilliseconds(10000);
528
asapersson09f05612017-05-15 23:40:18 -0700529 // Enable quality adaptation.
asapersson0944a802017-04-07 00:57:58 -0700530 // Adapt changes: 2, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700531 quality_counts.fps = 0;
532 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700533 fake_clock_.AdvanceTimeMilliseconds(5000);
asapersson09f05612017-05-15 23:40:18 -0700534 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700535 fake_clock_.AdvanceTimeMilliseconds(9000);
asapersson09f05612017-05-15 23:40:18 -0700536 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700537 fake_clock_.AdvanceTimeMilliseconds(6000);
asapersson09f05612017-05-15 23:40:18 -0700538 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700539
asapersson09f05612017-05-15 23:40:18 -0700540 // Disable quality adaptation.
541 quality_counts.fps = -1;
542 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700543 fake_clock_.AdvanceTimeMilliseconds(30000);
544
asapersson09f05612017-05-15 23:40:18 -0700545 // Enable quality adaptation.
asapersson0944a802017-04-07 00:57:58 -0700546 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700547 quality_counts.resolution = 0;
548 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
549 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700550 fake_clock_.AdvanceTimeMilliseconds(10000);
551
asapersson09f05612017-05-15 23:40:18 -0700552 // Disable quality adaptation.
553 quality_counts.resolution = -1;
554 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700555 fake_clock_.AdvanceTimeMilliseconds(5000);
asapersson09f05612017-05-15 23:40:18 -0700556 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700557 fake_clock_.AdvanceTimeMilliseconds(20000);
558
asapersson0944a802017-04-07 00:57:58 -0700559 // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700560 statistics_proxy_.reset();
561 EXPECT_EQ(1,
562 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
563 EXPECT_EQ(
564 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
565}
566
asapersson0944a802017-04-07 00:57:58 -0700567TEST_F(SendStatisticsProxyTest,
568 AdaptChangesNotReported_ScalingNotEnabledVideoResumed) {
569 // First RTP packet sent.
570 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700571
asapersson0944a802017-04-07 00:57:58 -0700572 // Suspend and resume video.
573 statistics_proxy_->OnSuspendChange(true);
574 fake_clock_.AdvanceTimeMilliseconds(5000);
575 statistics_proxy_->OnSuspendChange(false);
576
577 // Min runtime has passed but scaling not enabled.
578 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
579 statistics_proxy_.reset();
580 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
581 EXPECT_EQ(0,
582 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
583}
584
585TEST_F(SendStatisticsProxyTest, QualityAdaptChangesStatsExcludesSuspendedTime) {
586 // First RTP packet sent.
587 UpdateDataCounters(kFirstSsrc);
588
asapersson09f05612017-05-15 23:40:18 -0700589 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700590 VideoStreamEncoder::AdaptCounts cpu_counts;
591 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson0944a802017-04-07 00:57:58 -0700592 // Adapt changes: 2, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700593 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700594 fake_clock_.AdvanceTimeMilliseconds(20000);
asapersson09f05612017-05-15 23:40:18 -0700595 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
596 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700597
598 // Suspend and resume video.
599 statistics_proxy_->OnSuspendChange(true);
600 fake_clock_.AdvanceTimeMilliseconds(30000);
601 statistics_proxy_->OnSuspendChange(false);
602
603 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700604 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700605 fake_clock_.AdvanceTimeMilliseconds(10000);
606
607 // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
608 statistics_proxy_.reset();
609 EXPECT_EQ(1,
610 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
611 EXPECT_EQ(
612 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
613}
614
615TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
616 // First RTP packet sent.
617 UpdateDataCounters(kFirstSsrc);
618
619 // Video not suspended.
620 statistics_proxy_->OnSuspendChange(false);
621 fake_clock_.AdvanceTimeMilliseconds(30000);
622
asapersson09f05612017-05-15 23:40:18 -0700623 // Enable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700624 VideoStreamEncoder::AdaptCounts cpu_counts;
625 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson0944a802017-04-07 00:57:58 -0700626 // Adapt changes: 1, elapsed time: 20 sec.
asapersson09f05612017-05-15 23:40:18 -0700627 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700628 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700629 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700630
631 // Video not suspended, stats time already started.
632 statistics_proxy_->OnSuspendChange(false);
633 fake_clock_.AdvanceTimeMilliseconds(10000);
634
asapersson09f05612017-05-15 23:40:18 -0700635 // Disable adaptation.
636 cpu_counts.fps = -1;
637 cpu_counts.resolution = -1;
638 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700639 fake_clock_.AdvanceTimeMilliseconds(30000);
640
641 // Suspend and resume video, stats time not started when scaling not enabled.
642 statistics_proxy_->OnSuspendChange(true);
643 fake_clock_.AdvanceTimeMilliseconds(30000);
644 statistics_proxy_->OnSuspendChange(false);
645 fake_clock_.AdvanceTimeMilliseconds(30000);
646
asapersson09f05612017-05-15 23:40:18 -0700647 // Enable adaptation.
asapersson0944a802017-04-07 00:57:58 -0700648 // Adapt changes: 1, elapsed time: 10 sec.
asapersson09f05612017-05-15 23:40:18 -0700649 cpu_counts.fps = 0;
650 cpu_counts.resolution = 0;
651 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700652 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700653 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700654
655 // Adapt changes: 2, elapsed time: 30 sec => 4 per minute.
656 statistics_proxy_.reset();
657 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
658 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 4));
659}
660
661TEST_F(SendStatisticsProxyTest, AdaptChangesStatsNotStartedIfVideoSuspended) {
662 // First RTP packet sent.
663 UpdateDataCounters(kFirstSsrc);
664
665 // Video suspended.
666 statistics_proxy_->OnSuspendChange(true);
667
asapersson09f05612017-05-15 23:40:18 -0700668 // Enable adaptation, stats time not started when suspended.
mflodmancc3d4422017-08-03 08:27:51 -0700669 VideoStreamEncoder::AdaptCounts cpu_counts;
670 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700671 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700672 fake_clock_.AdvanceTimeMilliseconds(10000);
673
674 // Resume video, stats time started.
675 // Adapt changes: 1, elapsed time: 10 sec.
676 statistics_proxy_->OnSuspendChange(false);
677 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700678 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700679
680 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
681 statistics_proxy_.reset();
682 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
683 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
684}
685
686TEST_F(SendStatisticsProxyTest, AdaptChangesStatsRestartsOnFirstSentPacket) {
asapersson09f05612017-05-15 23:40:18 -0700687 // Send first packet, adaptation enabled.
asapersson6eca98b2017-04-04 23:40:50 -0700688 // Elapsed time before first packet is sent should be excluded.
mflodmancc3d4422017-08-03 08:27:51 -0700689 VideoStreamEncoder::AdaptCounts cpu_counts;
690 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700691 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700692 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson0944a802017-04-07 00:57:58 -0700693 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700694
asapersson0944a802017-04-07 00:57:58 -0700695 // Adapt changes: 1, elapsed time: 10 sec.
asapersson6eca98b2017-04-04 23:40:50 -0700696 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700697 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson0944a802017-04-07 00:57:58 -0700698 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700699
asapersson0944a802017-04-07 00:57:58 -0700700 // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700701 statistics_proxy_.reset();
702 EXPECT_EQ(1,
703 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
704 EXPECT_EQ(
705 1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
706}
707
708TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
asapersson09f05612017-05-15 23:40:18 -0700709 // Enable and disable adaptation.
mflodmancc3d4422017-08-03 08:27:51 -0700710 VideoStreamEncoder::AdaptCounts cpu_counts;
711 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700712 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700713 fake_clock_.AdvanceTimeMilliseconds(60000);
asapersson09f05612017-05-15 23:40:18 -0700714 cpu_counts.fps = -1;
715 cpu_counts.resolution = -1;
716 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700717
718 // Send first packet, scaling disabled.
719 // Elapsed time before first packet is sent should be excluded.
asapersson0944a802017-04-07 00:57:58 -0700720 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700721 fake_clock_.AdvanceTimeMilliseconds(60000);
722
asapersson09f05612017-05-15 23:40:18 -0700723 // Enable adaptation.
724 cpu_counts.resolution = 0;
725 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700726 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson0944a802017-04-07 00:57:58 -0700727 UpdateDataCounters(kFirstSsrc);
asapersson6eca98b2017-04-04 23:40:50 -0700728
asapersson0944a802017-04-07 00:57:58 -0700729 // Adapt changes: 1, elapsed time: 20 sec.
asapersson6eca98b2017-04-04 23:40:50 -0700730 fake_clock_.AdvanceTimeMilliseconds(10000);
asapersson09f05612017-05-15 23:40:18 -0700731 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700732
asapersson0944a802017-04-07 00:57:58 -0700733 // Adapt changes: 1, elapsed time: 20 sec => 3 per minute.
asapersson6eca98b2017-04-04 23:40:50 -0700734 statistics_proxy_.reset();
735 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
736 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 3));
737}
738
739TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
asapersson09f05612017-05-15 23:40:18 -0700740 // First RTP packet sent, cpu adaptation enabled.
asapersson0944a802017-04-07 00:57:58 -0700741 UpdateDataCounters(kFirstSsrc);
mflodmancc3d4422017-08-03 08:27:51 -0700742 VideoStreamEncoder::AdaptCounts cpu_counts;
743 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700744 quality_counts.fps = -1;
745 quality_counts.resolution = -1;
746 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700747
asapersson0944a802017-04-07 00:57:58 -0700748 // Adapt changes: 2, elapsed time: 15 sec => 8 per minute.
asapersson09f05612017-05-15 23:40:18 -0700749 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700750 fake_clock_.AdvanceTimeMilliseconds(6000);
asapersson09f05612017-05-15 23:40:18 -0700751 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700752 fake_clock_.AdvanceTimeMilliseconds(9000);
753
754 // Switch content type, real-time stats should be updated.
755 VideoEncoderConfig config;
756 config.content_type = VideoEncoderConfig::ContentType::kScreen;
757 statistics_proxy_->OnEncoderReconfigured(config, 50);
758 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
759 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 8));
760 EXPECT_EQ(0,
761 metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
762
asapersson0944a802017-04-07 00:57:58 -0700763 // First RTP packet sent, scaling enabled.
764 UpdateDataCounters(kFirstSsrc);
asapersson09f05612017-05-15 23:40:18 -0700765 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700766
asapersson0944a802017-04-07 00:57:58 -0700767 // Adapt changes: 4, elapsed time: 120 sec => 2 per minute.
asapersson09f05612017-05-15 23:40:18 -0700768 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
769 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
770 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
771 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
asapersson6eca98b2017-04-04 23:40:50 -0700772 fake_clock_.AdvanceTimeMilliseconds(120000);
773
774 statistics_proxy_.reset();
775 EXPECT_EQ(1, metrics::NumSamples(
776 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu"));
777 EXPECT_EQ(1, metrics::NumEvents(
778 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu", 2));
779 EXPECT_EQ(0, metrics::NumSamples(
780 "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Quality"));
781}
782
asapersson59bac1a2016-01-07 23:36:00 -0800783TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
perkj803d97f2016-11-01 11:45:46 -0700784 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson59bac1a2016-01-07 23:36:00 -0800785 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
786
Pera48ddb72016-09-29 11:48:50 +0200787 // No switch, stats should not be updated.
788 VideoEncoderConfig config;
789 config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
790 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 06:29:46 -0700791 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-07 23:36:00 -0800792
793 // Switch to screenshare, real-time stats should be updated.
Pera48ddb72016-09-29 11:48:50 +0200794 config.content_type = VideoEncoderConfig::ContentType::kScreen;
795 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 06:29:46 -0700796 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-07 23:36:00 -0800797}
798
asapersson320e45a2016-11-29 01:40:35 -0800799TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) {
800 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
801 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
perkj803d97f2016-11-01 11:45:46 -0700802
asapersson320e45a2016-11-29 01:40:35 -0800803 statistics_proxy_.reset();
804 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
805 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputWidthInPixels", kWidth));
806 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputHeightInPixels"));
807 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputHeightInPixels", kHeight));
808}
809
810TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) {
Ã…sa Persson0122e842017-10-16 12:19:23 +0200811 const int64_t kMaxEncodedFrameWindowMs = 800;
812 const int kFps = 20;
813 const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
814 const int kMinSamples = // Sample added when removed from EncodedFrameMap.
815 SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
asapersson320e45a2016-11-29 01:40:35 -0800816 EncodedImage encoded_image;
Ã…sa Persson0122e842017-10-16 12:19:23 +0200817
818 // Not enough samples, stats should not be updated.
819 for (int i = 0; i < kMinSamples - 1; ++i) {
820 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
821 ++encoded_image._timeStamp;
asapersson320e45a2016-11-29 01:40:35 -0800822 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
823 }
Ã…sa Persson0122e842017-10-16 12:19:23 +0200824 SetUp(); // Reset stats proxy also causes histograms to be reported.
825 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
826 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
827
828 // Enough samples, max resolution per frame should be reported.
829 encoded_image._timeStamp = 0xfffffff0; // Will wrap.
830 for (int i = 0; i < kMinSamples; ++i) {
831 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
832 ++encoded_image._timeStamp;
833 encoded_image._encodedWidth = kWidth;
834 encoded_image._encodedHeight = kHeight;
835 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
836 encoded_image._encodedWidth = kWidth / 2;
837 encoded_image._encodedHeight = kHeight / 2;
838 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
839 }
840
asapersson320e45a2016-11-29 01:40:35 -0800841 statistics_proxy_.reset();
842 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
843 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentWidthInPixels", kWidth));
844 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
845 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentHeightInPixels", kHeight));
846}
847
848TEST_F(SendStatisticsProxyTest, InputFpsHistogramIsUpdated) {
849 const int kFps = 20;
850 const int kMinPeriodicSamples = 6;
851 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
852 for (int i = 0; i <= frames; ++i) {
853 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
854 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
855 }
856 statistics_proxy_.reset();
857 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
858 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
859}
860
861TEST_F(SendStatisticsProxyTest, SentFpsHistogramIsUpdated) {
862 EncodedImage encoded_image;
863 const int kFps = 20;
864 const int kMinPeriodicSamples = 6;
865 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000 + 1;
Ã…sa Persson0122e842017-10-16 12:19:23 +0200866 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800867 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
Ã…sa Persson0122e842017-10-16 12:19:23 +0200868 ++encoded_image._timeStamp;
869 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
870 // Frame with same timestamp should not be counted.
asapersson320e45a2016-11-29 01:40:35 -0800871 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
872 }
873 statistics_proxy_.reset();
874 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
875 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
876}
877
878TEST_F(SendStatisticsProxyTest, InputFpsHistogramExcludesSuspendedTime) {
879 const int kFps = 20;
880 const int kSuspendTimeMs = 10000;
881 const int kMinPeriodicSamples = 6;
882 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
883 for (int i = 0; i < frames; ++i) {
884 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
885 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
886 }
887 // Suspend.
888 statistics_proxy_->OnSuspendChange(true);
889 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
890
891 for (int i = 0; i < frames; ++i) {
892 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
893 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
894 }
895 // Suspended time interval should not affect the framerate.
896 statistics_proxy_.reset();
897 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
898 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
899}
900
901TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
902 EncodedImage encoded_image;
903 const int kFps = 20;
904 const int kSuspendTimeMs = 10000;
905 const int kMinPeriodicSamples = 6;
906 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
Ã…sa Persson0122e842017-10-16 12:19:23 +0200907 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800908 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
909 encoded_image._timeStamp = i + 1;
910 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
911 }
912 // Suspend.
913 statistics_proxy_->OnSuspendChange(true);
914 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
915
Ã…sa Persson0122e842017-10-16 12:19:23 +0200916 for (int i = 0; i < frames; ++i) {
asapersson320e45a2016-11-29 01:40:35 -0800917 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
918 encoded_image._timeStamp = i + 1;
919 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
920 }
921 // Suspended time interval should not affect the framerate.
922 statistics_proxy_.reset();
923 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
924 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
925}
926
asaperssonf4e44af2017-04-19 02:01:06 -0700927TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramNotUpdatedWhenDisabled) {
mflodmancc3d4422017-08-03 08:27:51 -0700928 VideoStreamEncoder::AdaptCounts cpu_counts;
929 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700930 cpu_counts.resolution = -1;
931 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asaperssonf4e44af2017-04-19 02:01:06 -0700932
933 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
934 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
935
936 statistics_proxy_.reset();
937 EXPECT_EQ(0,
938 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
939}
940
941TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramUpdated) {
mflodmancc3d4422017-08-03 08:27:51 -0700942 VideoStreamEncoder::AdaptCounts cpu_counts;
943 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -0700944 cpu_counts.resolution = 0;
945 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asaperssonf4e44af2017-04-19 02:01:06 -0700946
perkj803d97f2016-11-01 11:45:46 -0700947 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
948 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
949
asapersson09f05612017-05-15 23:40:18 -0700950 cpu_counts.resolution = 1;
951 statistics_proxy_->OnCpuAdaptationChanged(cpu_counts, quality_counts);
perkj803d97f2016-11-01 11:45:46 -0700952
953 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
954 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
955
956 statistics_proxy_.reset();
957 EXPECT_EQ(1,
958 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
959 EXPECT_EQ(
960 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
961}
962
asapersson4374a092016-07-27 00:39:09 -0700963TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) {
964 const int64_t kTimeSec = 3;
965 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
966 statistics_proxy_.reset();
967 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds"));
968 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds",
969 kTimeSec));
970}
971
972TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) {
973 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
974 statistics_proxy_.reset();
975 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType"));
976}
977
asapersson66d4b372016-12-19 06:50:53 -0800978TEST_F(SendStatisticsProxyTest, PauseEventHistogramIsUpdated) {
979 // First RTP packet sent.
980 UpdateDataCounters(kFirstSsrc);
981
982 // Min runtime has passed.
983 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
984 statistics_proxy_.reset();
985 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
986 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
987}
988
989TEST_F(SendStatisticsProxyTest,
990 PauseEventHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
991 // First RTP packet sent.
992 UpdateDataCounters(kFirstSsrc);
993
994 // Min runtime has not passed.
995 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
996 statistics_proxy_.reset();
997 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
998 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
999}
1000
1001TEST_F(SendStatisticsProxyTest,
1002 PauseEventHistogramIsNotUpdatedIfNoMediaIsSent) {
1003 // First RTP packet not sent.
1004 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1005 statistics_proxy_.reset();
1006 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1007}
1008
1009TEST_F(SendStatisticsProxyTest, NoPauseEvent) {
1010 // First RTP packet sent and min runtime passed.
1011 UpdateDataCounters(kFirstSsrc);
1012
1013 // No change. Video: 10000 ms, paused: 0 ms (0%).
1014 statistics_proxy_->OnSetEncoderTargetRate(50000);
1015 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1016 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1017
1018 statistics_proxy_.reset();
1019 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1020 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
1021 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1022 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 0));
1023}
1024
1025TEST_F(SendStatisticsProxyTest, OnePauseEvent) {
1026 // First RTP packet sent and min runtime passed.
1027 UpdateDataCounters(kFirstSsrc);
1028
1029 // One change. Video: 7000 ms, paused: 3000 ms (30%).
1030 statistics_proxy_->OnSetEncoderTargetRate(50000);
1031 fake_clock_.AdvanceTimeMilliseconds(7000);
1032 statistics_proxy_->OnSetEncoderTargetRate(0);
1033 fake_clock_.AdvanceTimeMilliseconds(3000);
1034 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1035
1036 statistics_proxy_.reset();
1037 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1038 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 1));
1039 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1040 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 30));
1041}
1042
1043TEST_F(SendStatisticsProxyTest, TwoPauseEvents) {
1044 // First RTP packet sent.
1045 UpdateDataCounters(kFirstSsrc);
1046
1047 // Two changes. Video: 19000 ms, paused: 1000 ms (5%).
1048 statistics_proxy_->OnSetEncoderTargetRate(0);
1049 fake_clock_.AdvanceTimeMilliseconds(1000);
1050 statistics_proxy_->OnSetEncoderTargetRate(50000); // Starts on bitrate > 0.
1051 fake_clock_.AdvanceTimeMilliseconds(7000);
1052 statistics_proxy_->OnSetEncoderTargetRate(60000);
1053 fake_clock_.AdvanceTimeMilliseconds(3000);
1054 statistics_proxy_->OnSetEncoderTargetRate(0);
1055 fake_clock_.AdvanceTimeMilliseconds(250);
1056 statistics_proxy_->OnSetEncoderTargetRate(0);
1057 fake_clock_.AdvanceTimeMilliseconds(750);
1058 statistics_proxy_->OnSetEncoderTargetRate(60000);
1059 fake_clock_.AdvanceTimeMilliseconds(5000);
1060 statistics_proxy_->OnSetEncoderTargetRate(50000);
1061 fake_clock_.AdvanceTimeMilliseconds(4000);
1062 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1063
1064 statistics_proxy_.reset();
1065 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1066 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 2));
1067 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1068 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 5));
1069}
1070
1071TEST_F(SendStatisticsProxyTest,
1072 PausedTimeHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
1073 // First RTP packet sent.
1074 UpdateDataCounters(kFirstSsrc);
1075 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1076
1077 // Min runtime has not passed.
1078 statistics_proxy_->OnSetEncoderTargetRate(50000);
1079 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
1080 statistics_proxy_->OnSetEncoderTargetRate(0); // VideoSendStream::Stop
1081
1082 statistics_proxy_.reset();
1083 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1084}
1085
asapersson118ef002016-03-31 00:00:19 -07001086TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
asapersson118ef002016-03-31 00:00:19 -07001087 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001088 CodecSpecificInfo codec_info;
1089 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 00:00:19 -07001090
perkj803d97f2016-11-01 11:45:46 -07001091 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 05:05:54 -07001092 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 00:00:19 -07001093 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001094 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1095 codec_info.codecSpecific.VP8.simulcastIdx = 1;
asapersson118ef002016-03-31 00:00:19 -07001096 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 05:05:54 -07001097 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 00:00:19 -07001098 }
1099 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001100 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
1101 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0));
1102 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1"));
1103 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1));
asapersson118ef002016-03-31 00:00:19 -07001104}
1105
1106TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
1107 VideoSendStream::Config config(nullptr);
1108 config.rtp.ssrcs.push_back(kFirstSsrc);
1109 statistics_proxy_.reset(new SendStatisticsProxy(
1110 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1111
asapersson118ef002016-03-31 00:00:19 -07001112 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001113 CodecSpecificInfo codec_info;
1114 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 00:00:19 -07001115
perkj803d97f2016-11-01 11:45:46 -07001116 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 05:05:54 -07001117 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 00:00:19 -07001118 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001119 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 00:00:19 -07001120 }
1121 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001122 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8"));
1123 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0));
asapersson118ef002016-03-31 00:00:19 -07001124}
1125
asapersson5265fed2016-04-18 02:58:47 -07001126TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
asapersson5265fed2016-04-18 02:58:47 -07001127 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001128 CodecSpecificInfo codec_info;
1129 codec_info.codecType = kVideoCodecVP9;
1130 codec_info.codecSpecific.VP9.num_spatial_layers = 2;
asapersson5265fed2016-04-18 02:58:47 -07001131
perkj803d97f2016-11-01 11:45:46 -07001132 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 02:58:47 -07001133 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001134 codec_info.codecSpecific.VP9.spatial_idx = 0;
1135 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001136 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 05:05:54 -07001137 codec_info.codecSpecific.VP9.spatial_idx = 1;
1138 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001139 }
1140 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001141 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
1142 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0));
1143 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1"));
1144 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1));
asapersson5265fed2016-04-18 02:58:47 -07001145}
1146
1147TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
1148 VideoSendStream::Config config(nullptr);
1149 config.rtp.ssrcs.push_back(kFirstSsrc);
1150 statistics_proxy_.reset(new SendStatisticsProxy(
1151 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1152
asapersson5265fed2016-04-18 02:58:47 -07001153 EncodedImage encoded_image;
kjellander02b3d272016-04-20 05:05:54 -07001154 CodecSpecificInfo codec_info;
1155 codec_info.codecType = kVideoCodecVP9;
1156 codec_info.codecSpecific.VP9.num_spatial_layers = 1;
asapersson5265fed2016-04-18 02:58:47 -07001157
perkj803d97f2016-11-01 11:45:46 -07001158 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 02:58:47 -07001159 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 05:05:54 -07001160 codec_info.codecSpecific.VP9.spatial_idx = 0;
1161 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 02:58:47 -07001162 }
1163 statistics_proxy_.reset();
asapersson01d70a32016-05-20 06:29:46 -07001164 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9"));
1165 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0));
asapersson5265fed2016-04-18 02:58:47 -07001166}
1167
asapersson827cab32016-11-02 09:08:47 -07001168TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_H264) {
1169 EncodedImage encoded_image;
1170 CodecSpecificInfo codec_info;
1171 codec_info.codecType = kVideoCodecH264;
1172
1173 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1174 encoded_image.qp_ = kQpIdx0;
1175 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1176 }
1177 statistics_proxy_.reset();
1178 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.H264"));
1179 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.H264", kQpIdx0));
1180}
1181
asapersson4ee70462016-10-31 04:05:12 -07001182TEST_F(SendStatisticsProxyTest,
1183 BandwidthLimitedHistogramsNotUpdatedWhenDisabled) {
1184 EncodedImage encoded_image;
1185 // encoded_image.adapt_reason_.bw_resolutions_disabled by default: -1
perkj803d97f2016-11-01 11:45:46 -07001186 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001187 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1188
1189 // Histograms are updated when the statistics_proxy_ is deleted.
1190 statistics_proxy_.reset();
1191 EXPECT_EQ(0, metrics::NumSamples(
1192 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1193 EXPECT_EQ(0, metrics::NumSamples(
1194 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1195}
1196
1197TEST_F(SendStatisticsProxyTest,
1198 BandwidthLimitedHistogramsUpdatedWhenEnabled_NoResolutionDisabled) {
1199 const int kResolutionsDisabled = 0;
1200 EncodedImage encoded_image;
1201 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 11:45:46 -07001202 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001203 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1204
1205 // Histograms are updated when the statistics_proxy_ is deleted.
1206 statistics_proxy_.reset();
1207 EXPECT_EQ(1, metrics::NumSamples(
1208 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1209 EXPECT_EQ(1, metrics::NumEvents(
1210 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 0));
1211 // No resolution disabled.
1212 EXPECT_EQ(0, metrics::NumSamples(
1213 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1214}
1215
1216TEST_F(SendStatisticsProxyTest,
1217 BandwidthLimitedHistogramsUpdatedWhenEnabled_OneResolutionDisabled) {
1218 const int kResolutionsDisabled = 1;
1219 EncodedImage encoded_image;
1220 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 11:45:46 -07001221 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 04:05:12 -07001222 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1223
1224 // Histograms are updated when the statistics_proxy_ is deleted.
1225 statistics_proxy_.reset();
1226 EXPECT_EQ(1, metrics::NumSamples(
1227 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1228 EXPECT_EQ(1, metrics::NumEvents(
1229 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 100));
1230 // Resolutions disabled.
1231 EXPECT_EQ(1, metrics::NumSamples(
1232 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1233 EXPECT_EQ(
1234 1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionsDisabled",
1235 kResolutionsDisabled));
1236}
1237
1238TEST_F(SendStatisticsProxyTest,
1239 QualityLimitedHistogramsNotUpdatedWhenDisabled) {
mflodmancc3d4422017-08-03 08:27:51 -07001240 VideoStreamEncoder::AdaptCounts cpu_counts;
1241 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001242 quality_counts.resolution = -1;
1243 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001244 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001245 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001246 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001247
1248 // Histograms are updated when the statistics_proxy_ is deleted.
1249 statistics_proxy_.reset();
1250 EXPECT_EQ(
1251 0, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1252 EXPECT_EQ(0, metrics::NumSamples(
1253 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1254}
1255
1256TEST_F(SendStatisticsProxyTest,
1257 QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale) {
mflodmancc3d4422017-08-03 08:27:51 -07001258 VideoStreamEncoder::AdaptCounts cpu_counts;
1259 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001260 quality_counts.resolution = 0;
1261 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001262 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001263 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001264 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001265
1266 // Histograms are updated when the statistics_proxy_ is deleted.
1267 statistics_proxy_.reset();
1268 EXPECT_EQ(
1269 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1270 EXPECT_EQ(1, metrics::NumEvents(
1271 "WebRTC.Video.QualityLimitedResolutionInPercent", 0));
1272 // No resolution downscale.
1273 EXPECT_EQ(0, metrics::NumSamples(
1274 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1275}
1276
1277TEST_F(SendStatisticsProxyTest,
1278 QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales) {
1279 const int kDownscales = 2;
mflodmancc3d4422017-08-03 08:27:51 -07001280 VideoStreamEncoder::AdaptCounts cpu_counts;
1281 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001282 quality_counts.resolution = kDownscales;
1283 statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001284 EncodedImage encoded_image;
perkj803d97f2016-11-01 11:45:46 -07001285 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
kthelgason0cd27ba2016-12-19 06:32:16 -08001286 statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
asapersson4ee70462016-10-31 04:05:12 -07001287 // Histograms are updated when the statistics_proxy_ is deleted.
1288 statistics_proxy_.reset();
1289 EXPECT_EQ(
1290 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
1291 EXPECT_EQ(1, metrics::NumEvents(
1292 "WebRTC.Video.QualityLimitedResolutionInPercent", 100));
1293 // Resolution downscales.
1294 EXPECT_EQ(1, metrics::NumSamples(
1295 "WebRTC.Video.QualityLimitedResolutionDownscales"));
1296 EXPECT_EQ(
1297 1, metrics::NumEvents("WebRTC.Video.QualityLimitedResolutionDownscales",
1298 kDownscales));
1299}
1300
1301TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
1302 // Initially false.
1303 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1304 // No resolution scale by default.
1305 EncodedImage encoded_image;
1306 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1307 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
kthelgason0cd27ba2016-12-19 06:32:16 -08001308
1309 // Simulcast disabled resolutions
1310 encoded_image.adapt_reason_.bw_resolutions_disabled = 1;
1311 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1312 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
1313
asapersson4ee70462016-10-31 04:05:12 -07001314 encoded_image.adapt_reason_.bw_resolutions_disabled = 0;
asapersson4ee70462016-10-31 04:05:12 -07001315 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1316 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
kthelgason0cd27ba2016-12-19 06:32:16 -08001317
1318 // Resolution scaled due to quality.
mflodmancc3d4422017-08-03 08:27:51 -07001319 VideoStreamEncoder::AdaptCounts cpu_counts;
1320 VideoStreamEncoder::AdaptCounts quality_counts;
asapersson09f05612017-05-15 23:40:18 -07001321 quality_counts.resolution = 1;
1322 statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
asapersson4ee70462016-10-31 04:05:12 -07001323 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1324 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
1325}
1326
asapersson66d4b372016-12-19 06:50:53 -08001327TEST_F(SendStatisticsProxyTest, GetStatsReportsTargetMediaBitrate) {
1328 // Initially zero.
1329 EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
1330
1331 const int kBitrate = 100000;
1332 statistics_proxy_->OnSetEncoderTargetRate(kBitrate);
1333 EXPECT_EQ(kBitrate, statistics_proxy_->GetStats().target_media_bitrate_bps);
1334
1335 statistics_proxy_->OnSetEncoderTargetRate(0);
1336 EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
1337}
1338
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001339TEST_F(SendStatisticsProxyTest, NoSubstreams) {
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001340 uint32_t excluded_ssrc =
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001341 std::max(
1342 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()),
1343 *std::max_element(config_.rtp.rtx.ssrcs.begin(),
1344 config_.rtp.rtx.ssrcs.end())) +
1345 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001346 // From RtcpStatisticsCallback.
1347 RtcpStatistics rtcp_stats;
1348 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001349 rtcp_callback->StatisticsUpdated(rtcp_stats, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001350
1351 // From BitrateStatisticsObserver.
sprangcd349d92016-07-13 09:11:28 -07001352 uint32_t total = 0;
1353 uint32_t retransmit = 0;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001354 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001355 bitrate_observer->Notify(total, retransmit, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001356
1357 // From FrameCountObserver.
1358 FrameCountObserver* fps_observer = statistics_proxy_.get();
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00001359 FrameCounts frame_counts;
1360 frame_counts.key_frames = 1;
pbos@webrtc.org49096de2015-02-24 22:37:52 +00001361 fps_observer->FrameCountUpdated(frame_counts, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001362
1363 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
1364 EXPECT_TRUE(stats.substreams.empty());
1365}
1366
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001367TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
1368 static const int kEncodedWidth = 123;
1369 static const int kEncodedHeight = 81;
1370 EncodedImage encoded_image;
1371 encoded_image._encodedWidth = kEncodedWidth;
1372 encoded_image._encodedHeight = kEncodedHeight;
1373
kjellander02b3d272016-04-20 05:05:54 -07001374 CodecSpecificInfo codec_info;
1375 codec_info.codecType = kVideoCodecVP8;
1376 codec_info.codecSpecific.VP8.simulcastIdx = 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001377
kjellander02b3d272016-04-20 05:05:54 -07001378 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1379 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1380 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001381
1382 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001383 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1384 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
1385 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
1386 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001387
1388 // Forward almost to timeout, this should not have removed stats.
1389 fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
1390 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001391 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1392 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001393
1394 // Update the first SSRC with bogus RTCP stats to make sure that encoded
1395 // resolution still times out (no global timeout for all stats).
1396 RtcpStatistics rtcp_statistics;
1397 RtcpStatisticsCallback* rtcp_stats = statistics_proxy_.get();
1398 rtcp_stats->StatisticsUpdated(rtcp_statistics, config_.rtp.ssrcs[0]);
1399
1400 // Report stats for second SSRC to make sure it's not outdated along with the
1401 // first SSRC.
kjellander02b3d272016-04-20 05:05:54 -07001402 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1403 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001404
1405 // Forward 1 ms, reach timeout, substream 0 should have no resolution
1406 // reported, but substream 1 should.
1407 fake_clock_.AdvanceTimeMilliseconds(1);
1408 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00001409 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].width);
1410 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].height);
1411 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
1412 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00001413}
1414
Peter Boström20f3f942015-05-15 11:33:39 +02001415TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
1416 static const int kEncodedWidth = 123;
1417 static const int kEncodedHeight = 81;
1418 EncodedImage encoded_image;
1419 encoded_image._encodedWidth = kEncodedWidth;
1420 encoded_image._encodedHeight = kEncodedHeight;
1421
kjellander02b3d272016-04-20 05:05:54 -07001422 CodecSpecificInfo codec_info;
1423 codec_info.codecType = kVideoCodecVP8;
1424 codec_info.codecSpecific.VP8.simulcastIdx = 0;
Peter Boström20f3f942015-05-15 11:33:39 +02001425
kjellander02b3d272016-04-20 05:05:54 -07001426 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1427 codec_info.codecSpecific.VP8.simulcastIdx = 1;
1428 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
Peter Boström20f3f942015-05-15 11:33:39 +02001429
1430 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
1431 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
1432 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
1433 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
1434 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].width);
1435 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].height);
1436}
1437
1438TEST_F(SendStatisticsProxyTest, ClearsBitratesFromInactiveSsrcs) {
sprangcd349d92016-07-13 09:11:28 -07001439 uint32_t bitrate = 42;
Peter Boström20f3f942015-05-15 11:33:39 +02001440 BitrateStatisticsObserver* observer = statistics_proxy_.get();
1441 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[0]);
1442 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[1]);
1443
1444 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
1445
1446 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprangcd349d92016-07-13 09:11:28 -07001447 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 11:33:39 +02001448 stats.substreams[config_.rtp.ssrcs[0]].total_bitrate_bps);
sprangcd349d92016-07-13 09:11:28 -07001449 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 11:33:39 +02001450 stats.substreams[config_.rtp.ssrcs[0]].retransmit_bitrate_bps);
1451 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].total_bitrate_bps);
1452 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].retransmit_bitrate_bps);
1453}
1454
sprang07fb9be2016-02-24 07:55:00 -08001455TEST_F(SendStatisticsProxyTest, ResetsRtcpCountersOnContentChange) {
1456 RtcpPacketTypeCounterObserver* proxy =
1457 static_cast<RtcpPacketTypeCounterObserver*>(statistics_proxy_.get());
1458 RtcpPacketTypeCounter counters;
1459 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
1460 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1461 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1462
1463 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1464
1465 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
1466 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
1467 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
1468 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
1469 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
1470
1471 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1472 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1473
1474 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 11:48:50 +02001475 VideoEncoderConfig config;
1476 config.content_type = VideoEncoderConfig::ContentType::kScreen;
1477 statistics_proxy_->OnEncoderReconfigured(config, 50);
sprang07fb9be2016-02-24 07:55:00 -08001478
asapersson01d70a32016-05-20 06:29:46 -07001479 EXPECT_EQ(1,
1480 metrics::NumSamples("WebRTC.Video.NackPacketsReceivedPerMinute"));
1481 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsReceivedPerMinute"));
1482 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsReceivedPerMinute"));
1483 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001484 "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
1485
1486 const int kRate = 60 * 2; // Packets per minute with two streams.
1487
asapersson01d70a32016-05-20 06:29:46 -07001488 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NackPacketsReceivedPerMinute",
1489 1 * kRate));
1490 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FirPacketsReceivedPerMinute",
1491 2 * kRate));
1492 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PliPacketsReceivedPerMinute",
1493 3 * kRate));
1494 EXPECT_EQ(
1495 1, metrics::NumEvents("WebRTC.Video.UniqueNackRequestsReceivedInPercent",
1496 4 * 100 / 5));
sprang07fb9be2016-02-24 07:55:00 -08001497
1498 // New start time but same counter values.
1499 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1500 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1501
1502 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1503
1504 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
1505 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
1506 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
1507 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
1508 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
1509
1510 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
1511 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
1512
1513 SetUp(); // Reset stats proxy also causes histograms to be reported.
1514
asapersson01d70a32016-05-20 06:29:46 -07001515 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001516 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 06:29:46 -07001517 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001518 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 06:29:46 -07001519 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001520 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute"));
1521 EXPECT_EQ(
asapersson01d70a32016-05-20 06:29:46 -07001522 1, metrics::NumSamples(
sprang07fb9be2016-02-24 07:55:00 -08001523 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent"));
1524
asapersson01d70a32016-05-20 06:29:46 -07001525 EXPECT_EQ(1, metrics::NumEvents(
1526 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute",
1527 1 * kRate));
1528 EXPECT_EQ(1, metrics::NumEvents(
1529 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute",
1530 2 * kRate));
1531 EXPECT_EQ(1, metrics::NumEvents(
1532 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute",
1533 3 * kRate));
1534 EXPECT_EQ(1,
1535 metrics::NumEvents(
1536 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent",
1537 4 * 100 / 5));
sprang07fb9be2016-02-24 07:55:00 -08001538}
1539
asaperssona6a699a2016-11-25 03:52:46 -08001540TEST_F(SendStatisticsProxyTest, GetStatsReportsIsFlexFec) {
1541 statistics_proxy_.reset(
1542 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
1543 VideoEncoderConfig::ContentType::kRealtimeVideo));
1544
1545 StreamDataCountersCallback* proxy =
1546 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1547 StreamDataCounters counters;
1548 proxy->DataCountersUpdated(counters, kFirstSsrc);
1549 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
1550
1551 EXPECT_FALSE(GetStreamStats(kFirstSsrc).is_flexfec);
1552 EXPECT_TRUE(GetStreamStats(kFlexFecSsrc).is_flexfec);
1553}
1554
1555TEST_F(SendStatisticsProxyTest, SendBitratesAreReportedWithFlexFecEnabled) {
1556 statistics_proxy_.reset(
1557 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
1558 VideoEncoderConfig::ContentType::kRealtimeVideo));
1559
1560 StreamDataCountersCallback* proxy =
1561 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
asaperssona6a699a2016-11-25 03:52:46 -08001562 StreamDataCounters counters;
1563 StreamDataCounters rtx_counters;
asaperssona6a699a2016-11-25 03:52:46 -08001564
asapersson93e1e232017-02-06 05:18:35 -08001565 const int kMinRequiredPeriodSamples = 8;
1566 const int kPeriodIntervalMs = 2000;
1567 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1568 counters.transmitted.packets += 20;
1569 counters.transmitted.header_bytes += 500;
1570 counters.transmitted.padding_bytes += 1000;
1571 counters.transmitted.payload_bytes += 2000;
1572 counters.retransmitted.packets += 2;
1573 counters.retransmitted.header_bytes += 25;
1574 counters.retransmitted.padding_bytes += 100;
1575 counters.retransmitted.payload_bytes += 250;
1576 counters.fec = counters.retransmitted;
1577 rtx_counters.transmitted = counters.transmitted;
1578 // Advance one interval and update counters.
1579 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1580 proxy->DataCountersUpdated(counters, kFirstSsrc);
1581 proxy->DataCountersUpdated(counters, kSecondSsrc);
1582 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1583 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1584 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
1585 }
asaperssona6a699a2016-11-25 03:52:46 -08001586
asaperssona6a699a2016-11-25 03:52:46 -08001587 statistics_proxy_.reset();
asapersson93e1e232017-02-06 05:18:35 -08001588 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001589 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001590 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
1591 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1592 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1593 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
1594 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001595 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001596 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
1597 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001598 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001599 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
1600 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1601 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1602 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
1603 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
asaperssona6a699a2016-11-25 03:52:46 -08001604 EXPECT_EQ(1,
1605 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
asaperssona6a699a2016-11-25 03:52:46 -08001606 EXPECT_EQ(
asapersson93e1e232017-02-06 05:18:35 -08001607 1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
asaperssona6a699a2016-11-25 03:52:46 -08001608}
1609
Erik Språng22c2b482016-03-01 09:40:42 +01001610TEST_F(SendStatisticsProxyTest, ResetsRtpCountersOnContentChange) {
1611 StreamDataCountersCallback* proxy =
1612 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1613 StreamDataCounters counters;
1614 StreamDataCounters rtx_counters;
1615 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
Erik Språng22c2b482016-03-01 09:40:42 +01001616
asapersson93e1e232017-02-06 05:18:35 -08001617 const int kMinRequiredPeriodSamples = 8;
1618 const int kPeriodIntervalMs = 2000;
1619 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1620 counters.transmitted.packets += 20;
1621 counters.transmitted.header_bytes += 500;
1622 counters.transmitted.padding_bytes += 1000;
1623 counters.transmitted.payload_bytes += 2000;
1624 counters.retransmitted.packets += 2;
1625 counters.retransmitted.header_bytes += 25;
1626 counters.retransmitted.padding_bytes += 100;
1627 counters.retransmitted.payload_bytes += 250;
1628 counters.fec = counters.retransmitted;
1629 rtx_counters.transmitted = counters.transmitted;
1630 // Advance one interval and update counters.
1631 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1632 proxy->DataCountersUpdated(counters, kFirstSsrc);
1633 proxy->DataCountersUpdated(counters, kSecondSsrc);
1634 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1635 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1636 }
Erik Språng22c2b482016-03-01 09:40:42 +01001637
1638 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 11:48:50 +02001639 VideoEncoderConfig config;
1640 config.content_type = VideoEncoderConfig::ContentType::kScreen;
asapersson93e1e232017-02-06 05:18:35 -08001641 statistics_proxy_->OnEncoderReconfigured(config, 50000);
Erik Språng22c2b482016-03-01 09:40:42 +01001642
asapersson93e1e232017-02-06 05:18:35 -08001643 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asapersson01d70a32016-05-20 06:29:46 -07001644 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001645 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
1646 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1647 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1648 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
1649 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asapersson01d70a32016-05-20 06:29:46 -07001650 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001651 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
1652 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asapersson01d70a32016-05-20 06:29:46 -07001653 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001654 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
1655 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1656 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1657 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
1658 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
Erik Språng22c2b482016-03-01 09:40:42 +01001659 EXPECT_EQ(1,
asapersson01d70a32016-05-20 06:29:46 -07001660 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 09:40:42 +01001661 EXPECT_EQ(
asapersson93e1e232017-02-06 05:18:35 -08001662 1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
Erik Språng22c2b482016-03-01 09:40:42 +01001663
asapersson93e1e232017-02-06 05:18:35 -08001664 // New metric counters but same data counters.
Erik Språng22c2b482016-03-01 09:40:42 +01001665 // Double counter values, this should result in the same counts as before but
1666 // with new histogram names.
asapersson93e1e232017-02-06 05:18:35 -08001667 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1668 counters.transmitted.packets += 20;
1669 counters.transmitted.header_bytes += 500;
1670 counters.transmitted.padding_bytes += 1000;
1671 counters.transmitted.payload_bytes += 2000;
1672 counters.retransmitted.packets += 2;
1673 counters.retransmitted.header_bytes += 25;
1674 counters.retransmitted.padding_bytes += 100;
1675 counters.retransmitted.payload_bytes += 250;
1676 counters.fec = counters.retransmitted;
1677 rtx_counters.transmitted = counters.transmitted;
1678 // Advance one interval and update counters.
1679 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1680 proxy->DataCountersUpdated(counters, kFirstSsrc);
1681 proxy->DataCountersUpdated(counters, kSecondSsrc);
1682 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1683 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1684 }
Erik Språng22c2b482016-03-01 09:40:42 +01001685
asapersson93e1e232017-02-06 05:18:35 -08001686 // Reset stats proxy also causes histograms to be reported.
1687 statistics_proxy_.reset();
Erik Språng22c2b482016-03-01 09:40:42 +01001688
asapersson93e1e232017-02-06 05:18:35 -08001689 // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec = 56 kbps
asapersson01d70a32016-05-20 06:29:46 -07001690 EXPECT_EQ(1,
1691 metrics::NumSamples("WebRTC.Video.Screenshare.BitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001692 EXPECT_EQ(
1693 1, metrics::NumEvents("WebRTC.Video.Screenshare.BitrateSentInKbps", 56));
1694 // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec = 28 kbps
1695 EXPECT_EQ(
1696 1, metrics::NumSamples("WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
1697 EXPECT_EQ(1, metrics::NumEvents(
1698 "WebRTC.Video.Screenshare.RtxBitrateSentInKbps", 28));
1699 // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec = 12 kbps
asapersson01d70a32016-05-20 06:29:46 -07001700 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001701 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
asapersson01d70a32016-05-20 06:29:46 -07001702 EXPECT_EQ(1, metrics::NumEvents(
asapersson93e1e232017-02-06 05:18:35 -08001703 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps", 12));
1704 // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
asapersson01d70a32016-05-20 06:29:46 -07001705 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001706 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
asapersson93e1e232017-02-06 05:18:35 -08001707 EXPECT_EQ(1, metrics::NumEvents(
1708 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps", 16));
1709 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
1710 EXPECT_EQ(
1711 1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
1712 EXPECT_EQ(1, metrics::NumEvents(
1713 "WebRTC.Video.Screenshare.FecBitrateSentInKbps", 3));
1714 // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
asapersson01d70a32016-05-20 06:29:46 -07001715 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 09:40:42 +01001716 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
asapersson01d70a32016-05-20 06:29:46 -07001717 EXPECT_EQ(1,
1718 metrics::NumEvents(
asapersson93e1e232017-02-06 05:18:35 -08001719 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps", 3));
1720}
Erik Språng22c2b482016-03-01 09:40:42 +01001721
asapersson93e1e232017-02-06 05:18:35 -08001722TEST_F(SendStatisticsProxyTest, RtxBitrateIsZeroWhenEnabledAndNoRtxDataIsSent) {
1723 StreamDataCountersCallback* proxy =
1724 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1725 StreamDataCounters counters;
1726 StreamDataCounters rtx_counters;
Erik Språng22c2b482016-03-01 09:40:42 +01001727
asapersson93e1e232017-02-06 05:18:35 -08001728 const int kMinRequiredPeriodSamples = 8;
1729 const int kPeriodIntervalMs = 2000;
1730 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1731 counters.transmitted.packets += 20;
1732 counters.transmitted.header_bytes += 500;
1733 counters.transmitted.payload_bytes += 2000;
1734 counters.fec = counters.retransmitted;
1735 // Advance one interval and update counters.
1736 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1737 proxy->DataCountersUpdated(counters, kFirstSsrc);
1738 }
1739
1740 // RTX enabled. No data sent over RTX.
1741 statistics_proxy_.reset();
1742 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1743 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 0));
1744}
1745
1746TEST_F(SendStatisticsProxyTest, RtxBitrateNotReportedWhenNotEnabled) {
1747 VideoSendStream::Config config(nullptr);
1748 config.rtp.ssrcs.push_back(kFirstSsrc); // RTX not configured.
1749 statistics_proxy_.reset(new SendStatisticsProxy(
1750 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1751
1752 StreamDataCountersCallback* proxy =
1753 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1754 StreamDataCounters counters;
1755
1756 const int kMinRequiredPeriodSamples = 8;
1757 const int kPeriodIntervalMs = 2000;
1758 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1759 counters.transmitted.packets += 20;
1760 counters.transmitted.header_bytes += 500;
1761 counters.transmitted.payload_bytes += 2000;
1762 counters.fec = counters.retransmitted;
1763 // Advance one interval and update counters.
1764 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1765 proxy->DataCountersUpdated(counters, kFirstSsrc);
1766 }
1767
1768 // RTX not enabled.
1769 statistics_proxy_.reset();
1770 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1771}
1772
1773TEST_F(SendStatisticsProxyTest, FecBitrateIsZeroWhenEnabledAndNoFecDataIsSent) {
1774 StreamDataCountersCallback* proxy =
1775 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1776 StreamDataCounters counters;
1777 StreamDataCounters rtx_counters;
1778
1779 const int kMinRequiredPeriodSamples = 8;
1780 const int kPeriodIntervalMs = 2000;
1781 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1782 counters.transmitted.packets += 20;
1783 counters.transmitted.header_bytes += 500;
1784 counters.transmitted.payload_bytes += 2000;
1785 // Advance one interval and update counters.
1786 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1787 proxy->DataCountersUpdated(counters, kFirstSsrc);
1788 }
1789
1790 // FEC enabled. No FEC data sent.
1791 statistics_proxy_.reset();
1792 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1793 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 0));
1794}
1795
1796TEST_F(SendStatisticsProxyTest, FecBitrateNotReportedWhenNotEnabled) {
1797 VideoSendStream::Config config(nullptr);
1798 config.rtp.ssrcs.push_back(kFirstSsrc); // FEC not configured.
1799 statistics_proxy_.reset(new SendStatisticsProxy(
1800 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1801
1802 StreamDataCountersCallback* proxy =
1803 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1804 StreamDataCounters counters;
1805
1806 const int kMinRequiredPeriodSamples = 8;
1807 const int kPeriodIntervalMs = 2000;
1808 for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
1809 counters.transmitted.packets += 20;
1810 counters.transmitted.header_bytes += 500;
1811 counters.transmitted.payload_bytes += 2000;
1812 counters.fec = counters.retransmitted;
1813 // Advance one interval and update counters.
1814 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
1815 proxy->DataCountersUpdated(counters, kFirstSsrc);
1816 }
1817
1818 // FEC not enabled.
1819 statistics_proxy_.reset();
1820 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 09:40:42 +01001821}
1822
asapersson8d75ac72017-09-15 06:41:15 -07001823TEST_F(SendStatisticsProxyTest, GetStatsReportsEncoderImplementationName) {
1824 const char* kName = "encoderName";
1825 EncodedImage encoded_image;
1826 CodecSpecificInfo codec_info;
1827 codec_info.codec_name = kName;
1828 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1829 EXPECT_STREQ(
1830 kName, statistics_proxy_->GetStats().encoder_implementation_name.c_str());
1831}
1832
1833class ForcedFallbackTest : public SendStatisticsProxyTest {
1834 public:
1835 explicit ForcedFallbackTest(const std::string& field_trials)
1836 : SendStatisticsProxyTest(field_trials) {
1837 codec_info_.codecType = kVideoCodecVP8;
1838 codec_info_.codecSpecific.VP8.simulcastIdx = 0;
1839 codec_info_.codecSpecific.VP8.temporalIdx = 0;
1840 codec_info_.codec_name = "fake_codec";
1841 }
1842
1843 ~ForcedFallbackTest() override {}
1844
1845 protected:
1846 void InsertEncodedFrames(int num_frames, int interval_ms) {
1847 // First frame is not updating stats, insert initial frame.
1848 if (statistics_proxy_->GetStats().frames_encoded == 0) {
1849 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1850 }
1851 for (int i = 0; i < num_frames; ++i) {
1852 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1853 fake_clock_.AdvanceTimeMilliseconds(interval_ms);
1854 }
1855 // Add frame to include last time interval.
1856 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
1857 }
1858
1859 EncodedImage encoded_image_;
1860 CodecSpecificInfo codec_info_;
1861 const std::string kPrefix = "WebRTC.Video.Encoder.ForcedSw";
1862 const int kFrameIntervalMs = 1000;
1863 const int kMinFrames = 20; // Min run time 20 sec.
1864};
1865
1866class ForcedFallbackDisabled : public ForcedFallbackTest {
1867 public:
1868 ForcedFallbackDisabled()
1869 : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder/Disabled/") {}
1870};
1871
1872class ForcedFallbackEnabled : public ForcedFallbackTest {
1873 public:
1874 ForcedFallbackEnabled()
1875 : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder/Enabled-1,2," +
1876 std::to_string(kMinFirstFallbackIntervalMs) +
1877 ",4/") {}
1878};
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
1964TEST_F(ForcedFallbackEnabled, NoFallbackIfMinIntervalHasNotPassed) {
1965 InsertEncodedFrames(1, kMinFirstFallbackIntervalMs - 1);
1966 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
1974TEST_F(ForcedFallbackEnabled, FallbackIfMinIntervalPassed) {
1975 InsertEncodedFrames(1, kMinFirstFallbackIntervalMs);
1976 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