Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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/send_statistics_proxy.h" | 11 #include "webrtc/video/send_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <map> | 13 #include <map> |
| 14 #include <memory> | 14 #include <memory> |
| 15 #include <string> | 15 #include <string> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "webrtc/system_wrappers/include/metrics.h" | 18 #include "webrtc/system_wrappers/include/metrics.h" |
| 19 #include "webrtc/system_wrappers/include/metrics_default.h" | 19 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 20 #include "webrtc/test/field_trial.h" | |
| 20 #include "webrtc/test/gtest.h" | 21 #include "webrtc/test/gtest.h" |
| 21 | 22 |
| 22 namespace webrtc { | 23 namespace webrtc { |
| 23 namespace { | 24 namespace { |
| 24 const uint32_t kFirstSsrc = 17; | 25 const uint32_t kFirstSsrc = 17; |
| 25 const uint32_t kSecondSsrc = 42; | 26 const uint32_t kSecondSsrc = 42; |
| 26 const uint32_t kFirstRtxSsrc = 18; | 27 const uint32_t kFirstRtxSsrc = 18; |
| 27 const uint32_t kSecondRtxSsrc = 43; | 28 const uint32_t kSecondRtxSsrc = 43; |
| 28 const uint32_t kFlexFecSsrc = 55; | 29 const uint32_t kFlexFecSsrc = 55; |
| 29 const int kFpsPeriodicIntervalMs = 2000; | 30 const int kFpsPeriodicIntervalMs = 2000; |
| 30 const int kWidth = 640; | 31 const int kWidth = 640; |
| 31 const int kHeight = 480; | 32 const int kHeight = 480; |
| 32 const int kQpIdx0 = 21; | 33 const int kQpIdx0 = 21; |
| 33 const int kQpIdx1 = 39; | 34 const int kQpIdx1 = 39; |
| 35 const int kMinFirstFallbackIntervalMs = 1500; | |
| 34 const CodecSpecificInfo kDefaultCodecInfo = []() { | 36 const CodecSpecificInfo kDefaultCodecInfo = []() { |
| 35 CodecSpecificInfo codec_info; | 37 CodecSpecificInfo codec_info; |
| 36 codec_info.codecType = kVideoCodecVP8; | 38 codec_info.codecType = kVideoCodecVP8; |
| 37 codec_info.codecSpecific.VP8.simulcastIdx = 0; | 39 codec_info.codecSpecific.VP8.simulcastIdx = 0; |
| 38 return codec_info; | 40 return codec_info; |
| 39 }(); | 41 }(); |
| 40 } // namespace | 42 } // namespace |
| 41 | 43 |
| 42 class SendStatisticsProxyTest : public ::testing::Test { | 44 class SendStatisticsProxyTest : public ::testing::Test { |
| 43 public: | 45 public: |
| 44 SendStatisticsProxyTest() | 46 SendStatisticsProxyTest() : SendStatisticsProxyTest("") {} |
| 45 : fake_clock_(1234), config_(GetTestConfig()), avg_delay_ms_(0), | 47 explicit SendStatisticsProxyTest(const std::string& field_trials) |
| 48 : override_field_trials_(field_trials), | |
| 49 fake_clock_(1234), | |
| 50 config_(GetTestConfig()), | |
| 51 avg_delay_ms_(0), | |
| 46 max_delay_ms_(0) {} | 52 max_delay_ms_(0) {} |
| 47 virtual ~SendStatisticsProxyTest() {} | 53 virtual ~SendStatisticsProxyTest() {} |
| 48 | 54 |
| 49 protected: | 55 protected: |
| 50 virtual void SetUp() { | 56 virtual void SetUp() { |
| 51 metrics::Reset(); | 57 metrics::Reset(); |
| 52 statistics_proxy_.reset(new SendStatisticsProxy( | 58 statistics_proxy_.reset(new SendStatisticsProxy( |
| 53 &fake_clock_, GetTestConfig(), | 59 &fake_clock_, GetTestConfig(), |
| 54 VideoEncoderConfig::ContentType::kRealtimeVideo)); | 60 VideoEncoderConfig::ContentType::kRealtimeVideo)); |
| 55 expected_ = VideoSendStream::Stats(); | 61 expected_ = VideoSendStream::Stats(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets); | 139 EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets); |
| 134 | 140 |
| 135 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost); | 141 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost); |
| 136 EXPECT_EQ(a.rtcp_stats.packets_lost, b.rtcp_stats.packets_lost); | 142 EXPECT_EQ(a.rtcp_stats.packets_lost, b.rtcp_stats.packets_lost); |
| 137 EXPECT_EQ(a.rtcp_stats.extended_highest_sequence_number, | 143 EXPECT_EQ(a.rtcp_stats.extended_highest_sequence_number, |
| 138 b.rtcp_stats.extended_highest_sequence_number); | 144 b.rtcp_stats.extended_highest_sequence_number); |
| 139 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter); | 145 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter); |
| 140 } | 146 } |
| 141 } | 147 } |
| 142 | 148 |
| 149 test::ScopedFieldTrials override_field_trials_; | |
| 143 SimulatedClock fake_clock_; | 150 SimulatedClock fake_clock_; |
| 144 std::unique_ptr<SendStatisticsProxy> statistics_proxy_; | 151 std::unique_ptr<SendStatisticsProxy> statistics_proxy_; |
| 145 VideoSendStream::Config config_; | 152 VideoSendStream::Config config_; |
| 146 int avg_delay_ms_; | 153 int avg_delay_ms_; |
| 147 int max_delay_ms_; | 154 int max_delay_ms_; |
| 148 VideoSendStream::Stats expected_; | 155 VideoSendStream::Stats expected_; |
| 149 typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator | 156 typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator |
| 150 StreamIterator; | 157 StreamIterator; |
| 151 }; | 158 }; |
| 152 | 159 |
| (...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1792 // Advance one interval and update counters. | 1799 // Advance one interval and update counters. |
| 1793 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs); | 1800 fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs); |
| 1794 proxy->DataCountersUpdated(counters, kFirstSsrc); | 1801 proxy->DataCountersUpdated(counters, kFirstSsrc); |
| 1795 } | 1802 } |
| 1796 | 1803 |
| 1797 // FEC not enabled. | 1804 // FEC not enabled. |
| 1798 statistics_proxy_.reset(); | 1805 statistics_proxy_.reset(); |
| 1799 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps")); | 1806 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps")); |
| 1800 } | 1807 } |
| 1801 | 1808 |
| 1809 TEST_F(SendStatisticsProxyTest, GetStatsReportsEncoderImplementationName) { | |
| 1810 const char* kName = "encoderName"; | |
| 1811 EncodedImage encoded_image; | |
| 1812 CodecSpecificInfo codec_info; | |
| 1813 codec_info.codec_name = kName; | |
| 1814 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | |
| 1815 EXPECT_STREQ( | |
| 1816 kName, statistics_proxy_->GetStats().encoder_implementation_name.c_str()); | |
| 1817 } | |
| 1818 | |
|
brandtr
2017/09/14 12:30:12
Add unit test checking that FallbackTimeInPercent.
åsapersson
2017/09/14 14:41:44
Done.
| |
| 1819 class ForcedFallbackEnabled : public SendStatisticsProxyTest { | |
| 1820 public: | |
| 1821 ForcedFallbackEnabled() | |
| 1822 : SendStatisticsProxyTest( | |
| 1823 "WebRTC-VP8-Forced-Fallback-Encoder/Enabled-1,2," + | |
| 1824 std::to_string(kMinFirstFallbackIntervalMs) + ",4/") { | |
| 1825 codec_info_.codecType = kVideoCodecVP8; | |
| 1826 codec_info_.codecSpecific.VP8.simulcastIdx = 0; | |
| 1827 codec_info_.codecSpecific.VP8.temporalIdx = 0; | |
| 1828 codec_info_.codec_name = "fake_codec"; | |
| 1829 } | |
| 1830 | |
| 1831 protected: | |
| 1832 void InsertEncodedFrames(int num_frames, int interval_ms) { | |
| 1833 // First frame is not updating stats, insert initial frame. | |
| 1834 if (statistics_proxy_->GetStats().frames_encoded == 0) { | |
| 1835 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_); | |
| 1836 } | |
| 1837 for (int i = 0; i < num_frames; ++i) { | |
| 1838 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_); | |
| 1839 fake_clock_.AdvanceTimeMilliseconds(interval_ms); | |
| 1840 } | |
| 1841 statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_); | |
|
brandtr
2017/09/14 12:30:12
Add comment.
åsapersson
2017/09/14 14:41:44
Done.
| |
| 1842 } | |
| 1843 | |
| 1844 EncodedImage encoded_image_; | |
| 1845 CodecSpecificInfo codec_info_; | |
| 1846 const std::string kPrefix = "WebRTC.Video.Encoder.ForcedSw"; | |
| 1847 const int kFrameIntervalMs = 1000; | |
| 1848 const int kMinFrames = 20; // Min run time 20 sec. | |
| 1849 }; | |
| 1850 | |
| 1851 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfMinRunTimeHasNotPassed) { | |
| 1852 InsertEncodedFrames(kMinFrames, kFrameIntervalMs - 1); | |
| 1853 statistics_proxy_.reset(); | |
| 1854 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1855 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1856 } | |
| 1857 | |
| 1858 TEST_F(ForcedFallbackEnabled, StatsUpdated) { | |
| 1859 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1860 statistics_proxy_.reset(); | |
| 1861 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1862 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 0)); | |
| 1863 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1864 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 0)); | |
| 1865 } | |
| 1866 | |
| 1867 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfNotVp8) { | |
| 1868 codec_info_.codecType = kVideoCodecVP9; | |
| 1869 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1870 statistics_proxy_.reset(); | |
| 1871 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1872 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1873 } | |
| 1874 | |
| 1875 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForTemporalLayers) { | |
| 1876 codec_info_.codecSpecific.VP8.temporalIdx = 1; | |
| 1877 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1878 statistics_proxy_.reset(); | |
| 1879 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1880 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1881 } | |
| 1882 | |
| 1883 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForSimulcast) { | |
| 1884 codec_info_.codecSpecific.VP8.simulcastIdx = 1; | |
| 1885 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1886 statistics_proxy_.reset(); | |
| 1887 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1888 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1889 } | |
| 1890 | |
| 1891 TEST_F(ForcedFallbackEnabled, OneFallbackEvent) { | |
| 1892 // One change. Video: 20000 ms, fallback: 5000 ms (25%). | |
| 1893 InsertEncodedFrames(15, 1000); | |
| 1894 codec_info_.codec_name = "libvpx"; | |
| 1895 InsertEncodedFrames(5, 1000); | |
| 1896 | |
| 1897 statistics_proxy_.reset(); | |
| 1898 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1899 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25)); | |
| 1900 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1901 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3)); | |
| 1902 } | |
| 1903 | |
| 1904 TEST_F(ForcedFallbackEnabled, ThreeFallbackEvents) { | |
| 1905 codec_info_.codecSpecific.VP8.temporalIdx = kNoTemporalIdx; | |
|
brandtr
2017/09/14 12:30:12
Delete this line?
åsapersson
2017/09/14 14:41:44
Added comment..
| |
| 1906 const int kMaxFrameDiffMs = 2000; | |
| 1907 | |
| 1908 // Three changes. Video: 60000 ms, fallback: 15000 ms (25%). | |
| 1909 InsertEncodedFrames(10, 1000); | |
| 1910 codec_info_.codec_name = "libvpx"; | |
| 1911 InsertEncodedFrames(15, 500); | |
| 1912 codec_info_.codec_name = "notlibvpx"; | |
| 1913 InsertEncodedFrames(20, 1000); | |
| 1914 InsertEncodedFrames(3, kMaxFrameDiffMs); // Should not be included. | |
| 1915 InsertEncodedFrames(10, 1000); | |
| 1916 codec_info_.codec_name = "notlibvpx2"; | |
| 1917 InsertEncodedFrames(10, 500); | |
| 1918 codec_info_.codec_name = "libvpx"; | |
| 1919 InsertEncodedFrames(15, 500); | |
| 1920 | |
| 1921 statistics_proxy_.reset(); | |
| 1922 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1923 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25)); | |
| 1924 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1925 EXPECT_EQ(1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3)); | |
| 1926 } | |
| 1927 | |
| 1928 TEST_F(ForcedFallbackEnabled, NoFallbackIfMinIntervalHasNotPassed) { | |
| 1929 InsertEncodedFrames(1, kMinFirstFallbackIntervalMs - 1); | |
| 1930 codec_info_.codec_name = "libvpx"; | |
| 1931 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1932 | |
| 1933 statistics_proxy_.reset(); | |
| 1934 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1935 EXPECT_EQ(0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1936 } | |
| 1937 | |
| 1938 TEST_F(ForcedFallbackEnabled, FallbackIfMinIntervalPassed) { | |
| 1939 InsertEncodedFrames(1, kMinFirstFallbackIntervalMs); | |
| 1940 codec_info_.codec_name = "libvpx"; | |
| 1941 InsertEncodedFrames(kMinFrames, kFrameIntervalMs); | |
| 1942 | |
| 1943 statistics_proxy_.reset(); | |
| 1944 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8")); | |
| 1945 EXPECT_EQ(1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8")); | |
| 1946 } | |
| 1947 | |
| 1802 } // namespace webrtc | 1948 } // namespace webrtc |
| OLD | NEW |