1 /* 2 * Copyright (c) 2013 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 // This file includes unit tests for SendStatisticsProxy. 12 #include "webrtc/video/send_statistics_proxy.h" 13 14 #include <map> 15 #include <string> 16 #include <vector> 17 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace webrtc { 21 22 class SendStatisticsProxyTest : public ::testing::Test, 23 protected SendStatisticsProxy::StatsProvider { 24 public: 25 SendStatisticsProxyTest() : avg_delay_ms_(0), max_delay_ms_(0) {} 26 virtual ~SendStatisticsProxyTest() {} 27 28 protected: 29 virtual void SetUp() { 30 statistics_proxy_.reset( 31 new SendStatisticsProxy(GetTestConfig(), this)); 32 config_ = GetTestConfig(); 33 expected_ = VideoSendStream::Stats(); 34 } 35 36 VideoSendStream::Config GetTestConfig() { 37 VideoSendStream::Config config; 38 config.rtp.ssrcs.push_back(17); 39 config.rtp.ssrcs.push_back(42); 40 return config; 41 } 42 43 virtual bool GetSendSideDelay(VideoSendStream::Stats* stats) OVERRIDE { 44 stats->avg_delay_ms = avg_delay_ms_; 45 stats->max_delay_ms = max_delay_ms_; 46 return true; 47 } 48 49 virtual std::string GetCName() { return cname_; } 50 51 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) { 52 EXPECT_EQ(one.avg_delay_ms, other.avg_delay_ms); 53 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate); 54 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate); 55 EXPECT_EQ(one.avg_delay_ms, other.avg_delay_ms); 56 EXPECT_EQ(one.max_delay_ms, other.max_delay_ms); 57 EXPECT_EQ(one.suspended, other.suspended); 58 EXPECT_EQ(one.c_name, other.c_name); 59 60 EXPECT_EQ(one.substreams.size(), other.substreams.size()); 61 for (std::map<uint32_t, StreamStats>::const_iterator it = 62 one.substreams.begin(); 63 it != one.substreams.end(); 64 ++it) { 65 std::map<uint32_t, StreamStats>::const_iterator corresponding_it = 66 other.substreams.find(it->first); 67 ASSERT_TRUE(corresponding_it != other.substreams.end()); 68 const StreamStats& a = it->second; 69 const StreamStats& b = corresponding_it->second; 70 71 EXPECT_EQ(a.key_frames, b.key_frames); 72 EXPECT_EQ(a.delta_frames, b.delta_frames); 73 EXPECT_EQ(a.bitrate_bps, b.bitrate_bps); 74 75 EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes); 76 EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes); 77 EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes); 78 EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets); 79 EXPECT_EQ(a.rtp_stats.retransmitted_packets, 80 b.rtp_stats.retransmitted_packets); 81 EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets); 82 83 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost); 84 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost); 85 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number, 86 b.rtcp_stats.extended_max_sequence_number); 87 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter); 88 } 89 } 90 91 scoped_ptr<SendStatisticsProxy> statistics_proxy_; 92 VideoSendStream::Config config_; 93 int avg_delay_ms_; 94 int max_delay_ms_; 95 std::string cname_; 96 VideoSendStream::Stats expected_; 97 typedef std::map<uint32_t, StreamStats>::const_iterator StreamIterator; 98 }; 99 100 TEST_F(SendStatisticsProxyTest, RtcpStatistics) { 101 RtcpStatisticsCallback* callback = statistics_proxy_.get(); 102 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin(); 103 it != config_.rtp.ssrcs.end(); 104 ++it) { 105 const uint32_t ssrc = *it; 106 StreamStats& ssrc_stats = expected_.substreams[ssrc]; 107 108 // Add statistics with some arbitrary, but unique, numbers. 109 uint32_t offset = ssrc * sizeof(RtcpStatistics); 110 ssrc_stats.rtcp_stats.cumulative_lost = offset; 111 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1; 112 ssrc_stats.rtcp_stats.fraction_lost = offset + 2; 113 ssrc_stats.rtcp_stats.jitter = offset + 3; 114 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc); 115 } 116 117 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 118 ExpectEqual(expected_, stats); 119 } 120 121 TEST_F(SendStatisticsProxyTest, FrameRates) { 122 const int capture_fps = 31; 123 const int encode_fps = 29; 124 125 ViECaptureObserver* capture_observer = statistics_proxy_.get(); 126 capture_observer->CapturedFrameRate(0, capture_fps); 127 ViEEncoderObserver* encoder_observer = statistics_proxy_.get(); 128 encoder_observer->OutgoingRate(0, encode_fps, 0); 129 130 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 131 EXPECT_EQ(capture_fps, stats.input_frame_rate); 132 EXPECT_EQ(encode_fps, stats.encode_frame_rate); 133 } 134 135 TEST_F(SendStatisticsProxyTest, Suspended) { 136 // Verify that the value is false by default. 137 EXPECT_FALSE(statistics_proxy_->GetStats().suspended); 138 139 // Verify that we can set it to true. 140 ViEEncoderObserver* encoder_observer = statistics_proxy_.get(); 141 encoder_observer->SuspendChange(0, true); 142 EXPECT_TRUE(statistics_proxy_->GetStats().suspended); 143 144 // Verify that we can set it back to false again. 145 encoder_observer->SuspendChange(0, false); 146 EXPECT_FALSE(statistics_proxy_->GetStats().suspended); 147 } 148 149 TEST_F(SendStatisticsProxyTest, FrameCounts) { 150 FrameCountObserver* observer = statistics_proxy_.get(); 151 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin(); 152 it != config_.rtp.ssrcs.end(); 153 ++it) { 154 const uint32_t ssrc = *it; 155 // Add statistics with some arbitrary, but unique, numbers. 156 StreamStats& stats = expected_.substreams[ssrc]; 157 uint32_t offset = ssrc * sizeof(StreamStats); 158 stats.key_frames = offset; 159 stats.delta_frames = offset + 1; 160 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc); 161 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc); 162 } 163 164 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 165 ExpectEqual(expected_, stats); 166 } 167 168 TEST_F(SendStatisticsProxyTest, DataCounters) { 169 StreamDataCountersCallback* callback = statistics_proxy_.get(); 170 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin(); 171 it != config_.rtp.ssrcs.end(); 172 ++it) { 173 const uint32_t ssrc = *it; 174 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats; 175 // Add statistics with some arbitrary, but unique, numbers. 176 uint32_t offset = ssrc * sizeof(StreamDataCounters); 177 counters.bytes = offset; 178 counters.header_bytes = offset + 1; 179 counters.fec_packets = offset + 2; 180 counters.padding_bytes = offset + 3; 181 counters.retransmitted_packets = offset + 4; 182 counters.packets = offset + 5; 183 callback->DataCountersUpdated(counters, ssrc); 184 } 185 186 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 187 ExpectEqual(expected_, stats); 188 } 189 190 TEST_F(SendStatisticsProxyTest, Bitrate) { 191 BitrateStatisticsObserver* observer = statistics_proxy_.get(); 192 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin(); 193 it != config_.rtp.ssrcs.end(); 194 ++it) { 195 const uint32_t ssrc = *it; 196 BitrateStatistics bitrate; 197 bitrate.bitrate_bps = ssrc; 198 observer->Notify(bitrate, ssrc); 199 expected_.substreams[ssrc].bitrate_bps = ssrc; 200 } 201 202 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 203 ExpectEqual(expected_, stats); 204 } 205 206 TEST_F(SendStatisticsProxyTest, StreamStats) { 207 avg_delay_ms_ = 1; 208 max_delay_ms_ = 2; 209 cname_ = "qwertyuiop"; 210 211 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 212 213 EXPECT_EQ(avg_delay_ms_, stats.avg_delay_ms); 214 EXPECT_EQ(max_delay_ms_, stats.max_delay_ms); 215 EXPECT_EQ(cname_, stats.c_name); 216 } 217 218 TEST_F(SendStatisticsProxyTest, NoSubstreams) { 219 uint32_t exluded_ssrc = 220 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()) + 1; 221 // From RtcpStatisticsCallback. 222 RtcpStatistics rtcp_stats; 223 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get(); 224 rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc); 225 226 // From StreamDataCountersCallback. 227 StreamDataCounters rtp_stats; 228 StreamDataCountersCallback* rtp_callback = statistics_proxy_.get(); 229 rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc); 230 231 // From BitrateStatisticsObserver. 232 BitrateStatistics bitrate; 233 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get(); 234 bitrate_observer->Notify(bitrate, exluded_ssrc); 235 236 // From FrameCountObserver. 237 FrameCountObserver* fps_observer = statistics_proxy_.get(); 238 fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc); 239 240 VideoSendStream::Stats stats = statistics_proxy_->GetStats(); 241 EXPECT_TRUE(stats.substreams.empty()); 242 } 243 244 } // namespace webrtc 245