blob: 528ef09c88003d42a65f8e997d9f689e7ea36644 [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
11#include "webrtc/video/receive_statistics_proxy.h"
12
asapersson2077f2f2017-05-11 05:37:35 -070013#include <limits>
sakale5ba44e2016-10-26 07:09:24 -070014#include <memory>
15
nissef93752a2017-05-10 05:25:59 -070016#include "webrtc/api/video/i420_buffer.h"
hbos50cfe1f2017-01-23 07:21:55 -080017#include "webrtc/api/video/video_frame.h"
18#include "webrtc/api/video/video_rotation.h"
asapersson6966bd52017-01-03 00:44:06 -080019#include "webrtc/modules/video_coding/include/video_codec_interface.h"
asapersson0c43f772016-11-30 01:42:26 -080020#include "webrtc/system_wrappers/include/metrics.h"
asaperssonde9e5ff2016-11-02 07:14:03 -070021#include "webrtc/system_wrappers/include/metrics_default.h"
sakale5ba44e2016-10-26 07:09:24 -070022#include "webrtc/test/gtest.h"
23
24namespace webrtc {
asaperssonde9e5ff2016-11-02 07:14:03 -070025namespace {
26const int64_t kFreqOffsetProcessIntervalInMs = 40000;
asapersson46c4e3c2016-11-03 06:48:19 -070027const uint32_t kLocalSsrc = 123;
28const uint32_t kRemoteSsrc = 456;
29const int kMinRequiredSamples = 200;
asaperssonde9e5ff2016-11-02 07:14:03 -070030} // namespace
sakale5ba44e2016-10-26 07:09:24 -070031
32// TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
sprang892dab52017-08-15 05:00:33 -070033class ReceiveStatisticsProxyTest
34 : public ::testing::TestWithParam<webrtc::VideoContentType> {
sakale5ba44e2016-10-26 07:09:24 -070035 public:
36 ReceiveStatisticsProxyTest() : fake_clock_(1234), config_(GetTestConfig()) {}
37 virtual ~ReceiveStatisticsProxyTest() {}
38
39 protected:
40 virtual void SetUp() {
asaperssonde9e5ff2016-11-02 07:14:03 -070041 metrics::Reset();
sakale5ba44e2016-10-26 07:09:24 -070042 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_));
43 }
44
45 VideoReceiveStream::Config GetTestConfig() {
46 VideoReceiveStream::Config config(nullptr);
asapersson46c4e3c2016-11-03 06:48:19 -070047 config.rtp.local_ssrc = kLocalSsrc;
48 config.rtp.remote_ssrc = kRemoteSsrc;
sakale5ba44e2016-10-26 07:09:24 -070049 return config;
50 }
51
asapersson2077f2f2017-05-11 05:37:35 -070052 void InsertFirstRtpPacket(uint32_t ssrc) {
53 StreamDataCounters counters;
54 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
55 statistics_proxy_->DataCountersUpdated(counters, ssrc);
56 }
57
58 VideoFrame CreateFrame(int width, int height) {
59 VideoFrame frame(I420Buffer::Create(width, height), 0, 0, kVideoRotation_0);
60 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
61 return frame;
62 }
63
sakale5ba44e2016-10-26 07:09:24 -070064 SimulatedClock fake_clock_;
asaperssonde9e5ff2016-11-02 07:14:03 -070065 const VideoReceiveStream::Config config_;
sakale5ba44e2016-10-26 07:09:24 -070066 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
sakale5ba44e2016-10-26 07:09:24 -070067};
68
69TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) {
70 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
71 for (uint32_t i = 1; i <= 3; ++i) {
ilnik00d802b2017-04-11 10:34:31 -070072 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
73 VideoContentType::UNSPECIFIED);
sakale5ba44e2016-10-26 07:09:24 -070074 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
75 }
76}
77
sakalcc452e12017-02-09 04:53:45 -080078TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithQpResetsFramesDecoded) {
79 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
80 for (uint32_t i = 1; i <= 3; ++i) {
ilnik00d802b2017-04-11 10:34:31 -070081 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
82 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080083 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
84 }
ilnik00d802b2017-04-11 10:34:31 -070085 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(1u),
86 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080087 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_decoded);
88}
89
90TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) {
91 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070092 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
93 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080094 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070095 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
96 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080097 EXPECT_EQ(rtc::Optional<uint64_t>(130u),
98 statistics_proxy_->GetStats().qp_sum);
99}
100
ilnika79cc282017-08-23 05:24:10 -0700101TEST_F(ReceiveStatisticsProxyTest, ReportsMaxInterframeDelay) {
102 const int64_t kInterframeDelayMs1 = 100;
103 const int64_t kInterframeDelayMs2 = 200;
104 const int64_t kInterframeDelayMs3 = 100;
105 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700106 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
107 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700108 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700109
110 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
111 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
112 VideoContentType::UNSPECIFIED);
113 EXPECT_EQ(kInterframeDelayMs1,
ilnika79cc282017-08-23 05:24:10 -0700114 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700115
116 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
117 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
118 VideoContentType::UNSPECIFIED);
ilnika79cc282017-08-23 05:24:10 -0700119 EXPECT_EQ(kInterframeDelayMs2,
120 statistics_proxy_->GetStats().interframe_delay_max_ms);
121
122 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
123 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
124 VideoContentType::UNSPECIFIED);
125 // kInterframeDelayMs3 is smaller than kInterframeDelayMs2.
126 EXPECT_EQ(kInterframeDelayMs2,
127 statistics_proxy_->GetStats().interframe_delay_max_ms);
128}
129
130TEST_F(ReceiveStatisticsProxyTest, ReportInterframeDelayInWindow) {
131 const int64_t kInterframeDelayMs1 = 9000;
132 const int64_t kInterframeDelayMs2 = 7500;
133 const int64_t kInterframeDelayMs3 = 7000;
134 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
135 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
136 VideoContentType::UNSPECIFIED);
137 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
138
139 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
140 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
141 VideoContentType::UNSPECIFIED);
142 EXPECT_EQ(kInterframeDelayMs1,
143 statistics_proxy_->GetStats().interframe_delay_max_ms);
144
145 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
146 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
147 VideoContentType::UNSPECIFIED);
148 // Still first delay is the maximum
149 EXPECT_EQ(kInterframeDelayMs1,
150 statistics_proxy_->GetStats().interframe_delay_max_ms);
151
152 fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
153 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
154 VideoContentType::UNSPECIFIED);
155 // Now the first sample is out of the window, so the second is the maximum.
156 EXPECT_EQ(kInterframeDelayMs2,
157 statistics_proxy_->GetStats().interframe_delay_max_ms);
ilnikf04afde2017-07-07 01:26:24 -0700158}
159
sakalcc452e12017-02-09 04:53:45 -0800160TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) {
161 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -0700162 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
163 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800164 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
165}
166
167TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) {
168 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -0700169 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
170 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800171 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -0700172 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
173 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800174 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
175}
176
hbos50cfe1f2017-01-23 07:21:55 -0800177TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) {
178 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
ilnik00d802b2017-04-11 10:34:31 -0700179 webrtc::VideoFrame frame(webrtc::I420Buffer::Create(1, 1), 0, 0,
180 webrtc::kVideoRotation_0);
hbos50cfe1f2017-01-23 07:21:55 -0800181 for (uint32_t i = 1; i <= 3; ++i) {
182 statistics_proxy_->OnRenderedFrame(frame);
183 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
184 }
185}
186
asapersson46c4e3c2016-11-03 06:48:19 -0700187TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsSsrc) {
188 EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
189}
190
191TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsIncomingPayloadType) {
192 const int kPayloadType = 111;
193 statistics_proxy_->OnIncomingPayloadType(kPayloadType);
194 EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
195}
196
asapersson6966bd52017-01-03 00:44:06 -0800197TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecoderImplementationName) {
198 const char* kName = "decoderName";
199 statistics_proxy_->OnDecoderImplementationName(kName);
200 EXPECT_STREQ(
201 kName, statistics_proxy_->GetStats().decoder_implementation_name.c_str());
202}
203
philipela45102f2017-02-22 05:30:39 -0800204TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsOnCompleteFrame) {
205 const int kFrameSizeBytes = 1000;
ilnik6d5b4d62017-08-30 03:32:14 -0700206 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
207 VideoContentType::UNSPECIFIED);
philipela45102f2017-02-22 05:30:39 -0800208 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
209 EXPECT_EQ(1, stats.network_frame_rate);
philipela45102f2017-02-22 05:30:39 -0800210 EXPECT_EQ(1, stats.frame_counts.key_frames);
211 EXPECT_EQ(0, stats.frame_counts.delta_frames);
asapersson46c4e3c2016-11-03 06:48:19 -0700212}
213
214TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecodeTimingStats) {
215 const int kDecodeMs = 1;
216 const int kMaxDecodeMs = 2;
217 const int kCurrentDelayMs = 3;
218 const int kTargetDelayMs = 4;
219 const int kJitterBufferMs = 5;
220 const int kMinPlayoutDelayMs = 6;
221 const int kRenderDelayMs = 7;
222 const int64_t kRttMs = 8;
philipela45102f2017-02-22 05:30:39 -0800223 statistics_proxy_->OnRttUpdate(kRttMs, 0);
224 statistics_proxy_->OnFrameBufferTimingsUpdated(
asapersson46c4e3c2016-11-03 06:48:19 -0700225 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
philipela45102f2017-02-22 05:30:39 -0800226 kMinPlayoutDelayMs, kRenderDelayMs);
asapersson46c4e3c2016-11-03 06:48:19 -0700227 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
228 EXPECT_EQ(kDecodeMs, stats.decode_ms);
229 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
230 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
231 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
232 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
233 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
234 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
235}
236
asapersson6966bd52017-01-03 00:44:06 -0800237TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpPacketTypeCounts) {
238 const uint32_t kFirPackets = 33;
239 const uint32_t kPliPackets = 44;
240 const uint32_t kNackPackets = 55;
241 RtcpPacketTypeCounter counter;
242 counter.fir_packets = kFirPackets;
243 counter.pli_packets = kPliPackets;
244 counter.nack_packets = kNackPackets;
245 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
246 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
247 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
248 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
249 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
250}
251
252TEST_F(ReceiveStatisticsProxyTest,
253 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
254 RtcpPacketTypeCounter counter;
255 counter.fir_packets = 33;
256 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
257 EXPECT_EQ(0u,
258 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
259}
260
261TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsFrameCounts) {
262 const int kKeyFrames = 3;
263 const int kDeltaFrames = 22;
264 FrameCounts frame_counts;
265 frame_counts.key_frames = kKeyFrames;
266 frame_counts.delta_frames = kDeltaFrames;
267 statistics_proxy_->OnFrameCountsUpdated(frame_counts);
268 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
269 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
270 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
271}
272
asapersson46c4e3c2016-11-03 06:48:19 -0700273TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDiscardedPackets) {
274 const int kDiscardedPackets = 12;
275 statistics_proxy_->OnDiscardedPacketsUpdated(kDiscardedPackets);
276 EXPECT_EQ(kDiscardedPackets, statistics_proxy_->GetStats().discarded_packets);
277}
278
asapersson6966bd52017-01-03 00:44:06 -0800279TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpStats) {
280 const uint8_t kFracLost = 0;
281 const uint32_t kCumLost = 1;
282 const uint32_t kExtSeqNum = 10;
283 const uint32_t kJitter = 4;
284
285 RtcpStatistics rtcp_stats;
286 rtcp_stats.fraction_lost = kFracLost;
srte186d9c32017-08-04 05:03:53 -0700287 rtcp_stats.packets_lost = kCumLost;
288 rtcp_stats.extended_highest_sequence_number = kExtSeqNum;
asapersson6966bd52017-01-03 00:44:06 -0800289 rtcp_stats.jitter = kJitter;
290 statistics_proxy_->StatisticsUpdated(rtcp_stats, kRemoteSsrc);
291
292 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
293 EXPECT_EQ(kFracLost, stats.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700294 EXPECT_EQ(kCumLost, stats.rtcp_stats.packets_lost);
295 EXPECT_EQ(kExtSeqNum, stats.rtcp_stats.extended_highest_sequence_number);
asapersson6966bd52017-01-03 00:44:06 -0800296 EXPECT_EQ(kJitter, stats.rtcp_stats.jitter);
297}
298
299TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsCName) {
300 const char* kName = "cName";
301 statistics_proxy_->CNameChanged(kName, kRemoteSsrc);
302 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
303}
304
305TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsNoCNameForUnknownSsrc) {
306 const char* kName = "cName";
307 statistics_proxy_->CNameChanged(kName, kRemoteSsrc + 1);
308 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
309}
310
ilnik2edc6842017-07-06 03:06:50 -0700311TEST_F(ReceiveStatisticsProxyTest,
312 GetTimingFrameInfoReportsLongestTimingFrame) {
313 const int64_t kShortEndToEndDelay = 10;
314 const int64_t kMedEndToEndDelay = 20;
315 const int64_t kLongEndToEndDelay = 100;
316 const uint32_t kExpectedRtpTimestamp = 2;
317 TimingFrameInfo info;
318 rtc::Optional<TimingFrameInfo> result;
319 info.rtp_timestamp = kExpectedRtpTimestamp - 1;
320 info.capture_time_ms = 0;
321 info.decode_finish_ms = kShortEndToEndDelay;
322 statistics_proxy_->OnTimingFrameInfoUpdated(info);
323 info.rtp_timestamp =
324 kExpectedRtpTimestamp; // this frame should be reported in the end.
325 info.capture_time_ms = 0;
326 info.decode_finish_ms = kLongEndToEndDelay;
327 statistics_proxy_->OnTimingFrameInfoUpdated(info);
328 info.rtp_timestamp = kExpectedRtpTimestamp + 1;
329 info.capture_time_ms = 0;
330 info.decode_finish_ms = kMedEndToEndDelay;
331 statistics_proxy_->OnTimingFrameInfoUpdated(info);
332 result = statistics_proxy_->GetAndResetTimingFrameInfo();
333 EXPECT_TRUE(result);
334 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
335}
336
337TEST_F(ReceiveStatisticsProxyTest, GetTimingFrameInfoTimingFramesReportedOnce) {
338 const int64_t kShortEndToEndDelay = 10;
339 const uint32_t kExpectedRtpTimestamp = 2;
340 TimingFrameInfo info;
341 rtc::Optional<TimingFrameInfo> result;
342 info.rtp_timestamp = kExpectedRtpTimestamp;
343 info.capture_time_ms = 0;
344 info.decode_finish_ms = kShortEndToEndDelay;
345 statistics_proxy_->OnTimingFrameInfoUpdated(info);
346 result = statistics_proxy_->GetAndResetTimingFrameInfo();
347 EXPECT_TRUE(result);
348 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
349 result = statistics_proxy_->GetAndResetTimingFrameInfo();
350 EXPECT_FALSE(result);
351}
352
asapersson46c4e3c2016-11-03 06:48:19 -0700353TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
354 const int64_t kTimeSec = 3;
355 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
ilnik6d5b4d62017-08-30 03:32:14 -0700356 // Need at least one frame to report stream lifetime.
357 statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
asapersson46c4e3c2016-11-03 06:48:19 -0700358 // Histograms are updated when the statistics_proxy_ is deleted.
359 statistics_proxy_.reset();
360 EXPECT_EQ(1,
361 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
362 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
363 kTimeSec));
364}
365
ilnik6d5b4d62017-08-30 03:32:14 -0700366TEST_F(ReceiveStatisticsProxyTest,
367 LifetimeHistogramNotReportedForEmptyStreams) {
368 const int64_t kTimeSec = 3;
369 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
370 // No frames received.
371 // Histograms are updated when the statistics_proxy_ is deleted.
372 statistics_proxy_.reset();
373 EXPECT_EQ(0,
374 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
375}
376
palmkvista40672a2017-01-13 05:58:34 -0800377TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
378 // Based on the tuning parameters this will produce 7 uncertain states,
379 // then 10 certainly bad states. There has to be 10 certain states before
380 // any histograms are recorded.
381 const int kNumBadSamples = 17;
382
383 StreamDataCounters counters;
384 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
385 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
386
387 for (int i = 0; i < kNumBadSamples; ++i) {
388 // Since OnRenderedFrame is never called the fps in each sample will be 0,
389 // i.e. bad
390 fake_clock_.AdvanceTimeMilliseconds(1000);
391 statistics_proxy_->OnIncomingRate(0, 0);
392 }
393 // Histograms are updated when the statistics_proxy_ is deleted.
394 statistics_proxy_.reset();
395 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
396 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
397
398 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
399 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
400
401 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
402
403 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
404}
405
asapersson0c43f772016-11-30 01:42:26 -0800406TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
407 const uint32_t kCumLost1 = 1;
408 const uint32_t kExtSeqNum1 = 10;
409 const uint32_t kCumLost2 = 2;
410 const uint32_t kExtSeqNum2 = 20;
411
412 // One report block received.
413 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700414 rtcp_stats1.packets_lost = kCumLost1;
415 rtcp_stats1.extended_highest_sequence_number = kExtSeqNum1;
asapersson0c43f772016-11-30 01:42:26 -0800416 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
417
418 // Two report blocks received.
419 RtcpStatistics rtcp_stats2;
srte186d9c32017-08-04 05:03:53 -0700420 rtcp_stats2.packets_lost = kCumLost2;
421 rtcp_stats2.extended_highest_sequence_number = kExtSeqNum2;
asapersson0c43f772016-11-30 01:42:26 -0800422 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
423
424 // Two received report blocks but min run time has not passed.
425 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
426 SetUp(); // Reset stat proxy causes histograms to be updated.
427 EXPECT_EQ(0,
428 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
429
430 // Two report blocks received.
431 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
432 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
433
434 // Two received report blocks and min run time has passed.
435 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
436 SetUp();
437 EXPECT_EQ(1,
438 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
439 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
440 (kCumLost2 - kCumLost1) * 100 /
441 (kExtSeqNum2 - kExtSeqNum1)));
442}
443
444TEST_F(ReceiveStatisticsProxyTest,
445 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
446 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700447 rtcp_stats1.packets_lost = 1;
448 rtcp_stats1.extended_highest_sequence_number = 10;
asapersson0c43f772016-11-30 01:42:26 -0800449
450 // Min run time has passed but no received report block.
451 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
452 SetUp(); // Reset stat proxy causes histograms to be updated.
453 EXPECT_EQ(0,
454 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
455
456 // Min run time has passed but only one received report block.
457 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
458 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
459 SetUp();
460 EXPECT_EQ(0,
461 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
462}
463
asapersson2077f2f2017-05-11 05:37:35 -0700464TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) {
465 const int64_t kSyncOffsetMs = 22;
466 const double kFreqKhz = 90.0;
467 EXPECT_EQ(std::numeric_limits<int>::max(),
468 statistics_proxy_->GetStats().sync_offset_ms);
469 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
470 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms);
471}
472
asapersson46c4e3c2016-11-03 06:48:19 -0700473TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
474 const int64_t kSyncOffsetMs = 22;
475 const double kFreqKhz = 90.0;
476 for (int i = 0; i < kMinRequiredSamples; ++i)
477 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
478 // Histograms are updated when the statistics_proxy_ is deleted.
479 statistics_proxy_.reset();
480 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
481 EXPECT_EQ(1,
482 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
483}
484
asaperssonde9e5ff2016-11-02 07:14:03 -0700485TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
486 const int64_t kSyncOffsetMs = 22;
487 const double kFreqKhz = 90.0;
488 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
489 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
490 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
491 // Process interval passed, max diff: 2.
492 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
493 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
494 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
495 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
496 // Process interval passed, max diff: 4.
497 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
498 statistics_proxy_.reset();
499 // Average reported: (2 + 4) / 2 = 3.
500 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
501 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
502}
503
asapersson6966bd52017-01-03 00:44:06 -0800504TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
505 const int kQp = 22;
506 EncodedImage encoded_image;
507 encoded_image.qp_ = kQp;
508 CodecSpecificInfo codec_info;
509 codec_info.codecType = kVideoCodecVP8;
510
511 for (int i = 0; i < kMinRequiredSamples; ++i)
512 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
513
514 statistics_proxy_.reset();
515 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
516 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
517}
518
519TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
520 EncodedImage encoded_image;
521 encoded_image.qp_ = 22;
522 CodecSpecificInfo codec_info;
523 codec_info.codecType = kVideoCodecVP8;
524
525 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
526 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
527
528 statistics_proxy_.reset();
529 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
530}
531
532TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
533 EncodedImage encoded_image;
534 CodecSpecificInfo codec_info;
535 codec_info.codecType = kVideoCodecVP8;
536
537 for (int i = 0; i < kMinRequiredSamples; ++i)
538 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
539
540 statistics_proxy_.reset();
541 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
542}
543
asaperssonb99baf82017-04-20 04:05:43 -0700544TEST_F(ReceiveStatisticsProxyTest,
545 KeyFrameHistogramNotUpdatedForTooFewSamples) {
546 const bool kIsKeyFrame = false;
547 const int kFrameSizeBytes = 1000;
548
549 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700550 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
551 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700552
553 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
554 EXPECT_EQ(kMinRequiredSamples - 1,
555 statistics_proxy_->GetStats().frame_counts.delta_frames);
556
557 statistics_proxy_.reset();
558 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
559}
560
561TEST_F(ReceiveStatisticsProxyTest,
562 KeyFrameHistogramUpdatedForMinRequiredSamples) {
563 const bool kIsKeyFrame = false;
564 const int kFrameSizeBytes = 1000;
565
566 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700567 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
568 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700569
570 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
571 EXPECT_EQ(kMinRequiredSamples,
572 statistics_proxy_->GetStats().frame_counts.delta_frames);
573
574 statistics_proxy_.reset();
575 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
576 EXPECT_EQ(1,
577 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
578}
579
580TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
581 const int kFrameSizeBytes = 1000;
582
583 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700584 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
585 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700586
587 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700588 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
589 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700590
591 EXPECT_EQ(kMinRequiredSamples,
592 statistics_proxy_->GetStats().frame_counts.key_frames);
593 EXPECT_EQ(kMinRequiredSamples,
594 statistics_proxy_->GetStats().frame_counts.delta_frames);
595
596 statistics_proxy_.reset();
597 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
598 EXPECT_EQ(
599 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
600}
601
602TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
603 const int kDecodeMs = 1;
604 const int kMaxDecodeMs = 2;
605 const int kCurrentDelayMs = 3;
606 const int kTargetDelayMs = 4;
607 const int kJitterBufferMs = 5;
608 const int kMinPlayoutDelayMs = 6;
609 const int kRenderDelayMs = 7;
610
611 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
612 statistics_proxy_->OnFrameBufferTimingsUpdated(
613 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
614 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
615 }
616
617 statistics_proxy_.reset();
618 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
619 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
620 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
621 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
622 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
623}
624
625TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
626 const int kDecodeMs = 1;
627 const int kMaxDecodeMs = 2;
628 const int kCurrentDelayMs = 3;
629 const int kTargetDelayMs = 4;
630 const int kJitterBufferMs = 5;
631 const int kMinPlayoutDelayMs = 6;
632 const int kRenderDelayMs = 7;
633
634 for (int i = 0; i < kMinRequiredSamples; ++i) {
635 statistics_proxy_->OnFrameBufferTimingsUpdated(
636 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
637 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
638 }
639
640 statistics_proxy_.reset();
641 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
642 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
643 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
644 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
645 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
646
647 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
648 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
649 kJitterBufferMs));
650 EXPECT_EQ(1,
651 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
652 EXPECT_EQ(
653 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
654 EXPECT_EQ(1,
655 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
656}
657
sprang948b2752017-05-04 02:47:13 -0700658TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
659 const int kDefaultFps = 30;
660 const int kWidth = 320;
661 const int kHeight = 240;
662
663 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer(
664 I420Buffer::Create(kWidth, kHeight));
665 VideoFrame frame(video_frame_buffer, kVideoRotation_0, 0);
666
667 for (int i = 0; i < kDefaultFps; ++i) {
668 // Since OnRenderedFrame is never called the fps in each sample will be 0,
669 // i.e. bad
670 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
671 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
672 VideoContentType::UNSPECIFIED);
673 statistics_proxy_->OnRenderedFrame(frame);
674 fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
675 }
676
677 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
678 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
679
680 // FPS trackers in stats proxy have a 1000ms sliding window.
681 fake_clock_.AdvanceTimeMilliseconds(1000);
682 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
683 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
684}
685
asapersson2077f2f2017-05-11 05:37:35 -0700686TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) {
687 const int kWidth = 160;
688 const int kHeight = 120;
689 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
690 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
691 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
692
693 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
694
695 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
696 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
697 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
698}
699
700TEST_F(ReceiveStatisticsProxyTest,
701 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
702 const int kWidth = 160;
703 const int kHeight = 120;
704
705 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
706 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
707
708 statistics_proxy_.reset();
709 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
710 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
711 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
712 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
713}
714
715TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
716 const int kWidth = 160;
717 const int kHeight = 120;
718
719 for (int i = 0; i < kMinRequiredSamples; ++i)
720 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
721
722 statistics_proxy_.reset();
723 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
724 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
725 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
726 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
727 EXPECT_EQ(1,
728 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
729 EXPECT_EQ(1,
730 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
731}
732
733TEST_F(ReceiveStatisticsProxyTest,
734 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
735 InsertFirstRtpPacket(kRemoteSsrc);
736 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
737 1);
738
739 RtcpPacketTypeCounter counter;
740 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
741
742 statistics_proxy_.reset();
743 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
744 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
745 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
746}
747
748TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
749 InsertFirstRtpPacket(kRemoteSsrc);
750 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
751
752 const uint32_t kFirPackets = 100;
753 const uint32_t kPliPackets = 200;
754 const uint32_t kNackPackets = 300;
755
756 RtcpPacketTypeCounter counter;
757 counter.fir_packets = kFirPackets;
758 counter.pli_packets = kPliPackets;
759 counter.nack_packets = kNackPackets;
760 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
761
762 statistics_proxy_.reset();
763 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
764 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
765 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
766 EXPECT_EQ(
767 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
768 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
769 EXPECT_EQ(
770 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
771 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
772 EXPECT_EQ(
773 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
774 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
775}
776
sprang892dab52017-08-15 05:00:33 -0700777INSTANTIATE_TEST_CASE_P(ContentTypes,
778 ReceiveStatisticsProxyTest,
779 ::testing::Values(VideoContentType::UNSPECIFIED,
780 VideoContentType::SCREENSHARE));
781
782TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysAreReported) {
783 const VideoContentType content_type = GetParam();
784 const int kInterFrameDelayMs = 33;
785 for (int i = 0; i < kMinRequiredSamples; ++i) {
786 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
787 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
788 }
789 // One extra with with double the interval.
790 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
791 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
792
793 statistics_proxy_.reset();
794 const int kExpectedInterFrame =
795 (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
796 kInterFrameDelayMs * 2) /
797 kMinRequiredSamples;
ilnik6d5b4d62017-08-30 03:32:14 -0700798 if (videocontenttypehelpers::IsScreenshare(content_type)) {
799 EXPECT_EQ(
800 kExpectedInterFrame,
801 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
802 EXPECT_EQ(
803 kInterFrameDelayMs * 2,
804 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
805 } else {
806 EXPECT_EQ(kExpectedInterFrame,
807 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
808 EXPECT_EQ(kInterFrameDelayMs * 2,
809 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
sprang892dab52017-08-15 05:00:33 -0700810 }
811}
812
813TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithValidAverage) {
814 const VideoContentType content_type = GetParam();
815 const int kInterFrameDelayMs = 33;
816 for (int i = 0; i < kMinRequiredSamples; ++i) {
817 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
818 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
819 }
820
821 // |kMinRequiredSamples| samples, and thereby intervals, is required. That
822 // means we're one frame short of having a valid data set.
823 statistics_proxy_.reset();
824 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
825 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
826 EXPECT_EQ(
827 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
828 EXPECT_EQ(0, metrics::NumSamples(
829 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
830}
831
sprang3e86e7e2017-08-22 09:23:28 -0700832TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithPause) {
833 const VideoContentType content_type = GetParam();
834 const int kInterFrameDelayMs = 33;
835 for (int i = 0; i <= kMinRequiredSamples; ++i) {
836 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
837 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
838 }
839
840 // At this state, we should have a valid inter-frame delay.
841 // Indicate stream paused and make a large jump in time.
842 statistics_proxy_->OnStreamInactive();
843 fake_clock_.AdvanceTimeMilliseconds(5000);
844
845 // Insert two more frames. The interval during the pause should be disregarded
846 // in the stats.
847 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
848 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
849 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
850
851 statistics_proxy_.reset();
ilnik6d5b4d62017-08-30 03:32:14 -0700852 if (videocontenttypehelpers::IsScreenshare(content_type)) {
sprang3e86e7e2017-08-22 09:23:28 -0700853 EXPECT_EQ(
854 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
855 EXPECT_EQ(1, metrics::NumSamples(
856 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
857 EXPECT_EQ(
858 kInterFrameDelayMs,
859 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
860 EXPECT_EQ(
861 kInterFrameDelayMs,
862 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
863 } else {
864 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
865 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
866 EXPECT_EQ(kInterFrameDelayMs,
867 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
868 EXPECT_EQ(kInterFrameDelayMs,
869 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
870 }
871}
872
ilnik6d5b4d62017-08-30 03:32:14 -0700873TEST_P(ReceiveStatisticsProxyTest, StatsAreSlicedOnSimulcastAndExperiment) {
874 VideoContentType content_type = GetParam();
875 const uint8_t experiment_id = 1;
876 videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
877 const int kInterFrameDelayMs1 = 30;
878 const int kInterFrameDelayMs2 = 50;
879
880 videocontenttypehelpers::SetSimulcastId(&content_type, 1);
881 for (int i = 0; i <= kMinRequiredSamples; ++i) {
882 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs1);
883 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
884 }
885
886 videocontenttypehelpers::SetSimulcastId(&content_type, 2);
887 for (int i = 0; i <= kMinRequiredSamples; ++i) {
888 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
889 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
890 }
891 statistics_proxy_.reset();
892
893 if (videocontenttypehelpers::IsScreenshare(content_type)) {
894 EXPECT_EQ(
895 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
896 EXPECT_EQ(1, metrics::NumSamples(
897 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
898 EXPECT_EQ(1, metrics::NumSamples(
899 "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
900 EXPECT_EQ(1, metrics::NumSamples(
901 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
902 EXPECT_EQ(1, metrics::NumSamples(
903 "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
904 EXPECT_EQ(1, metrics::NumSamples(
905 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
906 EXPECT_EQ(1,
907 metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
908 ".ExperimentGroup0"));
909 EXPECT_EQ(
910 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
911 ".ExperimentGroup0"));
912 EXPECT_EQ(
913 kInterFrameDelayMs1,
914 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
915 EXPECT_EQ(
916 kInterFrameDelayMs2,
917 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
918 EXPECT_EQ(
919 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
920 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
921 EXPECT_EQ(
922 kInterFrameDelayMs2,
923 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
924 EXPECT_EQ(
925 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
926 metrics::MinSample(
927 "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
928 } else {
929 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
930 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
931 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
932 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
933 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
934 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
935 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
936 ".ExperimentGroup0"));
937 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
938 ".ExperimentGroup0"));
939 EXPECT_EQ(kInterFrameDelayMs1,
940 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
941 EXPECT_EQ(kInterFrameDelayMs2,
942 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
943 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
944 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
945 EXPECT_EQ(kInterFrameDelayMs2,
946 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
947 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
948 metrics::MinSample(
949 "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
950 }
951}
952
sakale5ba44e2016-10-26 07:09:24 -0700953} // namespace webrtc