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