blob: aa7c14f1a101a942a6683310acaee09ac58aa08b [file] [log] [blame]
sprang@webrtc.orgccd42842014-01-07 09:54:341/*
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
sprang@webrtc.orgccd42842014-01-07 09:54:3411#include "webrtc/video/send_statistics_proxy.h"
12
13#include <map>
kwiberg27f982b2016-03-01 19:52:3314#include <memory>
sprang@webrtc.orgccd42842014-01-07 09:54:3415#include <string>
16#include <vector>
17
sprang07fb9be2016-02-24 15:55:0018#include "webrtc/system_wrappers/include/metrics.h"
asapersson01d70a32016-05-20 13:29:4619#include "webrtc/system_wrappers/include/metrics_default.h"
kwibergac9f8762016-10-01 05:29:4320#include "webrtc/test/gtest.h"
sprang@webrtc.orgccd42842014-01-07 09:54:3421
22namespace webrtc {
asapersson5265fed2016-04-18 09:58:4723namespace {
24const uint32_t kFirstSsrc = 17;
25const uint32_t kSecondSsrc = 42;
26const uint32_t kFirstRtxSsrc = 18;
27const uint32_t kSecondRtxSsrc = 43;
asaperssona6a699a2016-11-25 11:52:4628const uint32_t kFlexFecSsrc = 55;
asapersson320e45a2016-11-29 09:40:3529const int kFpsPeriodicIntervalMs = 2000;
30const int kWidth = 640;
31const int kHeight = 480;
asapersson5265fed2016-04-18 09:58:4732const int kQpIdx0 = 21;
33const int kQpIdx1 = 39;
34} // namespace
sprang07fb9be2016-02-24 15:55:0035
stefan@webrtc.org168f23f2014-07-11 13:44:0236class SendStatisticsProxyTest : public ::testing::Test {
sprang@webrtc.orgccd42842014-01-07 09:54:3437 public:
pbos@webrtc.org273a4142014-12-01 15:23:2138 SendStatisticsProxyTest()
solenberg4fbae2b2015-08-28 11:07:1039 : fake_clock_(1234), config_(GetTestConfig()), avg_delay_ms_(0),
40 max_delay_ms_(0) {}
sprang@webrtc.orgccd42842014-01-07 09:54:3441 virtual ~SendStatisticsProxyTest() {}
42
43 protected:
44 virtual void SetUp() {
asapersson01d70a32016-05-20 13:29:4645 metrics::Reset();
sprangb4a1ae52015-12-03 16:10:0846 statistics_proxy_.reset(new SendStatisticsProxy(
47 &fake_clock_, GetTestConfig(),
48 VideoEncoderConfig::ContentType::kRealtimeVideo));
sprang@webrtc.orgccd42842014-01-07 09:54:3449 expected_ = VideoSendStream::Stats();
asapersson2e5cfcd2016-08-11 15:41:1850 for (const auto& ssrc : config_.rtp.ssrcs)
51 expected_.substreams[ssrc].is_rtx = false;
52 for (const auto& ssrc : config_.rtp.rtx.ssrcs)
53 expected_.substreams[ssrc].is_rtx = true;
sprang@webrtc.orgccd42842014-01-07 09:54:3454 }
55
56 VideoSendStream::Config GetTestConfig() {
solenberg4fbae2b2015-08-28 11:07:1057 VideoSendStream::Config config(nullptr);
sprang07fb9be2016-02-24 15:55:0058 config.rtp.ssrcs.push_back(kFirstSsrc);
59 config.rtp.ssrcs.push_back(kSecondSsrc);
60 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
61 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
brandtrb5f2c3f2016-10-05 06:28:3962 config.rtp.ulpfec.red_payload_type = 17;
sprang@webrtc.orgccd42842014-01-07 09:54:3463 return config;
64 }
65
asaperssona6a699a2016-11-25 11:52:4666 VideoSendStream::Config GetTestConfigWithFlexFec() {
67 VideoSendStream::Config config(nullptr);
68 config.rtp.ssrcs.push_back(kFirstSsrc);
69 config.rtp.ssrcs.push_back(kSecondSsrc);
70 config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
71 config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
72 config.rtp.flexfec.flexfec_payload_type = 50;
73 config.rtp.flexfec.flexfec_ssrc = kFlexFecSsrc;
74 return config;
75 }
76
77 VideoSendStream::StreamStats GetStreamStats(uint32_t ssrc) {
78 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
79 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
80 stats.substreams.find(ssrc);
81 EXPECT_NE(it, stats.substreams.end());
82 return it->second;
83 }
84
sprang@webrtc.org09315702014-02-07 12:06:2985 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
sprang@webrtc.org09315702014-02-07 12:06:2986 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
87 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
stefan@webrtc.org0bae1fa2014-11-05 14:05:2988 EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);
Pera48ddb72016-09-29 09:48:5089 EXPECT_EQ(one.preferred_media_bitrate_bps,
90 other.preferred_media_bitrate_bps);
henrik.lundin@webrtc.orgb10363f32014-03-13 13:31:2191 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:2992
93 EXPECT_EQ(one.substreams.size(), other.substreams.size());
pbos@webrtc.org09c77b92015-02-25 10:42:1694 for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
sprang@webrtc.org09315702014-02-07 12:06:2995 one.substreams.begin();
pbos@webrtc.org09c77b92015-02-25 10:42:1696 it != one.substreams.end(); ++it) {
97 std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
98 corresponding_it = other.substreams.find(it->first);
sprang@webrtc.org09315702014-02-07 12:06:2999 ASSERT_TRUE(corresponding_it != other.substreams.end());
pbos@webrtc.org09c77b92015-02-25 10:42:16100 const VideoSendStream::StreamStats& a = it->second;
101 const VideoSendStream::StreamStats& b = corresponding_it->second;
sprang@webrtc.org09315702014-02-07 12:06:29102
asapersson2e5cfcd2016-08-11 15:41:18103 EXPECT_EQ(a.is_rtx, b.is_rtx);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16104 EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
105 EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29106 EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02107 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
108 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29109
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59110 EXPECT_EQ(a.rtp_stats.transmitted.payload_bytes,
111 b.rtp_stats.transmitted.payload_bytes);
112 EXPECT_EQ(a.rtp_stats.transmitted.header_bytes,
113 b.rtp_stats.transmitted.header_bytes);
114 EXPECT_EQ(a.rtp_stats.transmitted.padding_bytes,
115 b.rtp_stats.transmitted.padding_bytes);
116 EXPECT_EQ(a.rtp_stats.transmitted.packets,
117 b.rtp_stats.transmitted.packets);
118 EXPECT_EQ(a.rtp_stats.retransmitted.packets,
119 b.rtp_stats.retransmitted.packets);
120 EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets);
sprang@webrtc.org09315702014-02-07 12:06:29121
122 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
123 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
124 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
125 b.rtcp_stats.extended_max_sequence_number);
126 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
127 }
128 }
129
pbos@webrtc.org273a4142014-12-01 15:23:21130 SimulatedClock fake_clock_;
kwiberg27f982b2016-03-01 19:52:33131 std::unique_ptr<SendStatisticsProxy> statistics_proxy_;
sprang@webrtc.orgccd42842014-01-07 09:54:34132 VideoSendStream::Config config_;
133 int avg_delay_ms_;
134 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34135 VideoSendStream::Stats expected_;
pbos@webrtc.org09c77b92015-02-25 10:42:16136 typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
137 StreamIterator;
sprang@webrtc.orgccd42842014-01-07 09:54:34138};
139
140TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
141 RtcpStatisticsCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-03 06:44:01142 for (const auto& ssrc : config_.rtp.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16143 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34144
145 // Add statistics with some arbitrary, but unique, numbers.
146 uint32_t offset = ssrc * sizeof(RtcpStatistics);
147 ssrc_stats.rtcp_stats.cumulative_lost = offset;
148 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
149 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
150 ssrc_stats.rtcp_stats.jitter = offset + 3;
151 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
152 }
asapersson35151f32016-05-03 06:44:01153 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
pbos@webrtc.org09c77b92015-02-25 10:42:16154 VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34155
stefan@webrtc.org58e2d262014-08-14 15:10:49156 // Add statistics with some arbitrary, but unique, numbers.
157 uint32_t offset = ssrc * sizeof(RtcpStatistics);
158 ssrc_stats.rtcp_stats.cumulative_lost = offset;
159 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
160 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
161 ssrc_stats.rtcp_stats.jitter = offset + 3;
162 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
163 }
sprang@webrtc.orgccd42842014-01-07 09:54:34164 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29165 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34166}
167
stefan@webrtc.org0bae1fa2014-11-05 14:05:29168TEST_F(SendStatisticsProxyTest, EncodedBitrateAndFramerate) {
Peter Boström7083e112015-09-22 14:28:51169 int media_bitrate_bps = 500;
170 int encode_fps = 29;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29171
perkj275afc52016-09-01 07:21:16172 statistics_proxy_->OnEncoderStatsUpdate(encode_fps, media_bitrate_bps);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29173
174 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
175 EXPECT_EQ(media_bitrate_bps, stats.media_bitrate_bps);
sprang@webrtc.orgccd42842014-01-07 09:54:34176 EXPECT_EQ(encode_fps, stats.encode_frame_rate);
177}
178
henrik.lundin@webrtc.orgb10363f32014-03-13 13:31:21179TEST_F(SendStatisticsProxyTest, Suspended) {
180 // Verify that the value is false by default.
181 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
182
183 // Verify that we can set it to true.
Peter Boström7083e112015-09-22 14:28:51184 statistics_proxy_->OnSuspendChange(true);
henrik.lundin@webrtc.orgb10363f32014-03-13 13:31:21185 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
186
187 // Verify that we can set it back to false again.
Peter Boström7083e112015-09-22 14:28:51188 statistics_proxy_->OnSuspendChange(false);
henrik.lundin@webrtc.orgb10363f32014-03-13 13:31:21189 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
190}
191
sprang@webrtc.orgccd42842014-01-07 09:54:34192TEST_F(SendStatisticsProxyTest, FrameCounts) {
193 FrameCountObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-03 06:44:01194 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34195 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16196 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
197 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16198 FrameCounts frame_counts;
199 frame_counts.key_frames = offset;
200 frame_counts.delta_frames = offset + 1;
201 stats.frame_counts = frame_counts;
202 observer->FrameCountUpdated(frame_counts, ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34203 }
asapersson35151f32016-05-03 06:44:01204 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49205 // Add statistics with some arbitrary, but unique, numbers.
pbos@webrtc.org09c77b92015-02-25 10:42:16206 VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
207 uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
pbos@webrtc.orgce4e9a32014-12-18 13:50:16208 FrameCounts frame_counts;
209 frame_counts.key_frames = offset;
210 frame_counts.delta_frames = offset + 1;
211 stats.frame_counts = frame_counts;
212 observer->FrameCountUpdated(frame_counts, ssrc);
stefan@webrtc.org58e2d262014-08-14 15:10:49213 }
sprang@webrtc.orgccd42842014-01-07 09:54:34214
215 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29216 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34217}
218
219TEST_F(SendStatisticsProxyTest, DataCounters) {
220 StreamDataCountersCallback* callback = statistics_proxy_.get();
asapersson35151f32016-05-03 06:44:01221 for (const auto& ssrc : config_.rtp.ssrcs) {
sprang@webrtc.orgccd42842014-01-07 09:54:34222 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
223 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14224 size_t offset = ssrc * sizeof(StreamDataCounters);
225 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59226 counters.transmitted.payload_bytes = offset;
227 counters.transmitted.header_bytes = offset + 1;
228 counters.fec.packets = offset_uint32 + 2;
229 counters.transmitted.padding_bytes = offset + 3;
230 counters.retransmitted.packets = offset_uint32 + 4;
231 counters.transmitted.packets = offset_uint32 + 5;
sprang@webrtc.orgccd42842014-01-07 09:54:34232 callback->DataCountersUpdated(counters, ssrc);
233 }
asapersson35151f32016-05-03 06:44:01234 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49235 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
236 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14237 size_t offset = ssrc * sizeof(StreamDataCounters);
238 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59239 counters.transmitted.payload_bytes = offset;
240 counters.transmitted.header_bytes = offset + 1;
241 counters.fec.packets = offset_uint32 + 2;
242 counters.transmitted.padding_bytes = offset + 3;
243 counters.retransmitted.packets = offset_uint32 + 4;
244 counters.transmitted.packets = offset_uint32 + 5;
stefan@webrtc.org58e2d262014-08-14 15:10:49245 callback->DataCountersUpdated(counters, ssrc);
246 }
sprang@webrtc.orgccd42842014-01-07 09:54:34247
248 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29249 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34250}
251
252TEST_F(SendStatisticsProxyTest, Bitrate) {
253 BitrateStatisticsObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-03 06:44:01254 for (const auto& ssrc : config_.rtp.ssrcs) {
sprangcd349d92016-07-13 16:11:28255 uint32_t total;
256 uint32_t retransmit;
stefan@webrtc.org168f23f2014-07-11 13:44:02257 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 16:11:28258 total = ssrc;
259 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29260 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 16:11:28261 expected_.substreams[ssrc].total_bitrate_bps = total;
262 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
sprang@webrtc.orgccd42842014-01-07 09:54:34263 }
asapersson35151f32016-05-03 06:44:01264 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
sprangcd349d92016-07-13 16:11:28265 uint32_t total;
266 uint32_t retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49267 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprangcd349d92016-07-13 16:11:28268 total = ssrc;
269 retransmit = ssrc + 1;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29270 observer->Notify(total, retransmit, ssrc);
sprangcd349d92016-07-13 16:11:28271 expected_.substreams[ssrc].total_bitrate_bps = total;
272 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49273 }
sprang@webrtc.orgccd42842014-01-07 09:54:34274
275 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29276 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34277}
278
stefan@webrtc.org168f23f2014-07-11 13:44:02279TEST_F(SendStatisticsProxyTest, SendSideDelay) {
280 SendSideDelayObserver* observer = statistics_proxy_.get();
asapersson35151f32016-05-03 06:44:01281 for (const auto& ssrc : config_.rtp.ssrcs) {
stefan@webrtc.org168f23f2014-07-11 13:44:02282 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
283 // stream.
284 int avg_delay_ms = ssrc;
285 int max_delay_ms = ssrc + 1;
286 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
287 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
288 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
289 }
asapersson35151f32016-05-03 06:44:01290 for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
stefan@webrtc.org58e2d262014-08-14 15:10:49291 // 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 }
sprang@webrtc.orgccd42842014-01-07 09:54:34299 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02300 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34301}
302
Peter Boströme4499152016-02-05 10:13:28303TEST_F(SendStatisticsProxyTest, OnEncodedFrameTimeMeasured) {
asapersson1aa420b2015-12-07 11:12:22304 const int kEncodeTimeMs = 11;
Peter Boströme4499152016-02-05 10:13:28305 CpuOveruseMetrics metrics;
306 metrics.encode_usage_percent = 80;
307 statistics_proxy_->OnEncodedFrameTimeMeasured(kEncodeTimeMs, metrics);
asapersson1aa420b2015-12-07 11:12:22308
309 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
310 EXPECT_EQ(kEncodeTimeMs, stats.avg_encode_time_ms);
Peter Boströme4499152016-02-05 10:13:28311 EXPECT_EQ(metrics.encode_usage_percent, stats.encode_usage_percent);
asapersson1aa420b2015-12-07 11:12:22312}
313
Pera48ddb72016-09-29 09:48:50314TEST_F(SendStatisticsProxyTest, OnEncoderReconfiguredChangePreferredBitrate) {
315 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
316 EXPECT_EQ(0, stats.preferred_media_bitrate_bps);
317 const int kPreferredMediaBitrateBps = 50;
318
319 VideoEncoderConfig config;
320 statistics_proxy_->OnEncoderReconfigured(config, kPreferredMediaBitrateBps);
321 stats = statistics_proxy_->GetStats();
322 EXPECT_EQ(kPreferredMediaBitrateBps, stats.preferred_media_bitrate_bps);
323}
324
sakal43536c32016-10-24 08:46:43325TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesFramesEncoded) {
326 EncodedImage encoded_image;
327 CodecSpecificInfo codec_info;
328 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_encoded);
329 for (uint32_t i = 1; i <= 3; ++i) {
330 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
331 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded);
332 }
333}
334
sakal87da4042016-10-31 13:53:47335TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesQpSum) {
336 EncodedImage encoded_image;
337 CodecSpecificInfo codec_info;
338 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
339 encoded_image.qp_ = 3;
340 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
341 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
342 encoded_image.qp_ = 127;
343 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
344 EXPECT_EQ(rtc::Optional<uint64_t>(130u),
345 statistics_proxy_->GetStats().qp_sum);
346}
347
348TEST_F(SendStatisticsProxyTest, OnSendEncodedImageWithoutQpQpSumWontExist) {
349 EncodedImage encoded_image;
350 CodecSpecificInfo codec_info;
351 encoded_image.qp_ = -1;
352 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
353 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
354 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
355}
356
asapersson59bac1a2016-01-08 07:36:00357TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
perkj803d97f2016-11-01 18:45:46358 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson59bac1a2016-01-08 07:36:00359 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
360
Pera48ddb72016-09-29 09:48:50361 // No switch, stats should not be updated.
362 VideoEncoderConfig config;
363 config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
364 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 13:29:46365 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-08 07:36:00366
367 // Switch to screenshare, real-time stats should be updated.
Pera48ddb72016-09-29 09:48:50368 config.content_type = VideoEncoderConfig::ContentType::kScreen;
369 statistics_proxy_->OnEncoderReconfigured(config, 50);
asapersson01d70a32016-05-20 13:29:46370 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
asapersson59bac1a2016-01-08 07:36:00371}
372
asapersson320e45a2016-11-29 09:40:35373TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) {
374 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
375 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
perkj803d97f2016-11-01 18:45:46376
asapersson320e45a2016-11-29 09:40:35377 statistics_proxy_.reset();
378 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
379 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputWidthInPixels", kWidth));
380 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputHeightInPixels"));
381 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputHeightInPixels", kHeight));
382}
383
384TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) {
385 EncodedImage encoded_image;
386 encoded_image._encodedWidth = kWidth;
387 encoded_image._encodedHeight = kHeight;
388 for (int i = 0; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
389 encoded_image._timeStamp = i + 1;
390 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
391 }
392 statistics_proxy_.reset();
393 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
394 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentWidthInPixels", kWidth));
395 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
396 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentHeightInPixels", kHeight));
397}
398
399TEST_F(SendStatisticsProxyTest, InputFpsHistogramIsUpdated) {
400 const int kFps = 20;
401 const int kMinPeriodicSamples = 6;
402 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
403 for (int i = 0; i <= frames; ++i) {
404 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
405 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
406 }
407 statistics_proxy_.reset();
408 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
409 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
410}
411
412TEST_F(SendStatisticsProxyTest, SentFpsHistogramIsUpdated) {
413 EncodedImage encoded_image;
414 const int kFps = 20;
415 const int kMinPeriodicSamples = 6;
416 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000 + 1;
417 for (int i = 0; i <= frames; ++i) {
418 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
419 encoded_image._timeStamp = i + 1;
420 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
421 }
422 statistics_proxy_.reset();
423 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
424 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
425}
426
427TEST_F(SendStatisticsProxyTest, InputFpsHistogramExcludesSuspendedTime) {
428 const int kFps = 20;
429 const int kSuspendTimeMs = 10000;
430 const int kMinPeriodicSamples = 6;
431 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
432 for (int i = 0; i < frames; ++i) {
433 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
434 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
435 }
436 // Suspend.
437 statistics_proxy_->OnSuspendChange(true);
438 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
439
440 for (int i = 0; i < frames; ++i) {
441 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
442 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
443 }
444 // Suspended time interval should not affect the framerate.
445 statistics_proxy_.reset();
446 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
447 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
448}
449
450TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
451 EncodedImage encoded_image;
452 const int kFps = 20;
453 const int kSuspendTimeMs = 10000;
454 const int kMinPeriodicSamples = 6;
455 int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
456 for (int i = 0; i <= frames; ++i) {
457 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
458 encoded_image._timeStamp = i + 1;
459 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
460 }
461 // Suspend.
462 statistics_proxy_->OnSuspendChange(true);
463 fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
464
465 for (int i = 0; i <= frames; ++i) {
466 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
467 encoded_image._timeStamp = i + 1;
468 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
469 }
470 // Suspended time interval should not affect the framerate.
471 statistics_proxy_.reset();
472 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
473 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
474}
475
476TEST_F(SendStatisticsProxyTest, CpuLimitedResolutionUpdated) {
perkj803d97f2016-11-01 18:45:46477 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
478 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
479
480 statistics_proxy_->OnCpuRestrictedResolutionChanged(true);
481
482 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
483 statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
484
485 statistics_proxy_.reset();
486 EXPECT_EQ(1,
487 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
488 EXPECT_EQ(
489 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
490}
491
asapersson4374a092016-07-27 07:39:09492TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) {
493 const int64_t kTimeSec = 3;
494 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
495 statistics_proxy_.reset();
496 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds"));
497 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds",
498 kTimeSec));
499}
500
501TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) {
502 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
503 statistics_proxy_.reset();
504 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType"));
505}
506
asapersson118ef002016-03-31 07:00:19507TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
asapersson118ef002016-03-31 07:00:19508 EncodedImage encoded_image;
kjellander02b3d272016-04-20 12:05:54509 CodecSpecificInfo codec_info;
510 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 07:00:19511
perkj803d97f2016-11-01 18:45:46512 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 12:05:54513 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 07:00:19514 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 12:05:54515 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
516 codec_info.codecSpecific.VP8.simulcastIdx = 1;
asapersson118ef002016-03-31 07:00:19517 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 12:05:54518 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 07:00:19519 }
520 statistics_proxy_.reset();
asapersson01d70a32016-05-20 13:29:46521 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
522 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0));
523 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1"));
524 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1));
asapersson118ef002016-03-31 07:00:19525}
526
527TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
528 VideoSendStream::Config config(nullptr);
529 config.rtp.ssrcs.push_back(kFirstSsrc);
530 statistics_proxy_.reset(new SendStatisticsProxy(
531 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
532
asapersson118ef002016-03-31 07:00:19533 EncodedImage encoded_image;
kjellander02b3d272016-04-20 12:05:54534 CodecSpecificInfo codec_info;
535 codec_info.codecType = kVideoCodecVP8;
asapersson118ef002016-03-31 07:00:19536
perkj803d97f2016-11-01 18:45:46537 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
kjellander02b3d272016-04-20 12:05:54538 codec_info.codecSpecific.VP8.simulcastIdx = 0;
asapersson118ef002016-03-31 07:00:19539 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 12:05:54540 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson118ef002016-03-31 07:00:19541 }
542 statistics_proxy_.reset();
asapersson01d70a32016-05-20 13:29:46543 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8"));
544 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0));
asapersson118ef002016-03-31 07:00:19545}
546
asapersson5265fed2016-04-18 09:58:47547TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
asapersson5265fed2016-04-18 09:58:47548 EncodedImage encoded_image;
kjellander02b3d272016-04-20 12:05:54549 CodecSpecificInfo codec_info;
550 codec_info.codecType = kVideoCodecVP9;
551 codec_info.codecSpecific.VP9.num_spatial_layers = 2;
asapersson5265fed2016-04-18 09:58:47552
perkj803d97f2016-11-01 18:45:46553 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 09:58:47554 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 12:05:54555 codec_info.codecSpecific.VP9.spatial_idx = 0;
556 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 09:58:47557 encoded_image.qp_ = kQpIdx1;
kjellander02b3d272016-04-20 12:05:54558 codec_info.codecSpecific.VP9.spatial_idx = 1;
559 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 09:58:47560 }
561 statistics_proxy_.reset();
asapersson01d70a32016-05-20 13:29:46562 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
563 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0));
564 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1"));
565 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1));
asapersson5265fed2016-04-18 09:58:47566}
567
568TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
569 VideoSendStream::Config config(nullptr);
570 config.rtp.ssrcs.push_back(kFirstSsrc);
571 statistics_proxy_.reset(new SendStatisticsProxy(
572 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
573
asapersson5265fed2016-04-18 09:58:47574 EncodedImage encoded_image;
kjellander02b3d272016-04-20 12:05:54575 CodecSpecificInfo codec_info;
576 codec_info.codecType = kVideoCodecVP9;
577 codec_info.codecSpecific.VP9.num_spatial_layers = 1;
asapersson5265fed2016-04-18 09:58:47578
perkj803d97f2016-11-01 18:45:46579 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
asapersson5265fed2016-04-18 09:58:47580 encoded_image.qp_ = kQpIdx0;
kjellander02b3d272016-04-20 12:05:54581 codec_info.codecSpecific.VP9.spatial_idx = 0;
582 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
asapersson5265fed2016-04-18 09:58:47583 }
584 statistics_proxy_.reset();
asapersson01d70a32016-05-20 13:29:46585 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9"));
586 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0));
asapersson5265fed2016-04-18 09:58:47587}
588
asapersson827cab32016-11-02 16:08:47589TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_H264) {
590 EncodedImage encoded_image;
591 CodecSpecificInfo codec_info;
592 codec_info.codecType = kVideoCodecH264;
593
594 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
595 encoded_image.qp_ = kQpIdx0;
596 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
597 }
598 statistics_proxy_.reset();
599 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.H264"));
600 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.H264", kQpIdx0));
601}
602
asapersson4ee70462016-10-31 11:05:12603TEST_F(SendStatisticsProxyTest,
604 BandwidthLimitedHistogramsNotUpdatedWhenDisabled) {
605 EncodedImage encoded_image;
606 // encoded_image.adapt_reason_.bw_resolutions_disabled by default: -1
perkj803d97f2016-11-01 18:45:46607 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12608 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
609
610 // Histograms are updated when the statistics_proxy_ is deleted.
611 statistics_proxy_.reset();
612 EXPECT_EQ(0, metrics::NumSamples(
613 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
614 EXPECT_EQ(0, metrics::NumSamples(
615 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
616}
617
618TEST_F(SendStatisticsProxyTest,
619 BandwidthLimitedHistogramsUpdatedWhenEnabled_NoResolutionDisabled) {
620 const int kResolutionsDisabled = 0;
621 EncodedImage encoded_image;
622 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 18:45:46623 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12624 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
625
626 // Histograms are updated when the statistics_proxy_ is deleted.
627 statistics_proxy_.reset();
628 EXPECT_EQ(1, metrics::NumSamples(
629 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
630 EXPECT_EQ(1, metrics::NumEvents(
631 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 0));
632 // No resolution disabled.
633 EXPECT_EQ(0, metrics::NumSamples(
634 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
635}
636
637TEST_F(SendStatisticsProxyTest,
638 BandwidthLimitedHistogramsUpdatedWhenEnabled_OneResolutionDisabled) {
639 const int kResolutionsDisabled = 1;
640 EncodedImage encoded_image;
641 encoded_image.adapt_reason_.bw_resolutions_disabled = kResolutionsDisabled;
perkj803d97f2016-11-01 18:45:46642 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12643 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
644
645 // Histograms are updated when the statistics_proxy_ is deleted.
646 statistics_proxy_.reset();
647 EXPECT_EQ(1, metrics::NumSamples(
648 "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
649 EXPECT_EQ(1, metrics::NumEvents(
650 "WebRTC.Video.BandwidthLimitedResolutionInPercent", 100));
651 // Resolutions disabled.
652 EXPECT_EQ(1, metrics::NumSamples(
653 "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
654 EXPECT_EQ(
655 1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionsDisabled",
656 kResolutionsDisabled));
657}
658
659TEST_F(SendStatisticsProxyTest,
660 QualityLimitedHistogramsNotUpdatedWhenDisabled) {
661 EncodedImage encoded_image;
662 // encoded_image.adapt_reason_.quality_resolution_downscales disabled by
663 // default: -1
perkj803d97f2016-11-01 18:45:46664 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12665 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
666
667 // Histograms are updated when the statistics_proxy_ is deleted.
668 statistics_proxy_.reset();
669 EXPECT_EQ(
670 0, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
671 EXPECT_EQ(0, metrics::NumSamples(
672 "WebRTC.Video.QualityLimitedResolutionDownscales"));
673}
674
675TEST_F(SendStatisticsProxyTest,
676 QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale) {
677 const int kDownscales = 0;
678 EncodedImage encoded_image;
679 encoded_image.adapt_reason_.quality_resolution_downscales = kDownscales;
perkj803d97f2016-11-01 18:45:46680 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12681 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
682
683 // Histograms are updated when the statistics_proxy_ is deleted.
684 statistics_proxy_.reset();
685 EXPECT_EQ(
686 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
687 EXPECT_EQ(1, metrics::NumEvents(
688 "WebRTC.Video.QualityLimitedResolutionInPercent", 0));
689 // No resolution downscale.
690 EXPECT_EQ(0, metrics::NumSamples(
691 "WebRTC.Video.QualityLimitedResolutionDownscales"));
692}
693
694TEST_F(SendStatisticsProxyTest,
695 QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales) {
696 const int kDownscales = 2;
697 EncodedImage encoded_image;
698 encoded_image.adapt_reason_.quality_resolution_downscales = kDownscales;
perkj803d97f2016-11-01 18:45:46699 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
asapersson4ee70462016-10-31 11:05:12700 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
701
702 // Histograms are updated when the statistics_proxy_ is deleted.
703 statistics_proxy_.reset();
704 EXPECT_EQ(
705 1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
706 EXPECT_EQ(1, metrics::NumEvents(
707 "WebRTC.Video.QualityLimitedResolutionInPercent", 100));
708 // Resolution downscales.
709 EXPECT_EQ(1, metrics::NumSamples(
710 "WebRTC.Video.QualityLimitedResolutionDownscales"));
711 EXPECT_EQ(
712 1, metrics::NumEvents("WebRTC.Video.QualityLimitedResolutionDownscales",
713 kDownscales));
714}
715
716TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
717 // Initially false.
718 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
719 // No resolution scale by default.
720 EncodedImage encoded_image;
721 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
722 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
723 // Resolution not scaled.
724 encoded_image.adapt_reason_.bw_resolutions_disabled = 0;
725 encoded_image.adapt_reason_.quality_resolution_downscales = 0;
726 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
727 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
728 // Resolution scaled due to bandwidth.
729 encoded_image.adapt_reason_.bw_resolutions_disabled = 1;
730 encoded_image.adapt_reason_.quality_resolution_downscales = 0;
731 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
732 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
733 // Resolution not scaled.
734 encoded_image.adapt_reason_.bw_resolutions_disabled = 0;
735 encoded_image.adapt_reason_.quality_resolution_downscales = 0;
736 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
737 EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
738 // Resolution scaled due to quality.
739 encoded_image.adapt_reason_.bw_resolutions_disabled = 0;
740 encoded_image.adapt_reason_.quality_resolution_downscales = 1;
741 statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
742 EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
743}
744
sprang@webrtc.orgccd42842014-01-07 09:54:34745TEST_F(SendStatisticsProxyTest, NoSubstreams) {
pbos@webrtc.org49096de2015-02-24 22:37:52746 uint32_t excluded_ssrc =
stefan@webrtc.org58e2d262014-08-14 15:10:49747 std::max(
748 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()),
749 *std::max_element(config_.rtp.rtx.ssrcs.begin(),
750 config_.rtp.rtx.ssrcs.end())) +
751 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34752 // From RtcpStatisticsCallback.
753 RtcpStatistics rtcp_stats;
754 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52755 rtcp_callback->StatisticsUpdated(rtcp_stats, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34756
757 // From BitrateStatisticsObserver.
sprangcd349d92016-07-13 16:11:28758 uint32_t total = 0;
759 uint32_t retransmit = 0;
sprang@webrtc.orgccd42842014-01-07 09:54:34760 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
pbos@webrtc.org49096de2015-02-24 22:37:52761 bitrate_observer->Notify(total, retransmit, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34762
763 // From FrameCountObserver.
764 FrameCountObserver* fps_observer = statistics_proxy_.get();
pbos@webrtc.orgce4e9a32014-12-18 13:50:16765 FrameCounts frame_counts;
766 frame_counts.key_frames = 1;
pbos@webrtc.org49096de2015-02-24 22:37:52767 fps_observer->FrameCountUpdated(frame_counts, excluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34768
769 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
770 EXPECT_TRUE(stats.substreams.empty());
771}
772
pbos@webrtc.org273a4142014-12-01 15:23:21773TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
774 static const int kEncodedWidth = 123;
775 static const int kEncodedHeight = 81;
776 EncodedImage encoded_image;
777 encoded_image._encodedWidth = kEncodedWidth;
778 encoded_image._encodedHeight = kEncodedHeight;
779
kjellander02b3d272016-04-20 12:05:54780 CodecSpecificInfo codec_info;
781 codec_info.codecType = kVideoCodecVP8;
782 codec_info.codecSpecific.VP8.simulcastIdx = 0;
pbos@webrtc.org273a4142014-12-01 15:23:21783
kjellander02b3d272016-04-20 12:05:54784 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
785 codec_info.codecSpecific.VP8.simulcastIdx = 1;
786 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21787
788 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16789 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
790 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
791 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
792 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21793
794 // Forward almost to timeout, this should not have removed stats.
795 fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
796 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16797 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
798 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21799
800 // Update the first SSRC with bogus RTCP stats to make sure that encoded
801 // resolution still times out (no global timeout for all stats).
802 RtcpStatistics rtcp_statistics;
803 RtcpStatisticsCallback* rtcp_stats = statistics_proxy_.get();
804 rtcp_stats->StatisticsUpdated(rtcp_statistics, config_.rtp.ssrcs[0]);
805
806 // Report stats for second SSRC to make sure it's not outdated along with the
807 // first SSRC.
kjellander02b3d272016-04-20 12:05:54808 codec_info.codecSpecific.VP8.simulcastIdx = 1;
809 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
pbos@webrtc.org273a4142014-12-01 15:23:21810
811 // Forward 1 ms, reach timeout, substream 0 should have no resolution
812 // reported, but substream 1 should.
813 fake_clock_.AdvanceTimeMilliseconds(1);
814 stats = statistics_proxy_->GetStats();
pbos@webrtc.org09c77b92015-02-25 10:42:16815 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].width);
816 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].height);
817 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
818 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
pbos@webrtc.org273a4142014-12-01 15:23:21819}
820
Peter Boström20f3f942015-05-15 09:33:39821TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
822 static const int kEncodedWidth = 123;
823 static const int kEncodedHeight = 81;
824 EncodedImage encoded_image;
825 encoded_image._encodedWidth = kEncodedWidth;
826 encoded_image._encodedHeight = kEncodedHeight;
827
kjellander02b3d272016-04-20 12:05:54828 CodecSpecificInfo codec_info;
829 codec_info.codecType = kVideoCodecVP8;
830 codec_info.codecSpecific.VP8.simulcastIdx = 0;
Peter Boström20f3f942015-05-15 09:33:39831
kjellander02b3d272016-04-20 12:05:54832 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
833 codec_info.codecSpecific.VP8.simulcastIdx = 1;
834 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
Peter Boström20f3f942015-05-15 09:33:39835
836 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
837 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
838 EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
839 EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
840 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].width);
841 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].height);
842}
843
844TEST_F(SendStatisticsProxyTest, ClearsBitratesFromInactiveSsrcs) {
sprangcd349d92016-07-13 16:11:28845 uint32_t bitrate = 42;
Peter Boström20f3f942015-05-15 09:33:39846 BitrateStatisticsObserver* observer = statistics_proxy_.get();
847 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[0]);
848 observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[1]);
849
850 statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
851
852 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprangcd349d92016-07-13 16:11:28853 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 09:33:39854 stats.substreams[config_.rtp.ssrcs[0]].total_bitrate_bps);
sprangcd349d92016-07-13 16:11:28855 EXPECT_EQ(static_cast<int>(bitrate),
Peter Boström20f3f942015-05-15 09:33:39856 stats.substreams[config_.rtp.ssrcs[0]].retransmit_bitrate_bps);
857 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].total_bitrate_bps);
858 EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].retransmit_bitrate_bps);
859}
860
sprang07fb9be2016-02-24 15:55:00861TEST_F(SendStatisticsProxyTest, ResetsRtcpCountersOnContentChange) {
862 RtcpPacketTypeCounterObserver* proxy =
863 static_cast<RtcpPacketTypeCounterObserver*>(statistics_proxy_.get());
864 RtcpPacketTypeCounter counters;
865 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
866 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
867 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
868
869 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
870
871 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
872 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
873 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
874 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
875 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
876
877 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
878 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
879
880 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 09:48:50881 VideoEncoderConfig config;
882 config.content_type = VideoEncoderConfig::ContentType::kScreen;
883 statistics_proxy_->OnEncoderReconfigured(config, 50);
sprang07fb9be2016-02-24 15:55:00884
asapersson01d70a32016-05-20 13:29:46885 EXPECT_EQ(1,
886 metrics::NumSamples("WebRTC.Video.NackPacketsReceivedPerMinute"));
887 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsReceivedPerMinute"));
888 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsReceivedPerMinute"));
889 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 15:55:00890 "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
891
892 const int kRate = 60 * 2; // Packets per minute with two streams.
893
asapersson01d70a32016-05-20 13:29:46894 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.NackPacketsReceivedPerMinute",
895 1 * kRate));
896 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.FirPacketsReceivedPerMinute",
897 2 * kRate));
898 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.PliPacketsReceivedPerMinute",
899 3 * kRate));
900 EXPECT_EQ(
901 1, metrics::NumEvents("WebRTC.Video.UniqueNackRequestsReceivedInPercent",
902 4 * 100 / 5));
sprang07fb9be2016-02-24 15:55:00903
904 // New start time but same counter values.
905 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
906 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
907
908 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
909
910 counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
911 counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
912 counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
913 counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
914 counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
915
916 proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
917 proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
918
919 SetUp(); // Reset stats proxy also causes histograms to be reported.
920
asapersson01d70a32016-05-20 13:29:46921 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 15:55:00922 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 13:29:46923 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 15:55:00924 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute"));
asapersson01d70a32016-05-20 13:29:46925 EXPECT_EQ(1, metrics::NumSamples(
sprang07fb9be2016-02-24 15:55:00926 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute"));
927 EXPECT_EQ(
asapersson01d70a32016-05-20 13:29:46928 1, metrics::NumSamples(
sprang07fb9be2016-02-24 15:55:00929 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent"));
930
asapersson01d70a32016-05-20 13:29:46931 EXPECT_EQ(1, metrics::NumEvents(
932 "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute",
933 1 * kRate));
934 EXPECT_EQ(1, metrics::NumEvents(
935 "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute",
936 2 * kRate));
937 EXPECT_EQ(1, metrics::NumEvents(
938 "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute",
939 3 * kRate));
940 EXPECT_EQ(1,
941 metrics::NumEvents(
942 "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent",
943 4 * 100 / 5));
sprang07fb9be2016-02-24 15:55:00944}
945
asaperssona6a699a2016-11-25 11:52:46946TEST_F(SendStatisticsProxyTest, GetStatsReportsIsFlexFec) {
947 statistics_proxy_.reset(
948 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
949 VideoEncoderConfig::ContentType::kRealtimeVideo));
950
951 StreamDataCountersCallback* proxy =
952 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
953 StreamDataCounters counters;
954 proxy->DataCountersUpdated(counters, kFirstSsrc);
955 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
956
957 EXPECT_FALSE(GetStreamStats(kFirstSsrc).is_flexfec);
958 EXPECT_TRUE(GetStreamStats(kFlexFecSsrc).is_flexfec);
959}
960
961TEST_F(SendStatisticsProxyTest, SendBitratesAreReportedWithFlexFecEnabled) {
962 statistics_proxy_.reset(
963 new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
964 VideoEncoderConfig::ContentType::kRealtimeVideo));
965
966 StreamDataCountersCallback* proxy =
967 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
968
969 StreamDataCounters counters;
970 StreamDataCounters rtx_counters;
971 proxy->DataCountersUpdated(counters, kFirstSsrc);
972 proxy->DataCountersUpdated(counters, kSecondSsrc);
973 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
974 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
975 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
976
977 counters.transmitted.header_bytes = 5000;
978 counters.transmitted.packets = 20;
979 counters.transmitted.padding_bytes = 10000;
980 counters.transmitted.payload_bytes = 20000;
981 counters.retransmitted.header_bytes = 400;
982 counters.retransmitted.packets = 2;
983 counters.retransmitted.padding_bytes = 1000;
984 counters.retransmitted.payload_bytes = 2000;
985 counters.fec = counters.retransmitted;
986 rtx_counters.transmitted = counters.transmitted;
987
988 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
989 proxy->DataCountersUpdated(counters, kFirstSsrc);
990 proxy->DataCountersUpdated(counters, kSecondSsrc);
991 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
992 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
993 proxy->DataCountersUpdated(counters, kFlexFecSsrc);
994
995 // Reset stats proxy causes histograms to be reported.
996 statistics_proxy_.reset();
997 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
998 EXPECT_EQ(1,
999 metrics::NumEvents(
1000 "WebRTC.Video.BitrateSentInKbps",
1001 static_cast<int>((counters.transmitted.TotalBytes() * 4 * 8) /
1002 metrics::kMinRunTimeInSeconds / 1000)));
1003
1004 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
1005 EXPECT_EQ(1, metrics::NumEvents(
1006 "WebRTC.Video.MediaBitrateSentInKbps",
1007 static_cast<int>((counters.MediaPayloadBytes() * 2 * 8) /
1008 metrics::kMinRunTimeInSeconds / 1000)));
1009
1010 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
1011 EXPECT_EQ(1,
1012 metrics::NumEvents(
1013 "WebRTC.Video.PaddingBitrateSentInKbps",
1014 static_cast<int>((counters.transmitted.padding_bytes * 4 * 8) /
1015 metrics::kMinRunTimeInSeconds / 1000)));
1016
1017 EXPECT_EQ(1,
1018 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
1019 EXPECT_EQ(1,
1020 metrics::NumEvents(
1021 "WebRTC.Video.RetransmittedBitrateSentInKbps",
1022 static_cast<int>((counters.retransmitted.TotalBytes() * 2 * 8) /
1023 metrics::kMinRunTimeInSeconds / 1000)));
1024
1025 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
1026 EXPECT_EQ(
1027 1, metrics::NumEvents(
1028 "WebRTC.Video.RtxBitrateSentInKbps",
1029 static_cast<int>((rtx_counters.transmitted.TotalBytes() * 2 * 8) /
1030 metrics::kMinRunTimeInSeconds / 1000)));
1031
1032 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1033 EXPECT_EQ(1, metrics::NumEvents(
1034 "WebRTC.Video.FecBitrateSentInKbps",
1035 static_cast<int>((counters.fec.TotalBytes() * 2 * 8) /
1036 metrics::kMinRunTimeInSeconds / 1000)));
1037}
1038
Erik Språng22c2b482016-03-01 08:40:421039TEST_F(SendStatisticsProxyTest, ResetsRtpCountersOnContentChange) {
1040 StreamDataCountersCallback* proxy =
1041 static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
1042 StreamDataCounters counters;
1043 StreamDataCounters rtx_counters;
1044 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
1045 proxy->DataCountersUpdated(counters, kFirstSsrc);
1046 proxy->DataCountersUpdated(counters, kSecondSsrc);
1047 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1048 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1049
asaperssona6a699a2016-11-25 11:52:461050 counters.transmitted.header_bytes = 5000;
Erik Språng22c2b482016-03-01 08:40:421051 counters.transmitted.packets = 20;
asaperssona6a699a2016-11-25 11:52:461052 counters.transmitted.padding_bytes = 10000;
1053 counters.transmitted.payload_bytes = 20000;
Erik Språng22c2b482016-03-01 08:40:421054
asaperssona6a699a2016-11-25 11:52:461055 counters.retransmitted.header_bytes = 400;
Erik Språng22c2b482016-03-01 08:40:421056 counters.retransmitted.packets = 2;
asaperssona6a699a2016-11-25 11:52:461057 counters.retransmitted.padding_bytes = 1000;
1058 counters.retransmitted.payload_bytes = 2000;
Erik Språng22c2b482016-03-01 08:40:421059
1060 counters.fec = counters.retransmitted;
1061
1062 rtx_counters.transmitted = counters.transmitted;
1063
1064 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1065 proxy->DataCountersUpdated(counters, kFirstSsrc);
1066 proxy->DataCountersUpdated(counters, kSecondSsrc);
1067 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1068 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1069
1070 // Changing content type causes histograms to be reported.
Pera48ddb72016-09-29 09:48:501071 VideoEncoderConfig config;
1072 config.content_type = VideoEncoderConfig::ContentType::kScreen;
1073 statistics_proxy_->OnEncoderReconfigured(config, 50);
Erik Språng22c2b482016-03-01 08:40:421074
asapersson01d70a32016-05-20 13:29:461075 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
1076 EXPECT_EQ(1,
1077 metrics::NumEvents(
1078 "WebRTC.Video.BitrateSentInKbps",
1079 static_cast<int>((counters.transmitted.TotalBytes() * 4 * 8) /
1080 metrics::kMinRunTimeInSeconds / 1000)));
1081
1082 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
1083 EXPECT_EQ(1, metrics::NumEvents(
1084 "WebRTC.Video.MediaBitrateSentInKbps",
1085 static_cast<int>((counters.MediaPayloadBytes() * 2 * 8) /
1086 metrics::kMinRunTimeInSeconds / 1000)));
1087
1088 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
1089 EXPECT_EQ(1,
1090 metrics::NumEvents(
1091 "WebRTC.Video.PaddingBitrateSentInKbps",
1092 static_cast<int>((counters.transmitted.padding_bytes * 4 * 8) /
1093 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421094
1095 EXPECT_EQ(1,
asapersson01d70a32016-05-20 13:29:461096 metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 08:40:421097 EXPECT_EQ(1,
asapersson01d70a32016-05-20 13:29:461098 metrics::NumEvents(
1099 "WebRTC.Video.RetransmittedBitrateSentInKbps",
1100 static_cast<int>((counters.retransmitted.TotalBytes() * 2 * 8) /
1101 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421102
asapersson01d70a32016-05-20 13:29:461103 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
Erik Språng22c2b482016-03-01 08:40:421104 EXPECT_EQ(
asapersson01d70a32016-05-20 13:29:461105 1, metrics::NumEvents(
1106 "WebRTC.Video.RtxBitrateSentInKbps",
1107 static_cast<int>((rtx_counters.transmitted.TotalBytes() * 2 * 8) /
1108 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421109
asapersson01d70a32016-05-20 13:29:461110 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
1111 EXPECT_EQ(1, metrics::NumEvents(
1112 "WebRTC.Video.FecBitrateSentInKbps",
asaperssona6a699a2016-11-25 11:52:461113 static_cast<int>((counters.fec.TotalBytes() * 2 * 8) /
asapersson01d70a32016-05-20 13:29:461114 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421115
1116 // New start time but same counter values.
1117 proxy->DataCountersUpdated(counters, kFirstSsrc);
1118 proxy->DataCountersUpdated(counters, kSecondSsrc);
1119 proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
1120 proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
1121
1122 // Double counter values, this should result in the same counts as before but
1123 // with new histogram names.
1124 StreamDataCounters new_counters = counters;
1125 new_counters.Add(counters);
1126 StreamDataCounters new_rtx_counters = rtx_counters;
1127 new_rtx_counters.Add(rtx_counters);
1128
1129 fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
1130 proxy->DataCountersUpdated(new_counters, kFirstSsrc);
1131 proxy->DataCountersUpdated(new_counters, kSecondSsrc);
1132 proxy->DataCountersUpdated(new_rtx_counters, kFirstRtxSsrc);
1133 proxy->DataCountersUpdated(new_rtx_counters, kSecondRtxSsrc);
1134
1135 SetUp(); // Reset stats proxy also causes histograms to be reported.
1136
asapersson01d70a32016-05-20 13:29:461137 EXPECT_EQ(1,
1138 metrics::NumSamples("WebRTC.Video.Screenshare.BitrateSentInKbps"));
1139 EXPECT_EQ(1,
1140 metrics::NumEvents(
1141 "WebRTC.Video.Screenshare.BitrateSentInKbps",
1142 static_cast<int>((counters.transmitted.TotalBytes() * 4 * 8) /
1143 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421144
asapersson01d70a32016-05-20 13:29:461145 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 08:40:421146 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
asapersson01d70a32016-05-20 13:29:461147 EXPECT_EQ(1, metrics::NumEvents(
1148 "WebRTC.Video.Screenshare.MediaBitrateSentInKbps",
1149 static_cast<int>((counters.MediaPayloadBytes() * 2 * 8) /
1150 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421151
asapersson01d70a32016-05-20 13:29:461152 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 08:40:421153 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
asapersson01d70a32016-05-20 13:29:461154 EXPECT_EQ(1,
1155 metrics::NumEvents(
1156 "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps",
1157 static_cast<int>((counters.transmitted.padding_bytes * 4 * 8) /
1158 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421159
asapersson01d70a32016-05-20 13:29:461160 EXPECT_EQ(1, metrics::NumSamples(
Erik Språng22c2b482016-03-01 08:40:421161 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
asapersson01d70a32016-05-20 13:29:461162 EXPECT_EQ(1,
1163 metrics::NumEvents(
1164 "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps",
1165 static_cast<int>((counters.retransmitted.TotalBytes() * 2 * 8) /
1166 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421167
asapersson01d70a32016-05-20 13:29:461168 EXPECT_EQ(
1169 1, metrics::NumSamples("WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
1170 EXPECT_EQ(
1171 1, metrics::NumEvents(
1172 "WebRTC.Video.Screenshare.RtxBitrateSentInKbps",
1173 static_cast<int>((rtx_counters.transmitted.TotalBytes() * 2 * 8) /
1174 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421175
asapersson01d70a32016-05-20 13:29:461176 EXPECT_EQ(
1177 1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
1178 EXPECT_EQ(1, metrics::NumEvents(
1179 "WebRTC.Video.Screenshare.FecBitrateSentInKbps",
asaperssona6a699a2016-11-25 11:52:461180 static_cast<int>((counters.fec.TotalBytes() * 2 * 8) /
asapersson01d70a32016-05-20 13:29:461181 metrics::kMinRunTimeInSeconds / 1000)));
Erik Språng22c2b482016-03-01 08:40:421182}
1183
sprang@webrtc.orgccd42842014-01-07 09:54:341184} // namespace webrtc