blob: 0b8b3a6be153b8ac4eec5d231268c1640a13ef60 [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,
ilnik75204c52017-09-04 03:35:40 -0700312 ReportsLongestTimingFrameInfo) {
ilnik2edc6842017-07-06 03:06:50 -0700313 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);
ilnik75204c52017-09-04 03:35:40 -0700332 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700333 EXPECT_TRUE(result);
334 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
335}
336
ilnik75204c52017-09-04 03:35:40 -0700337TEST_F(ReceiveStatisticsProxyTest, RespectsReportingIntervalForTimingFrames) {
338 TimingFrameInfo info;
ilnik2edc6842017-07-06 03:06:50 -0700339 const int64_t kShortEndToEndDelay = 10;
340 const uint32_t kExpectedRtpTimestamp = 2;
ilnik75204c52017-09-04 03:35:40 -0700341 const int64_t kShortDelayMs = 1000;
342 const int64_t kLongDelayMs = 10000;
ilnik2edc6842017-07-06 03:06:50 -0700343 rtc::Optional<TimingFrameInfo> result;
344 info.rtp_timestamp = kExpectedRtpTimestamp;
345 info.capture_time_ms = 0;
346 info.decode_finish_ms = kShortEndToEndDelay;
347 statistics_proxy_->OnTimingFrameInfoUpdated(info);
ilnik75204c52017-09-04 03:35:40 -0700348 fake_clock_.AdvanceTimeMilliseconds(kShortDelayMs);
349 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700350 EXPECT_TRUE(result);
351 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
ilnik75204c52017-09-04 03:35:40 -0700352 fake_clock_.AdvanceTimeMilliseconds(kLongDelayMs);
353 result = statistics_proxy_->GetStats().timing_frame_info;
ilnik2edc6842017-07-06 03:06:50 -0700354 EXPECT_FALSE(result);
355}
356
asapersson46c4e3c2016-11-03 06:48:19 -0700357TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
358 const int64_t kTimeSec = 3;
359 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
ilnik6d5b4d62017-08-30 03:32:14 -0700360 // Need at least one frame to report stream lifetime.
361 statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
asapersson46c4e3c2016-11-03 06:48:19 -0700362 // Histograms are updated when the statistics_proxy_ is deleted.
363 statistics_proxy_.reset();
364 EXPECT_EQ(1,
365 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
366 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
367 kTimeSec));
368}
369
ilnik6d5b4d62017-08-30 03:32:14 -0700370TEST_F(ReceiveStatisticsProxyTest,
371 LifetimeHistogramNotReportedForEmptyStreams) {
372 const int64_t kTimeSec = 3;
373 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
374 // No frames received.
375 // Histograms are updated when the statistics_proxy_ is deleted.
376 statistics_proxy_.reset();
377 EXPECT_EQ(0,
378 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
379}
380
palmkvista40672a2017-01-13 05:58:34 -0800381TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
382 // Based on the tuning parameters this will produce 7 uncertain states,
383 // then 10 certainly bad states. There has to be 10 certain states before
384 // any histograms are recorded.
385 const int kNumBadSamples = 17;
386
387 StreamDataCounters counters;
388 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
389 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
390
391 for (int i = 0; i < kNumBadSamples; ++i) {
392 // Since OnRenderedFrame is never called the fps in each sample will be 0,
393 // i.e. bad
394 fake_clock_.AdvanceTimeMilliseconds(1000);
395 statistics_proxy_->OnIncomingRate(0, 0);
396 }
397 // Histograms are updated when the statistics_proxy_ is deleted.
398 statistics_proxy_.reset();
399 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
400 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
401
402 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
403 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
404
405 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
406
407 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
408}
409
asapersson0c43f772016-11-30 01:42:26 -0800410TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
411 const uint32_t kCumLost1 = 1;
412 const uint32_t kExtSeqNum1 = 10;
413 const uint32_t kCumLost2 = 2;
414 const uint32_t kExtSeqNum2 = 20;
415
416 // One report block received.
417 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700418 rtcp_stats1.packets_lost = kCumLost1;
419 rtcp_stats1.extended_highest_sequence_number = kExtSeqNum1;
asapersson0c43f772016-11-30 01:42:26 -0800420 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
421
422 // Two report blocks received.
423 RtcpStatistics rtcp_stats2;
srte186d9c32017-08-04 05:03:53 -0700424 rtcp_stats2.packets_lost = kCumLost2;
425 rtcp_stats2.extended_highest_sequence_number = kExtSeqNum2;
asapersson0c43f772016-11-30 01:42:26 -0800426 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
427
428 // Two received report blocks but min run time has not passed.
429 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
430 SetUp(); // Reset stat proxy causes histograms to be updated.
431 EXPECT_EQ(0,
432 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
433
434 // Two report blocks received.
435 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
436 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
437
438 // Two received report blocks and min run time has passed.
439 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
440 SetUp();
441 EXPECT_EQ(1,
442 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
443 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
444 (kCumLost2 - kCumLost1) * 100 /
445 (kExtSeqNum2 - kExtSeqNum1)));
446}
447
448TEST_F(ReceiveStatisticsProxyTest,
449 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
450 RtcpStatistics rtcp_stats1;
srte186d9c32017-08-04 05:03:53 -0700451 rtcp_stats1.packets_lost = 1;
452 rtcp_stats1.extended_highest_sequence_number = 10;
asapersson0c43f772016-11-30 01:42:26 -0800453
454 // Min run time has passed but no received report block.
455 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
456 SetUp(); // Reset stat proxy causes histograms to be updated.
457 EXPECT_EQ(0,
458 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
459
460 // Min run time has passed but only one received report block.
461 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
462 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
463 SetUp();
464 EXPECT_EQ(0,
465 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
466}
467
asapersson2077f2f2017-05-11 05:37:35 -0700468TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) {
469 const int64_t kSyncOffsetMs = 22;
470 const double kFreqKhz = 90.0;
471 EXPECT_EQ(std::numeric_limits<int>::max(),
472 statistics_proxy_->GetStats().sync_offset_ms);
473 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
474 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms);
475}
476
asapersson46c4e3c2016-11-03 06:48:19 -0700477TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
478 const int64_t kSyncOffsetMs = 22;
479 const double kFreqKhz = 90.0;
480 for (int i = 0; i < kMinRequiredSamples; ++i)
481 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
482 // Histograms are updated when the statistics_proxy_ is deleted.
483 statistics_proxy_.reset();
484 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
485 EXPECT_EQ(1,
486 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
487}
488
asaperssonde9e5ff2016-11-02 07:14:03 -0700489TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
490 const int64_t kSyncOffsetMs = 22;
491 const double kFreqKhz = 90.0;
492 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
493 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
494 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
495 // Process interval passed, max diff: 2.
496 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
497 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
498 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
499 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
500 // Process interval passed, max diff: 4.
501 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
502 statistics_proxy_.reset();
503 // Average reported: (2 + 4) / 2 = 3.
504 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
505 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
506}
507
asapersson6966bd52017-01-03 00:44:06 -0800508TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
509 const int kQp = 22;
510 EncodedImage encoded_image;
511 encoded_image.qp_ = kQp;
512 CodecSpecificInfo codec_info;
513 codec_info.codecType = kVideoCodecVP8;
514
515 for (int i = 0; i < kMinRequiredSamples; ++i)
516 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
517
518 statistics_proxy_.reset();
519 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
520 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
521}
522
523TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
524 EncodedImage encoded_image;
525 encoded_image.qp_ = 22;
526 CodecSpecificInfo codec_info;
527 codec_info.codecType = kVideoCodecVP8;
528
529 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
530 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
531
532 statistics_proxy_.reset();
533 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
534}
535
536TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
537 EncodedImage encoded_image;
538 CodecSpecificInfo codec_info;
539 codec_info.codecType = kVideoCodecVP8;
540
541 for (int i = 0; i < kMinRequiredSamples; ++i)
542 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
543
544 statistics_proxy_.reset();
545 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
546}
547
asaperssonb99baf82017-04-20 04:05:43 -0700548TEST_F(ReceiveStatisticsProxyTest,
549 KeyFrameHistogramNotUpdatedForTooFewSamples) {
550 const bool kIsKeyFrame = false;
551 const int kFrameSizeBytes = 1000;
552
553 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700554 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
555 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700556
557 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
558 EXPECT_EQ(kMinRequiredSamples - 1,
559 statistics_proxy_->GetStats().frame_counts.delta_frames);
560
561 statistics_proxy_.reset();
562 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
563}
564
565TEST_F(ReceiveStatisticsProxyTest,
566 KeyFrameHistogramUpdatedForMinRequiredSamples) {
567 const bool kIsKeyFrame = false;
568 const int kFrameSizeBytes = 1000;
569
570 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700571 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
572 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700573
574 EXPECT_EQ(0, 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(1,
581 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
582}
583
584TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
585 const int kFrameSizeBytes = 1000;
586
587 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700588 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
589 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700590
591 for (int i = 0; i < kMinRequiredSamples; ++i)
ilnik6d5b4d62017-08-30 03:32:14 -0700592 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
593 VideoContentType::UNSPECIFIED);
asaperssonb99baf82017-04-20 04:05:43 -0700594
595 EXPECT_EQ(kMinRequiredSamples,
596 statistics_proxy_->GetStats().frame_counts.key_frames);
597 EXPECT_EQ(kMinRequiredSamples,
598 statistics_proxy_->GetStats().frame_counts.delta_frames);
599
600 statistics_proxy_.reset();
601 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
602 EXPECT_EQ(
603 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
604}
605
606TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
607 const int kDecodeMs = 1;
608 const int kMaxDecodeMs = 2;
609 const int kCurrentDelayMs = 3;
610 const int kTargetDelayMs = 4;
611 const int kJitterBufferMs = 5;
612 const int kMinPlayoutDelayMs = 6;
613 const int kRenderDelayMs = 7;
614
615 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
616 statistics_proxy_->OnFrameBufferTimingsUpdated(
617 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
618 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
619 }
620
621 statistics_proxy_.reset();
622 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
623 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
624 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
625 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
626 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
627}
628
629TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
630 const int kDecodeMs = 1;
631 const int kMaxDecodeMs = 2;
632 const int kCurrentDelayMs = 3;
633 const int kTargetDelayMs = 4;
634 const int kJitterBufferMs = 5;
635 const int kMinPlayoutDelayMs = 6;
636 const int kRenderDelayMs = 7;
637
638 for (int i = 0; i < kMinRequiredSamples; ++i) {
639 statistics_proxy_->OnFrameBufferTimingsUpdated(
640 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
641 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
642 }
643
644 statistics_proxy_.reset();
645 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
646 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
647 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
648 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
649 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
650
651 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
652 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
653 kJitterBufferMs));
654 EXPECT_EQ(1,
655 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
656 EXPECT_EQ(
657 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
658 EXPECT_EQ(1,
659 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
660}
661
sprang948b2752017-05-04 02:47:13 -0700662TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
663 const int kDefaultFps = 30;
664 const int kWidth = 320;
665 const int kHeight = 240;
666
667 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer(
668 I420Buffer::Create(kWidth, kHeight));
669 VideoFrame frame(video_frame_buffer, kVideoRotation_0, 0);
670
671 for (int i = 0; i < kDefaultFps; ++i) {
672 // Since OnRenderedFrame is never called the fps in each sample will be 0,
673 // i.e. bad
674 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
675 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
676 VideoContentType::UNSPECIFIED);
677 statistics_proxy_->OnRenderedFrame(frame);
678 fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
679 }
680
681 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
682 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
683
684 // FPS trackers in stats proxy have a 1000ms sliding window.
685 fake_clock_.AdvanceTimeMilliseconds(1000);
686 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
687 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
688}
689
asapersson2077f2f2017-05-11 05:37:35 -0700690TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) {
691 const int kWidth = 160;
692 const int kHeight = 120;
693 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
694 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
695 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
696
697 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
698
699 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
700 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
701 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
702}
703
704TEST_F(ReceiveStatisticsProxyTest,
705 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
706 const int kWidth = 160;
707 const int kHeight = 120;
708
709 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
710 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
711
712 statistics_proxy_.reset();
713 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
714 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
715 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
716 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
717}
718
719TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
720 const int kWidth = 160;
721 const int kHeight = 120;
722
723 for (int i = 0; i < kMinRequiredSamples; ++i)
724 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
725
726 statistics_proxy_.reset();
727 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
728 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
729 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
730 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
731 EXPECT_EQ(1,
732 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
733 EXPECT_EQ(1,
734 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
735}
736
737TEST_F(ReceiveStatisticsProxyTest,
738 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
739 InsertFirstRtpPacket(kRemoteSsrc);
740 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
741 1);
742
743 RtcpPacketTypeCounter counter;
744 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
745
746 statistics_proxy_.reset();
747 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
748 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
749 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
750}
751
752TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
753 InsertFirstRtpPacket(kRemoteSsrc);
754 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
755
756 const uint32_t kFirPackets = 100;
757 const uint32_t kPliPackets = 200;
758 const uint32_t kNackPackets = 300;
759
760 RtcpPacketTypeCounter counter;
761 counter.fir_packets = kFirPackets;
762 counter.pli_packets = kPliPackets;
763 counter.nack_packets = kNackPackets;
764 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
765
766 statistics_proxy_.reset();
767 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
768 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
769 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
770 EXPECT_EQ(
771 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
772 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
773 EXPECT_EQ(
774 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
775 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
776 EXPECT_EQ(
777 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
778 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
779}
780
sprang892dab52017-08-15 05:00:33 -0700781INSTANTIATE_TEST_CASE_P(ContentTypes,
782 ReceiveStatisticsProxyTest,
783 ::testing::Values(VideoContentType::UNSPECIFIED,
784 VideoContentType::SCREENSHARE));
785
786TEST_P(ReceiveStatisticsProxyTest, InterFrameDelaysAreReported) {
787 const VideoContentType content_type = GetParam();
788 const int kInterFrameDelayMs = 33;
789 for (int i = 0; i < kMinRequiredSamples; ++i) {
790 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
791 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
792 }
793 // One extra with with double the interval.
794 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
795 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
796
797 statistics_proxy_.reset();
798 const int kExpectedInterFrame =
799 (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
800 kInterFrameDelayMs * 2) /
801 kMinRequiredSamples;
ilnik6d5b4d62017-08-30 03:32:14 -0700802 if (videocontenttypehelpers::IsScreenshare(content_type)) {
803 EXPECT_EQ(
804 kExpectedInterFrame,
805 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
806 EXPECT_EQ(
807 kInterFrameDelayMs * 2,
808 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
809 } else {
810 EXPECT_EQ(kExpectedInterFrame,
811 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
812 EXPECT_EQ(kInterFrameDelayMs * 2,
813 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
sprang892dab52017-08-15 05:00:33 -0700814 }
815}
816
817TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithValidAverage) {
818 const VideoContentType content_type = GetParam();
819 const int kInterFrameDelayMs = 33;
820 for (int i = 0; i < kMinRequiredSamples; ++i) {
821 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
822 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
823 }
824
825 // |kMinRequiredSamples| samples, and thereby intervals, is required. That
826 // means we're one frame short of having a valid data set.
827 statistics_proxy_.reset();
828 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
829 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
830 EXPECT_EQ(
831 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
832 EXPECT_EQ(0, metrics::NumSamples(
833 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
834}
835
sprang3e86e7e2017-08-22 09:23:28 -0700836TEST_P(ReceiveStatisticsProxyTest, MaxInterFrameDelayOnlyWithPause) {
837 const VideoContentType content_type = GetParam();
838 const int kInterFrameDelayMs = 33;
839 for (int i = 0; i <= kMinRequiredSamples; ++i) {
840 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
841 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
842 }
843
844 // At this state, we should have a valid inter-frame delay.
845 // Indicate stream paused and make a large jump in time.
846 statistics_proxy_->OnStreamInactive();
847 fake_clock_.AdvanceTimeMilliseconds(5000);
848
849 // Insert two more frames. The interval during the pause should be disregarded
850 // in the stats.
851 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
852 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
853 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
854
855 statistics_proxy_.reset();
ilnik6d5b4d62017-08-30 03:32:14 -0700856 if (videocontenttypehelpers::IsScreenshare(content_type)) {
sprang3e86e7e2017-08-22 09:23:28 -0700857 EXPECT_EQ(
858 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
859 EXPECT_EQ(1, metrics::NumSamples(
860 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
861 EXPECT_EQ(
862 kInterFrameDelayMs,
863 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
864 EXPECT_EQ(
865 kInterFrameDelayMs,
866 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
867 } else {
868 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
869 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
870 EXPECT_EQ(kInterFrameDelayMs,
871 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
872 EXPECT_EQ(kInterFrameDelayMs,
873 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
874 }
875}
876
ilnik6d5b4d62017-08-30 03:32:14 -0700877TEST_P(ReceiveStatisticsProxyTest, StatsAreSlicedOnSimulcastAndExperiment) {
878 VideoContentType content_type = GetParam();
879 const uint8_t experiment_id = 1;
880 videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
881 const int kInterFrameDelayMs1 = 30;
882 const int kInterFrameDelayMs2 = 50;
883
884 videocontenttypehelpers::SetSimulcastId(&content_type, 1);
885 for (int i = 0; i <= kMinRequiredSamples; ++i) {
886 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs1);
887 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
888 }
889
890 videocontenttypehelpers::SetSimulcastId(&content_type, 2);
891 for (int i = 0; i <= kMinRequiredSamples; ++i) {
892 fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
893 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), content_type);
894 }
895 statistics_proxy_.reset();
896
897 if (videocontenttypehelpers::IsScreenshare(content_type)) {
898 EXPECT_EQ(
899 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
900 EXPECT_EQ(1, metrics::NumSamples(
901 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
902 EXPECT_EQ(1, metrics::NumSamples(
903 "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
904 EXPECT_EQ(1, metrics::NumSamples(
905 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
906 EXPECT_EQ(1, metrics::NumSamples(
907 "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
908 EXPECT_EQ(1, metrics::NumSamples(
909 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
910 EXPECT_EQ(1,
911 metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
912 ".ExperimentGroup0"));
913 EXPECT_EQ(
914 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
915 ".ExperimentGroup0"));
916 EXPECT_EQ(
917 kInterFrameDelayMs1,
918 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
919 EXPECT_EQ(
920 kInterFrameDelayMs2,
921 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
922 EXPECT_EQ(
923 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
924 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
925 EXPECT_EQ(
926 kInterFrameDelayMs2,
927 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
928 EXPECT_EQ(
929 (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
930 metrics::MinSample(
931 "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
932 } else {
933 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
934 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
935 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
936 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
937 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
938 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
939 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
940 ".ExperimentGroup0"));
941 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
942 ".ExperimentGroup0"));
943 EXPECT_EQ(kInterFrameDelayMs1,
944 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
945 EXPECT_EQ(kInterFrameDelayMs2,
946 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
947 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
948 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
949 EXPECT_EQ(kInterFrameDelayMs2,
950 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
951 EXPECT_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
952 metrics::MinSample(
953 "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
954 }
955}
956
sakale5ba44e2016-10-26 07:09:24 -0700957} // namespace webrtc