1 /*
2 * Copyright (c) 2019 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 #include "test/peer_scenario/peer_scenario_client.h"
11
12 #include <limits>
13 #include <memory>
14 #include <utility>
15
16 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
17 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
18 #include "api/rtc_event_log/rtc_event_log_factory.h"
19 #include "api/task_queue/default_task_queue_factory.h"
20 #include "api/test/create_time_controller.h"
21 #include "api/transport/field_trial_based_config.h"
22 #include "api/video_codecs/builtin_video_decoder_factory.h"
23 #include "api/video_codecs/builtin_video_encoder_factory.h"
24 #include "media/engine/webrtc_media_engine.h"
25 #include "modules/audio_device/include/test_audio_device.h"
26 #include "p2p/client/basic_port_allocator.h"
27 #include "test/fake_decoder.h"
28 #include "test/fake_vp8_encoder.h"
29 #include "test/frame_generator_capturer.h"
30 #include "test/peer_scenario/sdp_callbacks.h"
31
32 namespace webrtc {
33 namespace test {
34
35 namespace {
36
37 constexpr char kCommonStreamId[] = "stream_id";
38
CreateEndpoints(NetworkEmulationManager * net,std::map<int,EmulatedEndpointConfig> endpoint_configs)39 std::map<int, EmulatedEndpoint*> CreateEndpoints(
40 NetworkEmulationManager* net,
41 std::map<int, EmulatedEndpointConfig> endpoint_configs) {
42 std::map<int, EmulatedEndpoint*> endpoints;
43 for (const auto& kv : endpoint_configs)
44 endpoints[kv.first] = net->CreateEndpoint(kv.second);
45 return endpoints;
46 }
47
48 class LambdaPeerConnectionObserver final : public PeerConnectionObserver {
49 public:
LambdaPeerConnectionObserver(PeerScenarioClient::CallbackHandlers * handlers)50 explicit LambdaPeerConnectionObserver(
51 PeerScenarioClient::CallbackHandlers* handlers)
52 : handlers_(handlers) {}
OnSignalingChange(PeerConnectionInterface::SignalingState new_state)53 void OnSignalingChange(
54 PeerConnectionInterface::SignalingState new_state) override {
55 for (const auto& handler : handlers_->on_signaling_change)
56 handler(new_state);
57 }
OnDataChannel(rtc::scoped_refptr<DataChannelInterface> data_channel)58 void OnDataChannel(
59 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
60 for (const auto& handler : handlers_->on_data_channel)
61 handler(data_channel);
62 }
OnRenegotiationNeeded()63 void OnRenegotiationNeeded() override {
64 for (const auto& handler : handlers_->on_renegotiation_needed)
65 handler();
66 }
OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)67 void OnStandardizedIceConnectionChange(
68 PeerConnectionInterface::IceConnectionState new_state) override {
69 for (const auto& handler : handlers_->on_standardized_ice_connection_change)
70 handler(new_state);
71 }
OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state)72 void OnConnectionChange(
73 PeerConnectionInterface::PeerConnectionState new_state) override {
74 for (const auto& handler : handlers_->on_connection_change)
75 handler(new_state);
76 }
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)77 void OnIceGatheringChange(
78 PeerConnectionInterface::IceGatheringState new_state) override {
79 for (const auto& handler : handlers_->on_ice_gathering_change)
80 handler(new_state);
81 }
OnIceCandidate(const IceCandidateInterface * candidate)82 void OnIceCandidate(const IceCandidateInterface* candidate) override {
83 for (const auto& handler : handlers_->on_ice_candidate)
84 handler(candidate);
85 }
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)86 void OnIceCandidateError(const std::string& address,
87 int port,
88 const std::string& url,
89 int error_code,
90 const std::string& error_text) override {
91 for (const auto& handler : handlers_->on_ice_candidate_error)
92 handler(address, port, url, error_code, error_text);
93 }
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)94 void OnIceCandidatesRemoved(
95 const std::vector<cricket::Candidate>& candidates) override {
96 for (const auto& handler : handlers_->on_ice_candidates_removed)
97 handler(candidates);
98 }
OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)99 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
100 const std::vector<rtc::scoped_refptr<MediaStreamInterface> >&
101 streams) override {
102 for (const auto& handler : handlers_->on_add_track)
103 handler(receiver, streams);
104 }
OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver)105 void OnTrack(
106 rtc::scoped_refptr<RtpTransceiverInterface> transceiver) override {
107 for (const auto& handler : handlers_->on_track)
108 handler(transceiver);
109 }
OnRemoveTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver)110 void OnRemoveTrack(
111 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
112 for (const auto& handler : handlers_->on_remove_track)
113 handler(receiver);
114 }
115
116 private:
117 PeerScenarioClient::CallbackHandlers* handlers_;
118 };
119
120 class FakeVideoEncoderFactory : public VideoEncoderFactory {
121 public:
FakeVideoEncoderFactory(Clock * clock)122 FakeVideoEncoderFactory(Clock* clock) : clock_(clock) {}
GetSupportedFormats() const123 std::vector<SdpVideoFormat> GetSupportedFormats() const override {
124 return {SdpVideoFormat("VP8")};
125 }
QueryVideoEncoder(const SdpVideoFormat & format) const126 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override {
127 RTC_CHECK_EQ(format.name, "VP8");
128 CodecInfo info;
129 return info;
130 }
CreateVideoEncoder(const SdpVideoFormat & format)131 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
132 const SdpVideoFormat& format) override {
133 return std::make_unique<FakeVp8Encoder>(clock_);
134 }
135
136 private:
137 Clock* const clock_;
138 };
139 class FakeVideoDecoderFactory : public VideoDecoderFactory {
140 public:
GetSupportedFormats() const141 std::vector<SdpVideoFormat> GetSupportedFormats() const override {
142 return {SdpVideoFormat("VP8")};
143 }
CreateVideoDecoder(const SdpVideoFormat & format)144 std::unique_ptr<VideoDecoder> CreateVideoDecoder(
145 const SdpVideoFormat& format) override {
146 return std::make_unique<FakeDecoder>();
147 }
148 };
149 } // namespace
150
PeerScenarioClient(NetworkEmulationManager * net,rtc::Thread * signaling_thread,std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,PeerScenarioClient::Config config)151 PeerScenarioClient::PeerScenarioClient(
152 NetworkEmulationManager* net,
153 rtc::Thread* signaling_thread,
154 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
155 PeerScenarioClient::Config config)
156 : endpoints_(CreateEndpoints(net, config.endpoints)),
157 task_queue_factory_(net->time_controller()->GetTaskQueueFactory()),
158 signaling_thread_(signaling_thread),
159 log_writer_factory_(std::move(log_writer_factory)),
160 worker_thread_(net->time_controller()->CreateThread("worker")),
161 handlers_(config.handlers),
162 observer_(new LambdaPeerConnectionObserver(&handlers_)) {
163 handlers_.on_track.push_back(
164 [this](rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
165 auto track = transceiver->receiver()->track().get();
166 if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
167 auto* video = static_cast<VideoTrackInterface*>(track);
168 RTC_DCHECK_RUN_ON(signaling_thread_);
169 for (auto* sink : track_id_to_video_sinks_[track->id()]) {
170 video->AddOrUpdateSink(sink, rtc::VideoSinkWants());
171 }
172 }
173 });
174 handlers_.on_signaling_change.push_back(
175 [this](PeerConnectionInterface::SignalingState state) {
176 RTC_DCHECK_RUN_ON(signaling_thread_);
177 if (state == PeerConnectionInterface::SignalingState::kStable &&
178 peer_connection_->current_remote_description()) {
179 for (const auto& candidate : pending_ice_candidates_) {
180 RTC_CHECK(peer_connection_->AddIceCandidate(candidate.get()));
181 }
182 pending_ice_candidates_.clear();
183 }
184 });
185
186 std::vector<EmulatedEndpoint*> endpoints_vector;
187 for (const auto& kv : endpoints_)
188 endpoints_vector.push_back(kv.second);
189 auto* manager = net->CreateEmulatedNetworkManagerInterface(endpoints_vector);
190
191 PeerConnectionFactoryDependencies pcf_deps;
192 pcf_deps.network_thread = manager->network_thread();
193 pcf_deps.signaling_thread = signaling_thread_;
194 pcf_deps.worker_thread = worker_thread_.get();
195 pcf_deps.call_factory =
196 CreateTimeControllerBasedCallFactory(net->time_controller());
197 pcf_deps.task_queue_factory =
198 net->time_controller()->CreateTaskQueueFactory();
199 pcf_deps.event_log_factory =
200 std::make_unique<RtcEventLogFactory>(task_queue_factory_);
201 pcf_deps.trials = std::make_unique<FieldTrialBasedConfig>();
202
203 cricket::MediaEngineDependencies media_deps;
204 media_deps.task_queue_factory = task_queue_factory_;
205 media_deps.adm = TestAudioDeviceModule::Create(
206 task_queue_factory_,
207 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
208 config.audio.pulsed_noise->amplitude *
209 std::numeric_limits<int16_t>::max(),
210 config.audio.sample_rate, config.audio.channels),
211 TestAudioDeviceModule::CreateDiscardRenderer(config.audio.sample_rate));
212
213 media_deps.audio_processing = AudioProcessingBuilder().Create();
214 if (config.video.use_fake_codecs) {
215 media_deps.video_encoder_factory =
216 std::make_unique<FakeVideoEncoderFactory>(
217 net->time_controller()->GetClock());
218 media_deps.video_decoder_factory =
219 std::make_unique<FakeVideoDecoderFactory>();
220 } else {
221 media_deps.video_encoder_factory = CreateBuiltinVideoEncoderFactory();
222 media_deps.video_decoder_factory = CreateBuiltinVideoDecoderFactory();
223 }
224 media_deps.audio_encoder_factory = CreateBuiltinAudioEncoderFactory();
225 media_deps.audio_decoder_factory = CreateBuiltinAudioDecoderFactory();
226 media_deps.trials = pcf_deps.trials.get();
227
228 pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps));
229 pcf_deps.fec_controller_factory = nullptr;
230 pcf_deps.network_controller_factory = nullptr;
231 pcf_deps.network_state_predictor_factory = nullptr;
232
233 pc_factory_ = CreateModularPeerConnectionFactory(std::move(pcf_deps));
234 PeerConnectionFactoryInterface::Options pc_options;
235 pc_options.disable_encryption = config.disable_encryption;
236 pc_factory_->SetOptions(pc_options);
237
238 PeerConnectionDependencies pc_deps(observer_.get());
239 pc_deps.allocator =
240 std::make_unique<cricket::BasicPortAllocator>(manager->network_manager());
241 pc_deps.allocator->set_flags(pc_deps.allocator->flags() |
242 cricket::PORTALLOCATOR_DISABLE_TCP);
243 peer_connection_ =
244 pc_factory_->CreatePeerConnection(config.rtc_config, std::move(pc_deps));
245 if (log_writer_factory_) {
246 peer_connection_->StartRtcEventLog(log_writer_factory_->Create(".rtc.dat"),
247 /*output_period_ms=*/1000);
248 }
249 }
250
endpoint(int index)251 EmulatedEndpoint* PeerScenarioClient::endpoint(int index) {
252 RTC_CHECK_GT(endpoints_.size(), index);
253 return endpoints_.at(index);
254 }
255
CreateAudio(std::string track_id,cricket::AudioOptions options)256 PeerScenarioClient::AudioSendTrack PeerScenarioClient::CreateAudio(
257 std::string track_id,
258 cricket::AudioOptions options) {
259 RTC_DCHECK_RUN_ON(signaling_thread_);
260 AudioSendTrack res;
261 auto source = pc_factory_->CreateAudioSource(options);
262 auto track = pc_factory_->CreateAudioTrack(track_id, source);
263 res.track = track;
264 res.sender = peer_connection_->AddTrack(track, {kCommonStreamId}).value();
265 return res;
266 }
267
CreateVideo(std::string track_id,VideoSendTrackConfig config)268 PeerScenarioClient::VideoSendTrack PeerScenarioClient::CreateVideo(
269 std::string track_id,
270 VideoSendTrackConfig config) {
271 RTC_DCHECK_RUN_ON(signaling_thread_);
272 VideoSendTrack res;
273 auto capturer = FrameGeneratorCapturer::Create(clock(), *task_queue_factory_,
274 config.generator);
275 res.capturer = capturer.get();
276 capturer->Init();
277 res.source =
278 new rtc::RefCountedObject<FrameGeneratorCapturerVideoTrackSource>(
279 std::move(capturer), config.screencast);
280 auto track = pc_factory_->CreateVideoTrack(track_id, res.source);
281 res.track = track;
282 res.sender = peer_connection_->AddTrack(track, {kCommonStreamId}).MoveValue();
283 return res;
284 }
285
AddVideoReceiveSink(std::string track_id,rtc::VideoSinkInterface<VideoFrame> * video_sink)286 void PeerScenarioClient::AddVideoReceiveSink(
287 std::string track_id,
288 rtc::VideoSinkInterface<VideoFrame>* video_sink) {
289 RTC_DCHECK_RUN_ON(signaling_thread_);
290 track_id_to_video_sinks_[track_id].push_back(video_sink);
291 }
292
CreateAndSetSdp(std::function<void (SessionDescriptionInterface *)> munge_offer,std::function<void (std::string)> offer_handler)293 void PeerScenarioClient::CreateAndSetSdp(
294 std::function<void(SessionDescriptionInterface*)> munge_offer,
295 std::function<void(std::string)> offer_handler) {
296 RTC_DCHECK_RUN_ON(signaling_thread_);
297 peer_connection_->CreateOffer(
298 SdpCreateObserver([=](SessionDescriptionInterface* offer) {
299 RTC_DCHECK_RUN_ON(signaling_thread_);
300 if (munge_offer) {
301 munge_offer(offer);
302 }
303 std::string sdp_offer;
304 RTC_CHECK(offer->ToString(&sdp_offer));
305 peer_connection_->SetLocalDescription(
306 SdpSetObserver(
307 [sdp_offer, offer_handler]() { offer_handler(sdp_offer); }),
308 offer);
309 }),
310 PeerConnectionInterface::RTCOfferAnswerOptions());
311 }
312
SetSdpOfferAndGetAnswer(std::string remote_offer,std::function<void (std::string)> answer_handler)313 void PeerScenarioClient::SetSdpOfferAndGetAnswer(
314 std::string remote_offer,
315 std::function<void(std::string)> answer_handler) {
316 if (!signaling_thread_->IsCurrent()) {
317 signaling_thread_->PostTask(RTC_FROM_HERE, [=] {
318 SetSdpOfferAndGetAnswer(remote_offer, answer_handler);
319 });
320 return;
321 }
322 RTC_DCHECK_RUN_ON(signaling_thread_);
323 peer_connection_->SetRemoteDescription(
324 CreateSessionDescription(SdpType::kOffer, remote_offer),
325 SdpSetObserver([=]() {
326 RTC_DCHECK_RUN_ON(signaling_thread_);
327 peer_connection_->CreateAnswer(
328 SdpCreateObserver([=](SessionDescriptionInterface* answer) {
329 RTC_DCHECK_RUN_ON(signaling_thread_);
330 std::string sdp_answer;
331 answer->ToString(&sdp_answer);
332 RTC_LOG(LS_INFO) << sdp_answer;
333 peer_connection_->SetLocalDescription(
334 SdpSetObserver([answer_handler, sdp_answer]() {
335 answer_handler(sdp_answer);
336 }),
337 answer);
338 }),
339 PeerConnectionInterface::RTCOfferAnswerOptions());
340 }));
341 }
342
SetSdpAnswer(std::string remote_answer,std::function<void (const SessionDescriptionInterface &)> done_handler)343 void PeerScenarioClient::SetSdpAnswer(
344 std::string remote_answer,
345 std::function<void(const SessionDescriptionInterface&)> done_handler) {
346 if (!signaling_thread_->IsCurrent()) {
347 signaling_thread_->PostTask(
348 RTC_FROM_HERE, [=] { SetSdpAnswer(remote_answer, done_handler); });
349 return;
350 }
351 RTC_DCHECK_RUN_ON(signaling_thread_);
352 peer_connection_->SetRemoteDescription(
353 CreateSessionDescription(SdpType::kAnswer, remote_answer),
354 SdpSetObserver([remote_answer, done_handler] {
355 auto answer = CreateSessionDescription(SdpType::kAnswer, remote_answer);
356 done_handler(*answer);
357 }));
358 }
359
AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate)360 void PeerScenarioClient::AddIceCandidate(
361 std::unique_ptr<IceCandidateInterface> candidate) {
362 RTC_DCHECK_RUN_ON(signaling_thread_);
363 if (peer_connection_->signaling_state() ==
364 PeerConnectionInterface::SignalingState::kStable &&
365 peer_connection_->current_remote_description()) {
366 RTC_CHECK(peer_connection_->AddIceCandidate(candidate.get()));
367 } else {
368 pending_ice_candidates_.push_back(std::move(candidate));
369 }
370 }
371
372 } // namespace test
373 } // namespace webrtc
374