1 /*
2 * Copyright 2020 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 "video/receive_statistics_proxy2.h"
12
13 #include <limits>
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <utility>
18
19 #include "absl/types/optional.h"
20 #include "api/scoped_refptr.h"
21 #include "api/units/frequency.h"
22 #include "api/units/time_delta.h"
23 #include "api/video/i420_buffer.h"
24 #include "api/video/video_frame.h"
25 #include "api/video/video_frame_buffer.h"
26 #include "api/video/video_rotation.h"
27 #include "rtc_base/thread.h"
28 #include "system_wrappers/include/metrics.h"
29 #include "test/gtest.h"
30 #include "test/scoped_key_value_config.h"
31 #include "test/time_controller/simulated_time_controller.h"
32 #include "video/video_receive_stream2.h"
33
34 namespace webrtc {
35 namespace internal {
36 namespace {
37 const TimeDelta kFreqOffsetProcessInterval = TimeDelta::Seconds(40);
38 const uint32_t kRemoteSsrc = 456;
39 const int kMinRequiredSamples = 200;
40 const int kWidth = 1280;
41 const int kHeight = 720;
42 } // namespace
43
44 // TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
45 class ReceiveStatisticsProxy2Test : public ::testing::Test {
46 public:
ReceiveStatisticsProxy2Test()47 ReceiveStatisticsProxy2Test() : time_controller_(Timestamp::Millis(1234)) {
48 metrics::Reset();
49 statistics_proxy_ = std::make_unique<ReceiveStatisticsProxy>(
50 kRemoteSsrc, time_controller_.GetClock(),
51 time_controller_.GetMainThread());
52 }
53
~ReceiveStatisticsProxy2Test()54 ~ReceiveStatisticsProxy2Test() override { statistics_proxy_.reset(); }
55
56 protected:
57 // Convenience method to avoid too many explict flushes.
FlushAndGetStats()58 VideoReceiveStreamInterface::Stats FlushAndGetStats() {
59 time_controller_.AdvanceTime(TimeDelta::Zero());
60 return statistics_proxy_->GetStats();
61 }
62
FlushAndUpdateHistograms(absl::optional<int> fraction_lost,const StreamDataCounters & rtp_stats,const StreamDataCounters * rtx_stats)63 void FlushAndUpdateHistograms(absl::optional<int> fraction_lost,
64 const StreamDataCounters& rtp_stats,
65 const StreamDataCounters* rtx_stats) {
66 time_controller_.AdvanceTime(TimeDelta::Zero());
67 statistics_proxy_->UpdateHistograms(fraction_lost, rtp_stats, rtx_stats);
68 }
69
CreateFrame(int width,int height)70 VideoFrame CreateFrame(int width, int height) {
71 return CreateVideoFrame(width, height, 0);
72 }
73
CreateFrameWithRenderTime(Timestamp render_time)74 VideoFrame CreateFrameWithRenderTime(Timestamp render_time) {
75 return CreateFrameWithRenderTimeMs(render_time.ms());
76 }
77
CreateFrameWithRenderTimeMs(int64_t render_time_ms)78 VideoFrame CreateFrameWithRenderTimeMs(int64_t render_time_ms) {
79 return CreateVideoFrame(kWidth, kHeight, render_time_ms);
80 }
81
CreateVideoFrame(int width,int height,int64_t render_time_ms)82 VideoFrame CreateVideoFrame(int width, int height, int64_t render_time_ms) {
83 VideoFrame frame =
84 VideoFrame::Builder()
85 .set_video_frame_buffer(I420Buffer::Create(width, height))
86 .set_timestamp_rtp(0)
87 .set_timestamp_ms(render_time_ms)
88 .set_rotation(kVideoRotation_0)
89 .build();
90 frame.set_ntp_time_ms(
91 time_controller_.GetClock()->CurrentNtpInMilliseconds());
92 return frame;
93 }
94
95 // Return the current fake time as a Timestamp.
Now()96 Timestamp Now() { return time_controller_.GetClock()->CurrentTime(); }
97
98 // Creates a VideoFrameMetaData instance with a timestamp.
MetaData(const VideoFrame & frame,Timestamp ts)99 VideoFrameMetaData MetaData(const VideoFrame& frame, Timestamp ts) {
100 return VideoFrameMetaData(frame, ts);
101 }
102
103 // Creates a VideoFrameMetaData instance with the current fake time.
MetaData(const VideoFrame & frame)104 VideoFrameMetaData MetaData(const VideoFrame& frame) {
105 return VideoFrameMetaData(frame, Now());
106 }
107
108 test::ScopedKeyValueConfig field_trials_;
109 GlobalSimulatedTimeController time_controller_;
110 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
111 };
112
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesFramesDecoded)113 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesFramesDecoded) {
114 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
115 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
116 for (uint32_t i = 1; i <= 3; ++i) {
117 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
118 VideoContentType::UNSPECIFIED);
119 EXPECT_EQ(i, FlushAndGetStats().frames_decoded);
120 }
121 }
122
TEST_F(ReceiveStatisticsProxy2Test,DecodedFpsIsReported)123 TEST_F(ReceiveStatisticsProxy2Test, DecodedFpsIsReported) {
124 const Frequency kFps = Frequency::Hertz(20);
125 const int kRequiredSamples =
126 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) * kFps;
127 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
128 for (int i = 0; i < kRequiredSamples; ++i) {
129 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
130 VideoContentType::UNSPECIFIED);
131 time_controller_.AdvanceTime(1 / kFps);
132 }
133 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
134 EXPECT_METRIC_EQ(1,
135 metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
136 EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond",
137 kFps.hertz()));
138 }
139
TEST_F(ReceiveStatisticsProxy2Test,DecodedFpsIsNotReportedForTooFewSamples)140 TEST_F(ReceiveStatisticsProxy2Test, DecodedFpsIsNotReportedForTooFewSamples) {
141 const Frequency kFps = Frequency::Hertz(20);
142 const int kRequiredSamples =
143 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) * kFps;
144 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
145 for (int i = 0; i < kRequiredSamples - 1; ++i) {
146 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
147 VideoContentType::UNSPECIFIED);
148 time_controller_.AdvanceTime(1 / kFps);
149 }
150 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
151 EXPECT_METRIC_EQ(0,
152 metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
153 }
154
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithQpDoesNotResetFramesDecodedOrTotalDecodeTime)155 TEST_F(ReceiveStatisticsProxy2Test,
156 OnDecodedFrameWithQpDoesNotResetFramesDecodedOrTotalDecodeTime) {
157 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
158 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
159 TimeDelta expected_total_decode_time = TimeDelta::Zero();
160 unsigned int expected_frames_decoded = 0;
161 for (uint32_t i = 1; i <= 3; ++i) {
162 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
163 TimeDelta::Millis(1),
164 VideoContentType::UNSPECIFIED);
165 expected_total_decode_time += TimeDelta::Millis(1);
166 ++expected_frames_decoded;
167 time_controller_.AdvanceTime(TimeDelta::Zero());
168 EXPECT_EQ(expected_frames_decoded,
169 statistics_proxy_->GetStats().frames_decoded);
170 EXPECT_EQ(expected_total_decode_time,
171 statistics_proxy_->GetStats().total_decode_time);
172 }
173 statistics_proxy_->OnDecodedFrame(frame, 1u, TimeDelta::Millis(3),
174 VideoContentType::UNSPECIFIED);
175 ++expected_frames_decoded;
176 expected_total_decode_time += TimeDelta::Millis(3);
177 time_controller_.AdvanceTime(TimeDelta::Zero());
178 EXPECT_EQ(expected_frames_decoded,
179 statistics_proxy_->GetStats().frames_decoded);
180 EXPECT_EQ(expected_total_decode_time,
181 statistics_proxy_->GetStats().total_decode_time);
182 }
183
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesProcessingDelay)184 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesProcessingDelay) {
185 const TimeDelta kProcessingDelay = TimeDelta::Millis(10);
186 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
187 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
188 TimeDelta expected_total_processing_delay = TimeDelta::Zero();
189 unsigned int expected_frames_decoded = 0;
190 // We set receive time fixed and increase the clock by 10ms
191 // in the loop which will increase the processing delay by
192 // 10/20/30ms respectively.
193 RtpPacketInfos::vector_type packet_infos = {RtpPacketInfo(
194 /*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{}, /*receive_time=*/Now())};
195 frame.set_packet_infos(RtpPacketInfos(packet_infos));
196 for (int i = 1; i <= 3; ++i) {
197 time_controller_.AdvanceTime(kProcessingDelay);
198 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt,
199 TimeDelta::Millis(1),
200 VideoContentType::UNSPECIFIED);
201 expected_total_processing_delay += i * kProcessingDelay;
202 ++expected_frames_decoded;
203 time_controller_.AdvanceTime(TimeDelta::Zero());
204 EXPECT_EQ(expected_frames_decoded,
205 statistics_proxy_->GetStats().frames_decoded);
206 EXPECT_EQ(expected_total_processing_delay,
207 statistics_proxy_->GetStats().total_processing_delay);
208 }
209 time_controller_.AdvanceTime(kProcessingDelay);
210 statistics_proxy_->OnDecodedFrame(frame, 1u, TimeDelta::Millis(3),
211 VideoContentType::UNSPECIFIED);
212 ++expected_frames_decoded;
213 expected_total_processing_delay += 4 * kProcessingDelay;
214 time_controller_.AdvanceTime(TimeDelta::Zero());
215 EXPECT_EQ(expected_frames_decoded,
216 statistics_proxy_->GetStats().frames_decoded);
217 EXPECT_EQ(expected_total_processing_delay,
218 statistics_proxy_->GetStats().total_processing_delay);
219 }
220
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesAssemblyTime)221 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesAssemblyTime) {
222 const TimeDelta kAssemblyTime = TimeDelta::Millis(7);
223 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
224 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
225 TimeDelta expected_total_assembly_time = TimeDelta::Zero();
226 unsigned int expected_frames_decoded = 0;
227 unsigned int expected_frames_assembled_from_multiple_packets = 0;
228
229 // A single-packet frame will not increase total assembly time
230 // and frames assembled.
231 RtpPacketInfos::vector_type single_packet_frame = {RtpPacketInfo(
232 /*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{}, /*receive_time=*/Now())};
233 frame.set_packet_infos(RtpPacketInfos(single_packet_frame));
234 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Millis(1),
235 VideoContentType::UNSPECIFIED);
236 ++expected_frames_decoded;
237 time_controller_.AdvanceTime(TimeDelta::Zero());
238 EXPECT_EQ(expected_total_assembly_time,
239 statistics_proxy_->GetStats().total_assembly_time);
240 EXPECT_EQ(
241 expected_frames_assembled_from_multiple_packets,
242 statistics_proxy_->GetStats().frames_assembled_from_multiple_packets);
243
244 // In an ordered frame the first and last packet matter.
245 RtpPacketInfos::vector_type ordered_frame = {
246 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
247 /*receive_time=*/Now()),
248 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
249 /*receive_time=*/Now() + kAssemblyTime),
250 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
251 /*receive_time=*/Now() + 2 * kAssemblyTime),
252 };
253 frame.set_packet_infos(RtpPacketInfos(ordered_frame));
254 statistics_proxy_->OnDecodedFrame(frame, 1u, TimeDelta::Millis(3),
255 VideoContentType::UNSPECIFIED);
256 ++expected_frames_decoded;
257 ++expected_frames_assembled_from_multiple_packets;
258 expected_total_assembly_time += 2 * kAssemblyTime;
259 time_controller_.AdvanceTime(TimeDelta::Zero());
260 EXPECT_EQ(expected_frames_decoded,
261 statistics_proxy_->GetStats().frames_decoded);
262 EXPECT_EQ(expected_total_assembly_time,
263 statistics_proxy_->GetStats().total_assembly_time);
264 EXPECT_EQ(
265 expected_frames_assembled_from_multiple_packets,
266 statistics_proxy_->GetStats().frames_assembled_from_multiple_packets);
267
268 // "First" and "last" are in receive time, not sequence number.
269 RtpPacketInfos::vector_type unordered_frame = {
270 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
271 /*receive_time=*/Now() + 2 * kAssemblyTime),
272 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
273 /*receive_time=*/Now()),
274 RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
275 /*receive_time=*/Now() + kAssemblyTime),
276 };
277 frame.set_packet_infos(RtpPacketInfos(unordered_frame));
278 statistics_proxy_->OnDecodedFrame(frame, 1u, TimeDelta::Millis(3),
279 VideoContentType::UNSPECIFIED);
280 ++expected_frames_decoded;
281 ++expected_frames_assembled_from_multiple_packets;
282 expected_total_assembly_time += 2 * kAssemblyTime;
283 time_controller_.AdvanceTime(TimeDelta::Zero());
284 EXPECT_EQ(expected_frames_decoded,
285 statistics_proxy_->GetStats().frames_decoded);
286 EXPECT_EQ(expected_total_assembly_time,
287 statistics_proxy_->GetStats().total_assembly_time);
288 EXPECT_EQ(
289 expected_frames_assembled_from_multiple_packets,
290 statistics_proxy_->GetStats().frames_assembled_from_multiple_packets);
291 }
292
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesQpSum)293 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesQpSum) {
294 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
295 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
296 statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
297 VideoContentType::UNSPECIFIED);
298 EXPECT_EQ(3u, FlushAndGetStats().qp_sum);
299 statistics_proxy_->OnDecodedFrame(frame, 127u, TimeDelta::Zero(),
300 VideoContentType::UNSPECIFIED);
301 EXPECT_EQ(130u, FlushAndGetStats().qp_sum);
302 }
303
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesTotalDecodeTime)304 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesTotalDecodeTime) {
305 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
306 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
307 statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Millis(4),
308 VideoContentType::UNSPECIFIED);
309 EXPECT_EQ(4u, FlushAndGetStats().total_decode_time.ms());
310 statistics_proxy_->OnDecodedFrame(frame, 127u, TimeDelta::Millis(7),
311 VideoContentType::UNSPECIFIED);
312 EXPECT_EQ(11u, FlushAndGetStats().total_decode_time.ms());
313 }
314
TEST_F(ReceiveStatisticsProxy2Test,ReportsContentType)315 TEST_F(ReceiveStatisticsProxy2Test, ReportsContentType) {
316 const std::string kRealtimeString("realtime");
317 const std::string kScreenshareString("screen");
318 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
319 EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
320 statistics_proxy_->GetStats().content_type));
321 statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
322 VideoContentType::SCREENSHARE);
323 EXPECT_EQ(kScreenshareString,
324 videocontenttypehelpers::ToString(FlushAndGetStats().content_type));
325 statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
326 VideoContentType::UNSPECIFIED);
327 EXPECT_EQ(kRealtimeString,
328 videocontenttypehelpers::ToString(FlushAndGetStats().content_type));
329 }
330
TEST_F(ReceiveStatisticsProxy2Test,ReportsMaxTotalInterFrameDelay)331 TEST_F(ReceiveStatisticsProxy2Test, ReportsMaxTotalInterFrameDelay) {
332 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
333 const TimeDelta kInterFrameDelay1 = TimeDelta::Millis(100);
334 const TimeDelta kInterFrameDelay2 = TimeDelta::Millis(200);
335 const TimeDelta kInterFrameDelay3 = TimeDelta::Millis(300);
336 double expected_total_inter_frame_delay = 0;
337 double expected_total_squared_inter_frame_delay = 0;
338 EXPECT_EQ(expected_total_inter_frame_delay,
339 statistics_proxy_->GetStats().total_inter_frame_delay);
340 EXPECT_EQ(expected_total_squared_inter_frame_delay,
341 statistics_proxy_->GetStats().total_squared_inter_frame_delay);
342
343 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
344 VideoContentType::UNSPECIFIED);
345 EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
346 FlushAndGetStats().total_inter_frame_delay);
347 EXPECT_DOUBLE_EQ(expected_total_squared_inter_frame_delay,
348 FlushAndGetStats().total_squared_inter_frame_delay);
349
350 time_controller_.AdvanceTime(kInterFrameDelay1);
351 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
352 VideoContentType::UNSPECIFIED);
353 expected_total_inter_frame_delay += kInterFrameDelay1.seconds<double>();
354 expected_total_squared_inter_frame_delay +=
355 pow(kInterFrameDelay1.seconds<double>(), 2.0);
356 EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
357 FlushAndGetStats().total_inter_frame_delay);
358 EXPECT_DOUBLE_EQ(
359 expected_total_squared_inter_frame_delay,
360 statistics_proxy_->GetStats().total_squared_inter_frame_delay);
361
362 time_controller_.AdvanceTime(kInterFrameDelay2);
363 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
364 VideoContentType::UNSPECIFIED);
365 expected_total_inter_frame_delay += kInterFrameDelay2.seconds<double>();
366 expected_total_squared_inter_frame_delay +=
367 pow(kInterFrameDelay2.seconds<double>(), 2.0);
368 EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
369 FlushAndGetStats().total_inter_frame_delay);
370 EXPECT_DOUBLE_EQ(
371 expected_total_squared_inter_frame_delay,
372 statistics_proxy_->GetStats().total_squared_inter_frame_delay);
373
374 time_controller_.AdvanceTime(kInterFrameDelay3);
375 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
376 VideoContentType::UNSPECIFIED);
377 expected_total_inter_frame_delay += kInterFrameDelay3.seconds<double>();
378 expected_total_squared_inter_frame_delay +=
379 pow(kInterFrameDelay3.seconds<double>(), 2.0);
380 EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
381 FlushAndGetStats().total_inter_frame_delay);
382 EXPECT_DOUBLE_EQ(
383 expected_total_squared_inter_frame_delay,
384 statistics_proxy_->GetStats().total_squared_inter_frame_delay);
385 }
386
TEST_F(ReceiveStatisticsProxy2Test,ReportsMaxInterframeDelay)387 TEST_F(ReceiveStatisticsProxy2Test, ReportsMaxInterframeDelay) {
388 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
389 const TimeDelta kInterframeDelay1 = TimeDelta::Millis(100);
390 const TimeDelta kInterframeDelay2 = TimeDelta::Millis(200);
391 const TimeDelta kInterframeDelay3 = TimeDelta::Millis(100);
392 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
393 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
394 VideoContentType::UNSPECIFIED);
395 EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
396
397 time_controller_.AdvanceTime(kInterframeDelay1);
398 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
399 VideoContentType::UNSPECIFIED);
400 EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
401
402 time_controller_.AdvanceTime(kInterframeDelay2);
403 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
404 VideoContentType::UNSPECIFIED);
405 EXPECT_EQ(kInterframeDelay2.ms(), FlushAndGetStats().interframe_delay_max_ms);
406
407 time_controller_.AdvanceTime(kInterframeDelay3);
408 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
409 VideoContentType::UNSPECIFIED);
410 // kInterframeDelay3 is smaller than kInterframeDelay2.
411 EXPECT_EQ(kInterframeDelay2.ms(), FlushAndGetStats().interframe_delay_max_ms);
412 }
413
TEST_F(ReceiveStatisticsProxy2Test,ReportInterframeDelayInWindow)414 TEST_F(ReceiveStatisticsProxy2Test, ReportInterframeDelayInWindow) {
415 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
416 const TimeDelta kInterframeDelay1 = TimeDelta::Millis(900);
417 const TimeDelta kInterframeDelay2 = TimeDelta::Millis(750);
418 const TimeDelta kInterframeDelay3 = TimeDelta::Millis(700);
419 EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
420 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
421 VideoContentType::UNSPECIFIED);
422 EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
423
424 time_controller_.AdvanceTime(kInterframeDelay1);
425 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
426 VideoContentType::UNSPECIFIED);
427 EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
428
429 time_controller_.AdvanceTime(kInterframeDelay2);
430 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
431 VideoContentType::UNSPECIFIED);
432 // Still first delay is the maximum
433 EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
434
435 time_controller_.AdvanceTime(kInterframeDelay3);
436 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
437 VideoContentType::UNSPECIFIED);
438 // Now the first sample is out of the window, so the second is the maximum.
439 EXPECT_EQ(kInterframeDelay2.ms(), FlushAndGetStats().interframe_delay_max_ms);
440 }
441
TEST_F(ReceiveStatisticsProxy2Test,ReportsFreezeMetrics)442 TEST_F(ReceiveStatisticsProxy2Test, ReportsFreezeMetrics) {
443 const TimeDelta kFreezeDuration = TimeDelta::Seconds(1);
444
445 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
446 EXPECT_EQ(0u, stats.freeze_count);
447 EXPECT_FALSE(stats.total_freezes_duration_ms);
448
449 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
450 for (size_t i = 0; i < VideoQualityObserver::kMinFrameSamplesToDetectFreeze;
451 ++i) {
452 time_controller_.AdvanceTime(TimeDelta::Millis(30));
453 statistics_proxy_->OnRenderedFrame(MetaData(frame));
454 }
455
456 // Freeze.
457 time_controller_.AdvanceTime(kFreezeDuration);
458 statistics_proxy_->OnRenderedFrame(MetaData(frame));
459
460 stats = statistics_proxy_->GetStats();
461 EXPECT_EQ(1u, stats.freeze_count);
462 EXPECT_EQ(kFreezeDuration.ms(), stats.total_freezes_duration_ms);
463 }
464
TEST_F(ReceiveStatisticsProxy2Test,ReportsPauseMetrics)465 TEST_F(ReceiveStatisticsProxy2Test, ReportsPauseMetrics) {
466 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
467 ASSERT_EQ(0u, stats.pause_count);
468 ASSERT_EQ(0u, stats.total_pauses_duration_ms);
469
470 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
471 statistics_proxy_->OnRenderedFrame(MetaData(frame));
472
473 // Pause.
474 time_controller_.AdvanceTime(TimeDelta::Millis(5432));
475 statistics_proxy_->OnStreamInactive();
476 statistics_proxy_->OnRenderedFrame(MetaData(frame));
477
478 stats = statistics_proxy_->GetStats();
479 EXPECT_EQ(1u, stats.pause_count);
480 EXPECT_EQ(5432u, stats.total_pauses_duration_ms);
481 }
482
TEST_F(ReceiveStatisticsProxy2Test,PauseBeforeFirstAndAfterLastFrameIgnored)483 TEST_F(ReceiveStatisticsProxy2Test, PauseBeforeFirstAndAfterLastFrameIgnored) {
484 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
485 ASSERT_EQ(0u, stats.pause_count);
486 ASSERT_EQ(0u, stats.total_pauses_duration_ms);
487
488 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
489
490 // Pause -> Frame -> Pause
491 time_controller_.AdvanceTime(TimeDelta::Seconds(5));
492 statistics_proxy_->OnStreamInactive();
493 statistics_proxy_->OnRenderedFrame(MetaData(frame));
494
495 time_controller_.AdvanceTime(TimeDelta::Millis(30));
496 statistics_proxy_->OnRenderedFrame(MetaData(frame));
497
498 time_controller_.AdvanceTime(TimeDelta::Seconds(5));
499 statistics_proxy_->OnStreamInactive();
500
501 stats = statistics_proxy_->GetStats();
502 EXPECT_EQ(0u, stats.pause_count);
503 EXPECT_EQ(0u, stats.total_pauses_duration_ms);
504 }
505
TEST_F(ReceiveStatisticsProxy2Test,ReportsFramesDuration)506 TEST_F(ReceiveStatisticsProxy2Test, ReportsFramesDuration) {
507 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
508 ASSERT_EQ(0u, stats.total_frames_duration_ms);
509
510 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
511
512 // Emulate delay before first frame is rendered. This is needed to ensure
513 // that frame duration only covers time since first frame is rendered and
514 // not the total time.
515 time_controller_.AdvanceTime(TimeDelta::Millis(5432));
516 for (int i = 0; i <= 10; ++i) {
517 time_controller_.AdvanceTime(TimeDelta::Millis(30));
518 statistics_proxy_->OnRenderedFrame(MetaData(frame));
519 }
520
521 stats = statistics_proxy_->GetStats();
522 EXPECT_EQ(10 * 30u, stats.total_frames_duration_ms);
523 }
524
TEST_F(ReceiveStatisticsProxy2Test,ReportsSumSquaredFrameDurations)525 TEST_F(ReceiveStatisticsProxy2Test, ReportsSumSquaredFrameDurations) {
526 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
527 ASSERT_EQ(0u, stats.sum_squared_frame_durations);
528
529 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
530 for (int i = 0; i <= 10; ++i) {
531 time_controller_.AdvanceTime(TimeDelta::Millis(30));
532 statistics_proxy_->OnRenderedFrame(MetaData(frame));
533 }
534
535 stats = statistics_proxy_->GetStats();
536 const double kExpectedSumSquaredFrameDurationsSecs =
537 10 * (30 / 1000.0 * 30 / 1000.0);
538 EXPECT_EQ(kExpectedSumSquaredFrameDurationsSecs,
539 stats.sum_squared_frame_durations);
540 }
541
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithoutQpQpSumWontExist)542 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameWithoutQpQpSumWontExist) {
543 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
544 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
545 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
546 VideoContentType::UNSPECIFIED);
547 EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
548 }
549
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithoutQpResetsQpSum)550 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameWithoutQpResetsQpSum) {
551 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
552 EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
553 statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
554 VideoContentType::UNSPECIFIED);
555 EXPECT_EQ(3u, FlushAndGetStats().qp_sum);
556 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
557 VideoContentType::UNSPECIFIED);
558 EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
559 }
560
TEST_F(ReceiveStatisticsProxy2Test,OnRenderedFrameIncreasesFramesRendered)561 TEST_F(ReceiveStatisticsProxy2Test, OnRenderedFrameIncreasesFramesRendered) {
562 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
563 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
564 for (uint32_t i = 1; i <= 3; ++i) {
565 statistics_proxy_->OnRenderedFrame(MetaData(frame));
566 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
567 }
568 }
569
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsSsrc)570 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsSsrc) {
571 EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
572 }
573
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsIncomingPayloadType)574 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsIncomingPayloadType) {
575 const int kPayloadType = 111;
576 statistics_proxy_->OnIncomingPayloadType(kPayloadType);
577 time_controller_.AdvanceTime(TimeDelta::Zero());
578 EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
579 }
580
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsDecoderInfo)581 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsDecoderInfo) {
582 auto init_stats = statistics_proxy_->GetStats();
583 EXPECT_EQ(init_stats.decoder_implementation_name, "unknown");
584 EXPECT_EQ(init_stats.power_efficient_decoder, absl::nullopt);
585
586 const VideoDecoder::DecoderInfo decoder_info{
587 .implementation_name = "decoderName", .is_hardware_accelerated = true};
588 statistics_proxy_->OnDecoderInfo(decoder_info);
589 time_controller_.AdvanceTime(TimeDelta::Zero());
590 auto stats = statistics_proxy_->GetStats();
591 EXPECT_EQ(decoder_info.implementation_name,
592 stats.decoder_implementation_name);
593 EXPECT_TRUE(stats.power_efficient_decoder);
594 }
595
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsOnCompleteFrame)596 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsOnCompleteFrame) {
597 const int kFrameSizeBytes = 1000;
598 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
599 VideoContentType::UNSPECIFIED);
600 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
601 EXPECT_EQ(1, stats.network_frame_rate);
602 EXPECT_EQ(1, stats.frame_counts.key_frames);
603 EXPECT_EQ(0, stats.frame_counts.delta_frames);
604 }
605
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsOnDroppedFrame)606 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsOnDroppedFrame) {
607 unsigned int dropped_frames = 0;
608 for (int i = 0; i < 10; ++i) {
609 statistics_proxy_->OnDroppedFrames(i);
610 dropped_frames += i;
611 }
612 VideoReceiveStreamInterface::Stats stats = FlushAndGetStats();
613 EXPECT_EQ(dropped_frames, stats.frames_dropped);
614 }
615
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsDecodeTimingStats)616 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsDecodeTimingStats) {
617 const int kMaxDecodeMs = 2;
618 const int kCurrentDelayMs = 3;
619 const int kTargetDelayMs = 4;
620 const int kJitterBufferMs = 5;
621 const int kMinPlayoutDelayMs = 6;
622 const int kRenderDelayMs = 7;
623 const int64_t kRttMs = 8;
624 statistics_proxy_->OnRttUpdate(kRttMs);
625 statistics_proxy_->OnFrameBufferTimingsUpdated(
626 kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
627 kMinPlayoutDelayMs, kRenderDelayMs);
628 VideoReceiveStreamInterface::Stats stats = FlushAndGetStats();
629 EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
630 EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
631 EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
632 EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
633 EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
634 EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
635 }
636
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsRtcpPacketTypeCounts)637 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsRtcpPacketTypeCounts) {
638 const uint32_t kFirPackets = 33;
639 const uint32_t kPliPackets = 44;
640 const uint32_t kNackPackets = 55;
641 RtcpPacketTypeCounter counter;
642 counter.fir_packets = kFirPackets;
643 counter.pli_packets = kPliPackets;
644 counter.nack_packets = kNackPackets;
645 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
646 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
647 EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
648 EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
649 EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
650 }
651
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc)652 TEST_F(ReceiveStatisticsProxy2Test,
653 GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
654 RtcpPacketTypeCounter counter;
655 counter.fir_packets = 33;
656 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
657 EXPECT_EQ(0u,
658 statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
659 }
660
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsFrameCounts)661 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsFrameCounts) {
662 const int kKeyFrames = 3;
663 const int kDeltaFrames = 22;
664 for (int i = 0; i < kKeyFrames; i++) {
665 statistics_proxy_->OnCompleteFrame(true, 0, VideoContentType::UNSPECIFIED);
666 }
667 for (int i = 0; i < kDeltaFrames; i++) {
668 statistics_proxy_->OnCompleteFrame(false, 0, VideoContentType::UNSPECIFIED);
669 }
670
671 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
672 EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
673 EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
674 }
675
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsCName)676 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsCName) {
677 const char* kName = "cName";
678 statistics_proxy_->OnCname(kRemoteSsrc, kName);
679 EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
680 }
681
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsNoCNameForUnknownSsrc)682 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsNoCNameForUnknownSsrc) {
683 const char* kName = "cName";
684 statistics_proxy_->OnCname(kRemoteSsrc + 1, kName);
685 EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
686 }
687
TEST_F(ReceiveStatisticsProxy2Test,ReportsLongestTimingFrameInfo)688 TEST_F(ReceiveStatisticsProxy2Test, ReportsLongestTimingFrameInfo) {
689 const int64_t kShortEndToEndDelay = 10;
690 const int64_t kMedEndToEndDelay = 20;
691 const int64_t kLongEndToEndDelay = 100;
692 const uint32_t kExpectedRtpTimestamp = 2;
693 TimingFrameInfo info;
694 absl::optional<TimingFrameInfo> result;
695 info.rtp_timestamp = kExpectedRtpTimestamp - 1;
696 info.capture_time_ms = 0;
697 info.decode_finish_ms = kShortEndToEndDelay;
698 statistics_proxy_->OnTimingFrameInfoUpdated(info);
699 info.rtp_timestamp =
700 kExpectedRtpTimestamp; // this frame should be reported in the end.
701 info.capture_time_ms = 0;
702 info.decode_finish_ms = kLongEndToEndDelay;
703 statistics_proxy_->OnTimingFrameInfoUpdated(info);
704 info.rtp_timestamp = kExpectedRtpTimestamp + 1;
705 info.capture_time_ms = 0;
706 info.decode_finish_ms = kMedEndToEndDelay;
707 statistics_proxy_->OnTimingFrameInfoUpdated(info);
708 result = FlushAndGetStats().timing_frame_info;
709 EXPECT_TRUE(result);
710 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
711 }
712
TEST_F(ReceiveStatisticsProxy2Test,RespectsReportingIntervalForTimingFrames)713 TEST_F(ReceiveStatisticsProxy2Test, RespectsReportingIntervalForTimingFrames) {
714 TimingFrameInfo info;
715 const int64_t kShortEndToEndDelay = 10;
716 const uint32_t kExpectedRtpTimestamp = 2;
717 const TimeDelta kShortDelay = TimeDelta::Seconds(1);
718 const TimeDelta kLongDelay = TimeDelta::Seconds(10);
719 absl::optional<TimingFrameInfo> result;
720 info.rtp_timestamp = kExpectedRtpTimestamp;
721 info.capture_time_ms = 0;
722 info.decode_finish_ms = kShortEndToEndDelay;
723 statistics_proxy_->OnTimingFrameInfoUpdated(info);
724 time_controller_.AdvanceTime(kShortDelay);
725 result = FlushAndGetStats().timing_frame_info;
726 EXPECT_TRUE(result);
727 EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
728 time_controller_.AdvanceTime(kLongDelay);
729 result = statistics_proxy_->GetStats().timing_frame_info;
730 EXPECT_FALSE(result);
731 }
732
TEST_F(ReceiveStatisticsProxy2Test,LifetimeHistogramIsUpdated)733 TEST_F(ReceiveStatisticsProxy2Test, LifetimeHistogramIsUpdated) {
734 const TimeDelta kLifetime = TimeDelta::Seconds(3);
735 time_controller_.AdvanceTime(kLifetime);
736 // Need at least one frame to report stream lifetime.
737 statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
738 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
739 nullptr);
740 EXPECT_METRIC_EQ(
741 1, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
742 EXPECT_METRIC_EQ(
743 1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
744 kLifetime.seconds()));
745 }
746
TEST_F(ReceiveStatisticsProxy2Test,LifetimeHistogramNotReportedForEmptyStreams)747 TEST_F(ReceiveStatisticsProxy2Test,
748 LifetimeHistogramNotReportedForEmptyStreams) {
749 const TimeDelta kLifetime = TimeDelta::Seconds(3);
750 time_controller_.AdvanceTime(kLifetime);
751 // No frames received.
752 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
753 nullptr);
754 EXPECT_METRIC_EQ(
755 0, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
756 }
757
TEST_F(ReceiveStatisticsProxy2Test,BadCallHistogramsAreUpdated)758 TEST_F(ReceiveStatisticsProxy2Test, BadCallHistogramsAreUpdated) {
759 // Based on the tuning parameters this will produce 7 uncertain states,
760 // then 10 certainly bad states. There has to be 10 certain states before
761 // any histograms are recorded.
762 const int kNumBadSamples = 17;
763 // We only count one sample per second.
764 const TimeDelta kBadFameInterval = TimeDelta::Millis(1100);
765
766 StreamDataCounters counters;
767 counters.first_packet_time_ms = Now().ms();
768
769 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
770
771 for (int i = 0; i < kNumBadSamples; ++i) {
772 time_controller_.AdvanceTime(kBadFameInterval);
773 statistics_proxy_->OnRenderedFrame(MetaData(frame));
774 }
775 statistics_proxy_->UpdateHistograms(absl::nullopt, counters, nullptr);
776 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
777 EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
778
779 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
780 EXPECT_METRIC_EQ(1,
781 metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
782
783 EXPECT_METRIC_EQ(
784 0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
785
786 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
787 }
788
TEST_F(ReceiveStatisticsProxy2Test,PacketLossHistogramIsUpdated)789 TEST_F(ReceiveStatisticsProxy2Test, PacketLossHistogramIsUpdated) {
790 statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
791 EXPECT_METRIC_EQ(
792 0, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
793
794 // Restart
795 SetUp();
796
797 // Min run time has passed.
798 time_controller_.AdvanceTime(
799 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
800 statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
801 EXPECT_METRIC_EQ(
802 1, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
803 EXPECT_METRIC_EQ(
804 1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent", 10));
805 }
806
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsPlayoutTimestamp)807 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsPlayoutTimestamp) {
808 const int64_t kVideoNtpMs = 21;
809 const int64_t kSyncOffsetMs = 22;
810 const double kFreqKhz = 90.0;
811 EXPECT_EQ(absl::nullopt,
812 statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
813 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
814 EXPECT_EQ(kVideoNtpMs, FlushAndGetStats().estimated_playout_ntp_timestamp_ms);
815 time_controller_.AdvanceTime(TimeDelta::Millis(13));
816 EXPECT_EQ(kVideoNtpMs + 13,
817 statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
818 time_controller_.AdvanceTime(TimeDelta::Millis(5));
819 EXPECT_EQ(kVideoNtpMs + 13 + 5,
820 statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
821 }
822
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsAvSyncOffset)823 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsAvSyncOffset) {
824 const int64_t kVideoNtpMs = 21;
825 const int64_t kSyncOffsetMs = 22;
826 const double kFreqKhz = 90.0;
827 EXPECT_EQ(std::numeric_limits<int>::max(),
828 statistics_proxy_->GetStats().sync_offset_ms);
829 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
830 EXPECT_EQ(kSyncOffsetMs, FlushAndGetStats().sync_offset_ms);
831 }
832
TEST_F(ReceiveStatisticsProxy2Test,AvSyncOffsetHistogramIsUpdated)833 TEST_F(ReceiveStatisticsProxy2Test, AvSyncOffsetHistogramIsUpdated) {
834 const int64_t kVideoNtpMs = 21;
835 const int64_t kSyncOffsetMs = 22;
836 const double kFreqKhz = 90.0;
837 for (int i = 0; i < kMinRequiredSamples; ++i) {
838 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
839 kFreqKhz);
840 }
841 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
842 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
843 EXPECT_METRIC_EQ(
844 1, metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
845 }
846
TEST_F(ReceiveStatisticsProxy2Test,RtpToNtpFrequencyOffsetHistogramIsUpdated)847 TEST_F(ReceiveStatisticsProxy2Test, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
848 const int64_t kVideoNtpMs = 21;
849 const int64_t kSyncOffsetMs = 22;
850 const double kFreqKhz = 90.0;
851 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
852 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
853 kFreqKhz + 2.2);
854 time_controller_.AdvanceTime(kFreqOffsetProcessInterval);
855 //) Process interval passed, max diff: 2.
856 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
857 kFreqKhz + 1.1);
858 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
859 kFreqKhz - 4.2);
860 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
861 kFreqKhz - 0.9);
862 time_controller_.AdvanceTime(kFreqOffsetProcessInterval);
863 //) Process interval passed, max diff: 4.
864 statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
865 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
866 // Average reported: (2 + 4) / 2 = 3.
867 EXPECT_METRIC_EQ(1,
868 metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
869 EXPECT_METRIC_EQ(
870 1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
871 }
872
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsUpdated)873 TEST_F(ReceiveStatisticsProxy2Test, Vp8QpHistogramIsUpdated) {
874 const int kQp = 22;
875
876 for (int i = 0; i < kMinRequiredSamples; ++i)
877 statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
878
879 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
880 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
881 EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
882 }
883
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsNotUpdatedForTooFewSamples)884 TEST_F(ReceiveStatisticsProxy2Test,
885 Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
886 const int kQp = 22;
887
888 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
889 statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
890
891 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
892 nullptr);
893 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
894 }
895
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsNotUpdatedIfNoQpValue)896 TEST_F(ReceiveStatisticsProxy2Test, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
897 for (int i = 0; i < kMinRequiredSamples; ++i)
898 statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
899
900 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
901 nullptr);
902 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
903 }
904
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramNotUpdatedForTooFewSamples)905 TEST_F(ReceiveStatisticsProxy2Test,
906 KeyFrameHistogramNotUpdatedForTooFewSamples) {
907 const bool kIsKeyFrame = false;
908 const int kFrameSizeBytes = 1000;
909
910 for (int i = 0; i < kMinRequiredSamples - 1; ++i)
911 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
912 VideoContentType::UNSPECIFIED);
913
914 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
915 EXPECT_EQ(kMinRequiredSamples - 1,
916 statistics_proxy_->GetStats().frame_counts.delta_frames);
917
918 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
919 nullptr);
920 EXPECT_METRIC_EQ(
921 0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
922 }
923
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramUpdatedForMinRequiredSamples)924 TEST_F(ReceiveStatisticsProxy2Test,
925 KeyFrameHistogramUpdatedForMinRequiredSamples) {
926 const bool kIsKeyFrame = false;
927 const int kFrameSizeBytes = 1000;
928
929 for (int i = 0; i < kMinRequiredSamples; ++i)
930 statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
931 VideoContentType::UNSPECIFIED);
932
933 EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
934 EXPECT_EQ(kMinRequiredSamples,
935 statistics_proxy_->GetStats().frame_counts.delta_frames);
936
937 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
938 nullptr);
939 EXPECT_METRIC_EQ(
940 1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
941 EXPECT_METRIC_EQ(
942 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
943 }
944
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramIsUpdated)945 TEST_F(ReceiveStatisticsProxy2Test, KeyFrameHistogramIsUpdated) {
946 const int kFrameSizeBytes = 1000;
947
948 for (int i = 0; i < kMinRequiredSamples; ++i)
949 statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
950 VideoContentType::UNSPECIFIED);
951
952 for (int i = 0; i < kMinRequiredSamples; ++i)
953 statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
954 VideoContentType::UNSPECIFIED);
955
956 EXPECT_EQ(kMinRequiredSamples,
957 statistics_proxy_->GetStats().frame_counts.key_frames);
958 EXPECT_EQ(kMinRequiredSamples,
959 statistics_proxy_->GetStats().frame_counts.delta_frames);
960
961 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
962 nullptr);
963 EXPECT_METRIC_EQ(
964 1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
965 EXPECT_METRIC_EQ(
966 1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
967 }
968
TEST_F(ReceiveStatisticsProxy2Test,TimingHistogramsNotUpdatedForTooFewSamples)969 TEST_F(ReceiveStatisticsProxy2Test,
970 TimingHistogramsNotUpdatedForTooFewSamples) {
971 const int kMaxDecodeMs = 2;
972 const int kCurrentDelayMs = 3;
973 const int kTargetDelayMs = 4;
974 const int kJitterBufferMs = 5;
975 const int kMinPlayoutDelayMs = 6;
976 const int kRenderDelayMs = 7;
977
978 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
979 statistics_proxy_->OnFrameBufferTimingsUpdated(
980 kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
981 kMinPlayoutDelayMs, kRenderDelayMs);
982 }
983
984 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
985 nullptr);
986 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
987 EXPECT_METRIC_EQ(0,
988 metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
989 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
990 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
991 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
992 }
993
TEST_F(ReceiveStatisticsProxy2Test,TimingHistogramsAreUpdated)994 TEST_F(ReceiveStatisticsProxy2Test, TimingHistogramsAreUpdated) {
995 const int kMaxDecodeMs = 2;
996 const int kCurrentDelayMs = 3;
997 const int kTargetDelayMs = 4;
998 const int kJitterBufferMs = 5;
999 const int kMinPlayoutDelayMs = 6;
1000 const int kRenderDelayMs = 7;
1001
1002 for (int i = 0; i < kMinRequiredSamples; ++i) {
1003 statistics_proxy_->OnFrameBufferTimingsUpdated(
1004 kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
1005 kMinPlayoutDelayMs, kRenderDelayMs);
1006 }
1007
1008 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1009 EXPECT_METRIC_EQ(1,
1010 metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
1011 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
1012 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
1013 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
1014
1015 EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
1016 kJitterBufferMs));
1017 EXPECT_METRIC_EQ(
1018 1, metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
1019 EXPECT_METRIC_EQ(
1020 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
1021 EXPECT_METRIC_EQ(
1022 1, metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
1023 }
1024
TEST_F(ReceiveStatisticsProxy2Test,DoesNotReportStaleFramerates)1025 TEST_F(ReceiveStatisticsProxy2Test, DoesNotReportStaleFramerates) {
1026 const Frequency kDefaultFps = Frequency::Hertz(30);
1027 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1028
1029 for (int i = 0; i < kDefaultFps.hertz(); ++i) {
1030 // Since OnRenderedFrame is never called the fps in each sample will be 0,
1031 // i.e. bad
1032 frame.set_ntp_time_ms(
1033 time_controller_.GetClock()->CurrentNtpInMilliseconds());
1034 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1035 VideoContentType::UNSPECIFIED);
1036 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1037 time_controller_.AdvanceTime(1 / kDefaultFps);
1038 }
1039
1040 // Why -1? Because RateStatistics does not consider the first frame in the
1041 // rate as it will appear in the previous bucket.
1042 EXPECT_EQ(kDefaultFps.hertz() - 1,
1043 statistics_proxy_->GetStats().decode_frame_rate);
1044 EXPECT_EQ(kDefaultFps.hertz() - 1,
1045 statistics_proxy_->GetStats().render_frame_rate);
1046
1047 // FPS trackers in stats proxy have a 1000ms sliding window.
1048 time_controller_.AdvanceTime(TimeDelta::Seconds(1));
1049 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
1050 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
1051 }
1052
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsReceivedFrameStats)1053 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsReceivedFrameStats) {
1054 EXPECT_EQ(0, statistics_proxy_->GetStats().width);
1055 EXPECT_EQ(0, statistics_proxy_->GetStats().height);
1056 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
1057
1058 statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
1059
1060 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
1061 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
1062 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
1063 }
1064
TEST_F(ReceiveStatisticsProxy2Test,ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples)1065 TEST_F(ReceiveStatisticsProxy2Test,
1066 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
1067 for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
1068 statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
1069 }
1070
1071 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1072 nullptr);
1073 EXPECT_METRIC_EQ(0,
1074 metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
1075 EXPECT_METRIC_EQ(0,
1076 metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
1077 EXPECT_METRIC_EQ(0,
1078 metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
1079 EXPECT_METRIC_EQ(
1080 0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
1081 }
1082
TEST_F(ReceiveStatisticsProxy2Test,ReceivedFrameHistogramsAreUpdated)1083 TEST_F(ReceiveStatisticsProxy2Test, ReceivedFrameHistogramsAreUpdated) {
1084 for (int i = 0; i < kMinRequiredSamples; ++i) {
1085 statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
1086 }
1087
1088 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1089 nullptr);
1090 EXPECT_METRIC_EQ(1,
1091 metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
1092 EXPECT_METRIC_EQ(1,
1093 metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
1094 EXPECT_METRIC_EQ(1,
1095 metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
1096 EXPECT_METRIC_EQ(
1097 1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
1098 EXPECT_METRIC_EQ(
1099 1, metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
1100 EXPECT_METRIC_EQ(
1101 1, metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
1102 }
1103
TEST_F(ReceiveStatisticsProxy2Test,ZeroDelayReportedIfFrameNotDelayed)1104 TEST_F(ReceiveStatisticsProxy2Test, ZeroDelayReportedIfFrameNotDelayed) {
1105 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1106 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1107 VideoContentType::UNSPECIFIED);
1108
1109 // Frame not delayed, delayed frames to render: 0%.
1110 statistics_proxy_->OnRenderedFrame(
1111 MetaData(CreateFrameWithRenderTime(Now())));
1112
1113 // Min run time has passed.
1114 time_controller_.AdvanceTime(
1115 TimeDelta::Seconds((metrics::kMinRunTimeInSeconds)));
1116 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1117 EXPECT_METRIC_EQ(1,
1118 metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1119 EXPECT_METRIC_EQ(
1120 1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 0));
1121 EXPECT_METRIC_EQ(0, metrics::NumSamples(
1122 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1123 }
1124
TEST_F(ReceiveStatisticsProxy2Test,DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed)1125 TEST_F(ReceiveStatisticsProxy2Test,
1126 DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed) {
1127 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1128 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1129 VideoContentType::UNSPECIFIED);
1130
1131 // Frame not delayed, delayed frames to render: 0%.
1132 statistics_proxy_->OnRenderedFrame(
1133 MetaData(CreateFrameWithRenderTime(Now())));
1134
1135 // Min run time has not passed.
1136 time_controller_.AdvanceTime(
1137 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) - TimeDelta::Millis(1));
1138 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1139 nullptr);
1140 EXPECT_METRIC_EQ(0,
1141 metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1142 EXPECT_METRIC_EQ(0, metrics::NumSamples(
1143 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1144 }
1145
TEST_F(ReceiveStatisticsProxy2Test,DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames)1146 TEST_F(ReceiveStatisticsProxy2Test,
1147 DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames) {
1148 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1149 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1150 VideoContentType::UNSPECIFIED);
1151
1152 // Min run time has passed. No rendered frames.
1153 time_controller_.AdvanceTime(
1154 TimeDelta::Seconds((metrics::kMinRunTimeInSeconds)));
1155 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1156 nullptr);
1157 EXPECT_METRIC_EQ(0,
1158 metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1159 EXPECT_METRIC_EQ(0, metrics::NumSamples(
1160 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1161 }
1162
TEST_F(ReceiveStatisticsProxy2Test,DelayReportedIfFrameIsDelayed)1163 TEST_F(ReceiveStatisticsProxy2Test, DelayReportedIfFrameIsDelayed) {
1164 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1165 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1166 VideoContentType::UNSPECIFIED);
1167
1168 // Frame delayed 1 ms, delayed frames to render: 100%.
1169 statistics_proxy_->OnRenderedFrame(
1170 MetaData(CreateFrameWithRenderTimeMs(Now().ms() - 1)));
1171
1172 // Min run time has passed.
1173 time_controller_.AdvanceTime(
1174 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
1175 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1176 EXPECT_METRIC_EQ(1,
1177 metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1178 EXPECT_METRIC_EQ(
1179 1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 100));
1180 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1181 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1182 EXPECT_METRIC_EQ(
1183 1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs",
1184 1));
1185 }
1186
TEST_F(ReceiveStatisticsProxy2Test,AverageDelayOfDelayedFramesIsReported)1187 TEST_F(ReceiveStatisticsProxy2Test, AverageDelayOfDelayedFramesIsReported) {
1188 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1189 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1190 VideoContentType::UNSPECIFIED);
1191
1192 // Two frames delayed (6 ms, 10 ms), delayed frames to render: 50%.
1193 const int64_t kNowMs = Now().ms();
1194
1195 statistics_proxy_->OnRenderedFrame(
1196 MetaData(CreateFrameWithRenderTimeMs(kNowMs - 10)));
1197 statistics_proxy_->OnRenderedFrame(
1198 MetaData(CreateFrameWithRenderTimeMs(kNowMs - 6)));
1199 statistics_proxy_->OnRenderedFrame(
1200 MetaData(CreateFrameWithRenderTimeMs(kNowMs)));
1201 statistics_proxy_->OnRenderedFrame(
1202 MetaData(CreateFrameWithRenderTimeMs(kNowMs + 1)));
1203
1204 // Min run time has passed.
1205 time_controller_.AdvanceTime(
1206 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
1207 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1208 EXPECT_METRIC_EQ(1,
1209 metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1210 EXPECT_METRIC_EQ(
1211 1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 50));
1212 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1213 "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1214 EXPECT_METRIC_EQ(
1215 1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs",
1216 8));
1217 }
1218
TEST_F(ReceiveStatisticsProxy2Test,RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed)1219 TEST_F(ReceiveStatisticsProxy2Test,
1220 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
1221 StreamDataCounters data_counters;
1222 data_counters.first_packet_time_ms =
1223 time_controller_.GetClock()->TimeInMilliseconds();
1224
1225 time_controller_.AdvanceTime(
1226 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) - TimeDelta::Millis(1));
1227
1228 RtcpPacketTypeCounter counter;
1229 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
1230
1231 statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
1232 EXPECT_METRIC_EQ(0,
1233 metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
1234 EXPECT_METRIC_EQ(0,
1235 metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
1236 EXPECT_METRIC_EQ(
1237 0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
1238 }
1239
TEST_F(ReceiveStatisticsProxy2Test,RtcpHistogramsAreUpdated)1240 TEST_F(ReceiveStatisticsProxy2Test, RtcpHistogramsAreUpdated) {
1241 StreamDataCounters data_counters;
1242 data_counters.first_packet_time_ms =
1243 time_controller_.GetClock()->TimeInMilliseconds();
1244 time_controller_.AdvanceTime(
1245 TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
1246
1247 const uint32_t kFirPackets = 100;
1248 const uint32_t kPliPackets = 200;
1249 const uint32_t kNackPackets = 300;
1250
1251 RtcpPacketTypeCounter counter;
1252 counter.fir_packets = kFirPackets;
1253 counter.pli_packets = kPliPackets;
1254 counter.nack_packets = kNackPackets;
1255 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
1256
1257 statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
1258 EXPECT_METRIC_EQ(1,
1259 metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
1260 EXPECT_METRIC_EQ(1,
1261 metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
1262 EXPECT_METRIC_EQ(
1263 1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
1264 EXPECT_METRIC_EQ(
1265 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
1266 kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
1267 EXPECT_METRIC_EQ(
1268 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
1269 kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
1270 EXPECT_METRIC_EQ(
1271 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
1272 kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
1273 }
1274
1275 class ReceiveStatisticsProxy2TestWithFreezeDuration
1276 : public ReceiveStatisticsProxy2Test,
1277 public ::testing::WithParamInterface<
1278 std::tuple<uint32_t, uint32_t, uint32_t>> {
1279 protected:
1280 const uint32_t frame_duration_ms_ = {std::get<0>(GetParam())};
1281 const uint32_t freeze_duration_ms_ = {std::get<1>(GetParam())};
1282 const uint32_t expected_freeze_count_ = {std::get<2>(GetParam())};
1283 };
1284
1285 // It is a freeze if:
1286 // frame_duration_ms >= max(3 * avg_frame_duration, avg_frame_duration + 150)
1287 // where avg_frame_duration is average duration of last 30 frames including
1288 // the current one.
1289 //
1290 // Condition 1: 3 * avg_frame_duration > avg_frame_duration + 150
1291 const auto kFreezeDetectionCond1Freeze = std::make_tuple(150, 483, 1);
1292 const auto kFreezeDetectionCond1NotFreeze = std::make_tuple(150, 482, 0);
1293 // Condition 2: 3 * avg_frame_duration < avg_frame_duration + 150
1294 const auto kFreezeDetectionCond2Freeze = std::make_tuple(30, 185, 1);
1295 const auto kFreezeDetectionCond2NotFreeze = std::make_tuple(30, 184, 0);
1296
1297 INSTANTIATE_TEST_SUITE_P(_,
1298 ReceiveStatisticsProxy2TestWithFreezeDuration,
1299 ::testing::Values(kFreezeDetectionCond1Freeze,
1300 kFreezeDetectionCond1NotFreeze,
1301 kFreezeDetectionCond2Freeze,
1302 kFreezeDetectionCond2NotFreeze));
1303
TEST_P(ReceiveStatisticsProxy2TestWithFreezeDuration,FreezeDetection)1304 TEST_P(ReceiveStatisticsProxy2TestWithFreezeDuration, FreezeDetection) {
1305 VideoReceiveStreamInterface::Stats stats = statistics_proxy_->GetStats();
1306 EXPECT_EQ(0u, stats.freeze_count);
1307 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1308
1309 // Add a very long frame. This is need to verify that average frame
1310 // duration, which is supposed to be calculated as mean of durations of
1311 // last 30 frames, is calculated correctly.
1312 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1313 time_controller_.AdvanceTime(TimeDelta::Seconds(2));
1314 for (size_t i = 0;
1315 i <= VideoQualityObserver::kAvgInterframeDelaysWindowSizeFrames; ++i) {
1316 time_controller_.AdvanceTime(TimeDelta::Millis(frame_duration_ms_));
1317 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1318 }
1319
1320 time_controller_.AdvanceTime(TimeDelta::Millis(freeze_duration_ms_));
1321 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1322
1323 stats = statistics_proxy_->GetStats();
1324 EXPECT_EQ(stats.freeze_count, expected_freeze_count_);
1325 }
1326
1327 class ReceiveStatisticsProxy2TestWithContent
1328 : public ReceiveStatisticsProxy2Test,
1329 public ::testing::WithParamInterface<webrtc::VideoContentType> {
1330 protected:
1331 const webrtc::VideoContentType content_type_{GetParam()};
1332 };
1333
1334 INSTANTIATE_TEST_SUITE_P(ContentTypes,
1335 ReceiveStatisticsProxy2TestWithContent,
1336 ::testing::Values(VideoContentType::UNSPECIFIED,
1337 VideoContentType::SCREENSHARE));
1338
TEST_P(ReceiveStatisticsProxy2TestWithContent,InterFrameDelaysAreReported)1339 TEST_P(ReceiveStatisticsProxy2TestWithContent, InterFrameDelaysAreReported) {
1340 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1341 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1342
1343 for (int i = 0; i < kMinRequiredSamples; ++i) {
1344 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1345 content_type_);
1346 time_controller_.AdvanceTime(kInterFrameDelay);
1347 }
1348 // One extra with double the interval.
1349 time_controller_.AdvanceTime(kInterFrameDelay);
1350 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1351 content_type_);
1352
1353 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1354 const TimeDelta kExpectedInterFrame =
1355 (kInterFrameDelay * (kMinRequiredSamples - 1) + kInterFrameDelay * 2) /
1356 kMinRequiredSamples;
1357 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1358 EXPECT_METRIC_EQ(
1359 kExpectedInterFrame.ms(),
1360 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1361 EXPECT_METRIC_EQ(
1362 kInterFrameDelay.ms() * 2,
1363 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1364 } else {
1365 EXPECT_METRIC_EQ(kExpectedInterFrame.ms(),
1366 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1367 EXPECT_METRIC_EQ(kInterFrameDelay.ms() * 2,
1368 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1369 }
1370 }
1371
TEST_P(ReceiveStatisticsProxy2TestWithContent,InterFrameDelaysPercentilesAreReported)1372 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1373 InterFrameDelaysPercentilesAreReported) {
1374 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1375 const int kLastFivePercentsSamples = kMinRequiredSamples * 5 / 100;
1376 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1377
1378 for (int i = 0; i <= kMinRequiredSamples - kLastFivePercentsSamples; ++i) {
1379 time_controller_.AdvanceTime(kInterFrameDelay);
1380 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1381 content_type_);
1382 }
1383 // Last 5% of intervals are double in size.
1384 for (int i = 0; i < kLastFivePercentsSamples; ++i) {
1385 time_controller_.AdvanceTime(2 * kInterFrameDelay);
1386 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1387 content_type_);
1388 }
1389 // Final sample is outlier and 10 times as big.
1390 time_controller_.AdvanceTime(10 * kInterFrameDelay);
1391 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1392 content_type_);
1393
1394 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1395 const TimeDelta kExpectedInterFrame = kInterFrameDelay * 2;
1396 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1397 EXPECT_METRIC_EQ(
1398 kExpectedInterFrame.ms(),
1399 metrics::MinSample(
1400 "WebRTC.Video.Screenshare.InterframeDelay95PercentileInMs"));
1401 } else {
1402 EXPECT_METRIC_EQ(
1403 kExpectedInterFrame.ms(),
1404 metrics::MinSample("WebRTC.Video.InterframeDelay95PercentileInMs"));
1405 }
1406 }
1407
TEST_P(ReceiveStatisticsProxy2TestWithContent,MaxInterFrameDelayOnlyWithValidAverage)1408 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1409 MaxInterFrameDelayOnlyWithValidAverage) {
1410 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1411 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1412
1413 for (int i = 0; i < kMinRequiredSamples; ++i) {
1414 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1415 content_type_);
1416 time_controller_.AdvanceTime(kInterFrameDelay);
1417 }
1418
1419 // `kMinRequiredSamples` samples, and thereby intervals, is required. That
1420 // means we're one frame short of having a valid data set.
1421 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1422 nullptr);
1423 EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1424 EXPECT_METRIC_EQ(0,
1425 metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1426 EXPECT_METRIC_EQ(
1427 0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1428 EXPECT_METRIC_EQ(0, metrics::NumSamples(
1429 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1430 }
1431
TEST_P(ReceiveStatisticsProxy2TestWithContent,MaxInterFrameDelayOnlyWithPause)1432 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1433 MaxInterFrameDelayOnlyWithPause) {
1434 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1435 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1436
1437 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1438 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1439 content_type_);
1440 time_controller_.AdvanceTime(kInterFrameDelay);
1441 }
1442
1443 // At this state, we should have a valid inter-frame delay.
1444 // Indicate stream paused and make a large jump in time.
1445 statistics_proxy_->OnStreamInactive();
1446 time_controller_.AdvanceTime(TimeDelta::Seconds(5));
1447 // Insert two more frames. The interval during the pause should be
1448 // disregarded in the stats.
1449 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1450 content_type_);
1451 time_controller_.AdvanceTime(kInterFrameDelay);
1452 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1453 content_type_);
1454
1455 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1456 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1457 EXPECT_METRIC_EQ(
1458 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1459 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1460 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1461 EXPECT_METRIC_EQ(
1462 kInterFrameDelay.ms(),
1463 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1464 EXPECT_METRIC_EQ(
1465 kInterFrameDelay.ms(),
1466 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1467 } else {
1468 EXPECT_METRIC_EQ(1,
1469 metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1470 EXPECT_METRIC_EQ(
1471 1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1472 EXPECT_METRIC_EQ(kInterFrameDelay.ms(),
1473 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1474 EXPECT_METRIC_EQ(kInterFrameDelay.ms(),
1475 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1476 }
1477 }
1478
TEST_P(ReceiveStatisticsProxy2TestWithContent,FreezesAreReported)1479 TEST_P(ReceiveStatisticsProxy2TestWithContent, FreezesAreReported) {
1480 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1481 const TimeDelta kFreezeDelay = TimeDelta::Millis(200);
1482 const TimeDelta kCallDuration =
1483 kMinRequiredSamples * kInterFrameDelay + kFreezeDelay;
1484 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1485
1486 for (int i = 0; i < kMinRequiredSamples; ++i) {
1487 VideoFrameMetaData meta = MetaData(frame);
1488 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1489 TimeDelta::Zero(), TimeDelta::Zero(),
1490 content_type_);
1491 statistics_proxy_->OnRenderedFrame(meta);
1492 time_controller_.AdvanceTime(kInterFrameDelay);
1493 }
1494 // Add extra freeze.
1495 time_controller_.AdvanceTime(kFreezeDelay);
1496 VideoFrameMetaData meta = MetaData(frame);
1497 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1498 TimeDelta::Zero(), TimeDelta::Zero(),
1499 content_type_);
1500 statistics_proxy_->OnRenderedFrame(meta);
1501
1502 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1503 const TimeDelta kExpectedTimeBetweenFreezes =
1504 kInterFrameDelay * (kMinRequiredSamples - 1);
1505 const int kExpectedNumberFreezesPerMinute = 60 / kCallDuration.seconds();
1506 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1507 EXPECT_METRIC_EQ(
1508 (kFreezeDelay + kInterFrameDelay).ms(),
1509 metrics::MinSample("WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1510 EXPECT_METRIC_EQ(kExpectedTimeBetweenFreezes.ms(),
1511 metrics::MinSample(
1512 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1513 EXPECT_METRIC_EQ(
1514 kExpectedNumberFreezesPerMinute,
1515 metrics::MinSample("WebRTC.Video.Screenshare.NumberFreezesPerMinute"));
1516 } else {
1517 EXPECT_METRIC_EQ((kFreezeDelay + kInterFrameDelay).ms(),
1518 metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1519 EXPECT_METRIC_EQ(
1520 kExpectedTimeBetweenFreezes.ms(),
1521 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1522 EXPECT_METRIC_EQ(kExpectedNumberFreezesPerMinute,
1523 metrics::MinSample("WebRTC.Video.NumberFreezesPerMinute"));
1524 }
1525 }
1526
TEST_P(ReceiveStatisticsProxy2TestWithContent,HarmonicFrameRateIsReported)1527 TEST_P(ReceiveStatisticsProxy2TestWithContent, HarmonicFrameRateIsReported) {
1528 const TimeDelta kFrameDuration = TimeDelta::Millis(33);
1529 const TimeDelta kFreezeDuration = TimeDelta::Millis(200);
1530 const TimeDelta kPauseDuration = TimeDelta::Seconds(10);
1531 const TimeDelta kCallDuration =
1532 kMinRequiredSamples * kFrameDuration + kFreezeDuration + kPauseDuration;
1533 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1534
1535 for (int i = 0; i < kMinRequiredSamples; ++i) {
1536 time_controller_.AdvanceTime(kFrameDuration);
1537 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1538 content_type_);
1539 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1540 }
1541
1542 // Freezes and pauses should be included into harmonic frame rate.
1543 // Add freeze.
1544 time_controller_.AdvanceTime(kFreezeDuration);
1545 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1546 content_type_);
1547 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1548
1549 // Add pause.
1550 time_controller_.AdvanceTime(kPauseDuration);
1551 statistics_proxy_->OnStreamInactive();
1552 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1553 content_type_);
1554 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1555
1556 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1557 double kSumSquaredFrameDurationSecs =
1558 (kMinRequiredSamples - 1) *
1559 (kFrameDuration.seconds<double>() * kFrameDuration.seconds<double>());
1560 kSumSquaredFrameDurationSecs +=
1561 kFreezeDuration.seconds<double>() * kFreezeDuration.seconds<double>();
1562 kSumSquaredFrameDurationSecs +=
1563 kPauseDuration.seconds<double>() * kPauseDuration.seconds<double>();
1564 const int kExpectedHarmonicFrameRateFps = std::round(
1565 kCallDuration.seconds<double>() / kSumSquaredFrameDurationSecs);
1566 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1567 EXPECT_METRIC_EQ(
1568 kExpectedHarmonicFrameRateFps,
1569 metrics::MinSample("WebRTC.Video.Screenshare.HarmonicFrameRate"));
1570 } else {
1571 EXPECT_METRIC_EQ(kExpectedHarmonicFrameRateFps,
1572 metrics::MinSample("WebRTC.Video.HarmonicFrameRate"));
1573 }
1574 }
1575
TEST_P(ReceiveStatisticsProxy2TestWithContent,PausesAreIgnored)1576 TEST_P(ReceiveStatisticsProxy2TestWithContent, PausesAreIgnored) {
1577 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1578 const TimeDelta kPauseDuration = TimeDelta::Seconds(10);
1579 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1580
1581 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1582 VideoFrameMetaData meta = MetaData(frame);
1583 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1584 TimeDelta::Zero(), TimeDelta::Zero(),
1585 content_type_);
1586 statistics_proxy_->OnRenderedFrame(meta);
1587 time_controller_.AdvanceTime(kInterFrameDelay);
1588 }
1589 // Add a pause.
1590 time_controller_.AdvanceTime(kPauseDuration);
1591 statistics_proxy_->OnStreamInactive();
1592 // Second playback interval with triple the length.
1593 for (int i = 0; i <= kMinRequiredSamples * 3; ++i) {
1594 VideoFrameMetaData meta = MetaData(frame);
1595 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1596 TimeDelta::Zero(), TimeDelta::Zero(),
1597 content_type_);
1598 statistics_proxy_->OnRenderedFrame(meta);
1599 time_controller_.AdvanceTime(kInterFrameDelay);
1600 }
1601
1602 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1603 // Average of two playback intervals.
1604 const TimeDelta kExpectedTimeBetweenFreezes =
1605 kInterFrameDelay * kMinRequiredSamples * 2;
1606 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1607 EXPECT_METRIC_EQ(-1, metrics::MinSample(
1608 "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1609 EXPECT_METRIC_EQ(kExpectedTimeBetweenFreezes.ms(),
1610 metrics::MinSample(
1611 "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1612 } else {
1613 EXPECT_METRIC_EQ(-1,
1614 metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1615 EXPECT_METRIC_EQ(
1616 kExpectedTimeBetweenFreezes.ms(),
1617 metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1618 }
1619 }
1620
TEST_P(ReceiveStatisticsProxy2TestWithContent,ManyPausesAtTheBeginning)1621 TEST_P(ReceiveStatisticsProxy2TestWithContent, ManyPausesAtTheBeginning) {
1622 const TimeDelta kInterFrameDelay = TimeDelta::Millis(33);
1623 const TimeDelta kPauseDuration = TimeDelta::Seconds(10);
1624 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1625
1626 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1627 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1628 content_type_);
1629 time_controller_.AdvanceTime(kInterFrameDelay);
1630 statistics_proxy_->OnStreamInactive();
1631 time_controller_.AdvanceTime(kPauseDuration);
1632 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1633 content_type_);
1634 time_controller_.AdvanceTime(kInterFrameDelay);
1635 }
1636
1637 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1638 nullptr);
1639 // No freezes should be detected, as all long inter-frame delays were
1640 // pauses.
1641 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1642 EXPECT_METRIC_EQ(-1, metrics::MinSample(
1643 "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1644 } else {
1645 EXPECT_METRIC_EQ(-1,
1646 metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1647 }
1648 }
1649
TEST_P(ReceiveStatisticsProxy2TestWithContent,TimeInHdReported)1650 TEST_P(ReceiveStatisticsProxy2TestWithContent, TimeInHdReported) {
1651 const TimeDelta kInterFrameDelay = TimeDelta::Millis(20);
1652 webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1653 webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1654
1655 // HD frames.
1656 for (int i = 0; i < kMinRequiredSamples; ++i) {
1657 VideoFrameMetaData meta = MetaData(frame_hd);
1658 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1659 TimeDelta::Zero(), TimeDelta::Zero(),
1660 content_type_);
1661 statistics_proxy_->OnRenderedFrame(meta);
1662 time_controller_.AdvanceTime(kInterFrameDelay);
1663 }
1664 // SD frames.
1665 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1666 VideoFrameMetaData meta = MetaData(frame_sd);
1667 statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, TimeDelta::Zero(),
1668 TimeDelta::Zero(), TimeDelta::Zero(),
1669 content_type_);
1670 statistics_proxy_->OnRenderedFrame(meta);
1671 time_controller_.AdvanceTime(kInterFrameDelay);
1672 }
1673 // Extra last frame.
1674 statistics_proxy_->OnRenderedFrame(MetaData(frame_sd));
1675
1676 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1677 nullptr);
1678 const int kExpectedTimeInHdPercents = 33;
1679 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1680 EXPECT_METRIC_EQ(
1681 kExpectedTimeInHdPercents,
1682 metrics::MinSample("WebRTC.Video.Screenshare.TimeInHdPercentage"));
1683 } else {
1684 EXPECT_METRIC_EQ(kExpectedTimeInHdPercents,
1685 metrics::MinSample("WebRTC.Video.TimeInHdPercentage"));
1686 }
1687 }
1688
TEST_P(ReceiveStatisticsProxy2TestWithContent,TimeInBlockyVideoReported)1689 TEST_P(ReceiveStatisticsProxy2TestWithContent, TimeInBlockyVideoReported) {
1690 const TimeDelta kInterFrameDelay = TimeDelta::Millis(20);
1691 const int kHighQp = 80;
1692 const int kLowQp = 30;
1693 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1694
1695 // High quality frames.
1696 for (int i = 0; i < kMinRequiredSamples; ++i) {
1697 VideoFrameMetaData meta = MetaData(frame);
1698 statistics_proxy_->OnDecodedFrame(meta, kLowQp, TimeDelta::Zero(),
1699 TimeDelta::Zero(), TimeDelta::Zero(),
1700 content_type_);
1701 statistics_proxy_->OnRenderedFrame(meta);
1702 time_controller_.AdvanceTime(kInterFrameDelay);
1703 }
1704 // Blocky frames.
1705 for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1706 VideoFrameMetaData meta = MetaData(frame);
1707 statistics_proxy_->OnDecodedFrame(meta, kHighQp, TimeDelta::Zero(),
1708 TimeDelta::Zero(), TimeDelta::Zero(),
1709 content_type_);
1710 statistics_proxy_->OnRenderedFrame(meta);
1711 time_controller_.AdvanceTime(kInterFrameDelay);
1712 }
1713 // Extra last frame.
1714 statistics_proxy_->OnDecodedFrame(frame, kHighQp, TimeDelta::Zero(),
1715 content_type_);
1716 statistics_proxy_->OnRenderedFrame(MetaData(frame));
1717
1718 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1719 const int kExpectedTimeInHdPercents = 66;
1720 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1721 EXPECT_METRIC_EQ(
1722 kExpectedTimeInHdPercents,
1723 metrics::MinSample(
1724 "WebRTC.Video.Screenshare.TimeInBlockyVideoPercentage"));
1725 } else {
1726 EXPECT_METRIC_EQ(
1727 kExpectedTimeInHdPercents,
1728 metrics::MinSample("WebRTC.Video.TimeInBlockyVideoPercentage"));
1729 }
1730 }
1731
TEST_P(ReceiveStatisticsProxy2TestWithContent,DownscalesReported)1732 TEST_P(ReceiveStatisticsProxy2TestWithContent, DownscalesReported) {
1733 // To ensure long enough call duration.
1734 const TimeDelta kInterFrameDelay = TimeDelta::Seconds(2);
1735
1736 webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1737 webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1738 webrtc::VideoFrame frame_ld = CreateFrame(320, 180);
1739
1740 // Call once to pass content type.
1741 statistics_proxy_->OnDecodedFrame(frame_hd, absl::nullopt, TimeDelta::Zero(),
1742 content_type_);
1743
1744 time_controller_.AdvanceTime(TimeDelta::Zero());
1745 statistics_proxy_->OnRenderedFrame(MetaData(frame_hd));
1746 time_controller_.AdvanceTime(kInterFrameDelay);
1747 // Downscale.
1748 statistics_proxy_->OnRenderedFrame(MetaData(frame_sd));
1749 time_controller_.AdvanceTime(kInterFrameDelay);
1750 // Downscale.
1751 statistics_proxy_->OnRenderedFrame(MetaData(frame_ld));
1752 time_controller_.AdvanceTime(kInterFrameDelay);
1753 statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1754 nullptr);
1755 const int kExpectedDownscales = 30; // 2 per 4 seconds = 30 per minute.
1756 if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1757 EXPECT_METRIC_EQ(
1758 kExpectedDownscales,
1759 metrics::MinSample("WebRTC.Video.Screenshare."
1760 "NumberResolutionDownswitchesPerMinute"));
1761 } else {
1762 EXPECT_METRIC_EQ(kExpectedDownscales,
1763 metrics::MinSample(
1764 "WebRTC.Video.NumberResolutionDownswitchesPerMinute"));
1765 }
1766 }
1767
TEST_P(ReceiveStatisticsProxy2TestWithContent,DecodeTimeReported)1768 TEST_P(ReceiveStatisticsProxy2TestWithContent, DecodeTimeReported) {
1769 const TimeDelta kInterFrameDelay = TimeDelta::Millis(20);
1770 const int kLowQp = 30;
1771 const TimeDelta kDecodeTime = TimeDelta::Millis(7);
1772
1773 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1774
1775 for (int i = 0; i < kMinRequiredSamples; ++i) {
1776 statistics_proxy_->OnDecodedFrame(frame, kLowQp, kDecodeTime,
1777 content_type_);
1778 time_controller_.AdvanceTime(kInterFrameDelay);
1779 }
1780 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1781 EXPECT_METRIC_EQ(
1782 1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeTime.ms()));
1783 }
1784
TEST_P(ReceiveStatisticsProxy2TestWithContent,StatsAreSlicedOnSimulcastAndExperiment)1785 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1786 StatsAreSlicedOnSimulcastAndExperiment) {
1787 const uint8_t experiment_id = 1;
1788 webrtc::VideoContentType content_type = content_type_;
1789 videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
1790 const TimeDelta kInterFrameDelay1 = TimeDelta::Millis(30);
1791 const TimeDelta kInterFrameDelay2 = TimeDelta::Millis(50);
1792 webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1793
1794 videocontenttypehelpers::SetSimulcastId(&content_type, 1);
1795 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1796 time_controller_.AdvanceTime(kInterFrameDelay1);
1797 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1798 content_type);
1799 }
1800
1801 videocontenttypehelpers::SetSimulcastId(&content_type, 2);
1802 for (int i = 0; i <= kMinRequiredSamples; ++i) {
1803 time_controller_.AdvanceTime(kInterFrameDelay2);
1804 statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
1805 content_type);
1806 }
1807 FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1808
1809 if (videocontenttypehelpers::IsScreenshare(content_type)) {
1810 EXPECT_METRIC_EQ(
1811 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1812 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1813 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1814 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1815 "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1816 EXPECT_METRIC_EQ(1,
1817 metrics::NumSamples(
1818 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
1819 EXPECT_METRIC_EQ(1, metrics::NumSamples(
1820 "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1821 EXPECT_METRIC_EQ(1,
1822 metrics::NumSamples(
1823 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
1824 EXPECT_METRIC_EQ(
1825 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
1826 ".ExperimentGroup0"));
1827 EXPECT_METRIC_EQ(
1828 1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
1829 ".ExperimentGroup0"));
1830 EXPECT_METRIC_EQ(
1831 kInterFrameDelay1.ms(),
1832 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1833 EXPECT_METRIC_EQ(
1834 kInterFrameDelay2.ms(),
1835 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1836 EXPECT_METRIC_EQ(
1837 ((kInterFrameDelay1 + kInterFrameDelay2) / 2).ms(),
1838 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1839 EXPECT_METRIC_EQ(
1840 kInterFrameDelay2.ms(),
1841 metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1842 EXPECT_METRIC_EQ(
1843 ((kInterFrameDelay1 + kInterFrameDelay2) / 2).ms(),
1844 metrics::MinSample(
1845 "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
1846 } else {
1847 EXPECT_METRIC_EQ(1,
1848 metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1849 EXPECT_METRIC_EQ(
1850 1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1851 EXPECT_METRIC_EQ(
1852 1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
1853 EXPECT_METRIC_EQ(
1854 1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
1855 EXPECT_METRIC_EQ(
1856 1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
1857 EXPECT_METRIC_EQ(
1858 1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
1859 EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
1860 ".ExperimentGroup0"));
1861 EXPECT_METRIC_EQ(1,
1862 metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
1863 ".ExperimentGroup0"));
1864 EXPECT_METRIC_EQ(kInterFrameDelay1.ms(),
1865 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
1866 EXPECT_METRIC_EQ(kInterFrameDelay2.ms(),
1867 metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
1868 EXPECT_METRIC_EQ((kInterFrameDelay1 + kInterFrameDelay2).ms() / 2,
1869 metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1870 EXPECT_METRIC_EQ(kInterFrameDelay2.ms(),
1871 metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1872 EXPECT_METRIC_EQ((kInterFrameDelay1 + kInterFrameDelay2).ms() / 2,
1873 metrics::MinSample(
1874 "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
1875 }
1876 }
1877
1878 } // namespace internal
1879 } // namespace webrtc
1880