blob: c930a2bc2d4330e817f71e2ba01a0d6fdd8df4cd [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);
39 return config;
40 }
41
sprang@webrtc.org09315702014-02-07 12:06:29 +000042 void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
sprang@webrtc.org09315702014-02-07 12:06:29 +000043 EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
44 EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +000045 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.org09315702014-02-07 12:06:29 +000046
47 EXPECT_EQ(one.substreams.size(), other.substreams.size());
48 for (std::map<uint32_t, StreamStats>::const_iterator it =
49 one.substreams.begin();
50 it != one.substreams.end();
51 ++it) {
52 std::map<uint32_t, StreamStats>::const_iterator corresponding_it =
53 other.substreams.find(it->first);
54 ASSERT_TRUE(corresponding_it != other.substreams.end());
55 const StreamStats& a = it->second;
56 const StreamStats& b = corresponding_it->second;
57
58 EXPECT_EQ(a.key_frames, b.key_frames);
59 EXPECT_EQ(a.delta_frames, b.delta_frames);
60 EXPECT_EQ(a.bitrate_bps, b.bitrate_bps);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000061 EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
62 EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
sprang@webrtc.org09315702014-02-07 12:06:29 +000063
64 EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
65 EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
66 EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
67 EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
68 EXPECT_EQ(a.rtp_stats.retransmitted_packets,
69 b.rtp_stats.retransmitted_packets);
70 EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
71
72 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
73 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
74 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
75 b.rtcp_stats.extended_max_sequence_number);
76 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
77 }
78 }
79
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000080 scoped_ptr<SendStatisticsProxy> statistics_proxy_;
81 VideoSendStream::Config config_;
82 int avg_delay_ms_;
83 int max_delay_ms_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000084 VideoSendStream::Stats expected_;
85 typedef std::map<uint32_t, StreamStats>::const_iterator StreamIterator;
86};
87
88TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
89 RtcpStatisticsCallback* callback = statistics_proxy_.get();
90 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
91 it != config_.rtp.ssrcs.end();
92 ++it) {
93 const uint32_t ssrc = *it;
94 StreamStats& ssrc_stats = expected_.substreams[ssrc];
95
96 // Add statistics with some arbitrary, but unique, numbers.
97 uint32_t offset = ssrc * sizeof(RtcpStatistics);
98 ssrc_stats.rtcp_stats.cumulative_lost = offset;
99 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
100 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
101 ssrc_stats.rtcp_stats.jitter = offset + 3;
102 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
103 }
104
105 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000106 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000107}
108
109TEST_F(SendStatisticsProxyTest, FrameRates) {
110 const int capture_fps = 31;
111 const int encode_fps = 29;
112
113 ViECaptureObserver* capture_observer = statistics_proxy_.get();
114 capture_observer->CapturedFrameRate(0, capture_fps);
115 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
116 encoder_observer->OutgoingRate(0, encode_fps, 0);
117
118 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
119 EXPECT_EQ(capture_fps, stats.input_frame_rate);
120 EXPECT_EQ(encode_fps, stats.encode_frame_rate);
121}
122
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000123TEST_F(SendStatisticsProxyTest, Suspended) {
124 // Verify that the value is false by default.
125 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
126
127 // Verify that we can set it to true.
128 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
129 encoder_observer->SuspendChange(0, true);
130 EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
131
132 // Verify that we can set it back to false again.
133 encoder_observer->SuspendChange(0, false);
134 EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
135}
136
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000137TEST_F(SendStatisticsProxyTest, FrameCounts) {
138 FrameCountObserver* observer = statistics_proxy_.get();
139 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
140 it != config_.rtp.ssrcs.end();
141 ++it) {
142 const uint32_t ssrc = *it;
143 // Add statistics with some arbitrary, but unique, numbers.
144 StreamStats& stats = expected_.substreams[ssrc];
145 uint32_t offset = ssrc * sizeof(StreamStats);
146 stats.key_frames = offset;
147 stats.delta_frames = offset + 1;
148 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
149 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
150 }
151
152 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000153 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000154}
155
156TEST_F(SendStatisticsProxyTest, DataCounters) {
157 StreamDataCountersCallback* callback = statistics_proxy_.get();
158 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
159 it != config_.rtp.ssrcs.end();
160 ++it) {
161 const uint32_t ssrc = *it;
162 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
163 // Add statistics with some arbitrary, but unique, numbers.
164 uint32_t offset = ssrc * sizeof(StreamDataCounters);
165 counters.bytes = offset;
166 counters.header_bytes = offset + 1;
167 counters.fec_packets = offset + 2;
168 counters.padding_bytes = offset + 3;
169 counters.retransmitted_packets = offset + 4;
170 counters.packets = offset + 5;
171 callback->DataCountersUpdated(counters, ssrc);
172 }
173
174 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000175 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000176}
177
178TEST_F(SendStatisticsProxyTest, Bitrate) {
179 BitrateStatisticsObserver* observer = statistics_proxy_.get();
180 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
181 it != config_.rtp.ssrcs.end();
182 ++it) {
183 const uint32_t ssrc = *it;
184 BitrateStatistics bitrate;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000185 // Use ssrc as bitrate_bps to get a unique value for each stream.
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000186 bitrate.bitrate_bps = ssrc;
187 observer->Notify(bitrate, ssrc);
188 expected_.substreams[ssrc].bitrate_bps = ssrc;
189 }
190
191 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
sprang@webrtc.org09315702014-02-07 12:06:29 +0000192 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000193}
194
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000195TEST_F(SendStatisticsProxyTest, SendSideDelay) {
196 SendSideDelayObserver* observer = statistics_proxy_.get();
197 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
198 it != config_.rtp.ssrcs.end();
199 ++it) {
200 const uint32_t ssrc = *it;
201 // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
202 // stream.
203 int avg_delay_ms = ssrc;
204 int max_delay_ms = ssrc + 1;
205 observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
206 expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
207 expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
208 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000209
210 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000211 ExpectEqual(expected_, stats);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000212}
213
214TEST_F(SendStatisticsProxyTest, NoSubstreams) {
215 uint32_t exluded_ssrc =
216 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()) + 1;
217 // From RtcpStatisticsCallback.
218 RtcpStatistics rtcp_stats;
219 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
220 rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc);
221
222 // From StreamDataCountersCallback.
223 StreamDataCounters rtp_stats;
224 StreamDataCountersCallback* rtp_callback = statistics_proxy_.get();
225 rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc);
226
227 // From BitrateStatisticsObserver.
228 BitrateStatistics bitrate;
229 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
230 bitrate_observer->Notify(bitrate, exluded_ssrc);
231
232 // From FrameCountObserver.
233 FrameCountObserver* fps_observer = statistics_proxy_.get();
234 fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
235
236 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
237 EXPECT_TRUE(stats.substreams.empty());
238}
239
240} // namespace webrtc