OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 <algorithm> | 11 #include <algorithm> |
12 #include <limits> | 12 #include <limits> |
13 #include <memory> | 13 #include <memory> |
14 #include <sstream> | 14 #include <sstream> |
15 #include <string> | 15 #include <string> |
16 | 16 |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/constructormagic.h" |
20 #include "webrtc/base/thread_annotations.h" | 21 #include "webrtc/base/thread_annotations.h" |
21 #include "webrtc/call.h" | 22 #include "webrtc/call.h" |
22 #include "webrtc/call/transport_adapter.h" | 23 #include "webrtc/call/transport_adapter.h" |
23 #include "webrtc/config.h" | 24 #include "webrtc/config.h" |
24 #include "webrtc/modules/audio_coding/include/audio_coding_module.h" | 25 #include "webrtc/modules/audio_coding/include/audio_coding_module.h" |
25 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 26 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
26 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 27 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
27 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 28 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
28 #include "webrtc/system_wrappers/include/rtp_to_ntp.h" | 29 #include "webrtc/system_wrappers/include/rtp_to_ntp.h" |
29 #include "webrtc/test/call_test.h" | 30 #include "webrtc/test/call_test.h" |
30 #include "webrtc/test/direct_transport.h" | 31 #include "webrtc/test/direct_transport.h" |
31 #include "webrtc/test/drifting_clock.h" | 32 #include "webrtc/test/drifting_clock.h" |
32 #include "webrtc/test/encoder_settings.h" | 33 #include "webrtc/test/encoder_settings.h" |
33 #include "webrtc/test/fake_audio_device.h" | 34 #include "webrtc/test/fake_audio_device.h" |
34 #include "webrtc/test/fake_decoder.h" | 35 #include "webrtc/test/fake_decoder.h" |
35 #include "webrtc/test/fake_encoder.h" | 36 #include "webrtc/test/fake_encoder.h" |
36 #include "webrtc/test/frame_generator.h" | 37 #include "webrtc/test/frame_generator.h" |
37 #include "webrtc/test/frame_generator_capturer.h" | 38 #include "webrtc/test/frame_generator_capturer.h" |
38 #include "webrtc/test/histogram.h" | 39 #include "webrtc/test/histogram.h" |
39 #include "webrtc/test/rtp_rtcp_observer.h" | 40 #include "webrtc/test/rtp_rtcp_observer.h" |
40 #include "webrtc/test/testsupport/fileutils.h" | 41 #include "webrtc/test/testsupport/fileutils.h" |
41 #include "webrtc/test/testsupport/perf_test.h" | 42 #include "webrtc/test/testsupport/perf_test.h" |
42 #include "webrtc/voice_engine/include/voe_base.h" | 43 #include "webrtc/voice_engine/include/voe_base.h" |
43 #include "webrtc/voice_engine/include/voe_codec.h" | 44 #include "webrtc/voice_engine/include/voe_codec.h" |
44 #include "webrtc/voice_engine/include/voe_network.h" | |
45 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | 45 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
46 #include "webrtc/voice_engine/include/voe_video_sync.h" | 46 #include "webrtc/voice_engine/include/voe_video_sync.h" |
47 | 47 |
48 using webrtc::test::DriftingClock; | 48 using webrtc::test::DriftingClock; |
49 using webrtc::test::FakeAudioDevice; | 49 using webrtc::test::FakeAudioDevice; |
50 | 50 |
51 namespace webrtc { | 51 namespace webrtc { |
52 | 52 |
53 class CallPerfTest : public test::CallTest { | 53 class CallPerfTest : public test::CallTest { |
54 protected: | 54 protected: |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 }; | 142 }; |
143 | 143 |
144 void CallPerfTest::TestAudioVideoSync(FecMode fec, | 144 void CallPerfTest::TestAudioVideoSync(FecMode fec, |
145 CreateOrder create_first, | 145 CreateOrder create_first, |
146 float video_ntp_speed, | 146 float video_ntp_speed, |
147 float video_rtp_speed, | 147 float video_rtp_speed, |
148 float audio_rtp_speed) { | 148 float audio_rtp_speed) { |
149 const char* kSyncGroup = "av_sync"; | 149 const char* kSyncGroup = "av_sync"; |
150 const uint32_t kAudioSendSsrc = 1234; | 150 const uint32_t kAudioSendSsrc = 1234; |
151 const uint32_t kAudioRecvSsrc = 5678; | 151 const uint32_t kAudioRecvSsrc = 5678; |
152 class AudioPacketReceiver : public PacketReceiver { | |
153 public: | |
154 AudioPacketReceiver(int channel, VoENetwork* voe_network) | |
155 : channel_(channel), | |
156 voe_network_(voe_network), | |
157 parser_(RtpHeaderParser::Create()) {} | |
158 DeliveryStatus DeliverPacket(MediaType media_type, | |
159 const uint8_t* packet, | |
160 size_t length, | |
161 const PacketTime& packet_time) override { | |
162 EXPECT_TRUE(media_type == MediaType::ANY || | |
163 media_type == MediaType::AUDIO); | |
164 int ret; | |
165 if (parser_->IsRtcp(packet, length)) { | |
166 ret = voe_network_->ReceivedRTCPPacket(channel_, packet, length); | |
167 } else { | |
168 ret = voe_network_->ReceivedRTPPacket(channel_, packet, length, | |
169 PacketTime()); | |
170 } | |
171 return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR; | |
172 } | |
173 | |
174 private: | |
175 int channel_; | |
176 VoENetwork* voe_network_; | |
177 std::unique_ptr<RtpHeaderParser> parser_; | |
178 }; | |
179 | 152 |
180 test::ClearHistograms(); | 153 test::ClearHistograms(); |
181 VoiceEngine* voice_engine = VoiceEngine::Create(); | 154 VoiceEngine* voice_engine = VoiceEngine::Create(); |
182 VoEBase* voe_base = VoEBase::GetInterface(voice_engine); | 155 VoEBase* voe_base = VoEBase::GetInterface(voice_engine); |
183 VoECodec* voe_codec = VoECodec::GetInterface(voice_engine); | 156 VoECodec* voe_codec = VoECodec::GetInterface(voice_engine); |
184 VoENetwork* voe_network = VoENetwork::GetInterface(voice_engine); | |
185 const std::string audio_filename = | 157 const std::string audio_filename = |
186 test::ResourcePath("voice_engine/audio_long16", "pcm"); | 158 test::ResourcePath("voice_engine/audio_long16", "pcm"); |
187 ASSERT_STRNE("", audio_filename.c_str()); | 159 ASSERT_STRNE("", audio_filename.c_str()); |
188 FakeAudioDevice fake_audio_device(Clock::GetRealTimeClock(), audio_filename, | 160 FakeAudioDevice fake_audio_device(Clock::GetRealTimeClock(), audio_filename, |
189 audio_rtp_speed); | 161 audio_rtp_speed); |
190 EXPECT_EQ(0, voe_base->Init(&fake_audio_device, nullptr)); | 162 EXPECT_EQ(0, voe_base->Init(&fake_audio_device, nullptr)); |
191 Config voe_config; | 163 Config voe_config; |
192 voe_config.Set<VoicePacing>(new VoicePacing(true)); | 164 voe_config.Set<VoicePacing>(new VoicePacing(true)); |
193 int send_channel_id = voe_base->CreateChannel(voe_config); | 165 int send_channel_id = voe_base->CreateChannel(voe_config); |
194 int recv_channel_id = voe_base->CreateChannel(); | 166 int recv_channel_id = voe_base->CreateChannel(); |
195 | 167 |
196 AudioState::Config send_audio_state_config; | 168 AudioState::Config send_audio_state_config; |
197 send_audio_state_config.voice_engine = voice_engine; | 169 send_audio_state_config.voice_engine = voice_engine; |
198 Call::Config sender_config; | 170 Call::Config sender_config; |
199 sender_config.audio_state = AudioState::Create(send_audio_state_config); | 171 sender_config.audio_state = AudioState::Create(send_audio_state_config); |
200 Call::Config receiver_config; | 172 Call::Config receiver_config; |
201 receiver_config.audio_state = sender_config.audio_state; | 173 receiver_config.audio_state = sender_config.audio_state; |
202 CreateCalls(sender_config, receiver_config); | 174 CreateCalls(sender_config, receiver_config); |
203 | 175 |
204 AudioPacketReceiver voe_send_packet_receiver(send_channel_id, voe_network); | |
205 AudioPacketReceiver voe_recv_packet_receiver(recv_channel_id, voe_network); | |
206 | 176 |
207 VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock()); | 177 VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock()); |
208 | 178 |
209 FakeNetworkPipe::Config net_config; | 179 // Helper class to ensure we deliver correct media_type to the receiving call. |
210 net_config.queue_delay_ms = 500; | 180 class MediaTypePacketReceiver : public PacketReceiver { |
211 net_config.loss_percent = 5; | 181 public: |
212 test::PacketTransport audio_send_transport( | 182 MediaTypePacketReceiver(PacketReceiver* packet_receiver, |
213 nullptr, &observer, test::PacketTransport::kSender, net_config); | 183 MediaType media_type) |
214 audio_send_transport.SetReceiver(&voe_recv_packet_receiver); | 184 : packet_receiver_(packet_receiver), media_type_(media_type) {} |
215 test::PacketTransport audio_receive_transport( | |
216 nullptr, &observer, test::PacketTransport::kReceiver, net_config); | |
217 audio_receive_transport.SetReceiver(&voe_send_packet_receiver); | |
218 | 185 |
219 internal::TransportAdapter send_transport_adapter(&audio_send_transport); | 186 DeliveryStatus DeliverPacket(MediaType media_type, |
220 send_transport_adapter.Enable(); | 187 const uint8_t* packet, |
221 EXPECT_EQ(0, voe_network->RegisterExternalTransport(send_channel_id, | 188 size_t length, |
222 send_transport_adapter)); | 189 const PacketTime& packet_time) override { |
| 190 return packet_receiver_->DeliverPacket(media_type_, packet, length, |
| 191 packet_time); |
| 192 } |
| 193 private: |
| 194 PacketReceiver* packet_receiver_; |
| 195 const MediaType media_type_; |
223 | 196 |
224 internal::TransportAdapter recv_transport_adapter(&audio_receive_transport); | 197 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MediaTypePacketReceiver); |
225 recv_transport_adapter.Enable(); | 198 }; |
226 EXPECT_EQ(0, voe_network->RegisterExternalTransport(recv_channel_id, | |
227 recv_transport_adapter)); | |
228 | 199 |
229 test::PacketTransport sync_send_transport(sender_call_.get(), &observer, | 200 FakeNetworkPipe::Config audio_net_config; |
230 test::PacketTransport::kSender, | 201 audio_net_config.queue_delay_ms = 500; |
231 FakeNetworkPipe::Config()); | 202 audio_net_config.loss_percent = 5; |
232 sync_send_transport.SetReceiver(receiver_call_->Receiver()); | 203 test::PacketTransport audio_send_transport(sender_call_.get(), &observer, |
233 test::PacketTransport sync_receive_transport(receiver_call_.get(), &observer, | 204 test::PacketTransport::kSender, |
234 test::PacketTransport::kReceiver, | 205 audio_net_config); |
235 FakeNetworkPipe::Config()); | 206 MediaTypePacketReceiver audio_receiver(receiver_call_->Receiver(), |
236 sync_receive_transport.SetReceiver(sender_call_->Receiver()); | 207 MediaType::AUDIO); |
| 208 audio_send_transport.SetReceiver(&audio_receiver); |
| 209 |
| 210 test::PacketTransport video_send_transport(sender_call_.get(), &observer, |
| 211 test::PacketTransport::kSender, |
| 212 FakeNetworkPipe::Config()); |
| 213 MediaTypePacketReceiver video_receiver(receiver_call_->Receiver(), |
| 214 MediaType::VIDEO); |
| 215 video_send_transport.SetReceiver(&video_receiver); |
| 216 |
| 217 test::PacketTransport receive_transport( |
| 218 receiver_call_.get(), &observer, test::PacketTransport::kReceiver, |
| 219 FakeNetworkPipe::Config()); |
| 220 receive_transport.SetReceiver(sender_call_->Receiver()); |
237 | 221 |
238 test::FakeDecoder fake_decoder; | 222 test::FakeDecoder fake_decoder; |
239 | 223 |
240 CreateSendConfig(1, 0, &sync_send_transport); | 224 CreateSendConfig(1, 0, &video_send_transport); |
241 CreateMatchingReceiveConfigs(&sync_receive_transport); | 225 CreateMatchingReceiveConfigs(&receive_transport); |
242 | 226 |
243 AudioSendStream::Config audio_send_config(&audio_send_transport); | 227 AudioSendStream::Config audio_send_config(&audio_send_transport); |
244 audio_send_config.voe_channel_id = send_channel_id; | 228 audio_send_config.voe_channel_id = send_channel_id; |
245 audio_send_config.rtp.ssrc = kAudioSendSsrc; | 229 audio_send_config.rtp.ssrc = kAudioSendSsrc; |
246 AudioSendStream* audio_send_stream = | 230 AudioSendStream* audio_send_stream = |
247 sender_call_->CreateAudioSendStream(audio_send_config); | 231 sender_call_->CreateAudioSendStream(audio_send_config); |
248 | 232 |
249 CodecInst isac = {103, "ISAC", 16000, 480, 1, 32000}; | 233 CodecInst isac = {103, "ISAC", 16000, 480, 1, 32000}; |
250 EXPECT_EQ(0, voe_codec->SetSendCodec(send_channel_id, isac)); | 234 EXPECT_EQ(0, voe_codec->SetSendCodec(send_channel_id, isac)); |
251 | 235 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 275 |
292 EXPECT_TRUE(observer.Wait()) | 276 EXPECT_TRUE(observer.Wait()) |
293 << "Timed out while waiting for audio and video to be synchronized."; | 277 << "Timed out while waiting for audio and video to be synchronized."; |
294 | 278 |
295 EXPECT_EQ(0, voe_base->StopSend(send_channel_id)); | 279 EXPECT_EQ(0, voe_base->StopSend(send_channel_id)); |
296 EXPECT_EQ(0, voe_base->StopReceive(recv_channel_id)); | 280 EXPECT_EQ(0, voe_base->StopReceive(recv_channel_id)); |
297 EXPECT_EQ(0, voe_base->StopPlayout(recv_channel_id)); | 281 EXPECT_EQ(0, voe_base->StopPlayout(recv_channel_id)); |
298 fake_audio_device.Stop(); | 282 fake_audio_device.Stop(); |
299 | 283 |
300 Stop(); | 284 Stop(); |
301 sync_send_transport.StopSending(); | 285 video_send_transport.StopSending(); |
302 sync_receive_transport.StopSending(); | |
303 audio_send_transport.StopSending(); | 286 audio_send_transport.StopSending(); |
304 audio_receive_transport.StopSending(); | 287 receive_transport.StopSending(); |
305 | 288 |
306 DestroyStreams(); | 289 DestroyStreams(); |
307 | 290 |
308 sender_call_->DestroyAudioSendStream(audio_send_stream); | 291 sender_call_->DestroyAudioSendStream(audio_send_stream); |
309 receiver_call_->DestroyAudioReceiveStream(audio_receive_stream); | 292 receiver_call_->DestroyAudioReceiveStream(audio_receive_stream); |
310 | 293 |
311 voe_base->DeleteChannel(send_channel_id); | 294 voe_base->DeleteChannel(send_channel_id); |
312 voe_base->DeleteChannel(recv_channel_id); | 295 voe_base->DeleteChannel(recv_channel_id); |
313 voe_base->Release(); | 296 voe_base->Release(); |
314 voe_codec->Release(); | 297 voe_codec->Release(); |
315 voe_network->Release(); | |
316 | 298 |
317 DestroyCalls(); | 299 DestroyCalls(); |
318 | 300 |
319 VoiceEngine::Delete(voice_engine); | 301 VoiceEngine::Delete(voice_engine); |
320 | 302 |
321 EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.AVSyncOffsetInMs")); | 303 EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.AVSyncOffsetInMs")); |
322 } | 304 } |
323 | 305 |
324 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoNtpDrift) { | 306 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoNtpDrift) { |
325 TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst, | 307 TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst, |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 int encoder_inits_; | 693 int encoder_inits_; |
712 uint32_t last_set_bitrate_; | 694 uint32_t last_set_bitrate_; |
713 VideoSendStream* send_stream_; | 695 VideoSendStream* send_stream_; |
714 VideoEncoderConfig encoder_config_; | 696 VideoEncoderConfig encoder_config_; |
715 } test; | 697 } test; |
716 | 698 |
717 RunBaseTest(&test); | 699 RunBaseTest(&test); |
718 } | 700 } |
719 | 701 |
720 } // namespace webrtc | 702 } // namespace webrtc |
OLD | NEW |