blob: ac75aad42e92622754af1e506da503a7684e4667 [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>
Yves Gerey3e707812018-11-28 16:47:49 +010015#include <string>
sakale5ba44e2016-10-26 07:09:24 -070016
Mirko Bonadeid9708072019-01-25 20:26:48 +010017#include "api/scoped_refptr.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/video/i420_buffer.h"
19#include "api/video/video_frame.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "api/video/video_frame_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "api/video/video_rotation.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "system_wrappers/include/metrics.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#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 +020031const int kWidth = 1280;
32const int kHeight = 720;
33
asaperssonde9e5ff2016-11-02 07:14:03 -070034} // namespace
sakale5ba44e2016-10-26 07:09:24 -070035
36// TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
sprang892dab52017-08-15 05:00:33 -070037class ReceiveStatisticsProxyTest
38 : public ::testing::TestWithParam<webrtc::VideoContentType> {
sakale5ba44e2016-10-26 07:09:24 -070039 public:
40 ReceiveStatisticsProxyTest() : fake_clock_(1234), config_(GetTestConfig()) {}
41 virtual ~ReceiveStatisticsProxyTest() {}
42
43 protected:
44 virtual void SetUp() {
asaperssonde9e5ff2016-11-02 07:14:03 -070045 metrics::Reset();
sakale5ba44e2016-10-26 07:09:24 -070046 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_));
47 }
48
49 VideoReceiveStream::Config GetTestConfig() {
50 VideoReceiveStream::Config config(nullptr);
asapersson46c4e3c2016-11-03 06:48:19 -070051 config.rtp.local_ssrc = kLocalSsrc;
52 config.rtp.remote_ssrc = kRemoteSsrc;
sakale5ba44e2016-10-26 07:09:24 -070053 return config;
54 }
55
asapersson2077f2f2017-05-11 05:37:35 -070056 void InsertFirstRtpPacket(uint32_t ssrc) {
57 StreamDataCounters counters;
58 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
59 statistics_proxy_->DataCountersUpdated(counters, ssrc);
60 }
61
62 VideoFrame CreateFrame(int width, int height) {
Åsa Persson81327d52018-06-05 13:34:33 +020063 return CreateVideoFrame(width, height, 0);
64 }
65
66 VideoFrame CreateFrameWithRenderTimeMs(int64_t render_time_ms) {
67 return CreateVideoFrame(kWidth, kHeight, render_time_ms);
68 }
69
70 VideoFrame CreateVideoFrame(int width, int height, int64_t render_time_ms) {
Artem Titov1ebfb6a2019-01-03 23:49:37 +010071 VideoFrame frame =
72 VideoFrame::Builder()
73 .set_video_frame_buffer(I420Buffer::Create(width, height))
74 .set_timestamp_rtp(0)
75 .set_timestamp_ms(render_time_ms)
76 .set_rotation(kVideoRotation_0)
77 .build();
asapersson2077f2f2017-05-11 05:37:35 -070078 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
79 return frame;
80 }
81
sakale5ba44e2016-10-26 07:09:24 -070082 SimulatedClock fake_clock_;
asaperssonde9e5ff2016-11-02 07:14:03 -070083 const VideoReceiveStream::Config config_;
sakale5ba44e2016-10-26 07:09:24 -070084 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
sakale5ba44e2016-10-26 07:09:24 -070085};
86
87TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) {
88 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
Sergey Silkin278f8252019-01-09 14:37:40 +010089 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
sakale5ba44e2016-10-26 07:09:24 -070090 for (uint32_t i = 1; i <= 3; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +010091 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
ilnik00d802b2017-04-11 10:34:31 -070092 VideoContentType::UNSPECIFIED);
sakale5ba44e2016-10-26 07:09:24 -070093 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
94 }
95}
96
Åsa Perssonb9b07ea2018-01-24 17:04:07 +010097TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsReported) {
98 const int kFps = 20;
99 const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
Sergey Silkin278f8252019-01-09 14:37:40 +0100100 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100101 for (int i = 0; i < kRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100102 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
103 VideoContentType::UNSPECIFIED);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100104 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
105 }
106 statistics_proxy_.reset();
107 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
108 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps));
109}
110
111TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsNotReportedForTooFewSamples) {
112 const int kFps = 20;
113 const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
Sergey Silkin278f8252019-01-09 14:37:40 +0100114 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100115 for (int i = 0; i < kRequiredSamples - 1; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100116 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
117 VideoContentType::UNSPECIFIED);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100118 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
119 }
120 statistics_proxy_.reset();
121 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
122}
123
124TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsReportedWithQpReset) {
125 const int kFps1 = 10;
Sergey Silkin278f8252019-01-09 14:37:40 +0100126 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100127 for (int i = 0; i < metrics::kMinRunTimeInSeconds * kFps1; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100128 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
129 VideoContentType::UNSPECIFIED);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100130 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps1);
131 }
132 // First QP value received, resets frames decoded.
133 const int kFps2 = 20;
134 for (int i = 0; i < metrics::kMinRunTimeInSeconds * kFps2; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100135 statistics_proxy_->OnDecodedFrame(frame, 1u, VideoContentType::UNSPECIFIED);
Åsa Perssonb9b07ea2018-01-24 17:04:07 +0100136 fake_clock_.AdvanceTimeMilliseconds(1000 / kFps2);
137 }
138 statistics_proxy_.reset();
139 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
140 EXPECT_EQ(1,
141 metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps2));
142}
143
sakalcc452e12017-02-09 04:53:45 -0800144TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithQpResetsFramesDecoded) {
145 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
Sergey Silkin278f8252019-01-09 14:37:40 +0100146 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
sakalcc452e12017-02-09 04:53:45 -0800147 for (uint32_t i = 1; i <= 3; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100148 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
ilnik00d802b2017-04-11 10:34:31 -0700149 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800150 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
151 }
Sergey Silkin278f8252019-01-09 14:37:40 +0100152 statistics_proxy_->OnDecodedFrame(frame, 1u, VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800153 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_decoded);
154}
155
156TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200157 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
Sergey Silkin278f8252019-01-09 14:37:40 +0100158 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
159 statistics_proxy_->OnDecodedFrame(frame, 3u, VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100160 EXPECT_EQ(3u, statistics_proxy_->GetStats().qp_sum);
Sergey Silkin278f8252019-01-09 14:37:40 +0100161 statistics_proxy_->OnDecodedFrame(frame, 127u, VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100162 EXPECT_EQ(130u, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800163}
164
ilnik2e1b40b2017-09-04 07:57:17 -0700165TEST_F(ReceiveStatisticsProxyTest, ReportsContentType) {
166 const std::string kRealtimeString("realtime");
167 const std::string kScreenshareString("screen");
Sergey Silkin278f8252019-01-09 14:37:40 +0100168 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
ilnik2e1b40b2017-09-04 07:57:17 -0700169 EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
170 statistics_proxy_->GetStats().content_type));
Sergey Silkin278f8252019-01-09 14:37:40 +0100171 statistics_proxy_->OnDecodedFrame(frame, 3u, VideoContentType::SCREENSHARE);
ilnik2e1b40b2017-09-04 07:57:17 -0700172 EXPECT_EQ(kScreenshareString, videocontenttypehelpers::ToString(
173 statistics_proxy_->GetStats().content_type));
Sergey Silkin278f8252019-01-09 14:37:40 +0100174 statistics_proxy_->OnDecodedFrame(frame, 3u, VideoContentType::UNSPECIFIED);
ilnik2e1b40b2017-09-04 07:57:17 -0700175 EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
176 statistics_proxy_->GetStats().content_type));
177}
178
ilnika79cc282017-08-23 05:24:10 -0700179TEST_F(ReceiveStatisticsProxyTest, ReportsMaxInterframeDelay) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100180 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
ilnika79cc282017-08-23 05:24:10 -0700181 const int64_t kInterframeDelayMs1 = 100;
182 const int64_t kInterframeDelayMs2 = 200;
183 const int64_t kInterframeDelayMs3 = 100;
184 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
Sergey Silkin278f8252019-01-09 14:37:40 +0100185 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200186 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700187 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700188
189 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
Sergey Silkin278f8252019-01-09 14:37:40 +0100190 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200191 VideoContentType::UNSPECIFIED);
ilnikf04afde2017-07-07 01:26:24 -0700192 EXPECT_EQ(kInterframeDelayMs1,
ilnika79cc282017-08-23 05:24:10 -0700193 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700194
195 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
Sergey Silkin278f8252019-01-09 14:37:40 +0100196 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200197 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700198 EXPECT_EQ(kInterframeDelayMs2,
199 statistics_proxy_->GetStats().interframe_delay_max_ms);
200
201 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
Sergey Silkin278f8252019-01-09 14:37:40 +0100202 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200203 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700204 // kInterframeDelayMs3 is smaller than kInterframeDelayMs2.
205 EXPECT_EQ(kInterframeDelayMs2,
206 statistics_proxy_->GetStats().interframe_delay_max_ms);
207}
208
209TEST_F(ReceiveStatisticsProxyTest, ReportInterframeDelayInWindow) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100210 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Ilya Nikolaevskiyb06b3582017-10-16 17:59:12 +0200211 const int64_t kInterframeDelayMs1 = 900;
212 const int64_t kInterframeDelayMs2 = 750;
213 const int64_t kInterframeDelayMs3 = 700;
ilnika79cc282017-08-23 05:24:10 -0700214 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
Sergey Silkin278f8252019-01-09 14:37:40 +0100215 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200216 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700217 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
218
219 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
Sergey Silkin278f8252019-01-09 14:37:40 +0100220 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200221 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700222 EXPECT_EQ(kInterframeDelayMs1,
223 statistics_proxy_->GetStats().interframe_delay_max_ms);
224
225 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
Sergey Silkin278f8252019-01-09 14:37:40 +0100226 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200227 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700228 // Still first delay is the maximum
229 EXPECT_EQ(kInterframeDelayMs1,
230 statistics_proxy_->GetStats().interframe_delay_max_ms);
231
232 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
Sergey Silkin278f8252019-01-09 14:37:40 +0100233 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +0200234 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700235 // Now the first sample is out of the window, so the second is the maximum.
236 EXPECT_EQ(kInterframeDelayMs2,
237 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700238}
239
sakalcc452e12017-02-09 04:53:45 -0800240TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100241 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200242 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
Sergey Silkin278f8252019-01-09 14:37:40 +0100243 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
ilnik00d802b2017-04-11 10:34:31 -0700244 VideoContentType::UNSPECIFIED);
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200245 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800246}
247
248TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100249 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200250 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
Sergey Silkin278f8252019-01-09 14:37:40 +0100251 statistics_proxy_->OnDecodedFrame(frame, 3u, VideoContentType::UNSPECIFIED);
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100252 EXPECT_EQ(3u, statistics_proxy_->GetStats().qp_sum);
Sergey Silkin278f8252019-01-09 14:37:40 +0100253 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
ilnik00d802b2017-04-11 10:34:31 -0700254 VideoContentType::UNSPECIFIED);
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200255 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
sakalcc452e12017-02-09 04:53:45 -0800256}
257
hbos50cfe1f2017-01-23 07:21:55 -0800258TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) {
259 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
Sergey Silkin278f8252019-01-09 14:37:40 +0100260 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
hbos50cfe1f2017-01-23 07:21:55 -0800261 for (uint32_t i = 1; i <= 3; ++i) {
262 statistics_proxy_->OnRenderedFrame(frame);
263 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
264 }
265}
266
asapersson46c4e3c2016-11-03 06:48:19 -0700267TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsSsrc) {
268 EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
269}
270
271TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsIncomingPayloadType) {
272 const int kPayloadType = 111;
273 statistics_proxy_->OnIncomingPayloadType(kPayloadType);
274 EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
275}
276
asapersson6966bd52017-01-03 00:44:06 -0800277TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecoderImplementationName) {
278 const char* kName = "decoderName";
279 statistics_proxy_->OnDecoderImplementationName(kName);
280 EXPECT_STREQ(
281 kName, statistics_proxy_->GetStats().decoder_implementation_name.c_str());
282}
283
philipela45102f2017-02-22 05:30:39 -0800284TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsOnCompleteFrame) {
285 const int kFrameSizeBytes = 1000;
ilnik6d5b4d62017-08-30 03:32:14 -0700286 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
287 VideoContentType::UNSPECIFIED);
philipela45102f2017-02-22 05:30:39 -0800288 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
289 EXPECT_EQ(1, stats.network_frame_rate);
philipela45102f2017-02-22 05:30:39 -0800290 EXPECT_EQ(1, stats.frame_counts.key_frames);
291 EXPECT_EQ(0, stats.frame_counts.delta_frames);
asapersson46c4e3c2016-11-03 06:48:19 -0700292}
293
294TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecodeTimingStats) {
295 const int kDecodeMs = 1;
296 const int kMaxDecodeMs = 2;
297 const int kCurrentDelayMs = 3;
298 const int kTargetDelayMs = 4;
299 const int kJitterBufferMs = 5;
300 const int kMinPlayoutDelayMs = 6;
301 const int kRenderDelayMs = 7;
302 const int64_t kRttMs = 8;
philipela45102f2017-02-22 05:30:39 -0800303 statistics_proxy_->OnRttUpdate(kRttMs, 0);
304 statistics_proxy_->OnFrameBufferTimingsUpdated(
asapersson46c4e3c2016-11-03 06:48:19 -0700305 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
philipela45102f2017-02-22 05:30:39 -0800306 kMinPlayoutDelayMs, kRenderDelayMs);
asapersson46c4e3c2016-11-03 06:48:19 -0700307 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
308 EXPECT_EQ(kDecodeMs, stats.decode_ms);
309 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
310 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
311 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
312 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
313 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
314 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
315}
316
asapersson6966bd52017-01-03 00:44:06 -0800317TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpPacketTypeCounts) {
318 const uint32_t kFirPackets = 33;
319 const uint32_t kPliPackets = 44;
320 const uint32_t kNackPackets = 55;
321 RtcpPacketTypeCounter counter;
322 counter.fir_packets = kFirPackets;
323 counter.pli_packets = kPliPackets;
324 counter.nack_packets = kNackPackets;
325 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
326 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
327 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
328 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
329 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
330}
331
332TEST_F(ReceiveStatisticsProxyTest,
333 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
334 RtcpPacketTypeCounter counter;
335 counter.fir_packets = 33;
336 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
337 EXPECT_EQ(0u,
338 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
339}
340
341TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsFrameCounts) {
342 const int kKeyFrames = 3;
343 const int kDeltaFrames = 22;
344 FrameCounts frame_counts;
345 frame_counts.key_frames = kKeyFrames;
346 frame_counts.delta_frames = kDeltaFrames;
347 statistics_proxy_->OnFrameCountsUpdated(frame_counts);
348 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
349 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
350 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
351}
352
asapersson46c4e3c2016-11-03 06:48:19 -0700353TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDiscardedPackets) {
354 const int kDiscardedPackets = 12;
355 statistics_proxy_->OnDiscardedPacketsUpdated(kDiscardedPackets);
356 EXPECT_EQ(kDiscardedPackets, statistics_proxy_->GetStats().discarded_packets);
357}
358
asapersson6966bd52017-01-03 00:44:06 -0800359TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpStats) {
360 const uint8_t kFracLost = 0;
Harald Alvestrandc7c41912017-12-08 09:59:34 +0100361 const int32_t kCumLost = 1;
asapersson6966bd52017-01-03 00:44:06 -0800362 const uint32_t kExtSeqNum = 10;
363 const uint32_t kJitter = 4;
364
365 RtcpStatistics rtcp_stats;
366 rtcp_stats.fraction_lost = kFracLost;
srte186d9c32017-08-04 05:03:53 -0700367 rtcp_stats.packets_lost = kCumLost;
368 rtcp_stats.extended_highest_sequence_number = kExtSeqNum;
asapersson6966bd52017-01-03 00:44:06 -0800369 rtcp_stats.jitter = kJitter;
370 statistics_proxy_->StatisticsUpdated(rtcp_stats, kRemoteSsrc);
371
372 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
373 EXPECT_EQ(kFracLost, stats.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700374 EXPECT_EQ(kCumLost, stats.rtcp_stats.packets_lost);
375 EXPECT_EQ(kExtSeqNum, stats.rtcp_stats.extended_highest_sequence_number);
asapersson6966bd52017-01-03 00:44:06 -0800376 EXPECT_EQ(kJitter, stats.rtcp_stats.jitter);
377}
378
379TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsCName) {
380 const char* kName = "cName";
381 statistics_proxy_->CNameChanged(kName, kRemoteSsrc);
382 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
383}
384
385TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsNoCNameForUnknownSsrc) {
386 const char* kName = "cName";
387 statistics_proxy_->CNameChanged(kName, kRemoteSsrc + 1);
388 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
389}
390
ilnik2edc6842017-07-06 03:06:50 -0700391TEST_F(ReceiveStatisticsProxyTest,
ilnik75204c52017-09-04 03:35:40 -0700392 ReportsLongestTimingFrameInfo) {
ilnik2edc6842017-07-06 03:06:50 -0700393 const int64_t kShortEndToEndDelay = 10;
394 const int64_t kMedEndToEndDelay = 20;
395 const int64_t kLongEndToEndDelay = 100;
396 const uint32_t kExpectedRtpTimestamp = 2;
397 TimingFrameInfo info;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200398 absl::optional<TimingFrameInfo> result;
ilnik2edc6842017-07-06 03:06:50 -0700399 info.rtp_timestamp = kExpectedRtpTimestamp - 1;
400 info.capture_time_ms = 0;
401 info.decode_finish_ms = kShortEndToEndDelay;
402 statistics_proxy_->OnTimingFrameInfoUpdated(info);
403 info.rtp_timestamp =
404 kExpectedRtpTimestamp; // this frame should be reported in the end.
405 info.capture_time_ms = 0;
406 info.decode_finish_ms = kLongEndToEndDelay;
407 statistics_proxy_->OnTimingFrameInfoUpdated(info);
408 info.rtp_timestamp = kExpectedRtpTimestamp + 1;
409 info.capture_time_ms = 0;
410 info.decode_finish_ms = kMedEndToEndDelay;
411 statistics_proxy_->OnTimingFrameInfoUpdated(info);
ilnik75204c52017-09-04 03:35:40 -0700412 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700413 EXPECT_TRUE(result);
414 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
415}
416
ilnik75204c52017-09-04 03:35:40 -0700417TEST_F(ReceiveStatisticsProxyTest, RespectsReportingIntervalForTimingFrames) {
418 TimingFrameInfo info;
ilnik2edc6842017-07-06 03:06:50 -0700419 const int64_t kShortEndToEndDelay = 10;
420 const uint32_t kExpectedRtpTimestamp = 2;
ilnik75204c52017-09-04 03:35:40 -0700421 const int64_t kShortDelayMs = 1000;
422 const int64_t kLongDelayMs = 10000;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200423 absl::optional<TimingFrameInfo> result;
ilnik2edc6842017-07-06 03:06:50 -0700424 info.rtp_timestamp = kExpectedRtpTimestamp;
425 info.capture_time_ms = 0;
426 info.decode_finish_ms = kShortEndToEndDelay;
427 statistics_proxy_->OnTimingFrameInfoUpdated(info);
ilnik75204c52017-09-04 03:35:40 -0700428 fake_clock_.AdvanceTimeMilliseconds(kShortDelayMs);
429 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700430 EXPECT_TRUE(result);
431 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
ilnik75204c52017-09-04 03:35:40 -0700432 fake_clock_.AdvanceTimeMilliseconds(kLongDelayMs);
433 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700434 EXPECT_FALSE(result);
435}
436
asapersson46c4e3c2016-11-03 06:48:19 -0700437TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
438 const int64_t kTimeSec = 3;
439 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
ilnik6d5b4d62017-08-30 03:32:14 -0700440 // Need at least one frame to report stream lifetime.
441 statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
asapersson46c4e3c2016-11-03 06:48:19 -0700442 // Histograms are updated when the statistics_proxy_ is deleted.
443 statistics_proxy_.reset();
444 EXPECT_EQ(1,
445 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
446 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
447 kTimeSec));
448}
449
ilnik6d5b4d62017-08-30 03:32:14 -0700450TEST_F(ReceiveStatisticsProxyTest,
451 LifetimeHistogramNotReportedForEmptyStreams) {
452 const int64_t kTimeSec = 3;
453 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
454 // No frames received.
455 // Histograms are updated when the statistics_proxy_ is deleted.
456 statistics_proxy_.reset();
457 EXPECT_EQ(0,
458 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
459}
460
palmkvista40672a2017-01-13 05:58:34 -0800461TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
462 // Based on the tuning parameters this will produce 7 uncertain states,
463 // then 10 certainly bad states. There has to be 10 certain states before
464 // any histograms are recorded.
465 const int kNumBadSamples = 17;
466
467 StreamDataCounters counters;
468 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
469 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
470
471 for (int i = 0; i < kNumBadSamples; ++i) {
472 // Since OnRenderedFrame is never called the fps in each sample will be 0,
473 // i.e. bad
474 fake_clock_.AdvanceTimeMilliseconds(1000);
475 statistics_proxy_->OnIncomingRate(0, 0);
476 }
477 // Histograms are updated when the statistics_proxy_ is deleted.
478 statistics_proxy_.reset();
479 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
480 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
481
482 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
483 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
484
485 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
486
487 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
488}
489
asapersson0c43f772016-11-30 01:42:26 -0800490TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
491 const uint32_t kCumLost1 = 1;
492 const uint32_t kExtSeqNum1 = 10;
493 const uint32_t kCumLost2 = 2;
494 const uint32_t kExtSeqNum2 = 20;
495
496 // One report block received.
497 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700498 rtcp_stats1.packets_lost = kCumLost1;
499 rtcp_stats1.extended_highest_sequence_number = kExtSeqNum1;
asapersson0c43f772016-11-30 01:42:26 -0800500 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
501
502 // Two report blocks received.
503 RtcpStatistics rtcp_stats2;
srte186d9c32017-08-04 05:03:53 -0700504 rtcp_stats2.packets_lost = kCumLost2;
505 rtcp_stats2.extended_highest_sequence_number = kExtSeqNum2;
asapersson0c43f772016-11-30 01:42:26 -0800506 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
507
508 // Two received report blocks but min run time has not passed.
509 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
510 SetUp(); // Reset stat proxy causes histograms to be updated.
511 EXPECT_EQ(0,
512 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
513
514 // Two report blocks received.
515 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
516 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
517
518 // Two received report blocks and min run time has passed.
519 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
520 SetUp();
521 EXPECT_EQ(1,
522 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
523 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
524 (kCumLost2 - kCumLost1) * 100 /
525 (kExtSeqNum2 - kExtSeqNum1)));
526}
527
528TEST_F(ReceiveStatisticsProxyTest,
529 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
530 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700531 rtcp_stats1.packets_lost = 1;
532 rtcp_stats1.extended_highest_sequence_number = 10;
asapersson0c43f772016-11-30 01:42:26 -0800533
534 // Min run time has passed but no received report block.
535 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
536 SetUp(); // Reset stat proxy causes histograms to be updated.
537 EXPECT_EQ(0,
538 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
539
540 // Min run time has passed but only one received report block.
541 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
542 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
543 SetUp();
544 EXPECT_EQ(0,
545 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
546}
547
asapersson2077f2f2017-05-11 05:37:35 -0700548TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) {
549 const int64_t kSyncOffsetMs = 22;
550 const double kFreqKhz = 90.0;
551 EXPECT_EQ(std::numeric_limits<int>::max(),
552 statistics_proxy_->GetStats().sync_offset_ms);
553 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
554 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms);
555}
556
asapersson46c4e3c2016-11-03 06:48:19 -0700557TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
558 const int64_t kSyncOffsetMs = 22;
559 const double kFreqKhz = 90.0;
560 for (int i = 0; i < kMinRequiredSamples; ++i)
561 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
562 // Histograms are updated when the statistics_proxy_ is deleted.
563 statistics_proxy_.reset();
564 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
565 EXPECT_EQ(1,
566 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
567}
568
asaperssonde9e5ff2016-11-02 07:14:03 -0700569TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
570 const int64_t kSyncOffsetMs = 22;
571 const double kFreqKhz = 90.0;
572 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
573 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
574 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
575 // Process interval passed, max diff: 2.
576 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
577 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
578 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
579 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
580 // Process interval passed, max diff: 4.
581 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
582 statistics_proxy_.reset();
583 // Average reported: (2 + 4) / 2 = 3.
584 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
585 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
586}
587
asapersson6966bd52017-01-03 00:44:06 -0800588TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
589 const int kQp = 22;
asapersson6966bd52017-01-03 00:44:06 -0800590
591 for (int i = 0; i < kMinRequiredSamples; ++i)
Niels Möller147013a2018-10-01 15:56:33 +0200592 statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
asapersson6966bd52017-01-03 00:44:06 -0800593
594 statistics_proxy_.reset();
595 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
596 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
597}
598
599TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
Niels Möller147013a2018-10-01 15:56:33 +0200600 const int kQp = 22;
asapersson6966bd52017-01-03 00:44:06 -0800601
602 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
Niels Möller147013a2018-10-01 15:56:33 +0200603 statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
asapersson6966bd52017-01-03 00:44:06 -0800604
605 statistics_proxy_.reset();
606 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
607}
608
609TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
asapersson6966bd52017-01-03 00:44:06 -0800610 for (int i = 0; i < kMinRequiredSamples; ++i)
Niels Möller147013a2018-10-01 15:56:33 +0200611 statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
asapersson6966bd52017-01-03 00:44:06 -0800612
613 statistics_proxy_.reset();
614 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
615}
616
asaperssonb99baf82017-04-20 04:05:43 -0700617TEST_F(ReceiveStatisticsProxyTest,
618 KeyFrameHistogramNotUpdatedForTooFewSamples) {
619 const bool kIsKeyFrame = false;
620 const int kFrameSizeBytes = 1000;
621
622 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700623 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
624 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700625
626 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
627 EXPECT_EQ(kMinRequiredSamples - 1,
628 statistics_proxy_->GetStats().frame_counts.delta_frames);
629
630 statistics_proxy_.reset();
631 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
632}
633
634TEST_F(ReceiveStatisticsProxyTest,
635 KeyFrameHistogramUpdatedForMinRequiredSamples) {
636 const bool kIsKeyFrame = false;
637 const int kFrameSizeBytes = 1000;
638
639 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700640 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
641 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700642
643 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
644 EXPECT_EQ(kMinRequiredSamples,
645 statistics_proxy_->GetStats().frame_counts.delta_frames);
646
647 statistics_proxy_.reset();
648 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
649 EXPECT_EQ(1,
650 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
651}
652
653TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
654 const int kFrameSizeBytes = 1000;
655
656 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700657 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
658 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700659
660 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700661 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
662 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700663
664 EXPECT_EQ(kMinRequiredSamples,
665 statistics_proxy_->GetStats().frame_counts.key_frames);
666 EXPECT_EQ(kMinRequiredSamples,
667 statistics_proxy_->GetStats().frame_counts.delta_frames);
668
669 statistics_proxy_.reset();
670 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
671 EXPECT_EQ(
672 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
673}
674
675TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
676 const int kDecodeMs = 1;
677 const int kMaxDecodeMs = 2;
678 const int kCurrentDelayMs = 3;
679 const int kTargetDelayMs = 4;
680 const int kJitterBufferMs = 5;
681 const int kMinPlayoutDelayMs = 6;
682 const int kRenderDelayMs = 7;
683
684 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
685 statistics_proxy_->OnFrameBufferTimingsUpdated(
686 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
687 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
688 }
689
690 statistics_proxy_.reset();
691 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
692 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
693 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
694 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
695 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
696}
697
698TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
699 const int kDecodeMs = 1;
700 const int kMaxDecodeMs = 2;
701 const int kCurrentDelayMs = 3;
702 const int kTargetDelayMs = 4;
703 const int kJitterBufferMs = 5;
704 const int kMinPlayoutDelayMs = 6;
705 const int kRenderDelayMs = 7;
706
707 for (int i = 0; i < kMinRequiredSamples; ++i) {
708 statistics_proxy_->OnFrameBufferTimingsUpdated(
709 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
710 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
711 }
712
713 statistics_proxy_.reset();
714 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
715 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
716 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
717 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
718 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
719
720 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
721 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
722 kJitterBufferMs));
723 EXPECT_EQ(1,
724 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
725 EXPECT_EQ(
726 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
727 EXPECT_EQ(1,
728 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
729}
730
sprang948b2752017-05-04 02:47:13 -0700731TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
732 const int kDefaultFps = 30;
Sergey Silkin278f8252019-01-09 14:37:40 +0100733 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
sprang948b2752017-05-04 02:47:13 -0700734
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());
Sergey Silkin278f8252019-01-09 14:37:40 +0100739 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
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) {
asapersson2077f2f2017-05-11 05:37:35 -0700755 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
756 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
757 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
758
759 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
760
761 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
762 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
763 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
764}
765
766TEST_F(ReceiveStatisticsProxyTest,
767 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
asapersson2077f2f2017-05-11 05:37:35 -0700768 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
769 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
770
771 statistics_proxy_.reset();
772 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
773 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
774 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
775 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
776}
777
778TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
asapersson2077f2f2017-05-11 05:37:35 -0700779 for (int i = 0; i < kMinRequiredSamples; ++i)
780 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
781
782 statistics_proxy_.reset();
783 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
784 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
785 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
786 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
787 EXPECT_EQ(1,
788 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
789 EXPECT_EQ(1,
790 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
791}
792
Åsa Persson81327d52018-06-05 13:34:33 +0200793TEST_F(ReceiveStatisticsProxyTest, ZeroDelayReportedIfFrameNotDelayed) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100794 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
795 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Åsa Persson81327d52018-06-05 13:34:33 +0200796 VideoContentType::UNSPECIFIED);
797
798 // Frame not delayed, delayed frames to render: 0%.
799 const int64_t kNowMs = fake_clock_.TimeInMilliseconds();
800 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs));
801
802 // Min run time has passed.
803 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
804 statistics_proxy_.reset();
805 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
806 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 0));
807 EXPECT_EQ(0, metrics::NumSamples(
808 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
809}
810
811TEST_F(ReceiveStatisticsProxyTest,
812 DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100813 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
814 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Åsa Persson81327d52018-06-05 13:34:33 +0200815 VideoContentType::UNSPECIFIED);
816
817 // Frame not delayed, delayed frames to render: 0%.
818 const int64_t kNowMs = fake_clock_.TimeInMilliseconds();
819 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs));
820
821 // Min run time has not passed.
822 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
823 1);
824 statistics_proxy_.reset();
825 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
826 EXPECT_EQ(0, metrics::NumSamples(
827 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
828}
829
830TEST_F(ReceiveStatisticsProxyTest,
831 DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100832 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
833 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Åsa Persson81327d52018-06-05 13:34:33 +0200834 VideoContentType::UNSPECIFIED);
835
836 // Min run time has passed. No rendered frames.
837 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
838 statistics_proxy_.reset();
839 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
840 EXPECT_EQ(0, metrics::NumSamples(
841 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
842}
843
844TEST_F(ReceiveStatisticsProxyTest, DelayReportedIfFrameIsDelayed) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100845 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
846 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Åsa Persson81327d52018-06-05 13:34:33 +0200847 VideoContentType::UNSPECIFIED);
848
849 // Frame delayed 1 ms, delayed frames to render: 100%.
850 const int64_t kNowMs = fake_clock_.TimeInMilliseconds();
851 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs - 1));
852
853 // Min run time has passed.
854 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
855 statistics_proxy_.reset();
856 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
857 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 100));
858 EXPECT_EQ(1, metrics::NumSamples(
859 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
860 EXPECT_EQ(1, metrics::NumEvents(
861 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs", 1));
862}
863
864TEST_F(ReceiveStatisticsProxyTest, AverageDelayOfDelayedFramesIsReported) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100865 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
866 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
Åsa Persson81327d52018-06-05 13:34:33 +0200867 VideoContentType::UNSPECIFIED);
868
869 // Two frames delayed (6 ms, 10 ms), delayed frames to render: 50%.
870 const int64_t kNowMs = fake_clock_.TimeInMilliseconds();
871 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs - 10));
872 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs - 6));
873 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs));
874 statistics_proxy_->OnRenderedFrame(CreateFrameWithRenderTimeMs(kNowMs + 1));
875
876 // Min run time has passed.
877 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
878 statistics_proxy_.reset();
879 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
880 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 50));
881 EXPECT_EQ(1, metrics::NumSamples(
882 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
883 EXPECT_EQ(1, metrics::NumEvents(
884 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs", 8));
885}
886
asapersson2077f2f2017-05-11 05:37:35 -0700887TEST_F(ReceiveStatisticsProxyTest,
888 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
889 InsertFirstRtpPacket(kRemoteSsrc);
890 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
891 1);
892
893 RtcpPacketTypeCounter counter;
894 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
895
896 statistics_proxy_.reset();
897 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
898 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
899 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
900}
901
902TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
903 InsertFirstRtpPacket(kRemoteSsrc);
904 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
905
906 const uint32_t kFirPackets = 100;
907 const uint32_t kPliPackets = 200;
908 const uint32_t kNackPackets = 300;
909
910 RtcpPacketTypeCounter counter;
911 counter.fir_packets = kFirPackets;
912 counter.pli_packets = kPliPackets;
913 counter.nack_packets = kNackPackets;
914 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
915
916 statistics_proxy_.reset();
917 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
918 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
919 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
920 EXPECT_EQ(
921 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
922 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
923 EXPECT_EQ(
924 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
925 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
926 EXPECT_EQ(
927 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
928 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
929}
930
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100931INSTANTIATE_TEST_SUITE_P(ContentTypes,
932 ReceiveStatisticsProxyTest,
933 ::testing::Values(VideoContentType::UNSPECIFIED,
934 VideoContentType::SCREENSHARE));
sprang892dab52017-08-15 05:00:33 -0700935
936TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysAreReported) {
937 const VideoContentType content_type = GetParam();
938 const int kInterFrameDelayMs = 33;
Sergey Silkin278f8252019-01-09 14:37:40 +0100939 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
940
sprang892dab52017-08-15 05:00:33 -0700941 for (int i = 0; i < kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +0100942 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang892dab52017-08-15 05:00:33 -0700943 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
944 }
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200945 // One extra with double the interval.
sprang892dab52017-08-15 05:00:33 -0700946 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +0100947 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang892dab52017-08-15 05:00:33 -0700948
949 statistics_proxy_.reset();
950 const int kExpectedInterFrame =
951 (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
952 kInterFrameDelayMs * 2) /
953 kMinRequiredSamples;
ilnik6d5b4d62017-08-30 03:32:14 -0700954 if (videocontenttypehelpers::IsScreenshare(content_type)) {
955 EXPECT_EQ(
956 kExpectedInterFrame,
957 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
958 EXPECT_EQ(
959 kInterFrameDelayMs * 2,
960 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
961 } else {
962 EXPECT_EQ(kExpectedInterFrame,
963 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
964 EXPECT_EQ(kInterFrameDelayMs * 2,
965 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
sprang892dab52017-08-15 05:00:33 -0700966 }
967}
968
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200969TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysPercentilesAreReported) {
970 const VideoContentType content_type = GetParam();
971 const int kInterFrameDelayMs = 33;
972 const int kLastFivePercentsSamples = kMinRequiredSamples * 5 / 100;
Sergey Silkin278f8252019-01-09 14:37:40 +0100973 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
974
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200975 for (int i = 0; i <= kMinRequiredSamples - kLastFivePercentsSamples; ++i) {
976 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +0100977 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200978 }
979 // Last 5% of intervals are double in size.
980 for (int i = 0; i < kLastFivePercentsSamples; ++i) {
981 fake_clock_.AdvanceTimeMilliseconds(2 * kInterFrameDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +0100982 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200983 }
984 // Final sample is outlier and 10 times as big.
985 fake_clock_.AdvanceTimeMilliseconds(10 * kInterFrameDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +0100986 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiydaa4f7a2017-10-06 12:29:47 +0200987
988 statistics_proxy_.reset();
989 const int kExpectedInterFrame = kInterFrameDelayMs * 2;
990 if (videocontenttypehelpers::IsScreenshare(content_type)) {
991 EXPECT_EQ(kExpectedInterFrame,
992 metrics::MinSample(
993 "WebRTC.Video.Screenshare.InterframeDelay95PercentileInMs"));
994 } else {
995 EXPECT_EQ(
996 kExpectedInterFrame,
997 metrics::MinSample("WebRTC.Video.InterframeDelay95PercentileInMs"));
998 }
999}
1000
sprang892dab52017-08-15 05:00:33 -07001001TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithValidAverage) {
1002 const VideoContentType content_type = GetParam();
1003 const int kInterFrameDelayMs = 33;
Sergey Silkin278f8252019-01-09 14:37:40 +01001004 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1005
sprang892dab52017-08-15 05:00:33 -07001006 for (int i = 0; i < kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001007 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang892dab52017-08-15 05:00:33 -07001008 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1009 }
1010
1011 // |kMinRequiredSamples| samples, and thereby intervals, is required. That
1012 // means we're one frame short of having a valid data set.
1013 statistics_proxy_.reset();
1014 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1015 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1016 EXPECT_EQ(
1017 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1018 EXPECT_EQ(0, metrics::NumSamples(
1019 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1020}
1021
sprang3e86e7e2017-08-22 09:23:28 -07001022TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithPause) {
1023 const VideoContentType content_type = GetParam();
1024 const int kInterFrameDelayMs = 33;
Sergey Silkin278f8252019-01-09 14:37:40 +01001025 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1026
sprang3e86e7e2017-08-22 09:23:28 -07001027 for (int i = 0; i <= kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001028 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang3e86e7e2017-08-22 09:23:28 -07001029 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1030 }
1031
1032 // At this state, we should have a valid inter-frame delay.
1033 // Indicate stream paused and make a large jump in time.
1034 statistics_proxy_->OnStreamInactive();
1035 fake_clock_.AdvanceTimeMilliseconds(5000);
1036
1037 // Insert two more frames. The interval during the pause should be disregarded
1038 // in the stats.
Sergey Silkin278f8252019-01-09 14:37:40 +01001039 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang3e86e7e2017-08-22 09:23:28 -07001040 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +01001041 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
sprang3e86e7e2017-08-22 09:23:28 -07001042
1043 statistics_proxy_.reset();
ilnik6d5b4d62017-08-30 03:32:14 -07001044 if (videocontenttypehelpers::IsScreenshare(content_type)) {
sprang3e86e7e2017-08-22 09:23:28 -07001045 EXPECT_EQ(
1046 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1047 EXPECT_EQ(1, metrics::NumSamples(
1048 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1049 EXPECT_EQ(
1050 kInterFrameDelayMs,
1051 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1052 EXPECT_EQ(
1053 kInterFrameDelayMs,
1054 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1055 } else {
1056 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1057 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1058 EXPECT_EQ(kInterFrameDelayMs,
1059 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1060 EXPECT_EQ(kInterFrameDelayMs,
1061 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1062 }
1063}
1064
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001065TEST_P(ReceiveStatisticsProxyTest, FreezesAreReported) {
1066 const VideoContentType content_type = GetParam();
1067 const int kInterFrameDelayMs = 33;
1068 const int kFreezeDelayMs = 200;
Sergey Silkinbea18ca2018-10-02 16:22:46 +02001069 const int kCallDurationMs =
1070 kMinRequiredSamples * kInterFrameDelayMs + kFreezeDelayMs;
Sergey Silkin278f8252019-01-09 14:37:40 +01001071 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1072
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001073 for (int i = 0; i < kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001074 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiycdc959f2018-10-10 13:15:09 +02001075 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001076 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1077 }
1078 // Add extra freeze.
1079 fake_clock_.AdvanceTimeMilliseconds(kFreezeDelayMs);
Sergey Silkin278f8252019-01-09 14:37:40 +01001080 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiycdc959f2018-10-10 13:15:09 +02001081 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001082
1083 statistics_proxy_.reset();
1084 const int kExpectedTimeBetweenFreezes =
1085 kInterFrameDelayMs * (kMinRequiredSamples - 1);
Sergey Silkinbea18ca2018-10-02 16:22:46 +02001086 const int kExpectedNumberFreezesPerMinute = 60 * 1000 / kCallDurationMs;
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001087 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1088 EXPECT_EQ(
1089 kFreezeDelayMs + kInterFrameDelayMs,
1090 metrics::MinSample("WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1091 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1092 metrics::MinSample(
1093 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
Sergey Silkinbea18ca2018-10-02 16:22:46 +02001094 EXPECT_EQ(
1095 kExpectedNumberFreezesPerMinute,
1096 metrics::MinSample("WebRTC.Video.Screenshare.NumberFreezesPerMinute"));
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001097 } else {
1098 EXPECT_EQ(kFreezeDelayMs + kInterFrameDelayMs,
1099 metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1100 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1101 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
Sergey Silkinbea18ca2018-10-02 16:22:46 +02001102 EXPECT_EQ(kExpectedNumberFreezesPerMinute,
1103 metrics::MinSample("WebRTC.Video.NumberFreezesPerMinute"));
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001104 }
1105}
1106
Sergey Silkin50e77452019-01-16 13:41:46 +01001107TEST_P(ReceiveStatisticsProxyTest, HarmonicFrameRateIsReported) {
1108 const VideoContentType content_type = GetParam();
1109 const int kInterFrameDelayMs = 33;
1110 const int kFreezeDelayMs = 200;
1111 const int kCallDurationMs =
1112 kMinRequiredSamples * kInterFrameDelayMs + kFreezeDelayMs;
1113 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1114
1115 for (int i = 0; i < kMinRequiredSamples; ++i) {
1116 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1117 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
1118 statistics_proxy_->OnRenderedFrame(frame);
1119 }
1120 // Add extra freeze.
1121 fake_clock_.AdvanceTimeMilliseconds(kFreezeDelayMs);
1122 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
1123 statistics_proxy_->OnRenderedFrame(frame);
1124
1125 statistics_proxy_.reset();
1126 double kSumSquaredInterframeDelaysSecs =
1127 (kMinRequiredSamples - 1) *
1128 (kInterFrameDelayMs / 1000.0 * kInterFrameDelayMs / 1000.0);
1129 kSumSquaredInterframeDelaysSecs +=
1130 kFreezeDelayMs / 1000.0 * kFreezeDelayMs / 1000.0;
1131 const int kExpectedHarmonicFrameRateFps =
1132 std::round(kCallDurationMs / (1000 * kSumSquaredInterframeDelaysSecs));
1133 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1134 EXPECT_EQ(kExpectedHarmonicFrameRateFps,
1135 metrics::MinSample("WebRTC.Video.Screenshare.HarmonicFrameRate"));
1136 } else {
1137 EXPECT_EQ(kExpectedHarmonicFrameRateFps,
1138 metrics::MinSample("WebRTC.Video.HarmonicFrameRate"));
1139 }
1140}
1141
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001142TEST_P(ReceiveStatisticsProxyTest, PausesAreIgnored) {
1143 const VideoContentType content_type = GetParam();
1144 const int kInterFrameDelayMs = 33;
1145 const int kPauseDurationMs = 10000;
Sergey Silkin278f8252019-01-09 14:37:40 +01001146 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1147
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001148 for (int i = 0; i <= kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001149 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiycdc959f2018-10-10 13:15:09 +02001150 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001151 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1152 }
1153 // Add a pause.
1154 fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1155 statistics_proxy_->OnStreamInactive();
1156
1157 // Second playback interval with triple the length.
1158 for (int i = 0; i <= kMinRequiredSamples * 3; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001159 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiycdc959f2018-10-10 13:15:09 +02001160 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001161 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1162 }
1163
1164 statistics_proxy_.reset();
1165 // Average of two playback intervals.
1166 const int kExpectedTimeBetweenFreezes =
1167 kInterFrameDelayMs * kMinRequiredSamples * 2;
1168 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1169 EXPECT_EQ(-1, metrics::MinSample(
1170 "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1171 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1172 metrics::MinSample(
1173 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1174 } else {
1175 EXPECT_EQ(-1, metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1176 EXPECT_EQ(kExpectedTimeBetweenFreezes,
1177 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1178 }
1179}
1180
Ilya Nikolaevskiy879f5a32018-05-31 09:47:17 +02001181TEST_P(ReceiveStatisticsProxyTest, ManyPausesAtTheBeginning) {
1182 const VideoContentType content_type = GetParam();
1183 const int kInterFrameDelayMs = 33;
1184 const int kPauseDurationMs = 10000;
Sergey Silkin278f8252019-01-09 14:37:40 +01001185 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1186
Ilya Nikolaevskiy879f5a32018-05-31 09:47:17 +02001187 for (int i = 0; i <= kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001188 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiy879f5a32018-05-31 09:47:17 +02001189 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1190
1191 statistics_proxy_->OnStreamInactive();
1192 fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1193
Sergey Silkin278f8252019-01-09 14:37:40 +01001194 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
Ilya Nikolaevskiy879f5a32018-05-31 09:47:17 +02001195 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1196 }
1197
1198 statistics_proxy_.reset();
1199 // No freezes should be detected, as all long inter-frame delays were pauses.
1200 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1201 EXPECT_EQ(-1, metrics::MinSample(
1202 "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1203 } else {
1204 EXPECT_EQ(-1, metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1205 }
1206}
1207
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001208TEST_P(ReceiveStatisticsProxyTest, TimeInHdReported) {
1209 const VideoContentType content_type = GetParam();
1210 const int kInterFrameDelayMs = 20;
Sergey Silkin278f8252019-01-09 14:37:40 +01001211 webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1212 webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1213
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001214 // HD frames.
1215 for (int i = 0; i < kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001216 statistics_proxy_->OnDecodedFrame(frame_hd, absl::nullopt, content_type);
1217 statistics_proxy_->OnRenderedFrame(frame_hd);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001218 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1219 }
1220 // SD frames.
1221 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001222 statistics_proxy_->OnDecodedFrame(frame_sd, absl::nullopt, content_type);
1223 statistics_proxy_->OnRenderedFrame(frame_sd);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001224 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1225 }
1226 // Extra last frame.
Sergey Silkin278f8252019-01-09 14:37:40 +01001227 statistics_proxy_->OnRenderedFrame(frame_sd);
1228
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001229 statistics_proxy_.reset();
1230 const int kExpectedTimeInHdPercents = 33;
1231 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1232 EXPECT_EQ(
1233 kExpectedTimeInHdPercents,
1234 metrics::MinSample("WebRTC.Video.Screenshare.TimeInHdPercentage"));
1235 } else {
1236 EXPECT_EQ(kExpectedTimeInHdPercents,
1237 metrics::MinSample("WebRTC.Video.TimeInHdPercentage"));
1238 }
1239}
1240
1241TEST_P(ReceiveStatisticsProxyTest, TimeInBlockyVideoReported) {
1242 const VideoContentType content_type = GetParam();
1243 const int kInterFrameDelayMs = 20;
1244 const int kHighQp = 80;
1245 const int kLowQp = 30;
Sergey Silkin278f8252019-01-09 14:37:40 +01001246 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1247
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001248 // High quality frames.
1249 for (int i = 0; i < kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001250 statistics_proxy_->OnDecodedFrame(frame, kLowQp, content_type);
1251 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001252 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1253 }
1254 // Blocky frames.
1255 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
Sergey Silkin278f8252019-01-09 14:37:40 +01001256 statistics_proxy_->OnDecodedFrame(frame, kHighQp, content_type);
1257 statistics_proxy_->OnRenderedFrame(frame);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001258 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1259 }
1260 // Extra last frame.
Sergey Silkin278f8252019-01-09 14:37:40 +01001261 statistics_proxy_->OnDecodedFrame(frame, kHighQp, content_type);
1262 statistics_proxy_->OnRenderedFrame(frame);
1263
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001264 statistics_proxy_.reset();
1265 const int kExpectedTimeInHdPercents = 66;
1266 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1267 EXPECT_EQ(kExpectedTimeInHdPercents,
1268 metrics::MinSample(
1269 "WebRTC.Video.Screenshare.TimeInBlockyVideoPercentage"));
1270 } else {
1271 EXPECT_EQ(kExpectedTimeInHdPercents,
1272 metrics::MinSample("WebRTC.Video.TimeInBlockyVideoPercentage"));
1273 }
1274}
1275
1276TEST_P(ReceiveStatisticsProxyTest, DownscalesReported) {
1277 const VideoContentType content_type = GetParam();
Sergey Silkin278f8252019-01-09 14:37:40 +01001278 const int kInterFrameDelayMs = 2000; // To ensure long enough call duration.
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001279
Sergey Silkin278f8252019-01-09 14:37:40 +01001280 webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1281 webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1282 webrtc::VideoFrame frame_ld = CreateFrame(320, 180);
1283
1284 // Call once to pass content type.
1285 statistics_proxy_->OnDecodedFrame(frame_hd, absl::nullopt, content_type);
1286
1287 statistics_proxy_->OnRenderedFrame(frame_hd);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001288 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1289
1290 // Downscale.
Sergey Silkin278f8252019-01-09 14:37:40 +01001291 statistics_proxy_->OnRenderedFrame(frame_sd);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001292 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1293
1294 // Downscale.
Sergey Silkin278f8252019-01-09 14:37:40 +01001295 statistics_proxy_->OnRenderedFrame(frame_ld);
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001296 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1297
1298 statistics_proxy_.reset();
Sergey Silkin278f8252019-01-09 14:37:40 +01001299 const int kExpectedDownscales = 30; // 2 per 4 seconds = 30 per minute.
Ilya Nikolaevskiy94150ee2018-05-23 11:53:19 +02001300 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1301 EXPECT_EQ(
1302 kExpectedDownscales,
1303 metrics::MinSample(
1304 "WebRTC.Video.Screenshare.NumberResolutionDownswitchesPerMinute"));
1305 } else {
1306 EXPECT_EQ(kExpectedDownscales,
1307 metrics::MinSample(
1308 "WebRTC.Video.NumberResolutionDownswitchesPerMinute"));
1309 }
1310}
1311
ilnik6d5b4d62017-08-30 03:32:14 -07001312TEST_P(ReceiveStatisticsProxyTest, StatsAreSlicedOnSimulcastAndExperiment) {
1313 VideoContentType content_type = GetParam();
1314 const uint8_t experiment_id = 1;
1315 videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
1316 const int kInterFrameDelayMs1 = 30;
1317 const int kInterFrameDelayMs2 = 50;
Sergey Silkin278f8252019-01-09 14:37:40 +01001318 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
ilnik6d5b4d62017-08-30 03:32:14 -07001319
1320 videocontenttypehelpers::SetSimulcastId(&content_type, 1);
1321 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1322 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs1);
Sergey Silkin278f8252019-01-09 14:37:40 +01001323 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
ilnik6d5b4d62017-08-30 03:32:14 -07001324 }
1325
1326 videocontenttypehelpers::SetSimulcastId(&content_type, 2);
1327 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1328 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
Sergey Silkin278f8252019-01-09 14:37:40 +01001329 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type);
ilnik6d5b4d62017-08-30 03:32:14 -07001330 }
1331 statistics_proxy_.reset();
1332
1333 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1334 EXPECT_EQ(
1335 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1336 EXPECT_EQ(1, metrics::NumSamples(
1337 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1338 EXPECT_EQ(1, metrics::NumSamples(
1339 "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1340 EXPECT_EQ(1, metrics::NumSamples(
1341 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
1342 EXPECT_EQ(1, metrics::NumSamples(
1343 "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1344 EXPECT_EQ(1, metrics::NumSamples(
1345 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
1346 EXPECT_EQ(1,
1347 metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
1348 ".ExperimentGroup0"));
1349 EXPECT_EQ(
1350 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
1351 ".ExperimentGroup0"));
1352 EXPECT_EQ(
1353 kInterFrameDelayMs1,
1354 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1355 EXPECT_EQ(
1356 kInterFrameDelayMs2,
1357 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1358 EXPECT_EQ(
1359 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1360 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1361 EXPECT_EQ(
1362 kInterFrameDelayMs2,
1363 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1364 EXPECT_EQ(
1365 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1366 metrics::MinSample(
1367 "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
1368 } else {
1369 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1370 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1371 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
1372 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
1373 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
1374 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
1375 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
1376 ".ExperimentGroup0"));
1377 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
1378 ".ExperimentGroup0"));
1379 EXPECT_EQ(kInterFrameDelayMs1,
1380 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
1381 EXPECT_EQ(kInterFrameDelayMs2,
1382 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
1383 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1384 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1385 EXPECT_EQ(kInterFrameDelayMs2,
1386 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1387 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1388 metrics::MinSample(
1389 "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
1390 }
1391}
sakale5ba44e2016-10-26 07:09:24 -07001392} // namespace webrtc