blob: 98ec7eddad24409ec3097b6c6568c3190be064a3 [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;
206 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes);
207 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
208 EXPECT_EQ(1, stats.network_frame_rate);
philipela45102f2017-02-22 05:30:39 -0800209 EXPECT_EQ(1, stats.frame_counts.key_frames);
210 EXPECT_EQ(0, stats.frame_counts.delta_frames);
asapersson46c4e3c2016-11-03 06:48:19 -0700211}
212
213TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecodeTimingStats) {
214 const int kDecodeMs = 1;
215 const int kMaxDecodeMs = 2;
216 const int kCurrentDelayMs = 3;
217 const int kTargetDelayMs = 4;
218 const int kJitterBufferMs = 5;
219 const int kMinPlayoutDelayMs = 6;
220 const int kRenderDelayMs = 7;
221 const int64_t kRttMs = 8;
philipela45102f2017-02-22 05:30:39 -0800222 statistics_proxy_->OnRttUpdate(kRttMs, 0);
223 statistics_proxy_->OnFrameBufferTimingsUpdated(
asapersson46c4e3c2016-11-03 06:48:19 -0700224 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
philipela45102f2017-02-22 05:30:39 -0800225 kMinPlayoutDelayMs, kRenderDelayMs);
asapersson46c4e3c2016-11-03 06:48:19 -0700226 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
227 EXPECT_EQ(kDecodeMs, stats.decode_ms);
228 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
229 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
230 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
231 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
232 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
233 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
234}
235
asapersson6966bd52017-01-03 00:44:06 -0800236TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpPacketTypeCounts) {
237 const uint32_t kFirPackets = 33;
238 const uint32_t kPliPackets = 44;
239 const uint32_t kNackPackets = 55;
240 RtcpPacketTypeCounter counter;
241 counter.fir_packets = kFirPackets;
242 counter.pli_packets = kPliPackets;
243 counter.nack_packets = kNackPackets;
244 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
245 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
246 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
247 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
248 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
249}
250
251TEST_F(ReceiveStatisticsProxyTest,
252 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
253 RtcpPacketTypeCounter counter;
254 counter.fir_packets = 33;
255 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
256 EXPECT_EQ(0u,
257 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
258}
259
260TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsFrameCounts) {
261 const int kKeyFrames = 3;
262 const int kDeltaFrames = 22;
263 FrameCounts frame_counts;
264 frame_counts.key_frames = kKeyFrames;
265 frame_counts.delta_frames = kDeltaFrames;
266 statistics_proxy_->OnFrameCountsUpdated(frame_counts);
267 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
268 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
269 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
270}
271
asapersson46c4e3c2016-11-03 06:48:19 -0700272TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDiscardedPackets) {
273 const int kDiscardedPackets = 12;
274 statistics_proxy_->OnDiscardedPacketsUpdated(kDiscardedPackets);
275 EXPECT_EQ(kDiscardedPackets, statistics_proxy_->GetStats().discarded_packets);
276}
277
asapersson6966bd52017-01-03 00:44:06 -0800278TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpStats) {
279 const uint8_t kFracLost = 0;
280 const uint32_t kCumLost = 1;
281 const uint32_t kExtSeqNum = 10;
282 const uint32_t kJitter = 4;
283
284 RtcpStatistics rtcp_stats;
285 rtcp_stats.fraction_lost = kFracLost;
srte186d9c32017-08-04 05:03:53 -0700286 rtcp_stats.packets_lost = kCumLost;
287 rtcp_stats.extended_highest_sequence_number = kExtSeqNum;
asapersson6966bd52017-01-03 00:44:06 -0800288 rtcp_stats.jitter = kJitter;
289 statistics_proxy_->StatisticsUpdated(rtcp_stats, kRemoteSsrc);
290
291 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
292 EXPECT_EQ(kFracLost, stats.rtcp_stats.fraction_lost);
srte186d9c32017-08-04 05:03:53 -0700293 EXPECT_EQ(kCumLost, stats.rtcp_stats.packets_lost);
294 EXPECT_EQ(kExtSeqNum, stats.rtcp_stats.extended_highest_sequence_number);
asapersson6966bd52017-01-03 00:44:06 -0800295 EXPECT_EQ(kJitter, stats.rtcp_stats.jitter);
296}
297
298TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsCName) {
299 const char* kName = "cName";
300 statistics_proxy_->CNameChanged(kName, kRemoteSsrc);
301 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
302}
303
304TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsNoCNameForUnknownSsrc) {
305 const char* kName = "cName";
306 statistics_proxy_->CNameChanged(kName, kRemoteSsrc + 1);
307 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
308}
309
ilnik2edc6842017-07-06 03:06:50 -0700310TEST_F(ReceiveStatisticsProxyTest,
311 GetTimingFrameInfoReportsLongestTimingFrame) {
312 const int64_t kShortEndToEndDelay = 10;
313 const int64_t kMedEndToEndDelay = 20;
314 const int64_t kLongEndToEndDelay = 100;
315 const uint32_t kExpectedRtpTimestamp = 2;
316 TimingFrameInfo info;
317 rtc::Optional<TimingFrameInfo> result;
318 info.rtp_timestamp = kExpectedRtpTimestamp - 1;
319 info.capture_time_ms = 0;
320 info.decode_finish_ms = kShortEndToEndDelay;
321 statistics_proxy_->OnTimingFrameInfoUpdated(info);
322 info.rtp_timestamp =
323 kExpectedRtpTimestamp; // this frame should be reported in the end.
324 info.capture_time_ms = 0;
325 info.decode_finish_ms = kLongEndToEndDelay;
326 statistics_proxy_->OnTimingFrameInfoUpdated(info);
327 info.rtp_timestamp = kExpectedRtpTimestamp + 1;
328 info.capture_time_ms = 0;
329 info.decode_finish_ms = kMedEndToEndDelay;
330 statistics_proxy_->OnTimingFrameInfoUpdated(info);
331 result = statistics_proxy_->GetAndResetTimingFrameInfo();
332 EXPECT_TRUE(result);
333 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
334}
335
336TEST_F(ReceiveStatisticsProxyTest, GetTimingFrameInfoTimingFramesReportedOnce) {
337 const int64_t kShortEndToEndDelay = 10;
338 const uint32_t kExpectedRtpTimestamp = 2;
339 TimingFrameInfo info;
340 rtc::Optional<TimingFrameInfo> result;
341 info.rtp_timestamp = kExpectedRtpTimestamp;
342 info.capture_time_ms = 0;
343 info.decode_finish_ms = kShortEndToEndDelay;
344 statistics_proxy_->OnTimingFrameInfoUpdated(info);
345 result = statistics_proxy_->GetAndResetTimingFrameInfo();
346 EXPECT_TRUE(result);
347 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
348 result = statistics_proxy_->GetAndResetTimingFrameInfo();
349 EXPECT_FALSE(result);
350}
351
asapersson46c4e3c2016-11-03 06:48:19 -0700352TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
353 const int64_t kTimeSec = 3;
354 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
355 // Histograms are updated when the statistics_proxy_ is deleted.
356 statistics_proxy_.reset();
357 EXPECT_EQ(1,
358 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
359 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
360 kTimeSec));
361}
362
palmkvista40672a2017-01-13 05:58:34 -0800363TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
364 // Based on the tuning parameters this will produce 7 uncertain states,
365 // then 10 certainly bad states. There has to be 10 certain states before
366 // any histograms are recorded.
367 const int kNumBadSamples = 17;
368
369 StreamDataCounters counters;
370 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
371 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
372
373 for (int i = 0; i < kNumBadSamples; ++i) {
374 // Since OnRenderedFrame is never called the fps in each sample will be 0,
375 // i.e. bad
376 fake_clock_.AdvanceTimeMilliseconds(1000);
377 statistics_proxy_->OnIncomingRate(0, 0);
378 }
379 // Histograms are updated when the statistics_proxy_ is deleted.
380 statistics_proxy_.reset();
381 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
382 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
383
384 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
385 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
386
387 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
388
389 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
390}
391
asapersson0c43f772016-11-30 01:42:26 -0800392TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
393 const uint32_t kCumLost1 = 1;
394 const uint32_t kExtSeqNum1 = 10;
395 const uint32_t kCumLost2 = 2;
396 const uint32_t kExtSeqNum2 = 20;
397
398 // One report block received.
399 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700400 rtcp_stats1.packets_lost = kCumLost1;
401 rtcp_stats1.extended_highest_sequence_number = kExtSeqNum1;
asapersson0c43f772016-11-30 01:42:26 -0800402 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
403
404 // Two report blocks received.
405 RtcpStatistics rtcp_stats2;
srte186d9c32017-08-04 05:03:53 -0700406 rtcp_stats2.packets_lost = kCumLost2;
407 rtcp_stats2.extended_highest_sequence_number = kExtSeqNum2;
asapersson0c43f772016-11-30 01:42:26 -0800408 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
409
410 // Two received report blocks but min run time has not passed.
411 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
412 SetUp(); // Reset stat proxy causes histograms to be updated.
413 EXPECT_EQ(0,
414 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
415
416 // Two report blocks received.
417 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
418 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
419
420 // Two received report blocks and min run time has passed.
421 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
422 SetUp();
423 EXPECT_EQ(1,
424 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
425 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
426 (kCumLost2 - kCumLost1) * 100 /
427 (kExtSeqNum2 - kExtSeqNum1)));
428}
429
430TEST_F(ReceiveStatisticsProxyTest,
431 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
432 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700433 rtcp_stats1.packets_lost = 1;
434 rtcp_stats1.extended_highest_sequence_number = 10;
asapersson0c43f772016-11-30 01:42:26 -0800435
436 // Min run time has passed but no received report block.
437 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
438 SetUp(); // Reset stat proxy causes histograms to be updated.
439 EXPECT_EQ(0,
440 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
441
442 // Min run time has passed but only one received report block.
443 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
444 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
445 SetUp();
446 EXPECT_EQ(0,
447 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
448}
449
asapersson2077f2f2017-05-11 05:37:35 -0700450TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) {
451 const int64_t kSyncOffsetMs = 22;
452 const double kFreqKhz = 90.0;
453 EXPECT_EQ(std::numeric_limits<int>::max(),
454 statistics_proxy_->GetStats().sync_offset_ms);
455 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
456 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms);
457}
458
asapersson46c4e3c2016-11-03 06:48:19 -0700459TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
460 const int64_t kSyncOffsetMs = 22;
461 const double kFreqKhz = 90.0;
462 for (int i = 0; i < kMinRequiredSamples; ++i)
463 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
464 // Histograms are updated when the statistics_proxy_ is deleted.
465 statistics_proxy_.reset();
466 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
467 EXPECT_EQ(1,
468 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
469}
470
asaperssonde9e5ff2016-11-02 07:14:03 -0700471TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
472 const int64_t kSyncOffsetMs = 22;
473 const double kFreqKhz = 90.0;
474 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
475 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
476 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
477 // Process interval passed, max diff: 2.
478 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
479 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
480 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
481 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
482 // Process interval passed, max diff: 4.
483 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
484 statistics_proxy_.reset();
485 // Average reported: (2 + 4) / 2 = 3.
486 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
487 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
488}
489
asapersson6966bd52017-01-03 00:44:06 -0800490TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
491 const int kQp = 22;
492 EncodedImage encoded_image;
493 encoded_image.qp_ = kQp;
494 CodecSpecificInfo codec_info;
495 codec_info.codecType = kVideoCodecVP8;
496
497 for (int i = 0; i < kMinRequiredSamples; ++i)
498 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
499
500 statistics_proxy_.reset();
501 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
502 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
503}
504
505TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
506 EncodedImage encoded_image;
507 encoded_image.qp_ = 22;
508 CodecSpecificInfo codec_info;
509 codec_info.codecType = kVideoCodecVP8;
510
511 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
512 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
513
514 statistics_proxy_.reset();
515 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
516}
517
518TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
519 EncodedImage encoded_image;
520 CodecSpecificInfo codec_info;
521 codec_info.codecType = kVideoCodecVP8;
522
523 for (int i = 0; i < kMinRequiredSamples; ++i)
524 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
525
526 statistics_proxy_.reset();
527 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
528}
529
asaperssonb99baf82017-04-20 04:05:43 -0700530TEST_F(ReceiveStatisticsProxyTest,
531 KeyFrameHistogramNotUpdatedForTooFewSamples) {
532 const bool kIsKeyFrame = false;
533 const int kFrameSizeBytes = 1000;
534
535 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
536 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes);
537
538 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
539 EXPECT_EQ(kMinRequiredSamples - 1,
540 statistics_proxy_->GetStats().frame_counts.delta_frames);
541
542 statistics_proxy_.reset();
543 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
544}
545
546TEST_F(ReceiveStatisticsProxyTest,
547 KeyFrameHistogramUpdatedForMinRequiredSamples) {
548 const bool kIsKeyFrame = false;
549 const int kFrameSizeBytes = 1000;
550
551 for (int i = 0; i < kMinRequiredSamples; ++i)
552 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes);
553
554 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
555 EXPECT_EQ(kMinRequiredSamples,
556 statistics_proxy_->GetStats().frame_counts.delta_frames);
557
558 statistics_proxy_.reset();
559 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
560 EXPECT_EQ(1,
561 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
562}
563
564TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
565 const int kFrameSizeBytes = 1000;
566
567 for (int i = 0; i < kMinRequiredSamples; ++i)
568 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes);
569
570 for (int i = 0; i < kMinRequiredSamples; ++i)
571 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes);
572
573 EXPECT_EQ(kMinRequiredSamples,
574 statistics_proxy_->GetStats().frame_counts.key_frames);
575 EXPECT_EQ(kMinRequiredSamples,
576 statistics_proxy_->GetStats().frame_counts.delta_frames);
577
578 statistics_proxy_.reset();
579 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
580 EXPECT_EQ(
581 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
582}
583
584TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
585 const int kDecodeMs = 1;
586 const int kMaxDecodeMs = 2;
587 const int kCurrentDelayMs = 3;
588 const int kTargetDelayMs = 4;
589 const int kJitterBufferMs = 5;
590 const int kMinPlayoutDelayMs = 6;
591 const int kRenderDelayMs = 7;
592
593 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
594 statistics_proxy_->OnFrameBufferTimingsUpdated(
595 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
596 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
597 }
598
599 statistics_proxy_.reset();
600 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
601 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
602 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
603 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
604 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
605}
606
607TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
608 const int kDecodeMs = 1;
609 const int kMaxDecodeMs = 2;
610 const int kCurrentDelayMs = 3;
611 const int kTargetDelayMs = 4;
612 const int kJitterBufferMs = 5;
613 const int kMinPlayoutDelayMs = 6;
614 const int kRenderDelayMs = 7;
615
616 for (int i = 0; i < kMinRequiredSamples; ++i) {
617 statistics_proxy_->OnFrameBufferTimingsUpdated(
618 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
619 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
620 }
621
622 statistics_proxy_.reset();
623 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
624 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
625 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
626 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
627 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
628
629 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
630 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
631 kJitterBufferMs));
632 EXPECT_EQ(1,
633 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
634 EXPECT_EQ(
635 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
636 EXPECT_EQ(1,
637 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
638}
639
sprang948b2752017-05-04 02:47:13 -0700640TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
641 const int kDefaultFps = 30;
642 const int kWidth = 320;
643 const int kHeight = 240;
644
645 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer(
646 I420Buffer::Create(kWidth, kHeight));
647 VideoFrame frame(video_frame_buffer, kVideoRotation_0, 0);
648
649 for (int i = 0; i < kDefaultFps; ++i) {
650 // Since OnRenderedFrame is never called the fps in each sample will be 0,
651 // i.e. bad
652 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
653 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
654 VideoContentType::UNSPECIFIED);
655 statistics_proxy_->OnRenderedFrame(frame);
656 fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
657 }
658
659 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
660 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
661
662 // FPS trackers in stats proxy have a 1000ms sliding window.
663 fake_clock_.AdvanceTimeMilliseconds(1000);
664 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
665 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
666}
667
asapersson2077f2f2017-05-11 05:37:35 -0700668TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) {
669 const int kWidth = 160;
670 const int kHeight = 120;
671 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
672 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
673 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
674
675 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
676
677 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
678 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
679 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
680}
681
682TEST_F(ReceiveStatisticsProxyTest,
683 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
684 const int kWidth = 160;
685 const int kHeight = 120;
686
687 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
688 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
689
690 statistics_proxy_.reset();
691 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
692 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
693 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
694 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
695}
696
697TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
698 const int kWidth = 160;
699 const int kHeight = 120;
700
701 for (int i = 0; i < kMinRequiredSamples; ++i)
702 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
703
704 statistics_proxy_.reset();
705 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
706 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
707 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
708 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
709 EXPECT_EQ(1,
710 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
711 EXPECT_EQ(1,
712 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
713}
714
715TEST_F(ReceiveStatisticsProxyTest,
716 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
717 InsertFirstRtpPacket(kRemoteSsrc);
718 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
719 1);
720
721 RtcpPacketTypeCounter counter;
722 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
723
724 statistics_proxy_.reset();
725 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
726 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
727 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
728}
729
730TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
731 InsertFirstRtpPacket(kRemoteSsrc);
732 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
733
734 const uint32_t kFirPackets = 100;
735 const uint32_t kPliPackets = 200;
736 const uint32_t kNackPackets = 300;
737
738 RtcpPacketTypeCounter counter;
739 counter.fir_packets = kFirPackets;
740 counter.pli_packets = kPliPackets;
741 counter.nack_packets = kNackPackets;
742 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
743
744 statistics_proxy_.reset();
745 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
746 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
747 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
748 EXPECT_EQ(
749 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
750 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
751 EXPECT_EQ(
752 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
753 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
754 EXPECT_EQ(
755 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
756 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
757}
758
sprang892dab52017-08-15 05:00:33 -0700759INSTANTIATE_TEST_CASE_P(ContentTypes,
760 ReceiveStatisticsProxyTest,
761 ::testing::Values(VideoContentType::UNSPECIFIED,
762 VideoContentType::SCREENSHARE));
763
764TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysAreReported) {
765 const VideoContentType content_type = GetParam();
766 const int kInterFrameDelayMs = 33;
767 for (int i = 0; i < kMinRequiredSamples; ++i) {
768 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
769 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
770 }
771 // One extra with with double the interval.
772 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
773 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
774
775 statistics_proxy_.reset();
776 const int kExpectedInterFrame =
777 (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
778 kInterFrameDelayMs * 2) /
779 kMinRequiredSamples;
780 switch (content_type) {
781 case VideoContentType::UNSPECIFIED:
782 EXPECT_EQ(kExpectedInterFrame,
783 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
784 EXPECT_EQ(kInterFrameDelayMs * 2,
785 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
786 break;
787 case VideoContentType::SCREENSHARE:
788 EXPECT_EQ(
789 kExpectedInterFrame,
790 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
791 EXPECT_EQ(kInterFrameDelayMs * 2,
792 metrics::MinSample(
793 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
794 break;
795 default:
796 RTC_NOTREACHED();
797 }
798}
799
800TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithValidAverage) {
801 const VideoContentType content_type = GetParam();
802 const int kInterFrameDelayMs = 33;
803 for (int i = 0; i < kMinRequiredSamples; ++i) {
804 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
805 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
806 }
807
808 // |kMinRequiredSamples| samples, and thereby intervals, is required. That
809 // means we're one frame short of having a valid data set.
810 statistics_proxy_.reset();
811 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
812 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
813 EXPECT_EQ(
814 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
815 EXPECT_EQ(0, metrics::NumSamples(
816 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
817}
818
sprang3e86e7e2017-08-22 09:23:28 -0700819TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithPause) {
820 const VideoContentType content_type = GetParam();
821 const int kInterFrameDelayMs = 33;
822 for (int i = 0; i <= kMinRequiredSamples; ++i) {
823 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
824 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
825 }
826
827 // At this state, we should have a valid inter-frame delay.
828 // Indicate stream paused and make a large jump in time.
829 statistics_proxy_->OnStreamInactive();
830 fake_clock_.AdvanceTimeMilliseconds(5000);
831
832 // Insert two more frames. The interval during the pause should be disregarded
833 // in the stats.
834 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
835 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
836 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
837
838 statistics_proxy_.reset();
839 if (content_type == VideoContentType::SCREENSHARE) {
840 EXPECT_EQ(
841 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
842 EXPECT_EQ(1, metrics::NumSamples(
843 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
844 EXPECT_EQ(
845 kInterFrameDelayMs,
846 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
847 EXPECT_EQ(
848 kInterFrameDelayMs,
849 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
850 } else {
851 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
852 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
853 EXPECT_EQ(kInterFrameDelayMs,
854 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
855 EXPECT_EQ(kInterFrameDelayMs,
856 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
857 }
858}
859
sakale5ba44e2016-10-26 07:09:24 -0700860} // namespace webrtc