Chromium Code Reviews| 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/video_frame.h" | 16 #include "webrtc/api/video/video_frame.h" |
| 16 #include "webrtc/api/video/video_rotation.h" | 17 #include "webrtc/api/video/video_rotation.h" |
| 17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 18 #include "webrtc/system_wrappers/include/metrics.h" | 19 #include "webrtc/system_wrappers/include/metrics.h" |
| 19 #include "webrtc/system_wrappers/include/metrics_default.h" | 20 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 20 #include "webrtc/test/gtest.h" | 21 #include "webrtc/test/gtest.h" |
| 21 | 22 |
| 22 namespace webrtc { | 23 namespace webrtc { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 39 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_)); | 40 statistics_proxy_.reset(new ReceiveStatisticsProxy(&config_, &fake_clock_)); |
| 40 } | 41 } |
| 41 | 42 |
| 42 VideoReceiveStream::Config GetTestConfig() { | 43 VideoReceiveStream::Config GetTestConfig() { |
| 43 VideoReceiveStream::Config config(nullptr); | 44 VideoReceiveStream::Config config(nullptr); |
| 44 config.rtp.local_ssrc = kLocalSsrc; | 45 config.rtp.local_ssrc = kLocalSsrc; |
| 45 config.rtp.remote_ssrc = kRemoteSsrc; | 46 config.rtp.remote_ssrc = kRemoteSsrc; |
| 46 return config; | 47 return config; |
| 47 } | 48 } |
| 48 | 49 |
| 50 void InsertFirstRtpPacket(uint32_t ssrc) { | |
| 51 StreamDataCounters counters; | |
| 52 counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds(); | |
| 53 statistics_proxy_->DataCountersUpdated(counters, ssrc); | |
| 54 } | |
| 55 | |
| 56 VideoFrame CreateFrame(int width, int height) { | |
| 57 VideoFrame frame(I420Buffer::Create(width, height), 0, 0, kVideoRotation_0); | |
| 58 frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds()); | |
| 59 return frame; | |
| 60 } | |
| 61 | |
| 49 SimulatedClock fake_clock_; | 62 SimulatedClock fake_clock_; |
| 50 const VideoReceiveStream::Config config_; | 63 const VideoReceiveStream::Config config_; |
| 51 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_; | 64 std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_; |
| 52 }; | 65 }; |
| 53 | 66 |
| 54 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) { | 67 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) { |
| 55 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); | 68 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); |
| 56 for (uint32_t i = 1; i <= 3; ++i) { | 69 for (uint32_t i = 1; i <= 3; ++i) { |
| 57 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), | 70 statistics_proxy_->OnDecodedFrame(rtc::Optional<uint8_t>(), |
| 58 VideoContentType::UNSPECIFIED); | 71 VideoContentType::UNSPECIFIED); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); | 337 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); |
| 325 | 338 |
| 326 // Min run time has passed but only one received report block. | 339 // Min run time has passed but only one received report block. |
| 327 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc); | 340 statistics_proxy_->StatisticsUpdated(rtcp_stats1, kRemoteSsrc); |
| 328 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); | 341 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); |
| 329 SetUp(); | 342 SetUp(); |
| 330 EXPECT_EQ(0, | 343 EXPECT_EQ(0, |
| 331 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); | 344 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); |
| 332 } | 345 } |
| 333 | 346 |
| 347 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) { | |
| 348 const int64_t kSyncOffsetMs = 22; | |
| 349 const double kFreqKhz = 90.0; | |
| 350 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 351 statistics_proxy_->GetStats().sync_offset_ms); | |
| 352 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); | |
| 353 EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms); | |
| 354 } | |
| 355 | |
| 334 TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) { | 356 TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) { |
| 335 const int64_t kSyncOffsetMs = 22; | 357 const int64_t kSyncOffsetMs = 22; |
| 336 const double kFreqKhz = 90.0; | 358 const double kFreqKhz = 90.0; |
| 337 for (int i = 0; i < kMinRequiredSamples; ++i) | 359 for (int i = 0; i < kMinRequiredSamples; ++i) |
| 338 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); | 360 statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); |
| 339 // Histograms are updated when the statistics_proxy_ is deleted. | 361 // Histograms are updated when the statistics_proxy_ is deleted. |
| 340 statistics_proxy_.reset(); | 362 statistics_proxy_.reset(); |
| 341 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs")); | 363 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs")); |
| 342 EXPECT_EQ(1, | 364 EXPECT_EQ(1, |
| 343 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs)); | 365 metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs)); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs", | 527 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs", |
| 506 kJitterBufferMs)); | 528 kJitterBufferMs)); |
| 507 EXPECT_EQ(1, | 529 EXPECT_EQ(1, |
| 508 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs)); | 530 metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs)); |
| 509 EXPECT_EQ( | 531 EXPECT_EQ( |
| 510 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs)); | 532 1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs)); |
| 511 EXPECT_EQ(1, | 533 EXPECT_EQ(1, |
| 512 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs)); | 534 metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs)); |
| 513 } | 535 } |
| 514 | 536 |
| 537 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) { | |
| 538 const int kWidth = 160; | |
| 539 const int kHeight = 120; | |
| 540 EXPECT_EQ(0, statistics_proxy_->GetStats().width); | |
| 541 EXPECT_EQ(0, statistics_proxy_->GetStats().height); | |
| 542 EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered); | |
| 543 | |
| 544 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); | |
| 545 | |
| 546 EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width); | |
| 547 EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height); | |
| 548 EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered); | |
| 549 } | |
| 550 | |
| 551 TEST_F(ReceiveStatisticsProxyTest, | |
| 552 ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) { | |
| 553 const int kWidth = 160; | |
| 554 const int kHeight = 120; | |
| 555 | |
| 556 for (int i = 0; i < kMinRequiredSamples - 1; ++i) | |
| 557 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); | |
| 558 | |
| 559 statistics_proxy_.reset(); | |
| 560 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); | |
| 561 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); | |
| 562 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); | |
| 563 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); | |
|
sprang_webrtc
2017/05/11 09:17:57
Should WebRTC.Video.Received(Width|Height)InPixels
åsapersson
2017/05/11 09:50:01
On line 560, 561?
sprang_webrtc
2017/05/11 10:54:58
Right, read too fast. Sorry!
| |
| 564 } | |
| 565 | |
| 566 TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) { | |
| 567 const int kWidth = 160; | |
| 568 const int kHeight = 120; | |
| 569 | |
| 570 for (int i = 0; i < kMinRequiredSamples; ++i) | |
| 571 statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); | |
| 572 | |
| 573 statistics_proxy_.reset(); | |
| 574 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); | |
| 575 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); | |
| 576 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); | |
| 577 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); | |
| 578 EXPECT_EQ(1, | |
| 579 metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth)); | |
| 580 EXPECT_EQ(1, | |
| 581 metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight)); | |
| 582 } | |
| 583 | |
| 584 TEST_F(ReceiveStatisticsProxyTest, | |
| 585 RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) { | |
| 586 InsertFirstRtpPacket(kRemoteSsrc); | |
| 587 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1); | |
|
sprang_webrtc
2017/05/11 09:17:57
nit: add parenthesis around (metrics::kMinRunTimeI
åsapersson
2017/05/11 09:50:00
Done.
| |
| 588 | |
| 589 RtcpPacketTypeCounter counter; | |
| 590 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); | |
| 591 | |
| 592 statistics_proxy_.reset(); | |
| 593 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); | |
| 594 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); | |
| 595 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); | |
| 596 } | |
| 597 | |
| 598 TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) { | |
| 599 InsertFirstRtpPacket(kRemoteSsrc); | |
| 600 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); | |
| 601 | |
| 602 const uint32_t kFirPackets = 100; | |
| 603 const uint32_t kPliPackets = 200; | |
| 604 const uint32_t kNackPackets = 300; | |
| 605 | |
| 606 RtcpPacketTypeCounter counter; | |
| 607 counter.fir_packets = kFirPackets; | |
| 608 counter.pli_packets = kPliPackets; | |
| 609 counter.nack_packets = kNackPackets; | |
| 610 statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); | |
| 611 | |
| 612 statistics_proxy_.reset(); | |
| 613 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); | |
| 614 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); | |
| 615 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); | |
| 616 EXPECT_EQ( | |
| 617 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute", | |
| 618 kFirPackets * 60 / metrics::kMinRunTimeInSeconds)); | |
| 619 EXPECT_EQ( | |
| 620 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute", | |
| 621 kPliPackets * 60 / metrics::kMinRunTimeInSeconds)); | |
| 622 EXPECT_EQ( | |
| 623 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute", | |
| 624 kNackPackets * 60 / metrics::kMinRunTimeInSeconds)); | |
| 625 } | |
| 626 | |
| 515 } // namespace webrtc | 627 } // namespace webrtc |
| OLD | NEW |