blob: f768452f09aa06e6e9ad783d0022b4f36119571e [file] [log] [blame]
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001/*
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
20namespace webrtc {
21
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000022class SendStatisticsProxyTest : public ::testing::Test {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000023 public:
24 SendStatisticsProxyTest() : avg_delay_ms_(0), max_delay_ms_(0) {}
25 virtual ~SendStatisticsProxyTest() {}
26
27 protected:
28 virtual void SetUp() {
29 statistics_proxy_.reset(
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000030 new SendStatisticsProxy(GetTestConfig()));
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000031 config_ = GetTestConfig();
32 expected_ = VideoSendStream::Stats();
33 }
34
35 VideoSendStream::Config GetTestConfig() {
36 VideoSendStream::Config config;
37 config.rtp.ssrcs.push_back(17);
38 config.rtp.ssrcs.push_back(42);
stefan@webrtc.org58e2d262014-08-14 15:10:49 +000039 config.rtp.rtx.ssrcs.push_back(18);
40 config.rtp.rtx.ssrcs.push_back(43);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000041 return config;
42 }
43
sprang@webrtc.org09315702014-02-07 12:06:29 +000044 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
sprang@webrtc.org09315702014-02-07 12:06:29 +000045 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
46 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +000047 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:29 +000048
49 EXPECT_EQ(one.substreams.size(), other.substreams.size());
50 for (std::map<uint32_t, StreamStats>::const_iterator it =
51 one.substreams.begin();
52 it != one.substreams.end();
53 ++it) {
54 std::map<uint32_t, StreamStats>::const_iterator corresponding_it =
55 other.substreams.find(it->first);
56 ASSERT_TRUE(corresponding_it != other.substreams.end());
57 const StreamStats& a = it->second;
58 const StreamStats& b = corresponding_it->second;
59
60 EXPECT_EQ(a.key_frames, b.key_frames);
61 EXPECT_EQ(a.delta_frames, b.delta_frames);
62 EXPECT_EQ(a.bitrate_bps, b.bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000063 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
64 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29 +000065
66 EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
67 EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
68 EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
69 EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
70 EXPECT_EQ(a.rtp_stats.retransmitted_packets,
71 b.rtp_stats.retransmitted_packets);
72 EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
73
74 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
75 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
76 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
77 b.rtcp_stats.extended_max_sequence_number);
78 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
79 }
80 }
81
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000082 scoped_ptr<SendStatisticsProxy> statistics_proxy_;
83 VideoSendStream::Config config_;
84 int avg_delay_ms_;
85 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000086 VideoSendStream::Stats expected_;
87 typedef std::map<uint32_t, StreamStats>::const_iterator StreamIterator;
88};
89
90TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
91 RtcpStatisticsCallback* callback = statistics_proxy_.get();
92 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
93 it != config_.rtp.ssrcs.end();
94 ++it) {
95 const uint32_t ssrc = *it;
96 StreamStats& ssrc_stats = expected_.substreams[ssrc];
97
98 // Add statistics with some arbitrary, but unique, numbers.
99 uint32_t offset = ssrc * sizeof(RtcpStatistics);
100 ssrc_stats.rtcp_stats.cumulative_lost = offset;
101 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
102 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
103 ssrc_stats.rtcp_stats.jitter = offset + 3;
104 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
105 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000106 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
107 it != config_.rtp.rtx.ssrcs.end();
108 ++it) {
109 const uint32_t ssrc = *it;
110 StreamStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000111
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000112 // Add statistics with some arbitrary, but unique, numbers.
113 uint32_t offset = ssrc * sizeof(RtcpStatistics);
114 ssrc_stats.rtcp_stats.cumulative_lost = offset;
115 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
116 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
117 ssrc_stats.rtcp_stats.jitter = offset + 3;
118 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
119 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000120 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000121 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000122}
123
124TEST_F(SendStatisticsProxyTest, FrameRates) {
125 const int capture_fps = 31;
126 const int encode_fps = 29;
127
128 ViECaptureObserver* capture_observer = statistics_proxy_.get();
129 capture_observer->CapturedFrameRate(0, capture_fps);
130 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
131 encoder_observer->OutgoingRate(0, encode_fps, 0);
132
133 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
134 EXPECT_EQ(capture_fps, stats.input_frame_rate);
135 EXPECT_EQ(encode_fps, stats.encode_frame_rate);
136}
137
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000138TEST_F(SendStatisticsProxyTest, Suspended) {
139 // Verify that the value is false by default.
140 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
141
142 // Verify that we can set it to true.
143 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
144 encoder_observer->SuspendChange(0, true);
145 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
146
147 // Verify that we can set it back to false again.
148 encoder_observer->SuspendChange(0, false);
149 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
150}
151
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000152TEST_F(SendStatisticsProxyTest, FrameCounts) {
153 FrameCountObserver* observer = statistics_proxy_.get();
154 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
155 it != config_.rtp.ssrcs.end();
156 ++it) {
157 const uint32_t ssrc = *it;
158 // Add statistics with some arbitrary, but unique, numbers.
159 StreamStats& stats = expected_.substreams[ssrc];
160 uint32_t offset = ssrc * sizeof(StreamStats);
161 stats.key_frames = offset;
162 stats.delta_frames = offset + 1;
163 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
164 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
165 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000166 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
167 it != config_.rtp.rtx.ssrcs.end();
168 ++it) {
169 const uint32_t ssrc = *it;
170 // Add statistics with some arbitrary, but unique, numbers.
171 StreamStats& stats = expected_.substreams[ssrc];
172 uint32_t offset = ssrc * sizeof(StreamStats);
173 stats.key_frames = offset;
174 stats.delta_frames = offset + 1;
175 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
176 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
177 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000178
179 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000180 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000181}
182
183TEST_F(SendStatisticsProxyTest, DataCounters) {
184 StreamDataCountersCallback* callback = statistics_proxy_.get();
185 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
186 it != config_.rtp.ssrcs.end();
187 ++it) {
188 const uint32_t ssrc = *it;
189 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
190 // Add statistics with some arbitrary, but unique, numbers.
191 uint32_t offset = ssrc * sizeof(StreamDataCounters);
192 counters.bytes = offset;
193 counters.header_bytes = offset + 1;
194 counters.fec_packets = offset + 2;
195 counters.padding_bytes = offset + 3;
196 counters.retransmitted_packets = offset + 4;
197 counters.packets = offset + 5;
198 callback->DataCountersUpdated(counters, ssrc);
199 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000200 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
201 it != config_.rtp.rtx.ssrcs.end();
202 ++it) {
203 const uint32_t ssrc = *it;
204 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
205 // Add statistics with some arbitrary, but unique, numbers.
206 uint32_t offset = ssrc * sizeof(StreamDataCounters);
207 counters.bytes = offset;
208 counters.header_bytes = offset + 1;
209 counters.fec_packets = offset + 2;
210 counters.padding_bytes = offset + 3;
211 counters.retransmitted_packets = offset + 4;
212 counters.packets = offset + 5;
213 callback->DataCountersUpdated(counters, ssrc);
214 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000215
216 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000217 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000218}
219
220TEST_F(SendStatisticsProxyTest, Bitrate) {
221 BitrateStatisticsObserver* observer = statistics_proxy_.get();
222 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
223 it != config_.rtp.ssrcs.end();
224 ++it) {
225 const uint32_t ssrc = *it;
226 BitrateStatistics bitrate;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000227 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000228 bitrate.bitrate_bps = ssrc;
229 observer->Notify(bitrate, ssrc);
230 expected_.substreams[ssrc].bitrate_bps = ssrc;
231 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000232 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
233 it != config_.rtp.rtx.ssrcs.end();
234 ++it) {
235 const uint32_t ssrc = *it;
236 BitrateStatistics bitrate;
237 // Use ssrc as bitrate_bps to get a unique value for each stream.
238 bitrate.bitrate_bps = ssrc;
239 observer->Notify(bitrate, ssrc);
240 expected_.substreams[ssrc].bitrate_bps = ssrc;
241 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000242
243 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000244 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000245}
246
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000247TEST_F(SendStatisticsProxyTest, SendSideDelay) {
248 SendSideDelayObserver* observer = statistics_proxy_.get();
249 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
250 it != config_.rtp.ssrcs.end();
251 ++it) {
252 const uint32_t ssrc = *it;
253 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
254 // stream.
255 int avg_delay_ms = ssrc;
256 int max_delay_ms = ssrc + 1;
257 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
258 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
259 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
260 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000261 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
262 it != config_.rtp.rtx.ssrcs.end();
263 ++it) {
264 const uint32_t ssrc = *it;
265 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
266 // stream.
267 int avg_delay_ms = ssrc;
268 int max_delay_ms = ssrc + 1;
269 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
270 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
271 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
272 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000273 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000274 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000275}
276
277TEST_F(SendStatisticsProxyTest, NoSubstreams) {
278 uint32_t exluded_ssrc =
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000279 std::max(
280 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()),
281 *std::max_element(config_.rtp.rtx.ssrcs.begin(),
282 config_.rtp.rtx.ssrcs.end())) +
283 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000284 // From RtcpStatisticsCallback.
285 RtcpStatistics rtcp_stats;
286 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
287 rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc);
288
289 // From StreamDataCountersCallback.
290 StreamDataCounters rtp_stats;
291 StreamDataCountersCallback* rtp_callback = statistics_proxy_.get();
292 rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc);
293
294 // From BitrateStatisticsObserver.
295 BitrateStatistics bitrate;
296 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
297 bitrate_observer->Notify(bitrate, exluded_ssrc);
298
299 // From FrameCountObserver.
300 FrameCountObserver* fps_observer = statistics_proxy_.get();
301 fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
302
303 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
304 EXPECT_TRUE(stats.substreams.empty());
305}
306
307} // namespace webrtc