blob: 427f3856a039301691c9748b192b7c8351de86a0 [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
13#include <memory>
14
nissef93752a2017-05-10 05:25:59 -070015#include "webrtc/api/video/i420_buffer.h"
hbos50cfe1f2017-01-23 07:21:55 -080016#include "webrtc/api/video/video_frame.h"
17#include "webrtc/api/video/video_rotation.h"
asapersson6966bd52017-01-03 00:44:06 -080018#include "webrtc/modules/video_coding/include/video_codec_interface.h"
asapersson0c43f772016-11-30 01:42:26 -080019#include "webrtc/system_wrappers/include/metrics.h"
asaperssonde9e5ff2016-11-02 07:14:03 -070020#include "webrtc/system_wrappers/include/metrics_default.h"
sakale5ba44e2016-10-26 07:09:24 -070021#include "webrtc/test/gtest.h"
22
23namespace webrtc {
asaperssonde9e5ff2016-11-02 07:14:03 -070024namespace {
25const int64_t kFreqOffsetProcessIntervalInMs = 40000;
asapersson46c4e3c2016-11-03 06:48:19 -070026const uint32_t kLocalSsrc = 123;
27const uint32_t kRemoteSsrc = 456;
28const int kMinRequiredSamples = 200;
asaperssonde9e5ff2016-11-02 07:14:03 -070029} // namespace
sakale5ba44e2016-10-26 07:09:24 -070030
31// TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
32class ReceiveStatisticsProxyTest : public ::testing::Test {
33 public:
34 ReceiveStatisticsProxyTest() : fake_clock_(1234), config_(GetTestConfig()) {}
35 virtual ~ReceiveStatisticsProxyTest() {}
36
37 protected:
38 virtual void SetUp() {
asaperssonde9e5ff2016-11-02 07:14:03 -070039 metrics::Reset();
sakale5ba44e2016-10-26 07:09:24 -070040 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_));
41 }
42
43 VideoReceiveStream::Config GetTestConfig() {
44 VideoReceiveStream::Config config(nullptr);
asapersson46c4e3c2016-11-03 06:48:19 -070045 config.rtp.local_ssrc = kLocalSsrc;
46 config.rtp.remote_ssrc = kRemoteSsrc;
sakale5ba44e2016-10-26 07:09:24 -070047 return config;
48 }
49
50 SimulatedClock fake_clock_;
asaperssonde9e5ff2016-11-02 07:14:03 -070051 const VideoReceiveStream::Config config_;
sakale5ba44e2016-10-26 07:09:24 -070052 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
sakale5ba44e2016-10-26 07:09:24 -070053};
54
55TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) {
56 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
57 for (uint32_t i = 1; i <= 3; ++i) {
ilnik00d802b2017-04-11 10:34:31 -070058 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
59 VideoContentType::UNSPECIFIED);
sakale5ba44e2016-10-26 07:09:24 -070060 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
61 }
62}
63
sakalcc452e12017-02-09 04:53:45 -080064TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithQpResetsFramesDecoded) {
65 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
66 for (uint32_t i = 1; i <= 3; ++i) {
ilnik00d802b2017-04-11 10:34:31 -070067 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
68 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080069 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded);
70 }
ilnik00d802b2017-04-11 10:34:31 -070071 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(1u),
72 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080073 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_decoded);
74}
75
76TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) {
77 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070078 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
79 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080080 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070081 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(127u),
82 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080083 EXPECT_EQ(rtc::Optional<uint64_t>(130u),
84 statistics_proxy_->GetStats().qp_sum);
85}
86
87TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) {
88 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070089 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
90 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080091 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
92}
93
94TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) {
95 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070096 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(3u),
97 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -080098 EXPECT_EQ(rtc::Optional<uint64_t>(3u), statistics_proxy_->GetStats().qp_sum);
ilnik00d802b2017-04-11 10:34:31 -070099 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
100 VideoContentType::UNSPECIFIED);
sakalcc452e12017-02-09 04:53:45 -0800101 EXPECT_EQ(rtc::Optional<uint64_t>(), statistics_proxy_->GetStats().qp_sum);
102}
103
hbos50cfe1f2017-01-23 07:21:55 -0800104TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) {
105 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
ilnik00d802b2017-04-11 10:34:31 -0700106 webrtc::VideoFrame frame(webrtc::I420Buffer::Create(1, 1), 0, 0,
107 webrtc::kVideoRotation_0);
hbos50cfe1f2017-01-23 07:21:55 -0800108 for (uint32_t i = 1; i <= 3; ++i) {
109 statistics_proxy_->OnRenderedFrame(frame);
110 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
111 }
112}
113
asapersson46c4e3c2016-11-03 06:48:19 -0700114TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsSsrc) {
115 EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
116}
117
118TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsIncomingPayloadType) {
119 const int kPayloadType = 111;
120 statistics_proxy_->OnIncomingPayloadType(kPayloadType);
121 EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
122}
123
asapersson6966bd52017-01-03 00:44:06 -0800124TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecoderImplementationName) {
125 const char* kName = "decoderName";
126 statistics_proxy_->OnDecoderImplementationName(kName);
127 EXPECT_STREQ(
128 kName, statistics_proxy_->GetStats().decoder_implementation_name.c_str());
129}
130
philipela45102f2017-02-22 05:30:39 -0800131TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsOnCompleteFrame) {
132 const int kFrameSizeBytes = 1000;
133 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes);
134 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
135 EXPECT_EQ(1, stats.network_frame_rate);
philipela45102f2017-02-22 05:30:39 -0800136 EXPECT_EQ(1, stats.frame_counts.key_frames);
137 EXPECT_EQ(0, stats.frame_counts.delta_frames);
asapersson46c4e3c2016-11-03 06:48:19 -0700138}
139
140TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecodeTimingStats) {
141 const int kDecodeMs = 1;
142 const int kMaxDecodeMs = 2;
143 const int kCurrentDelayMs = 3;
144 const int kTargetDelayMs = 4;
145 const int kJitterBufferMs = 5;
146 const int kMinPlayoutDelayMs = 6;
147 const int kRenderDelayMs = 7;
148 const int64_t kRttMs = 8;
philipela45102f2017-02-22 05:30:39 -0800149 statistics_proxy_->OnRttUpdate(kRttMs, 0);
150 statistics_proxy_->OnFrameBufferTimingsUpdated(
asapersson46c4e3c2016-11-03 06:48:19 -0700151 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
philipela45102f2017-02-22 05:30:39 -0800152 kMinPlayoutDelayMs, kRenderDelayMs);
asapersson46c4e3c2016-11-03 06:48:19 -0700153 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
154 EXPECT_EQ(kDecodeMs, stats.decode_ms);
155 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
156 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
157 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
158 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
159 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
160 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
161}
162
asapersson6966bd52017-01-03 00:44:06 -0800163TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpPacketTypeCounts) {
164 const uint32_t kFirPackets = 33;
165 const uint32_t kPliPackets = 44;
166 const uint32_t kNackPackets = 55;
167 RtcpPacketTypeCounter counter;
168 counter.fir_packets = kFirPackets;
169 counter.pli_packets = kPliPackets;
170 counter.nack_packets = kNackPackets;
171 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
172 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
173 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
174 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
175 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
176}
177
178TEST_F(ReceiveStatisticsProxyTest,
179 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
180 RtcpPacketTypeCounter counter;
181 counter.fir_packets = 33;
182 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
183 EXPECT_EQ(0u,
184 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
185}
186
187TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsFrameCounts) {
188 const int kKeyFrames = 3;
189 const int kDeltaFrames = 22;
190 FrameCounts frame_counts;
191 frame_counts.key_frames = kKeyFrames;
192 frame_counts.delta_frames = kDeltaFrames;
193 statistics_proxy_->OnFrameCountsUpdated(frame_counts);
194 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
195 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
196 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
197}
198
asapersson46c4e3c2016-11-03 06:48:19 -0700199TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDiscardedPackets) {
200 const int kDiscardedPackets = 12;
201 statistics_proxy_->OnDiscardedPacketsUpdated(kDiscardedPackets);
202 EXPECT_EQ(kDiscardedPackets, statistics_proxy_->GetStats().discarded_packets);
203}
204
asapersson6966bd52017-01-03 00:44:06 -0800205TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsRtcpStats) {
206 const uint8_t kFracLost = 0;
207 const uint32_t kCumLost = 1;
208 const uint32_t kExtSeqNum = 10;
209 const uint32_t kJitter = 4;
210
211 RtcpStatistics rtcp_stats;
212 rtcp_stats.fraction_lost = kFracLost;
213 rtcp_stats.cumulative_lost = kCumLost;
214 rtcp_stats.extended_max_sequence_number = kExtSeqNum;
215 rtcp_stats.jitter = kJitter;
216 statistics_proxy_->StatisticsUpdated(rtcp_stats, kRemoteSsrc);
217
218 VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
219 EXPECT_EQ(kFracLost, stats.rtcp_stats.fraction_lost);
220 EXPECT_EQ(kCumLost, stats.rtcp_stats.cumulative_lost);
221 EXPECT_EQ(kExtSeqNum, stats.rtcp_stats.extended_max_sequence_number);
222 EXPECT_EQ(kJitter, stats.rtcp_stats.jitter);
223}
224
225TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsCName) {
226 const char* kName = "cName";
227 statistics_proxy_->CNameChanged(kName, kRemoteSsrc);
228 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
229}
230
231TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsNoCNameForUnknownSsrc) {
232 const char* kName = "cName";
233 statistics_proxy_->CNameChanged(kName, kRemoteSsrc + 1);
234 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
235}
236
asapersson46c4e3c2016-11-03 06:48:19 -0700237TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
238 const int64_t kTimeSec = 3;
239 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
240 // Histograms are updated when the statistics_proxy_ is deleted.
241 statistics_proxy_.reset();
242 EXPECT_EQ(1,
243 metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
244 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
245 kTimeSec));
246}
247
palmkvista40672a2017-01-13 05:58:34 -0800248TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
249 // Based on the tuning parameters this will produce 7 uncertain states,
250 // then 10 certainly bad states. There has to be 10 certain states before
251 // any histograms are recorded.
252 const int kNumBadSamples = 17;
253
254 StreamDataCounters counters;
255 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
256 statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
257
258 for (int i = 0; i < kNumBadSamples; ++i) {
259 // Since OnRenderedFrame is never called the fps in each sample will be 0,
260 // i.e. bad
261 fake_clock_.AdvanceTimeMilliseconds(1000);
262 statistics_proxy_->OnIncomingRate(0, 0);
263 }
264 // Histograms are updated when the statistics_proxy_ is deleted.
265 statistics_proxy_.reset();
266 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
267 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
268
269 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
270 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
271
272 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
273
274 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
275}
276
asapersson0c43f772016-11-30 01:42:26 -0800277TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
278 const uint32_t kCumLost1 = 1;
279 const uint32_t kExtSeqNum1 = 10;
280 const uint32_t kCumLost2 = 2;
281 const uint32_t kExtSeqNum2 = 20;
282
283 // One report block received.
284 RtcpStatistics rtcp_stats1;
285 rtcp_stats1.cumulative_lost = kCumLost1;
286 rtcp_stats1.extended_max_sequence_number = kExtSeqNum1;
287 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
288
289 // Two report blocks received.
290 RtcpStatistics rtcp_stats2;
291 rtcp_stats2.cumulative_lost = kCumLost2;
292 rtcp_stats2.extended_max_sequence_number = kExtSeqNum2;
293 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
294
295 // Two received report blocks but min run time has not passed.
296 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
297 SetUp(); // Reset stat proxy causes histograms to be updated.
298 EXPECT_EQ(0,
299 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
300
301 // Two report blocks received.
302 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
303 statistics_proxy_->StatisticsUpdated(rtcp_stats2, kRemoteSsrc);
304
305 // Two received report blocks and min run time has passed.
306 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
307 SetUp();
308 EXPECT_EQ(1,
309 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
310 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent",
311 (kCumLost2 - kCumLost1) * 100 /
312 (kExtSeqNum2 - kExtSeqNum1)));
313}
314
315TEST_F(ReceiveStatisticsProxyTest,
316 PacketLossHistogramIsNotUpdatedIfLessThanTwoReportBlocksAreReceived) {
317 RtcpStatistics rtcp_stats1;
318 rtcp_stats1.cumulative_lost = 1;
319 rtcp_stats1.extended_max_sequence_number = 10;
320
321 // Min run time has passed but no received report block.
322 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
323 SetUp(); // Reset stat proxy causes histograms to be updated.
324 EXPECT_EQ(0,
325 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
326
327 // Min run time has passed but only one received report block.
328 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc);
329 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
330 SetUp();
331 EXPECT_EQ(0,
332 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
333}
334
asapersson46c4e3c2016-11-03 06:48:19 -0700335TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
336 const int64_t kSyncOffsetMs = 22;
337 const double kFreqKhz = 90.0;
338 for (int i = 0; i < kMinRequiredSamples; ++i)
339 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
340 // Histograms are updated when the statistics_proxy_ is deleted.
341 statistics_proxy_.reset();
342 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
343 EXPECT_EQ(1,
344 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
345}
346
asaperssonde9e5ff2016-11-02 07:14:03 -0700347TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
348 const int64_t kSyncOffsetMs = 22;
349 const double kFreqKhz = 90.0;
350 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
351 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 2.2);
352 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
353 // Process interval passed, max diff: 2.
354 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz + 1.1);
355 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 4.2);
356 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz - 0.9);
357 fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
358 // Process interval passed, max diff: 4.
359 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
360 statistics_proxy_.reset();
361 // Average reported: (2 + 4) / 2 = 3.
362 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
363 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
364}
365
asapersson6966bd52017-01-03 00:44:06 -0800366TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
367 const int kQp = 22;
368 EncodedImage encoded_image;
369 encoded_image.qp_ = kQp;
370 CodecSpecificInfo codec_info;
371 codec_info.codecType = kVideoCodecVP8;
372
373 for (int i = 0; i < kMinRequiredSamples; ++i)
374 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
375
376 statistics_proxy_.reset();
377 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
378 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
379}
380
381TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
382 EncodedImage encoded_image;
383 encoded_image.qp_ = 22;
384 CodecSpecificInfo codec_info;
385 codec_info.codecType = kVideoCodecVP8;
386
387 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
388 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
389
390 statistics_proxy_.reset();
391 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
392}
393
394TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
395 EncodedImage encoded_image;
396 CodecSpecificInfo codec_info;
397 codec_info.codecType = kVideoCodecVP8;
398
399 for (int i = 0; i < kMinRequiredSamples; ++i)
400 statistics_proxy_->OnPreDecode(encoded_image, &codec_info);
401
402 statistics_proxy_.reset();
403 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
404}
405
asaperssonb99baf82017-04-20 04:05:43 -0700406TEST_F(ReceiveStatisticsProxyTest,
407 KeyFrameHistogramNotUpdatedForTooFewSamples) {
408 const bool kIsKeyFrame = false;
409 const int kFrameSizeBytes = 1000;
410
411 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
412 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes);
413
414 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
415 EXPECT_EQ(kMinRequiredSamples - 1,
416 statistics_proxy_->GetStats().frame_counts.delta_frames);
417
418 statistics_proxy_.reset();
419 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
420}
421
422TEST_F(ReceiveStatisticsProxyTest,
423 KeyFrameHistogramUpdatedForMinRequiredSamples) {
424 const bool kIsKeyFrame = false;
425 const int kFrameSizeBytes = 1000;
426
427 for (int i = 0; i < kMinRequiredSamples; ++i)
428 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes);
429
430 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
431 EXPECT_EQ(kMinRequiredSamples,
432 statistics_proxy_->GetStats().frame_counts.delta_frames);
433
434 statistics_proxy_.reset();
435 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
436 EXPECT_EQ(1,
437 metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
438}
439
440TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
441 const int kFrameSizeBytes = 1000;
442
443 for (int i = 0; i < kMinRequiredSamples; ++i)
444 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes);
445
446 for (int i = 0; i < kMinRequiredSamples; ++i)
447 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes);
448
449 EXPECT_EQ(kMinRequiredSamples,
450 statistics_proxy_->GetStats().frame_counts.key_frames);
451 EXPECT_EQ(kMinRequiredSamples,
452 statistics_proxy_->GetStats().frame_counts.delta_frames);
453
454 statistics_proxy_.reset();
455 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
456 EXPECT_EQ(
457 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
458}
459
460TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
461 const int kDecodeMs = 1;
462 const int kMaxDecodeMs = 2;
463 const int kCurrentDelayMs = 3;
464 const int kTargetDelayMs = 4;
465 const int kJitterBufferMs = 5;
466 const int kMinPlayoutDelayMs = 6;
467 const int kRenderDelayMs = 7;
468
469 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
470 statistics_proxy_->OnFrameBufferTimingsUpdated(
471 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
472 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
473 }
474
475 statistics_proxy_.reset();
476 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
477 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
478 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
479 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
480 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
481}
482
483TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
484 const int kDecodeMs = 1;
485 const int kMaxDecodeMs = 2;
486 const int kCurrentDelayMs = 3;
487 const int kTargetDelayMs = 4;
488 const int kJitterBufferMs = 5;
489 const int kMinPlayoutDelayMs = 6;
490 const int kRenderDelayMs = 7;
491
492 for (int i = 0; i < kMinRequiredSamples; ++i) {
493 statistics_proxy_->OnFrameBufferTimingsUpdated(
494 kDecodeMs, kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs,
495 kJitterBufferMs, kMinPlayoutDelayMs, kRenderDelayMs);
496 }
497
498 statistics_proxy_.reset();
499 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
500 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
501 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
502 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
503 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
504
505 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
506 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
507 kJitterBufferMs));
508 EXPECT_EQ(1,
509 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
510 EXPECT_EQ(
511 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
512 EXPECT_EQ(1,
513 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
514}
515
sprang948b2752017-05-04 02:47:13 -0700516TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) {
517 const int kDefaultFps = 30;
518 const int kWidth = 320;
519 const int kHeight = 240;
520
521 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer(
522 I420Buffer::Create(kWidth, kHeight));
523 VideoFrame frame(video_frame_buffer, kVideoRotation_0, 0);
524
525 for (int i = 0; i < kDefaultFps; ++i) {
526 // Since OnRenderedFrame is never called the fps in each sample will be 0,
527 // i.e. bad
528 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
529 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(),
530 VideoContentType::UNSPECIFIED);
531 statistics_proxy_->OnRenderedFrame(frame);
532 fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
533 }
534
535 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
536 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
537
538 // FPS trackers in stats proxy have a 1000ms sliding window.
539 fake_clock_.AdvanceTimeMilliseconds(1000);
540 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
541 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
542}
543
sakale5ba44e2016-10-26 07:09:24 -0700544} // namespace webrtc