blob: 8f35ee4d03d7d53e483daed0e704be705593ad17 [file] [log] [blame]
sprang@webrtc.org49812e62014-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
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +000022class SendStatisticsProxyTest : public ::testing::Test,
23 protected SendStatisticsProxy::StatsProvider {
sprang@webrtc.org49812e62014-01-07 09:54:34 +000024 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
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +000051 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);
henrik.lundin@webrtc.org9376c692014-03-13 13:31:21 +000057 EXPECT_EQ(one.suspended, other.suspended);
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +000058 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
sprang@webrtc.org49812e62014-01-07 09:54:34 +000091 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
100TEST_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();
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +0000118 ExpectEqual(expected_, stats);
sprang@webrtc.org49812e62014-01-07 09:54:34 +0000119}
120
121TEST_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
henrik.lundin@webrtc.org9376c692014-03-13 13:31:21 +0000135TEST_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
sprang@webrtc.org49812e62014-01-07 09:54:34 +0000149TEST_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();
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +0000165 ExpectEqual(expected_, stats);
sprang@webrtc.org49812e62014-01-07 09:54:34 +0000166}
167
168TEST_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();
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +0000187 ExpectEqual(expected_, stats);
sprang@webrtc.org49812e62014-01-07 09:54:34 +0000188}
189
190TEST_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();
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +0000203 ExpectEqual(expected_, stats);
sprang@webrtc.org49812e62014-01-07 09:54:34 +0000204}
205
206TEST_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
218TEST_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