blob: f61f0865ac73f0ebe8cf8465ebb2092614c3c1b8 [file] [log] [blame]
sakale5ba44e2016-10-26 07:09:24 -07001/*
2 * Copyright 2016 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/receive_statistics_proxy.h"
sakale5ba44e2016-10-26 07:09:24 -070012
asapersson2077f2f2017-05-11 05:37:35 -070013#include <limits>
sakale5ba44e2016-10-26 07:09:24 -070014#include <memory>
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +020015#include <utility>
sakale5ba44e2016-10-26 07:09:24 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/video/i420_buffer.h"
18#include "api/video/video_frame.h"
19#include "api/video/video_rotation.h"
20#include "modules/video_coding/include/video_codec_interface.h"
21#include "system_wrappers/include/metrics.h"
22#include "system_wrappers/include/metrics_default.h"
23#include "test/gtest.h"
sakale5ba44e2016-10-26 07:09:24 -070024
25namespace webrtc {
asaperssonde9e5ff2016-11-02 07:14:03 -070026namespace {
27const int64_t kFreqOffsetProcessIntervalInMs = 40000;
asapersson46c4e3c2016-11-03 06:48:19 -070028const uint32_t kLocalSsrc = 123;
29const uint32_t kRemoteSsrc = 456;
30const int kMinRequiredSamples = 200;
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +020031
32const int kWidth = 1280;
33const int kHeight = 720;
34
asaperssonde9e5ff2016-11-02 07:14:03 -070035} // namespace
sakale5ba44e2016-10-26 07:09:24 -070036
37// TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
sprang892dab52017-08-15 05:00:33 -070038class ReceiveStatisticsProxyTest
39 : public ::testing::TestWithParam<webrtc::VideoContentType> {
sakale5ba44e2016-10-26 07:09:24 -070040 public:
41 ReceiveStatisticsProxyTest() : fake_clock_(1234), config_(GetTestConfig()) {}
42 virtual ~ReceiveStatisticsProxyTest() {}
43
44 protected:
45 virtual void SetUp() {
asaperssonde9e5ff2016-11-02 07:14:03 -070046 metrics::Reset();
sakale5ba44e2016-10-26 07:09:24 -070047 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_));
48 }
49
50 VideoReceiveStream::Config GetTestConfig() {
51 VideoReceiveStream::Config config(nullptr);
asapersson46c4e3c2016-11-03 06:48:19 -070052 config.rtp.local_ssrc = kLocalSsrc;
53 config.rtp.remote_ssrc = kRemoteSsrc;
sakale5ba44e2016-10-26 07:09:24 -070054 return config;
55 }
56
asapersson2077f2f2017-05-11 05:37:35 -070057 void InsertFirstRtpPacket(uint32_t ssrc) {
58 StreamDataCounters counters;
59 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
60 statistics_proxy_->DataCountersUpdated(counters, ssrc);
61 }
62
63 VideoFrame CreateFrame(int width, int height) {
64 VideoFrame frame(I420Buffer::Create(width, height), 0, 0, kVideoRotation_0);
65 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
66 return frame;
67 }
68
sakale5ba44e2016-10-26 07:09:24 -070069 SimulatedClock fake_clock_;
asaperssonde9e5ff2016-11-02 07:14:03 -070070 const VideoReceiveStream::Config config_;
sakale5ba44e2016-10-26 07:09:24 -070071 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
sakale5ba44e2016-10-26 07:09:24 -070072};
73
74TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) {
75 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
76 for (uint32_t i = 1; i <= 3; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +020077 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
ilnik00d802b2017-04-11 10:34:31 -070078 VideoContentType::UNSPECIFIED);
sakale5ba44e2016-10-26 07:09:24 -070079 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
80 }
81}
82
Åsa Perssonb9b07ea2018-01-24 17:04:07 +010083TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsReported) {
84 const int kFps = 20;
85 const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
86 for (int i = 0; i < kRequiredSamples; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +020087 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), kWidth, kHeight,
Åsa Perssonb9b07ea2018-01-24 17:04:07 +010088 VideoContentType::UNSPECIFIED);
89 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
90 }
91 statistics_proxy_.reset();
92 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
93 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps));
94}
95
96TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsNotReportedForTooFewSamples) {
97 const int kFps = 20;
98 const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
99 for (int i = 0; i < kRequiredSamples - 1; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200100 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), kWidth, kHeight,
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100101 VideoContentType::UNSPECIFIED);
102 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
103 }
104 statistics_proxy_.reset();
105 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
106}
107
108TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsReportedWithQpReset) {
109 const int kFps1 = 10;
110 for (int i = 0; i < metrics::kMinRunTimeInSeconds * kFps1; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200111 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), kWidth, kHeight,
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100112 VideoContentType::UNSPECIFIED);
113 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps1);
114 }
115 // First QP value received, resets frames decoded.
116 const int kFps2 = 20;
117 for (int i = 0; i < metrics::kMinRunTimeInSeconds * kFps2; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200118 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(1u), kWidth,
119 kHeight, VideoContentType::UNSPECIFIED);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100120 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps2);
121 }
122 statistics_proxy_.reset();
123 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
124 EXPECT_EQ(1,
125 metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps2));
126}
127
sakalcc452e12017-02-09 04:53:45 -0800128TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithQpResetsFramesDecoded) {
129 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
130 for (uint32_t i = 1; i <= 3; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200131 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
ilnik00d802b2017-04-11 10:34:31 -0700132 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800133 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
134 }
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200135 statistics_proxy_->OnDecodedFrame(1u, kWidth, kHeight,
136 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800137 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_decoded);
138}
139
140TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100141 EXPECT_EQ(rtc::nullopt, statistics_proxy_->GetStats().qp_sum);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200142 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
143 VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100144 EXPECT_EQ(3u, statistics_proxy_->GetStats().qp_sum);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200145 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
146 VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100147 EXPECT_EQ(130u, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800148}
149
ilnik2e1b40b2017-09-04 07:57:17 -0700150TEST_F(ReceiveStatisticsProxyTest, ReportsContentType) {
151 const std::string kRealtimeString("realtime");
152 const std::string kScreenshareString("screen");
153 EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
154 statistics_proxy_->GetStats().content_type));
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200155 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
156 VideoContentType::SCREENSHARE);
ilnik2e1b40b2017-09-04 07:57:17 -0700157 EXPECT_EQ(kScreenshareString, videocontenttypehelpers::ToString(
158 statistics_proxy_->GetStats().content_type));
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200159 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
160 VideoContentType::UNSPECIFIED);
ilnik2e1b40b2017-09-04 07:57:17 -0700161 EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
162 statistics_proxy_->GetStats().content_type));
163}
164
ilnika79cc282017-08-23 05:24:10 -0700165TEST_F(ReceiveStatisticsProxyTest, ReportsMaxInterframeDelay) {
166 const int64_t kInterframeDelayMs1 = 100;
167 const int64_t kInterframeDelayMs2 = 200;
168 const int64_t kInterframeDelayMs3 = 100;
169 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200170 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
171 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700172 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700173
174 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200175 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
176 VideoContentType::UNSPECIFIED);
ilnikf04afde2017-07-07 01:26:24 -0700177 EXPECT_EQ(kInterframeDelayMs1,
ilnika79cc282017-08-23 05:24:10 -0700178 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700179
180 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200181 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
182 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700183 EXPECT_EQ(kInterframeDelayMs2,
184 statistics_proxy_->GetStats().interframe_delay_max_ms);
185
186 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200187 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
188 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700189 // kInterframeDelayMs3 is smaller than kInterframeDelayMs2.
190 EXPECT_EQ(kInterframeDelayMs2,
191 statistics_proxy_->GetStats().interframe_delay_max_ms);
192}
193
194TEST_F(ReceiveStatisticsProxyTest, ReportInterframeDelayInWindow) {
Ilya Nikolaevskiyb06b3582017-10-16 17:59:12 +0200195 const int64_t kInterframeDelayMs1 = 900;
196 const int64_t kInterframeDelayMs2 = 750;
197 const int64_t kInterframeDelayMs3 = 700;
ilnika79cc282017-08-23 05:24:10 -0700198 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200199 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
200 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700201 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
202
203 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200204 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
205 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700206 EXPECT_EQ(kInterframeDelayMs1,
207 statistics_proxy_->GetStats().interframe_delay_max_ms);
208
209 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200210 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
211 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700212 // Still first delay is the maximum
213 EXPECT_EQ(kInterframeDelayMs1,
214 statistics_proxy_->GetStats().interframe_delay_max_ms);
215
216 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200217 statistics_proxy_->OnDecodedFrame(127u, kWidth, kHeight,
218 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700219 // Now the first sample is out of the window, so the second is the maximum.
220 EXPECT_EQ(kInterframeDelayMs2,
221 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700222}
223
sakalcc452e12017-02-09 04:53:45 -0800224TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100225 EXPECT_EQ(rtc::nullopt, statistics_proxy_->GetStats().qp_sum);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200226 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
ilnik00d802b2017-04-11 10:34:31 -0700227 VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100228 EXPECT_EQ(rtc::nullopt, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800229}
230
231TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100232 EXPECT_EQ(rtc::nullopt, statistics_proxy_->GetStats().qp_sum);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200233 statistics_proxy_->OnDecodedFrame(3u, kWidth, kHeight,
234 VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100235 EXPECT_EQ(3u, statistics_proxy_->GetStats().qp_sum);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200236 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
ilnik00d802b2017-04-11 10:34:31 -0700237 VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100238 EXPECT_EQ(rtc::nullopt, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800239}
240
hbos50cfe1f2017-01-23 07:21:55 -0800241TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) {
242 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
ilnik00d802b2017-04-11 10:34:31 -0700243 webrtc::VideoFrame frame(webrtc::I420Buffer::Create(1, 1), 0, 0,
244 webrtc::kVideoRotation_0);
hbos50cfe1f2017-01-23 07:21:55 -0800245 for (uint32_t i = 1; i <= 3; ++i) {
246 statistics_proxy_->OnRenderedFrame(frame);
247 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
248 }
249}
250
asapersson46c4e3c2016-11-03 06:48:19 -0700251TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsSsrc) {
252 EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
253}
254
255TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsIncomingPayloadType) {
256 const int kPayloadType = 111;
257 statistics_proxy_->OnIncomingPayloadType(kPayloadType);
258 EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
259}
260
asapersson6966bd52017-01-03 00:44:06 -0800261TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecoderImplementationName) {
262 const char* kName = "decoderName";
263 statistics_proxy_->OnDecoderImplementationName(kName);
264 EXPECT_STREQ(
265 kName, statistics_proxy_->GetStats().decoder_implementation_name.c_str());
266}
267
philipela45102f2017-02-22 05:30:39 -0800268TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsOnCompleteFrame) {
269 const int kFrameSizeBytes = 1000;
ilnik6d5b4d62017-08-30 03:32:14 -0700270 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
271 VideoContentType::UNSPECIFIED);
philipela45102f2017-02-22 05:30:39 -0800272 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
273 EXPECT_EQ(1, stats.network_frame_rate);
philipela45102f2017-02-22 05:30:39 -0800274 EXPECT_EQ(1, stats.frame_counts.key_frames);
275 EXPECT_EQ(0, stats.frame_counts.delta_frames);
asapersson46c4e3c2016-11-03 06:48:19 -0700276}
277
278TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecodeTimingStats) {
279 const int kDecodeMs = 1;
280 const int kMaxDecodeMs = 2;
281 const int kCurrentDelayMs = 3;
282 const int kTargetDelayMs = 4;
283 const int kJitterBufferMs = 5;
284 const int kMinPlayoutDelayMs = 6;
285 const int kRenderDelayMs = 7;
286 const int64_t kRttMs = 8;
philipela45102f2017-02-22 05:30:39 -0800287 statistics_proxy_->OnRttUpdate(kRttMs, 0);
288 statistics_proxy_->OnFrameBufferTimingsUpdated(
asapersson46c4e3c2016-11-03 06:48:19 -0700289 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
philipela45102f2017-02-22 05:30:39 -0800290 kMinPlayoutDelayMs, kRenderDelayMs);
asapersson46c4e3c2016-11-03 06:48:19 -0700291 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
292 EXPECT_EQ(kDecodeMs, stats.decode_ms);
293 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
294 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
295 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
296 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
297 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
298 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
299}
300
asapersson6966bd52017-01-03 00:44:06 -0800301TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpPacketTypeCounts) {
302 const uint32_t kFirPackets = 33;
303 const uint32_t kPliPackets = 44;
304 const uint32_t kNackPackets = 55;
305 RtcpPacketTypeCounter counter;
306 counter.fir_packets = kFirPackets;
307 counter.pli_packets = kPliPackets;
308 counter.nack_packets = kNackPackets;
309 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
310 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
311 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
312 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
313 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
314}
315
316TEST_F(ReceiveStatisticsProxyTest,
317 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
318 RtcpPacketTypeCounter counter;
319 counter.fir_packets = 33;
320 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
321 EXPECT_EQ(0u,
322 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
323}
324
325TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsFrameCounts) {
326 const int kKeyFrames = 3;
327 const int kDeltaFrames = 22;
328 FrameCounts frame_counts;
329 frame_counts.key_frames = kKeyFrames;
330 frame_counts.delta_frames = kDeltaFrames;
331 statistics_proxy_->OnFrameCountsUpdated(frame_counts);
332 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
333 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
334 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
335}
336
asapersson46c4e3c2016-11-03 06:48:19 -0700337TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDiscardedPackets) {
338 const int kDiscardedPackets = 12;
339 statistics_proxy_->OnDiscardedPacketsUpdated(kDiscardedPackets);
340 EXPECT_EQ(kDiscardedPackets, statistics_proxy_->GetStats().discarded_packets);
341}
342
asapersson6966bd52017-01-03 00:44:06 -0800343TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpStats) {
344 const uint8_t kFracLost = 0;
Harald Alvestrandc7c41912017-12-08 09:59:34 +0100345 const int32_t kCumLost = 1;
asapersson6966bd52017-01-03 00:44:06 -0800346 const uint32_t kExtSeqNum = 10;
347 const uint32_t kJitter = 4;
348
349 RtcpStatistics rtcp_stats;
350 rtcp_stats.fraction_lost = kFracLost;
srte186d9c32017-08-04 05:03:53 -0700351 rtcp_stats.packets_lost = kCumLost;
352 rtcp_stats.extended_highest_sequence_number = kExtSeqNum;
asapersson6966bd52017-01-03 00:44:06 -0800353 rtcp_stats.jitter = kJitter;
354 statistics_proxy_->StatisticsUpdated(rtcp_stats, kRemoteSsrc);
355
356 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
357 EXPECT_EQ(kFracLost, stats.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700358 EXPECT_EQ(kCumLost, stats.rtcp_stats.packets_lost);
359 EXPECT_EQ(kExtSeqNum, stats.rtcp_stats.extended_highest_sequence_number);
asapersson6966bd52017-01-03 00:44:06 -0800360 EXPECT_EQ(kJitter, stats.rtcp_stats.jitter);
361}
362
363TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsCName) {
364 const char* kName = "cName";
365 statistics_proxy_->CNameChanged(kName, kRemoteSsrc);
366 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
367}
368
369TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsNoCNameForUnknownSsrc) {
370 const char* kName = "cName";
371 statistics_proxy_->CNameChanged(kName, kRemoteSsrc + 1);
372 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
373}
374
ilnik2edc6842017-07-06 03:06:50 -0700375TEST_F(ReceiveStatisticsProxyTest,
ilnik75204c52017-09-04 03:35:40 -0700376 ReportsLongestTimingFrameInfo) {
ilnik2edc6842017-07-06 03:06:50 -0700377 const int64_t kShortEndToEndDelay = 10;
378 const int64_t kMedEndToEndDelay = 20;
379 const int64_t kLongEndToEndDelay = 100;
380 const uint32_t kExpectedRtpTimestamp = 2;
381 TimingFrameInfo info;
382 rtc::Optional<TimingFrameInfo> result;
383 info.rtp_timestamp = kExpectedRtpTimestamp - 1;
384 info.capture_time_ms = 0;
385 info.decode_finish_ms = kShortEndToEndDelay;
386 statistics_proxy_->OnTimingFrameInfoUpdated(info);
387 info.rtp_timestamp =
388 kExpectedRtpTimestamp; // this frame should be reported in the end.
389 info.capture_time_ms = 0;
390 info.decode_finish_ms = kLongEndToEndDelay;
391 statistics_proxy_->OnTimingFrameInfoUpdated(info);
392 info.rtp_timestamp = kExpectedRtpTimestamp + 1;
393 info.capture_time_ms = 0;
394 info.decode_finish_ms = kMedEndToEndDelay;
395 statistics_proxy_->OnTimingFrameInfoUpdated(info);
ilnik75204c52017-09-04 03:35:40 -0700396 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700397 EXPECT_TRUE(result);
398 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
399}
400
ilnik75204c52017-09-04 03:35:40 -0700401TEST_F(ReceiveStatisticsProxyTest, RespectsReportingIntervalForTimingFrames) {
402 TimingFrameInfo info;
ilnik2edc6842017-07-06 03:06:50 -0700403 const int64_t kShortEndToEndDelay = 10;
404 const uint32_t kExpectedRtpTimestamp = 2;
ilnik75204c52017-09-04 03:35:40 -0700405 const int64_t kShortDelayMs = 1000;
406 const int64_t kLongDelayMs = 10000;
ilnik2edc6842017-07-06 03:06:50 -0700407 rtc::Optional<TimingFrameInfo> result;
408 info.rtp_timestamp = kExpectedRtpTimestamp;
409 info.capture_time_ms = 0;
410 info.decode_finish_ms = kShortEndToEndDelay;
411 statistics_proxy_->OnTimingFrameInfoUpdated(info);
ilnik75204c52017-09-04 03:35:40 -0700412 fake_clock_.AdvanceTimeMilliseconds(kShortDelayMs);
413 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700414 EXPECT_TRUE(result);
415 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
ilnik75204c52017-09-04 03:35:40 -0700416 fake_clock_.AdvanceTimeMilliseconds(kLongDelayMs);
417 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700418 EXPECT_FALSE(result);
419}
420
asapersson46c4e3c2016-11-03 06:48:19 -0700421TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
422 const int64_t kTimeSec = 3;
423 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
ilnik6d5b4d62017-08-30 03:32:14 -0700424 // Need at least one frame to report stream lifetime.
425 statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
asapersson46c4e3c2016-11-03 06:48:19 -0700426 // Histograms are updated when the statistics_proxy_ is deleted.
427 statistics_proxy_.reset();
428 EXPECT_EQ(1,
429 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
430 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
431 kTimeSec));
432}
433
ilnik6d5b4d62017-08-30 03:32:14 -0700434TEST_F(ReceiveStatisticsProxyTest,
435 LifetimeHistogramNotReportedForEmptyStreams) {
436 const int64_t kTimeSec = 3;
437 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
438 // No frames received.
439 // Histograms are updated when the statistics_proxy_ is deleted.
440 statistics_proxy_.reset();
441 EXPECT_EQ(0,
442 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
443}
444
palmkvista40672a2017-01-13 05:58:34 -0800445TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
446 // Based on the tuning parameters this will produce 7 uncertain states,
447 // then 10 certainly bad states. There has to be 10 certain states before
448 // any histograms are recorded.
449 const int kNumBadSamples = 17;
450
451 StreamDataCounters counters;
452 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
453 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
454
455 for (int i = 0; i < kNumBadSamples; ++i) {
456 // Since OnRenderedFrame is never called the fps in each sample will be 0,
457 // i.e. bad
458 fake_clock_.AdvanceTimeMilliseconds(1000);
459 statistics_proxy_->OnIncomingRate(0, 0);
460 }
461 // Histograms are updated when the statistics_proxy_ is deleted.
462 statistics_proxy_.reset();
463 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
464 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
465
466 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
467 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
468
469 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
470
471 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
472}
473
asapersson0c43f772016-11-30 01:42:26 -0800474TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
475 const uint32_t kCumLost1 = 1;
476 const uint32_t kExtSeqNum1 = 10;
477 const uint32_t kCumLost2 = 2;
478 const uint32_t kExtSeqNum2 = 20;
479
480 // One report block received.
481 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700482 rtcp_stats1.packets_lost = kCumLost1;
483 rtcp_stats1.extended_highest_sequence_number = kExtSeqNum1;
asapersson0c43f772016-11-30 01:42:26 -0800484 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
485
486 // Two report blocks received.
487 RtcpStatistics rtcp_stats2;
srte186d9c32017-08-04 05:03:53 -0700488 rtcp_stats2.packets_lost = kCumLost2;
489 rtcp_stats2.extended_highest_sequence_number = kExtSeqNum2;
asapersson0c43f772016-11-30 01:42:26 -0800490 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
491
492 // Two received report blocks but min run time has not passed.
493 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
494 SetUp(); // Reset stat proxy causes histograms to be updated.
495 EXPECT_EQ(0,
496 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
497
498 // Two report blocks received.
499 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
500 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
501
502 // Two received report blocks and min run time has passed.
503 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
504 SetUp();
505 EXPECT_EQ(1,
506 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
507 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
508 (kCumLost2 - kCumLost1) * 100 /
509 (kExtSeqNum2 - kExtSeqNum1)));
510}
511
512TEST_F(ReceiveStatisticsProxyTest,
513 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
514 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700515 rtcp_stats1.packets_lost = 1;
516 rtcp_stats1.extended_highest_sequence_number = 10;
asapersson0c43f772016-11-30 01:42:26 -0800517
518 // Min run time has passed but no received report block.
519 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
520 SetUp(); // Reset stat proxy causes histograms to be updated.
521 EXPECT_EQ(0,
522 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
523
524 // Min run time has passed but only one received report block.
525 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
526 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
527 SetUp();
528 EXPECT_EQ(0,
529 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
530}
531
asapersson2077f2f2017-05-11 05:37:35 -0700532TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) {
533 const int64_t kSyncOffsetMs = 22;
534 const double kFreqKhz = 90.0;
535 EXPECT_EQ(std::numeric_limits<int>::max(),
536 statistics_proxy_->GetStats().sync_offset_ms);
537 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
538 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms);
539}
540
asapersson46c4e3c2016-11-03 06:48:19 -0700541TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
542 const int64_t kSyncOffsetMs = 22;
543 const double kFreqKhz = 90.0;
544 for (int i = 0; i < kMinRequiredSamples; ++i)
545 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
546 // Histograms are updated when the statistics_proxy_ is deleted.
547 statistics_proxy_.reset();
548 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
549 EXPECT_EQ(1,
550 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
551}
552
asaperssonde9e5ff2016-11-02 07:14:03 -0700553TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
554 const int64_t kSyncOffsetMs = 22;
555 const double kFreqKhz = 90.0;
556 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
557 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
558 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
559 // Process interval passed, max diff: 2.
560 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
561 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
562 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
563 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
564 // Process interval passed, max diff: 4.
565 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
566 statistics_proxy_.reset();
567 // Average reported: (2 + 4) / 2 = 3.
568 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
569 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
570}
571
asapersson6966bd52017-01-03 00:44:06 -0800572TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
573 const int kQp = 22;
574 EncodedImage encoded_image;
575 encoded_image.qp_ = kQp;
576 CodecSpecificInfo codec_info;
577 codec_info.codecType = kVideoCodecVP8;
578
579 for (int i = 0; i < kMinRequiredSamples; ++i)
580 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
581
582 statistics_proxy_.reset();
583 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
584 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
585}
586
587TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
588 EncodedImage encoded_image;
589 encoded_image.qp_ = 22;
590 CodecSpecificInfo codec_info;
591 codec_info.codecType = kVideoCodecVP8;
592
593 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
594 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
595
596 statistics_proxy_.reset();
597 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
598}
599
600TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
601 EncodedImage encoded_image;
602 CodecSpecificInfo codec_info;
603 codec_info.codecType = kVideoCodecVP8;
604
605 for (int i = 0; i < kMinRequiredSamples; ++i)
606 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
607
608 statistics_proxy_.reset();
609 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
610}
611
asaperssonb99baf82017-04-20 04:05:43 -0700612TEST_F(ReceiveStatisticsProxyTest,
613 KeyFrameHistogramNotUpdatedForTooFewSamples) {
614 const bool kIsKeyFrame = false;
615 const int kFrameSizeBytes = 1000;
616
617 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700618 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
619 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700620
621 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
622 EXPECT_EQ(kMinRequiredSamples - 1,
623 statistics_proxy_->GetStats().frame_counts.delta_frames);
624
625 statistics_proxy_.reset();
626 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
627}
628
629TEST_F(ReceiveStatisticsProxyTest,
630 KeyFrameHistogramUpdatedForMinRequiredSamples) {
631 const bool kIsKeyFrame = false;
632 const int kFrameSizeBytes = 1000;
633
634 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700635 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
636 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700637
638 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
639 EXPECT_EQ(kMinRequiredSamples,
640 statistics_proxy_->GetStats().frame_counts.delta_frames);
641
642 statistics_proxy_.reset();
643 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
644 EXPECT_EQ(1,
645 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
646}
647
648TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
649 const int kFrameSizeBytes = 1000;
650
651 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700652 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
653 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700654
655 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700656 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
657 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700658
659 EXPECT_EQ(kMinRequiredSamples,
660 statistics_proxy_->GetStats().frame_counts.key_frames);
661 EXPECT_EQ(kMinRequiredSamples,
662 statistics_proxy_->GetStats().frame_counts.delta_frames);
663
664 statistics_proxy_.reset();
665 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
666 EXPECT_EQ(
667 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
668}
669
670TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
671 const int kDecodeMs = 1;
672 const int kMaxDecodeMs = 2;
673 const int kCurrentDelayMs = 3;
674 const int kTargetDelayMs = 4;
675 const int kJitterBufferMs = 5;
676 const int kMinPlayoutDelayMs = 6;
677 const int kRenderDelayMs = 7;
678
679 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
680 statistics_proxy_->OnFrameBufferTimingsUpdated(
681 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
682 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
683 }
684
685 statistics_proxy_.reset();
686 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
687 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
688 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
689 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
690 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
691}
692
693TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
694 const int kDecodeMs = 1;
695 const int kMaxDecodeMs = 2;
696 const int kCurrentDelayMs = 3;
697 const int kTargetDelayMs = 4;
698 const int kJitterBufferMs = 5;
699 const int kMinPlayoutDelayMs = 6;
700 const int kRenderDelayMs = 7;
701
702 for (int i = 0; i < kMinRequiredSamples; ++i) {
703 statistics_proxy_->OnFrameBufferTimingsUpdated(
704 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
705 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
706 }
707
708 statistics_proxy_.reset();
709 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
710 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
711 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
712 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
713 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
714
715 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
716 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
717 kJitterBufferMs));
718 EXPECT_EQ(1,
719 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
720 EXPECT_EQ(
721 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
722 EXPECT_EQ(1,
723 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
724}
725
sprang948b2752017-05-04 02:47:13 -0700726TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
727 const int kDefaultFps = 30;
728 const int kWidth = 320;
729 const int kHeight = 240;
730
731 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer(
732 I420Buffer::Create(kWidth, kHeight));
733 VideoFrame frame(video_frame_buffer, kVideoRotation_0, 0);
734
735 for (int i = 0; i < kDefaultFps; ++i) {
736 // Since OnRenderedFrame is never called the fps in each sample will be 0,
737 // i.e. bad
738 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200739 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
sprang948b2752017-05-04 02:47:13 -0700740 VideoContentType::UNSPECIFIED);
741 statistics_proxy_->OnRenderedFrame(frame);
742 fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
743 }
744
745 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
746 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
747
748 // FPS trackers in stats proxy have a 1000ms sliding window.
749 fake_clock_.AdvanceTimeMilliseconds(1000);
750 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
751 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
752}
753
asapersson2077f2f2017-05-11 05:37:35 -0700754TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) {
755 const int kWidth = 160;
756 const int kHeight = 120;
757 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
758 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
759 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
760
761 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
762
763 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
764 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
765 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
766}
767
768TEST_F(ReceiveStatisticsProxyTest,
769 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
770 const int kWidth = 160;
771 const int kHeight = 120;
772
773 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
774 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
775
776 statistics_proxy_.reset();
777 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
778 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
779 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
780 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
781}
782
783TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
784 const int kWidth = 160;
785 const int kHeight = 120;
786
787 for (int i = 0; i < kMinRequiredSamples; ++i)
788 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
789
790 statistics_proxy_.reset();
791 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
792 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
793 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
794 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
795 EXPECT_EQ(1,
796 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
797 EXPECT_EQ(1,
798 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
799}
800
801TEST_F(ReceiveStatisticsProxyTest,
802 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
803 InsertFirstRtpPacket(kRemoteSsrc);
804 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
805 1);
806
807 RtcpPacketTypeCounter counter;
808 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
809
810 statistics_proxy_.reset();
811 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
812 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
813 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
814}
815
816TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
817 InsertFirstRtpPacket(kRemoteSsrc);
818 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
819
820 const uint32_t kFirPackets = 100;
821 const uint32_t kPliPackets = 200;
822 const uint32_t kNackPackets = 300;
823
824 RtcpPacketTypeCounter counter;
825 counter.fir_packets = kFirPackets;
826 counter.pli_packets = kPliPackets;
827 counter.nack_packets = kNackPackets;
828 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
829
830 statistics_proxy_.reset();
831 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
832 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
833 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
834 EXPECT_EQ(
835 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
836 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
837 EXPECT_EQ(
838 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
839 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
840 EXPECT_EQ(
841 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
842 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
843}
844
sprang892dab52017-08-15 05:00:33 -0700845INSTANTIATE_TEST_CASE_P(ContentTypes,
846 ReceiveStatisticsProxyTest,
847 ::testing::Values(VideoContentType::UNSPECIFIED,
848 VideoContentType::SCREENSHARE));
849
850TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysAreReported) {
851 const VideoContentType content_type = GetParam();
852 const int kInterFrameDelayMs = 33;
853 for (int i = 0; i < kMinRequiredSamples; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200854 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
855 content_type);
sprang892dab52017-08-15 05:00:33 -0700856 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
857 }
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200858 // One extra with double the interval.
sprang892dab52017-08-15 05:00:33 -0700859 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200860 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
861 content_type);
sprang892dab52017-08-15 05:00:33 -0700862
863 statistics_proxy_.reset();
864 const int kExpectedInterFrame =
865 (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
866 kInterFrameDelayMs * 2) /
867 kMinRequiredSamples;
ilnik6d5b4d62017-08-30 03:32:14 -0700868 if (videocontenttypehelpers::IsScreenshare(content_type)) {
869 EXPECT_EQ(
870 kExpectedInterFrame,
871 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
872 EXPECT_EQ(
873 kInterFrameDelayMs * 2,
874 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
875 } else {
876 EXPECT_EQ(kExpectedInterFrame,
877 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
878 EXPECT_EQ(kInterFrameDelayMs * 2,
879 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
sprang892dab52017-08-15 05:00:33 -0700880 }
881}
882
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200883TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysPercentilesAreReported) {
884 const VideoContentType content_type = GetParam();
885 const int kInterFrameDelayMs = 33;
886 const int kLastFivePercentsSamples = kMinRequiredSamples * 5 / 100;
887 for (int i = 0; i <= kMinRequiredSamples - kLastFivePercentsSamples; ++i) {
888 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200889 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
890 content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200891 }
892 // Last 5% of intervals are double in size.
893 for (int i = 0; i < kLastFivePercentsSamples; ++i) {
894 fake_clock_.AdvanceTimeMilliseconds(2 * kInterFrameDelayMs);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200895 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
896 content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200897 }
898 // Final sample is outlier and 10 times as big.
899 fake_clock_.AdvanceTimeMilliseconds(10 * kInterFrameDelayMs);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200900 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
901 content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200902
903 statistics_proxy_.reset();
904 const int kExpectedInterFrame = kInterFrameDelayMs * 2;
905 if (videocontenttypehelpers::IsScreenshare(content_type)) {
906 EXPECT_EQ(kExpectedInterFrame,
907 metrics::MinSample(
908 "WebRTC.Video.Screenshare.InterframeDelay95PercentileInMs"));
909 } else {
910 EXPECT_EQ(
911 kExpectedInterFrame,
912 metrics::MinSample("WebRTC.Video.InterframeDelay95PercentileInMs"));
913 }
914}
915
sprang892dab52017-08-15 05:00:33 -0700916TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithValidAverage) {
917 const VideoContentType content_type = GetParam();
918 const int kInterFrameDelayMs = 33;
919 for (int i = 0; i < kMinRequiredSamples; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200920 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
921 content_type);
sprang892dab52017-08-15 05:00:33 -0700922 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
923 }
924
925 // |kMinRequiredSamples| samples, and thereby intervals, is required. That
926 // means we're one frame short of having a valid data set.
927 statistics_proxy_.reset();
928 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
929 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
930 EXPECT_EQ(
931 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
932 EXPECT_EQ(0, metrics::NumSamples(
933 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
934}
935
sprang3e86e7e2017-08-22 09:23:28 -0700936TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithPause) {
937 const VideoContentType content_type = GetParam();
938 const int kInterFrameDelayMs = 33;
939 for (int i = 0; i <= kMinRequiredSamples; ++i) {
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200940 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
941 content_type);
sprang3e86e7e2017-08-22 09:23:28 -0700942 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
943 }
944
945 // At this state, we should have a valid inter-frame delay.
946 // Indicate stream paused and make a large jump in time.
947 statistics_proxy_->OnStreamInactive();
948 fake_clock_.AdvanceTimeMilliseconds(5000);
949
950 // Insert two more frames. The interval during the pause should be disregarded
951 // in the stats.
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200952 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
953 content_type);
sprang3e86e7e2017-08-22 09:23:28 -0700954 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200955 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
956 content_type);
sprang3e86e7e2017-08-22 09:23:28 -0700957
958 statistics_proxy_.reset();
ilnik6d5b4d62017-08-30 03:32:14 -0700959 if (videocontenttypehelpers::IsScreenshare(content_type)) {
sprang3e86e7e2017-08-22 09:23:28 -0700960 EXPECT_EQ(
961 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
962 EXPECT_EQ(1, metrics::NumSamples(
963 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
964 EXPECT_EQ(
965 kInterFrameDelayMs,
966 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
967 EXPECT_EQ(
968 kInterFrameDelayMs,
969 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
970 } else {
971 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
972 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
973 EXPECT_EQ(kInterFrameDelayMs,
974 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
975 EXPECT_EQ(kInterFrameDelayMs,
976 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
977 }
978}
979
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200980TEST_P(ReceiveStatisticsProxyTest, FreezesAreReported) {
981 const VideoContentType content_type = GetParam();
982 const int kInterFrameDelayMs = 33;
983 const int kFreezeDelayMs = 200;
984 for (int i = 0; i < kMinRequiredSamples; ++i) {
985 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
986 content_type);
987 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
988 }
989 // Add extra freeze.
990 fake_clock_.AdvanceTimeMilliseconds(kFreezeDelayMs);
991 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
992 content_type);
993
994 statistics_proxy_.reset();
995 const int kExpectedTimeBetweenFreezes =
996 kInterFrameDelayMs * (kMinRequiredSamples - 1);
997 if (videocontenttypehelpers::IsScreenshare(content_type)) {
998 EXPECT_EQ(
999 kFreezeDelayMs + kInterFrameDelayMs,
1000 metrics::MinSample("WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1001 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1002 metrics::MinSample(
1003 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1004 } else {
1005 EXPECT_EQ(kFreezeDelayMs + kInterFrameDelayMs,
1006 metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1007 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1008 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1009 }
1010}
1011
1012TEST_P(ReceiveStatisticsProxyTest, PausesAreIgnored) {
1013 const VideoContentType content_type = GetParam();
1014 const int kInterFrameDelayMs = 33;
1015 const int kPauseDurationMs = 10000;
1016 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1017 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
1018 content_type);
1019 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1020 }
1021 // Add a pause.
1022 fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1023 statistics_proxy_->OnStreamInactive();
1024
1025 // Second playback interval with triple the length.
1026 for (int i = 0; i <= kMinRequiredSamples * 3; ++i) {
1027 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
1028 content_type);
1029 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1030 }
1031
1032 statistics_proxy_.reset();
1033 // Average of two playback intervals.
1034 const int kExpectedTimeBetweenFreezes =
1035 kInterFrameDelayMs * kMinRequiredSamples * 2;
1036 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1037 EXPECT_EQ(-1, metrics::MinSample(
1038 "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1039 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1040 metrics::MinSample(
1041 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1042 } else {
1043 EXPECT_EQ(-1, metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1044 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1045 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1046 }
1047}
1048
1049TEST_P(ReceiveStatisticsProxyTest, TimeInHdReported) {
1050 const VideoContentType content_type = GetParam();
1051 const int kInterFrameDelayMs = 20;
1052 // HD frames.
1053 for (int i = 0; i < kMinRequiredSamples; ++i) {
1054 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
1055 content_type);
1056 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1057 }
1058 // SD frames.
1059 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1060 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth / 2, kHeight / 2,
1061 content_type);
1062 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1063 }
1064 // Extra last frame.
1065 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth / 2, kHeight / 2,
1066 content_type);
1067 statistics_proxy_.reset();
1068 const int kExpectedTimeInHdPercents = 33;
1069 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1070 EXPECT_EQ(
1071 kExpectedTimeInHdPercents,
1072 metrics::MinSample("WebRTC.Video.Screenshare.TimeInHdPercentage"));
1073 } else {
1074 EXPECT_EQ(kExpectedTimeInHdPercents,
1075 metrics::MinSample("WebRTC.Video.TimeInHdPercentage"));
1076 }
1077}
1078
1079TEST_P(ReceiveStatisticsProxyTest, TimeInBlockyVideoReported) {
1080 const VideoContentType content_type = GetParam();
1081 const int kInterFrameDelayMs = 20;
1082 const int kHighQp = 80;
1083 const int kLowQp = 30;
1084 // High quality frames.
1085 for (int i = 0; i < kMinRequiredSamples; ++i) {
1086 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth, kHeight, content_type);
1087 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1088 }
1089 // Blocky frames.
1090 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1091 statistics_proxy_->OnDecodedFrame(kHighQp, kWidth, kHeight, content_type);
1092 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1093 }
1094 // Extra last frame.
1095 statistics_proxy_->OnDecodedFrame(kHighQp, kWidth, kHeight, content_type);
1096 statistics_proxy_.reset();
1097 const int kExpectedTimeInHdPercents = 66;
1098 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1099 EXPECT_EQ(kExpectedTimeInHdPercents,
1100 metrics::MinSample(
1101 "WebRTC.Video.Screenshare.TimeInBlockyVideoPercentage"));
1102 } else {
1103 EXPECT_EQ(kExpectedTimeInHdPercents,
1104 metrics::MinSample("WebRTC.Video.TimeInBlockyVideoPercentage"));
1105 }
1106}
1107
1108TEST_P(ReceiveStatisticsProxyTest, DownscalesReported) {
1109 const VideoContentType content_type = GetParam();
1110 const int kInterFrameDelayMs = 1000; // To ensure long enough call duration.
1111 const int kLowQp = 30;
1112
1113 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth / 2, kHeight / 2,
1114 content_type);
1115 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1116
1117 // Downscale.
1118 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth, kHeight, content_type);
1119 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1120
1121 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth / 2, kHeight / 2,
1122 content_type);
1123 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1124
1125 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth / 2, kHeight / 2,
1126 content_type);
1127 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1128
1129 // Downscale.
1130 statistics_proxy_->OnDecodedFrame(kLowQp, kWidth / 4, kHeight / 4,
1131 content_type);
1132 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1133
1134 statistics_proxy_.reset();
1135 const int kExpectedDownscales = 30; // 2 per 5 seconds = 30 per minute.
1136 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1137 EXPECT_EQ(
1138 kExpectedDownscales,
1139 metrics::MinSample(
1140 "WebRTC.Video.Screenshare.NumberResolutionDownswitchesPerMinute"));
1141 } else {
1142 EXPECT_EQ(kExpectedDownscales,
1143 metrics::MinSample(
1144 "WebRTC.Video.NumberResolutionDownswitchesPerMinute"));
1145 }
1146}
1147
ilnik6d5b4d62017-08-30 03:32:14 -07001148TEST_P(ReceiveStatisticsProxyTest, StatsAreSlicedOnSimulcastAndExperiment) {
1149 VideoContentType content_type = GetParam();
1150 const uint8_t experiment_id = 1;
1151 videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
1152 const int kInterFrameDelayMs1 = 30;
1153 const int kInterFrameDelayMs2 = 50;
1154
1155 videocontenttypehelpers::SetSimulcastId(&content_type, 1);
1156 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1157 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs1);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001158 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
1159 content_type);
ilnik6d5b4d62017-08-30 03:32:14 -07001160 }
1161
1162 videocontenttypehelpers::SetSimulcastId(&content_type, 2);
1163 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1164 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001165 statistics_proxy_->OnDecodedFrame(rtc::nullopt, kWidth, kHeight,
1166 content_type);
ilnik6d5b4d62017-08-30 03:32:14 -07001167 }
1168 statistics_proxy_.reset();
1169
1170 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1171 EXPECT_EQ(
1172 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1173 EXPECT_EQ(1, metrics::NumSamples(
1174 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1175 EXPECT_EQ(1, metrics::NumSamples(
1176 "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1177 EXPECT_EQ(1, metrics::NumSamples(
1178 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
1179 EXPECT_EQ(1, metrics::NumSamples(
1180 "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1181 EXPECT_EQ(1, metrics::NumSamples(
1182 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
1183 EXPECT_EQ(1,
1184 metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
1185 ".ExperimentGroup0"));
1186 EXPECT_EQ(
1187 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
1188 ".ExperimentGroup0"));
1189 EXPECT_EQ(
1190 kInterFrameDelayMs1,
1191 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1192 EXPECT_EQ(
1193 kInterFrameDelayMs2,
1194 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1195 EXPECT_EQ(
1196 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1197 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1198 EXPECT_EQ(
1199 kInterFrameDelayMs2,
1200 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1201 EXPECT_EQ(
1202 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1203 metrics::MinSample(
1204 "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
1205 } else {
1206 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1207 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1208 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
1209 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
1210 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
1211 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
1212 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
1213 ".ExperimentGroup0"));
1214 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
1215 ".ExperimentGroup0"));
1216 EXPECT_EQ(kInterFrameDelayMs1,
1217 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
1218 EXPECT_EQ(kInterFrameDelayMs2,
1219 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
1220 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1221 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1222 EXPECT_EQ(kInterFrameDelayMs2,
1223 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1224 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1225 metrics::MinSample(
1226 "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
1227 }
1228}
sakale5ba44e2016-10-26 07:09:24 -07001229} // namespace webrtc