blob: 06abb9ed868eba93925666f6fc1bfdb7f258d2c1 [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);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000047 EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +000048 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:29 +000049
50 EXPECT_EQ(one.substreams.size(), other.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000051 for (std::map<uint32_t, SsrcStats>::const_iterator it =
sprang@webrtc.org09315702014-02-07 12:06:29 +000052 one.substreams.begin();
53 it != one.substreams.end();
54 ++it) {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000055 std::map<uint32_t, SsrcStats>::const_iterator corresponding_it =
sprang@webrtc.org09315702014-02-07 12:06:29 +000056 other.substreams.find(it->first);
57 ASSERT_TRUE(corresponding_it != other.substreams.end());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000058 const SsrcStats& a = it->second;
59 const SsrcStats& b = corresponding_it->second;
sprang@webrtc.org09315702014-02-07 12:06:29 +000060
61 EXPECT_EQ(a.key_frames, b.key_frames);
62 EXPECT_EQ(a.delta_frames, b.delta_frames);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000063 EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000064 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
65 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29 +000066
67 EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
68 EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
69 EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
70 EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
71 EXPECT_EQ(a.rtp_stats.retransmitted_packets,
72 b.rtp_stats.retransmitted_packets);
73 EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
74
75 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
76 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
77 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
78 b.rtcp_stats.extended_max_sequence_number);
79 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
80 }
81 }
82
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000083 scoped_ptr<SendStatisticsProxy> statistics_proxy_;
84 VideoSendStream::Config config_;
85 int avg_delay_ms_;
86 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000087 VideoSendStream::Stats expected_;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000088 typedef std::map<uint32_t, SsrcStats>::const_iterator StreamIterator;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000089};
90
91TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
92 RtcpStatisticsCallback* callback = statistics_proxy_.get();
93 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
94 it != config_.rtp.ssrcs.end();
95 ++it) {
96 const uint32_t ssrc = *it;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000097 SsrcStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000098
99 // Add statistics with some arbitrary, but unique, numbers.
100 uint32_t offset = ssrc * sizeof(RtcpStatistics);
101 ssrc_stats.rtcp_stats.cumulative_lost = offset;
102 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
103 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
104 ssrc_stats.rtcp_stats.jitter = offset + 3;
105 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
106 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000107 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
108 it != config_.rtp.rtx.ssrcs.end();
109 ++it) {
110 const uint32_t ssrc = *it;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000111 SsrcStats& ssrc_stats = expected_.substreams[ssrc];
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000112
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000113 // Add statistics with some arbitrary, but unique, numbers.
114 uint32_t offset = ssrc * sizeof(RtcpStatistics);
115 ssrc_stats.rtcp_stats.cumulative_lost = offset;
116 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
117 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
118 ssrc_stats.rtcp_stats.jitter = offset + 3;
119 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
120 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000121 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000122 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000123}
124
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000125TEST_F(SendStatisticsProxyTest, CaptureFramerate) {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000126 const int capture_fps = 31;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000127
128 ViECaptureObserver* capture_observer = statistics_proxy_.get();
129 capture_observer->CapturedFrameRate(0, capture_fps);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000130
131 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
132 EXPECT_EQ(capture_fps, stats.input_frame_rate);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000133}
134
135TEST_F(SendStatisticsProxyTest, EncodedBitrateAndFramerate) {
136 const int media_bitrate_bps = 500;
137 const int encode_fps = 29;
138
139 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
140 encoder_observer->OutgoingRate(0, encode_fps, media_bitrate_bps);
141
142 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
143 EXPECT_EQ(media_bitrate_bps, stats.media_bitrate_bps);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000144 EXPECT_EQ(encode_fps, stats.encode_frame_rate);
145}
146
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000147TEST_F(SendStatisticsProxyTest, Suspended) {
148 // Verify that the value is false by default.
149 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
150
151 // Verify that we can set it to true.
152 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
153 encoder_observer->SuspendChange(0, true);
154 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
155
156 // Verify that we can set it back to false again.
157 encoder_observer->SuspendChange(0, false);
158 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
159}
160
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000161TEST_F(SendStatisticsProxyTest, FrameCounts) {
162 FrameCountObserver* observer = statistics_proxy_.get();
163 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
164 it != config_.rtp.ssrcs.end();
165 ++it) {
166 const uint32_t ssrc = *it;
167 // Add statistics with some arbitrary, but unique, numbers.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000168 SsrcStats& stats = expected_.substreams[ssrc];
169 uint32_t offset = ssrc * sizeof(SsrcStats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000170 stats.key_frames = offset;
171 stats.delta_frames = offset + 1;
172 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
173 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
174 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000175 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
176 it != config_.rtp.rtx.ssrcs.end();
177 ++it) {
178 const uint32_t ssrc = *it;
179 // Add statistics with some arbitrary, but unique, numbers.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000180 SsrcStats& stats = expected_.substreams[ssrc];
181 uint32_t offset = ssrc * sizeof(SsrcStats);
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000182 stats.key_frames = offset;
183 stats.delta_frames = offset + 1;
184 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
185 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
186 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000187
188 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000189 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000190}
191
192TEST_F(SendStatisticsProxyTest, DataCounters) {
193 StreamDataCountersCallback* callback = statistics_proxy_.get();
194 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
195 it != config_.rtp.ssrcs.end();
196 ++it) {
197 const uint32_t ssrc = *it;
198 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
199 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000200 size_t offset = ssrc * sizeof(StreamDataCounters);
201 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000202 counters.bytes = offset;
203 counters.header_bytes = offset + 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000204 counters.fec_packets = offset_uint32 + 2;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000205 counters.padding_bytes = offset + 3;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000206 counters.retransmitted_packets = offset_uint32 + 4;
207 counters.packets = offset_uint32 + 5;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000208 callback->DataCountersUpdated(counters, ssrc);
209 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000210 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
211 it != config_.rtp.rtx.ssrcs.end();
212 ++it) {
213 const uint32_t ssrc = *it;
214 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
215 // Add statistics with some arbitrary, but unique, numbers.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000216 size_t offset = ssrc * sizeof(StreamDataCounters);
217 uint32_t offset_uint32 = static_cast<uint32_t>(offset);
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000218 counters.bytes = offset;
219 counters.header_bytes = offset + 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000220 counters.fec_packets = offset_uint32 + 2;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000221 counters.padding_bytes = offset + 3;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000222 counters.retransmitted_packets = offset_uint32 + 4;
223 counters.packets = offset_uint32 + 5;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000224 callback->DataCountersUpdated(counters, ssrc);
225 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000226
227 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000228 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000229}
230
231TEST_F(SendStatisticsProxyTest, Bitrate) {
232 BitrateStatisticsObserver* observer = statistics_proxy_.get();
233 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
234 it != config_.rtp.ssrcs.end();
235 ++it) {
236 const uint32_t ssrc = *it;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000237 BitrateStatistics total;
238 BitrateStatistics retransmit;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000239 // Use ssrc as bitrate_bps to get a unique value for each stream.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000240 total.bitrate_bps = ssrc;
241 retransmit.bitrate_bps = ssrc + 1;
242 observer->Notify(total, retransmit, ssrc);
243 expected_.substreams[ssrc].total_bitrate_bps = total.bitrate_bps;
244 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit.bitrate_bps;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000245 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000246 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
247 it != config_.rtp.rtx.ssrcs.end();
248 ++it) {
249 const uint32_t ssrc = *it;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000250 BitrateStatistics total;
251 BitrateStatistics retransmit;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000252 // Use ssrc as bitrate_bps to get a unique value for each stream.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000253 total.bitrate_bps = ssrc;
254 retransmit.bitrate_bps = ssrc + 1;
255 observer->Notify(total, retransmit, ssrc);
256 expected_.substreams[ssrc].total_bitrate_bps = total.bitrate_bps;
257 expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit.bitrate_bps;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000258 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000259
260 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000261 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000262}
263
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000264TEST_F(SendStatisticsProxyTest, SendSideDelay) {
265 SendSideDelayObserver* observer = statistics_proxy_.get();
266 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
267 it != config_.rtp.ssrcs.end();
268 ++it) {
269 const uint32_t ssrc = *it;
270 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
271 // stream.
272 int avg_delay_ms = ssrc;
273 int max_delay_ms = ssrc + 1;
274 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
275 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
276 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
277 }
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000278 for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
279 it != config_.rtp.rtx.ssrcs.end();
280 ++it) {
281 const uint32_t ssrc = *it;
282 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
283 // stream.
284 int avg_delay_ms = ssrc;
285 int max_delay_ms = ssrc + 1;
286 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
287 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
288 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
289 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000290 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000291 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000292}
293
294TEST_F(SendStatisticsProxyTest, NoSubstreams) {
295 uint32_t exluded_ssrc =
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000296 std::max(
297 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()),
298 *std::max_element(config_.rtp.rtx.ssrcs.begin(),
299 config_.rtp.rtx.ssrcs.end())) +
300 1;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000301 // From RtcpStatisticsCallback.
302 RtcpStatistics rtcp_stats;
303 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
304 rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc);
305
306 // From StreamDataCountersCallback.
307 StreamDataCounters rtp_stats;
308 StreamDataCountersCallback* rtp_callback = statistics_proxy_.get();
309 rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc);
310
311 // From BitrateStatisticsObserver.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000312 BitrateStatistics total;
313 BitrateStatistics retransmit;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000314 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000315 bitrate_observer->Notify(total, retransmit, exluded_ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000316
317 // From FrameCountObserver.
318 FrameCountObserver* fps_observer = statistics_proxy_.get();
319 fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
320
321 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
322 EXPECT_TRUE(stats.substreams.empty());
323}
324
325} // namespace webrtc