| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/video/receive_statistics_proxy.h" | 11 #include "webrtc/video/receive_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <limits> |
| 13 #include <memory> | 14 #include <memory> |
| 14 | 15 |
| 15 #include "webrtc/api/video/i420_buffer.h" | 16 #include "webrtc/api/video/i420_buffer.h" |
| 16 #include "webrtc/api/video/video_frame.h" | 17 #include "webrtc/api/video/video_frame.h" |
| 17 #include "webrtc/api/video/video_rotation.h" | 18 #include "webrtc/api/video/video_rotation.h" |
| 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 19 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 19 #include "webrtc/system_wrappers/include/metrics.h" | 20 #include "webrtc/system_wrappers/include/metrics.h" |
| 20 #include "webrtc/system_wrappers/include/metrics_default.h" | 21 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 21 #include "webrtc/test/gtest.h" | 22 #include "webrtc/test/gtest.h" |
| 22 | 23 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 40 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_)); | 41 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_)); |
| 41 } | 42 } |
| 42 | 43 |
| 43 VideoReceiveStream::Config GetTestConfig() { | 44 VideoReceiveStream::Config GetTestConfig() { |
| 44 VideoReceiveStream::Config config(nullptr); | 45 VideoReceiveStream::Config config(nullptr); |
| 45 config.rtp.local_ssrc = kLocalSsrc; | 46 config.rtp.local_ssrc = kLocalSsrc; |
| 46 config.rtp.remote_ssrc = kRemoteSsrc; | 47 config.rtp.remote_ssrc = kRemoteSsrc; |
| 47 return config; | 48 return config; |
| 48 } | 49 } |
| 49 | 50 |
| 51 void InsertFirstRtpPacket(uint32_t ssrc) { |
| 52 StreamDataCounters counters; |
| 53 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds(); |
| 54 statistics_proxy_->DataCountersUpdated(counters, ssrc); |
| 55 } |
| 56 |
| 57 VideoFrame CreateFrame(int width, int height) { |
| 58 VideoFrame frame(I420Buffer::Create(width, height), 0, 0, kVideoRotation_0); |
| 59 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds()); |
| 60 return frame; |
| 61 } |
| 62 |
| 50 SimulatedClock fake_clock_; | 63 SimulatedClock fake_clock_; |
| 51 const VideoReceiveStream::Config config_; | 64 const VideoReceiveStream::Config config_; |
| 52 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_; | 65 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_; |
| 53 }; | 66 }; |
| 54 | 67 |
| 55 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) { | 68 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) { |
| 56 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); | 69 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); |
| 57 for (uint32_t i = 1; i <= 3; ++i) { | 70 for (uint32_t i = 1; i <= 3; ++i) { |
| 58 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), | 71 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), |
| 59 VideoContentType::UNSPECIFIED); | 72 VideoContentType::UNSPECIFIED); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); | 338 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); |
| 326 | 339 |
| 327 // Min run time has passed but only one received report block. | 340 // Min run time has passed but only one received report block. |
| 328 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc); | 341 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc); |
| 329 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); | 342 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); |
| 330 SetUp(); | 343 SetUp(); |
| 331 EXPECT_EQ(0, | 344 EXPECT_EQ(0, |
| 332 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); | 345 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); |
| 333 } | 346 } |
| 334 | 347 |
| 348 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) { |
| 349 const int64_t kSyncOffsetMs = 22; |
| 350 const double kFreqKhz = 90.0; |
| 351 EXPECT_EQ(std::numeric_limits<int>::max(), |
| 352 statistics_proxy_->GetStats().sync_offset_ms); |
| 353 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); |
| 354 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms); |
| 355 } |
| 356 |
| 335 TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) { | 357 TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) { |
| 336 const int64_t kSyncOffsetMs = 22; | 358 const int64_t kSyncOffsetMs = 22; |
| 337 const double kFreqKhz = 90.0; | 359 const double kFreqKhz = 90.0; |
| 338 for (int i = 0; i < kMinRequiredSamples; ++i) | 360 for (int i = 0; i < kMinRequiredSamples; ++i) |
| 339 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); | 361 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); |
| 340 // Histograms are updated when the statistics_proxy_ is deleted. | 362 // Histograms are updated when the statistics_proxy_ is deleted. |
| 341 statistics_proxy_.reset(); | 363 statistics_proxy_.reset(); |
| 342 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs")); | 364 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs")); |
| 343 EXPECT_EQ(1, | 365 EXPECT_EQ(1, |
| 344 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs)); | 366 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs)); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 | 556 |
| 535 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate); | 557 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate); |
| 536 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate); | 558 EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate); |
| 537 | 559 |
| 538 // FPS trackers in stats proxy have a 1000ms sliding window. | 560 // FPS trackers in stats proxy have a 1000ms sliding window. |
| 539 fake_clock_.AdvanceTimeMilliseconds(1000); | 561 fake_clock_.AdvanceTimeMilliseconds(1000); |
| 540 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate); | 562 EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate); |
| 541 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate); | 563 EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate); |
| 542 } | 564 } |
| 543 | 565 |
| 566 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) { |
| 567 const int kWidth = 160; |
| 568 const int kHeight = 120; |
| 569 EXPECT_EQ(0, statistics_proxy_->GetStats().width); |
| 570 EXPECT_EQ(0, statistics_proxy_->GetStats().height); |
| 571 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered); |
| 572 |
| 573 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); |
| 574 |
| 575 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width); |
| 576 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height); |
| 577 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered); |
| 578 } |
| 579 |
| 580 TEST_F(ReceiveStatisticsProxyTest, |
| 581 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) { |
| 582 const int kWidth = 160; |
| 583 const int kHeight = 120; |
| 584 |
| 585 for (int i = 0; i < kMinRequiredSamples - 1; ++i) |
| 586 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); |
| 587 |
| 588 statistics_proxy_.reset(); |
| 589 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); |
| 590 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); |
| 591 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); |
| 592 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); |
| 593 } |
| 594 |
| 595 TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) { |
| 596 const int kWidth = 160; |
| 597 const int kHeight = 120; |
| 598 |
| 599 for (int i = 0; i < kMinRequiredSamples; ++i) |
| 600 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); |
| 601 |
| 602 statistics_proxy_.reset(); |
| 603 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); |
| 604 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); |
| 605 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); |
| 606 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); |
| 607 EXPECT_EQ(1, |
| 608 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth)); |
| 609 EXPECT_EQ(1, |
| 610 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight)); |
| 611 } |
| 612 |
| 613 TEST_F(ReceiveStatisticsProxyTest, |
| 614 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) { |
| 615 InsertFirstRtpPacket(kRemoteSsrc); |
| 616 fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) - |
| 617 1); |
| 618 |
| 619 RtcpPacketTypeCounter counter; |
| 620 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); |
| 621 |
| 622 statistics_proxy_.reset(); |
| 623 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); |
| 624 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); |
| 625 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); |
| 626 } |
| 627 |
| 628 TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) { |
| 629 InsertFirstRtpPacket(kRemoteSsrc); |
| 630 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); |
| 631 |
| 632 const uint32_t kFirPackets = 100; |
| 633 const uint32_t kPliPackets = 200; |
| 634 const uint32_t kNackPackets = 300; |
| 635 |
| 636 RtcpPacketTypeCounter counter; |
| 637 counter.fir_packets = kFirPackets; |
| 638 counter.pli_packets = kPliPackets; |
| 639 counter.nack_packets = kNackPackets; |
| 640 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); |
| 641 |
| 642 statistics_proxy_.reset(); |
| 643 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); |
| 644 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); |
| 645 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); |
| 646 EXPECT_EQ( |
| 647 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute", |
| 648 kFirPackets * 60 / metrics::kMinRunTimeInSeconds)); |
| 649 EXPECT_EQ( |
| 650 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute", |
| 651 kPliPackets * 60 / metrics::kMinRunTimeInSeconds)); |
| 652 EXPECT_EQ( |
| 653 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute", |
| 654 kNackPackets * 60 / metrics::kMinRunTimeInSeconds)); |
| 655 } |
| 656 |
| 544 } // namespace webrtc | 657 } // namespace webrtc |
| OLD | NEW |