OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 | 15 |
16 #include "webrtc/audio/audio_send_stream.h" | 16 #include "webrtc/audio/audio_send_stream.h" |
17 #include "webrtc/audio/audio_state.h" | 17 #include "webrtc/audio/audio_state.h" |
18 #include "webrtc/audio/conversion.h" | 18 #include "webrtc/audio/conversion.h" |
| 19 #include "webrtc/call/congestion_controller.h" |
| 20 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |
| 21 #include "webrtc/modules/pacing/paced_sender.h" |
19 #include "webrtc/test/mock_voe_channel_proxy.h" | 22 #include "webrtc/test/mock_voe_channel_proxy.h" |
20 #include "webrtc/test/mock_voice_engine.h" | 23 #include "webrtc/test/mock_voice_engine.h" |
| 24 #include "webrtc/video_engine/call_stats.h" |
21 | 25 |
22 namespace webrtc { | 26 namespace webrtc { |
23 namespace test { | 27 namespace test { |
24 namespace { | 28 namespace { |
25 | 29 |
26 using testing::_; | 30 using testing::_; |
27 using testing::Return; | 31 using testing::Return; |
28 | 32 |
29 const int kChannelId = 1; | 33 const int kChannelId = 1; |
30 const uint32_t kSsrc = 1234; | 34 const uint32_t kSsrc = 1234; |
31 const char* kCName = "foo_name"; | 35 const char* kCName = "foo_name"; |
32 const int kAudioLevelId = 2; | 36 const int kAudioLevelId = 2; |
33 const int kAbsSendTimeId = 3; | 37 const int kAbsSendTimeId = 3; |
| 38 const int kTransportSequenceNumberId = 4; |
34 const int kEchoDelayMedian = 254; | 39 const int kEchoDelayMedian = 254; |
35 const int kEchoDelayStdDev = -3; | 40 const int kEchoDelayStdDev = -3; |
36 const int kEchoReturnLoss = -65; | 41 const int kEchoReturnLoss = -65; |
37 const int kEchoReturnLossEnhancement = 101; | 42 const int kEchoReturnLossEnhancement = 101; |
38 const unsigned int kSpeechInputLevel = 96; | 43 const unsigned int kSpeechInputLevel = 96; |
39 const CallStatistics kCallStats = { | 44 const CallStatistics kCallStats = { |
40 1345, 1678, 1901, 1234, 112, 13456, 17890, 1567, -1890, -1123}; | 45 1345, 1678, 1901, 1234, 112, 13456, 17890, 1567, -1890, -1123}; |
41 const CodecInst kCodecInst = {-121, "codec_name_send", 48000, -231, -451, -671}; | 46 const CodecInst kCodecInst = {-121, "codec_name_send", 48000, -231, -451, -671}; |
42 const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354}; | 47 const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354}; |
43 | 48 |
44 struct ConfigHelper { | 49 struct ConfigHelper { |
45 ConfigHelper() : stream_config_(nullptr) { | 50 ConfigHelper() |
| 51 : stream_config_(nullptr), |
| 52 process_thread_(ProcessThread::Create("AudioTestThread")), |
| 53 congestion_controller_(process_thread_.get(), |
| 54 &call_stats_, |
| 55 &bitrate_observer_) { |
46 using testing::Invoke; | 56 using testing::Invoke; |
47 using testing::StrEq; | 57 using testing::StrEq; |
48 | 58 |
49 EXPECT_CALL(voice_engine_, | 59 EXPECT_CALL(voice_engine_, |
50 RegisterVoiceEngineObserver(_)).WillOnce(Return(0)); | 60 RegisterVoiceEngineObserver(_)).WillOnce(Return(0)); |
51 EXPECT_CALL(voice_engine_, | 61 EXPECT_CALL(voice_engine_, |
52 DeRegisterVoiceEngineObserver()).WillOnce(Return(0)); | 62 DeRegisterVoiceEngineObserver()).WillOnce(Return(0)); |
53 AudioState::Config config; | 63 AudioState::Config config; |
54 config.voice_engine = &voice_engine_; | 64 config.voice_engine = &voice_engine_; |
55 audio_state_ = AudioState::Create(config); | 65 audio_state_ = AudioState::Create(config); |
56 | 66 |
57 EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId)) | 67 EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId)) |
58 .WillOnce(Invoke([this](int channel_id) { | 68 .WillOnce(Invoke([this](int channel_id) { |
59 EXPECT_FALSE(channel_proxy_); | 69 EXPECT_FALSE(channel_proxy_); |
60 channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>(); | 70 channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>(); |
61 EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1); | 71 EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1); |
62 EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1); | 72 EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1); |
63 EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1); | 73 EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1); |
64 EXPECT_CALL(*channel_proxy_, | 74 EXPECT_CALL(*channel_proxy_, |
65 SetSendAbsoluteSenderTimeStatus(true, kAbsSendTimeId)).Times(1); | 75 SetSendAbsoluteSenderTimeStatus(true, kAbsSendTimeId)).Times(1); |
66 EXPECT_CALL(*channel_proxy_, | 76 EXPECT_CALL(*channel_proxy_, |
67 SetSendAudioLevelIndicationStatus(true, kAudioLevelId)).Times(1); | 77 SetSendAudioLevelIndicationStatus(true, kAudioLevelId)).Times(1); |
| 78 EXPECT_CALL(*channel_proxy_, EnableSendTransportSequenceNumber( |
| 79 kTransportSequenceNumberId)) |
| 80 .Times(1); |
| 81 EXPECT_CALL(*channel_proxy_, |
| 82 SetCongestionControlObjects( |
| 83 congestion_controller_.pacer(), |
| 84 congestion_controller_.GetTransportFeedbackObserver(), |
| 85 congestion_controller_.packet_router())) |
| 86 .Times(1); |
| 87 EXPECT_CALL(*channel_proxy_, |
| 88 SetCongestionControlObjects(nullptr, nullptr, nullptr)) |
| 89 .Times(1); |
68 return channel_proxy_; | 90 return channel_proxy_; |
69 })); | 91 })); |
70 stream_config_.voe_channel_id = kChannelId; | 92 stream_config_.voe_channel_id = kChannelId; |
71 stream_config_.rtp.ssrc = kSsrc; | 93 stream_config_.rtp.ssrc = kSsrc; |
72 stream_config_.rtp.c_name = kCName; | 94 stream_config_.rtp.c_name = kCName; |
73 stream_config_.rtp.extensions.push_back( | 95 stream_config_.rtp.extensions.push_back( |
74 RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId)); | 96 RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId)); |
75 stream_config_.rtp.extensions.push_back( | 97 stream_config_.rtp.extensions.push_back( |
76 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId)); | 98 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId)); |
| 99 stream_config_.rtp.extensions.push_back(RtpExtension( |
| 100 RtpExtension::kTransportSequenceNumber, kTransportSequenceNumberId)); |
77 } | 101 } |
78 | 102 |
79 AudioSendStream::Config& config() { return stream_config_; } | 103 AudioSendStream::Config& config() { return stream_config_; } |
80 rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; } | 104 rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; } |
| 105 CongestionController* congestion_controller() { |
| 106 return &congestion_controller_; |
| 107 } |
81 | 108 |
82 void SetupMockForGetStats() { | 109 void SetupMockForGetStats() { |
83 using testing::DoAll; | 110 using testing::DoAll; |
84 using testing::SetArgReferee; | 111 using testing::SetArgReferee; |
85 | 112 |
86 std::vector<ReportBlock> report_blocks; | 113 std::vector<ReportBlock> report_blocks; |
87 webrtc::ReportBlock block = kReportBlock; | 114 webrtc::ReportBlock block = kReportBlock; |
88 report_blocks.push_back(block); // Has wrong SSRC. | 115 report_blocks.push_back(block); // Has wrong SSRC. |
89 block.source_SSRC = kSsrc; | 116 block.source_SSRC = kSsrc; |
90 report_blocks.push_back(block); // Correct block. | 117 report_blocks.push_back(block); // Correct block. |
(...skipping 15 matching lines...) Expand all Loading... |
106 EXPECT_CALL(voice_engine_, GetEchoMetrics(_, _, _, _)) | 133 EXPECT_CALL(voice_engine_, GetEchoMetrics(_, _, _, _)) |
107 .WillRepeatedly(DoAll(SetArgReferee<0>(kEchoReturnLoss), | 134 .WillRepeatedly(DoAll(SetArgReferee<0>(kEchoReturnLoss), |
108 SetArgReferee<1>(kEchoReturnLossEnhancement), | 135 SetArgReferee<1>(kEchoReturnLossEnhancement), |
109 Return(0))); | 136 Return(0))); |
110 EXPECT_CALL(voice_engine_, GetEcDelayMetrics(_, _, _)) | 137 EXPECT_CALL(voice_engine_, GetEcDelayMetrics(_, _, _)) |
111 .WillRepeatedly(DoAll(SetArgReferee<0>(kEchoDelayMedian), | 138 .WillRepeatedly(DoAll(SetArgReferee<0>(kEchoDelayMedian), |
112 SetArgReferee<1>(kEchoDelayStdDev), Return(0))); | 139 SetArgReferee<1>(kEchoDelayStdDev), Return(0))); |
113 } | 140 } |
114 | 141 |
115 private: | 142 private: |
| 143 class NullBitrateObserver : public BitrateObserver { |
| 144 public: |
| 145 virtual void OnNetworkChanged(uint32_t bitrate_bps, |
| 146 uint8_t fraction_loss, |
| 147 int64_t rtt_ms) {} |
| 148 }; |
| 149 |
116 testing::StrictMock<MockVoiceEngine> voice_engine_; | 150 testing::StrictMock<MockVoiceEngine> voice_engine_; |
117 rtc::scoped_refptr<AudioState> audio_state_; | 151 rtc::scoped_refptr<AudioState> audio_state_; |
118 AudioSendStream::Config stream_config_; | 152 AudioSendStream::Config stream_config_; |
119 testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr; | 153 testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr; |
| 154 CallStats call_stats_; |
| 155 NullBitrateObserver bitrate_observer_; |
| 156 rtc::scoped_ptr<ProcessThread> process_thread_; |
| 157 CongestionController congestion_controller_; |
120 }; | 158 }; |
121 } // namespace | 159 } // namespace |
122 | 160 |
123 TEST(AudioSendStreamTest, ConfigToString) { | 161 TEST(AudioSendStreamTest, ConfigToString) { |
124 AudioSendStream::Config config(nullptr); | 162 AudioSendStream::Config config(nullptr); |
125 config.rtp.ssrc = kSsrc; | 163 config.rtp.ssrc = kSsrc; |
126 config.rtp.extensions.push_back( | 164 config.rtp.extensions.push_back( |
127 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId)); | 165 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId)); |
128 config.rtp.c_name = kCName; | 166 config.rtp.c_name = kCName; |
129 config.voe_channel_id = kChannelId; | 167 config.voe_channel_id = kChannelId; |
130 config.cng_payload_type = 42; | 168 config.cng_payload_type = 42; |
131 config.red_payload_type = 17; | 169 config.red_payload_type = 17; |
132 EXPECT_EQ( | 170 EXPECT_EQ( |
133 "{rtp: {ssrc: 1234, extensions: [{name: " | 171 "{rtp: {ssrc: 1234, extensions: [{name: " |
134 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, id: 3}], " | 172 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, id: 3}], " |
135 "c_name: foo_name}, voe_channel_id: 1, cng_payload_type: 42, " | 173 "c_name: foo_name}, voe_channel_id: 1, cng_payload_type: 42, " |
136 "red_payload_type: 17}", | 174 "red_payload_type: 17}", |
137 config.ToString()); | 175 config.ToString()); |
138 } | 176 } |
139 | 177 |
140 TEST(AudioSendStreamTest, ConstructDestruct) { | 178 TEST(AudioSendStreamTest, ConstructDestruct) { |
141 ConfigHelper helper; | 179 ConfigHelper helper; |
142 internal::AudioSendStream send_stream(helper.config(), helper.audio_state()); | 180 internal::AudioSendStream send_stream(helper.config(), helper.audio_state(), |
| 181 helper.congestion_controller()); |
143 } | 182 } |
144 | 183 |
145 TEST(AudioSendStreamTest, GetStats) { | 184 TEST(AudioSendStreamTest, GetStats) { |
146 ConfigHelper helper; | 185 ConfigHelper helper; |
147 internal::AudioSendStream send_stream(helper.config(), helper.audio_state()); | 186 internal::AudioSendStream send_stream(helper.config(), helper.audio_state(), |
| 187 helper.congestion_controller()); |
148 helper.SetupMockForGetStats(); | 188 helper.SetupMockForGetStats(); |
149 AudioSendStream::Stats stats = send_stream.GetStats(); | 189 AudioSendStream::Stats stats = send_stream.GetStats(); |
150 EXPECT_EQ(kSsrc, stats.local_ssrc); | 190 EXPECT_EQ(kSsrc, stats.local_ssrc); |
151 EXPECT_EQ(static_cast<int64_t>(kCallStats.bytesSent), stats.bytes_sent); | 191 EXPECT_EQ(static_cast<int64_t>(kCallStats.bytesSent), stats.bytes_sent); |
152 EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent); | 192 EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent); |
153 EXPECT_EQ(static_cast<int32_t>(kReportBlock.cumulative_num_packets_lost), | 193 EXPECT_EQ(static_cast<int32_t>(kReportBlock.cumulative_num_packets_lost), |
154 stats.packets_lost); | 194 stats.packets_lost); |
155 EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost); | 195 EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost); |
156 EXPECT_EQ(std::string(kCodecInst.plname), stats.codec_name); | 196 EXPECT_EQ(std::string(kCodecInst.plname), stats.codec_name); |
157 EXPECT_EQ(static_cast<int32_t>(kReportBlock.extended_highest_sequence_number), | 197 EXPECT_EQ(static_cast<int32_t>(kReportBlock.extended_highest_sequence_number), |
158 stats.ext_seqnum); | 198 stats.ext_seqnum); |
159 EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter / | 199 EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter / |
160 (kCodecInst.plfreq / 1000)), | 200 (kCodecInst.plfreq / 1000)), |
161 stats.jitter_ms); | 201 stats.jitter_ms); |
162 EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms); | 202 EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms); |
163 EXPECT_EQ(static_cast<int32_t>(kSpeechInputLevel), stats.audio_level); | 203 EXPECT_EQ(static_cast<int32_t>(kSpeechInputLevel), stats.audio_level); |
164 EXPECT_EQ(-1, stats.aec_quality_min); | 204 EXPECT_EQ(-1, stats.aec_quality_min); |
165 EXPECT_EQ(kEchoDelayMedian, stats.echo_delay_median_ms); | 205 EXPECT_EQ(kEchoDelayMedian, stats.echo_delay_median_ms); |
166 EXPECT_EQ(kEchoDelayStdDev, stats.echo_delay_std_ms); | 206 EXPECT_EQ(kEchoDelayStdDev, stats.echo_delay_std_ms); |
167 EXPECT_EQ(kEchoReturnLoss, stats.echo_return_loss); | 207 EXPECT_EQ(kEchoReturnLoss, stats.echo_return_loss); |
168 EXPECT_EQ(kEchoReturnLossEnhancement, stats.echo_return_loss_enhancement); | 208 EXPECT_EQ(kEchoReturnLossEnhancement, stats.echo_return_loss_enhancement); |
169 EXPECT_FALSE(stats.typing_noise_detected); | 209 EXPECT_FALSE(stats.typing_noise_detected); |
170 } | 210 } |
171 | 211 |
172 TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { | 212 TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { |
173 ConfigHelper helper; | 213 ConfigHelper helper; |
174 internal::AudioSendStream send_stream(helper.config(), helper.audio_state()); | 214 internal::AudioSendStream send_stream(helper.config(), helper.audio_state(), |
| 215 helper.congestion_controller()); |
175 helper.SetupMockForGetStats(); | 216 helper.SetupMockForGetStats(); |
176 EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); | 217 EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); |
177 | 218 |
178 internal::AudioState* internal_audio_state = | 219 internal::AudioState* internal_audio_state = |
179 static_cast<internal::AudioState*>(helper.audio_state().get()); | 220 static_cast<internal::AudioState*>(helper.audio_state().get()); |
180 VoiceEngineObserver* voe_observer = | 221 VoiceEngineObserver* voe_observer = |
181 static_cast<VoiceEngineObserver*>(internal_audio_state); | 222 static_cast<VoiceEngineObserver*>(internal_audio_state); |
182 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING); | 223 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING); |
183 EXPECT_TRUE(send_stream.GetStats().typing_noise_detected); | 224 EXPECT_TRUE(send_stream.GetStats().typing_noise_detected); |
184 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING); | 225 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING); |
185 EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); | 226 EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); |
186 } | 227 } |
187 } // namespace test | 228 } // namespace test |
188 } // namespace webrtc | 229 } // namespace webrtc |
OLD | NEW |