2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
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.
11 // This file includes unit tests for SendStatisticsProxy.
12 #include "webrtc/video/send_statistics_proxy.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 class SendStatisticsProxyTest : public ::testing::Test,
23 protected SendStatisticsProxy::StatsProvider {
25 SendStatisticsProxyTest() : avg_delay_ms_(0), max_delay_ms_(0) {}
26 virtual ~SendStatisticsProxyTest() {}
29 virtual void SetUp() {
30 statistics_proxy_.reset(
31 new SendStatisticsProxy(GetTestConfig(), this));
32 config_ = GetTestConfig();
33 expected_ = VideoSendStream::Stats();
36 VideoSendStream::Config GetTestConfig() {
37 VideoSendStream::Config config;
38 config.rtp.ssrcs.push_back(17);
39 config.rtp.ssrcs.push_back(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_;
49 virtual std::string GetCName() { return cname_; }
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.c_name, other.c_name);
59 EXPECT_EQ(one.substreams.size(), other.substreams.size());
60 for (std::map<uint32_t, StreamStats>::const_iterator it =
61 one.substreams.begin();
62 it != one.substreams.end();
64 std::map<uint32_t, StreamStats>::const_iterator corresponding_it =
65 other.substreams.find(it->first);
66 ASSERT_TRUE(corresponding_it != other.substreams.end());
67 const StreamStats& a = it->second;
68 const StreamStats& b = corresponding_it->second;
70 EXPECT_EQ(a.key_frames, b.key_frames);
71 EXPECT_EQ(a.delta_frames, b.delta_frames);
72 EXPECT_EQ(a.bitrate_bps, b.bitrate_bps);
74 EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
75 EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
76 EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
77 EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
78 EXPECT_EQ(a.rtp_stats.retransmitted_packets,
79 b.rtp_stats.retransmitted_packets);
80 EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
82 EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
83 EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
84 EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
85 b.rtcp_stats.extended_max_sequence_number);
86 EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
90 scoped_ptr<SendStatisticsProxy> statistics_proxy_;
91 VideoSendStream::Config config_;
95 VideoSendStream::Stats expected_;
96 typedef std::map<uint32_t, StreamStats>::const_iterator StreamIterator;
99 TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
100 RtcpStatisticsCallback* callback = statistics_proxy_.get();
101 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
102 it != config_.rtp.ssrcs.end();
104 const uint32_t ssrc = *it;
105 StreamStats& ssrc_stats = expected_.substreams[ssrc];
107 // Add statistics with some arbitrary, but unique, numbers.
108 uint32_t offset = ssrc * sizeof(RtcpStatistics);
109 ssrc_stats.rtcp_stats.cumulative_lost = offset;
110 ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
111 ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
112 ssrc_stats.rtcp_stats.jitter = offset + 3;
113 callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
116 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
117 ExpectEqual(expected_, stats);
120 TEST_F(SendStatisticsProxyTest, FrameRates) {
121 const int capture_fps = 31;
122 const int encode_fps = 29;
124 ViECaptureObserver* capture_observer = statistics_proxy_.get();
125 capture_observer->CapturedFrameRate(0, capture_fps);
126 ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
127 encoder_observer->OutgoingRate(0, encode_fps, 0);
129 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
130 EXPECT_EQ(capture_fps, stats.input_frame_rate);
131 EXPECT_EQ(encode_fps, stats.encode_frame_rate);
134 TEST_F(SendStatisticsProxyTest, FrameCounts) {
135 FrameCountObserver* observer = statistics_proxy_.get();
136 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
137 it != config_.rtp.ssrcs.end();
139 const uint32_t ssrc = *it;
140 // Add statistics with some arbitrary, but unique, numbers.
141 StreamStats& stats = expected_.substreams[ssrc];
142 uint32_t offset = ssrc * sizeof(StreamStats);
143 stats.key_frames = offset;
144 stats.delta_frames = offset + 1;
145 observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
146 observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
149 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
150 ExpectEqual(expected_, stats);
153 TEST_F(SendStatisticsProxyTest, DataCounters) {
154 StreamDataCountersCallback* callback = statistics_proxy_.get();
155 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
156 it != config_.rtp.ssrcs.end();
158 const uint32_t ssrc = *it;
159 StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
160 // Add statistics with some arbitrary, but unique, numbers.
161 uint32_t offset = ssrc * sizeof(StreamDataCounters);
162 counters.bytes = offset;
163 counters.header_bytes = offset + 1;
164 counters.fec_packets = offset + 2;
165 counters.padding_bytes = offset + 3;
166 counters.retransmitted_packets = offset + 4;
167 counters.packets = offset + 5;
168 callback->DataCountersUpdated(counters, ssrc);
171 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
172 ExpectEqual(expected_, stats);
175 TEST_F(SendStatisticsProxyTest, Bitrate) {
176 BitrateStatisticsObserver* observer = statistics_proxy_.get();
177 for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
178 it != config_.rtp.ssrcs.end();
180 const uint32_t ssrc = *it;
181 BitrateStatistics bitrate;
182 bitrate.bitrate_bps = ssrc;
183 observer->Notify(bitrate, ssrc);
184 expected_.substreams[ssrc].bitrate_bps = ssrc;
187 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
188 ExpectEqual(expected_, stats);
191 TEST_F(SendStatisticsProxyTest, StreamStats) {
194 cname_ = "qwertyuiop";
196 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
198 EXPECT_EQ(avg_delay_ms_, stats.avg_delay_ms);
199 EXPECT_EQ(max_delay_ms_, stats.max_delay_ms);
200 EXPECT_EQ(cname_, stats.c_name);
203 TEST_F(SendStatisticsProxyTest, NoSubstreams) {
204 uint32_t exluded_ssrc =
205 *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()) + 1;
206 // From RtcpStatisticsCallback.
207 RtcpStatistics rtcp_stats;
208 RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
209 rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc);
211 // From StreamDataCountersCallback.
212 StreamDataCounters rtp_stats;
213 StreamDataCountersCallback* rtp_callback = statistics_proxy_.get();
214 rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc);
216 // From BitrateStatisticsObserver.
217 BitrateStatistics bitrate;
218 BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
219 bitrate_observer->Notify(bitrate, exluded_ssrc);
221 // From FrameCountObserver.
222 FrameCountObserver* fps_observer = statistics_proxy_.get();
223 fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
225 VideoSendStream::Stats stats = statistics_proxy_->GetStats();
226 EXPECT_TRUE(stats.substreams.empty());
229 } // namespace webrtc