Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: talk/app/webrtc/peerconnection.cc

Issue 1393563002: Moving MediaStreamSignaling logic into PeerConnection. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Cleaning up comments, fixing naming, etc. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 11 matching lines...) Expand all
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/app/webrtc/peerconnection.h" 28 #include "talk/app/webrtc/peerconnection.h"
29 29
30 #include <vector> 30 #include <vector>
31 31
32 #include "talk/app/webrtc/audiotrack.h"
32 #include "talk/app/webrtc/dtmfsender.h" 33 #include "talk/app/webrtc/dtmfsender.h"
33 #include "talk/app/webrtc/jsepicecandidate.h" 34 #include "talk/app/webrtc/jsepicecandidate.h"
34 #include "talk/app/webrtc/jsepsessiondescription.h" 35 #include "talk/app/webrtc/jsepsessiondescription.h"
35 #include "talk/app/webrtc/mediaconstraintsinterface.h" 36 #include "talk/app/webrtc/mediaconstraintsinterface.h"
37 #include "talk/app/webrtc/mediastream.h"
38 #include "talk/app/webrtc/mediastreamproxy.h"
39 #include "talk/app/webrtc/mediastreamtrackproxy.h"
40 #include "talk/app/webrtc/remoteaudiosource.h"
41 #include "talk/app/webrtc/remotevideocapturer.h"
36 #include "talk/app/webrtc/rtpreceiver.h" 42 #include "talk/app/webrtc/rtpreceiver.h"
37 #include "talk/app/webrtc/rtpsender.h" 43 #include "talk/app/webrtc/rtpsender.h"
38 #include "talk/app/webrtc/streamcollection.h" 44 #include "talk/app/webrtc/streamcollection.h"
45 #include "talk/app/webrtc/videosource.h"
46 #include "talk/app/webrtc/videotrack.h"
47 #include "talk/media/sctp/sctpdataengine.h"
39 #include "webrtc/p2p/client/basicportallocator.h" 48 #include "webrtc/p2p/client/basicportallocator.h"
40 #include "talk/session/media/channelmanager.h" 49 #include "talk/session/media/channelmanager.h"
41 #include "webrtc/base/logging.h" 50 #include "webrtc/base/logging.h"
42 #include "webrtc/base/stringencode.h" 51 #include "webrtc/base/stringencode.h"
52 #include "webrtc/base/stringutils.h"
43 #include "webrtc/system_wrappers/interface/field_trial.h" 53 #include "webrtc/system_wrappers/interface/field_trial.h"
44 54
45 namespace { 55 namespace {
46 56
57 using webrtc::DataChannel;
58 using webrtc::MediaConstraintsInterface;
59 using webrtc::MediaStreamInterface;
47 using webrtc::PeerConnectionInterface; 60 using webrtc::PeerConnectionInterface;
61 using webrtc::StreamCollection;
62
63 static const char kDefaultStreamLabel[] = "default";
64 static const char kDefaultAudioTrackLabel[] = "defaulta0";
65 static const char kDefaultVideoTrackLabel[] = "defaultv0";
48 66
49 // The min number of tokens must present in Turn host uri. 67 // The min number of tokens must present in Turn host uri.
50 // e.g. user@turn.example.org 68 // e.g. user@turn.example.org
51 static const size_t kTurnHostTokensNum = 2; 69 static const size_t kTurnHostTokensNum = 2;
52 // Number of tokens must be preset when TURN uri has transport param. 70 // Number of tokens must be preset when TURN uri has transport param.
53 static const size_t kTurnTransportTokensNum = 2; 71 static const size_t kTurnTransportTokensNum = 2;
54 // The default stun port. 72 // The default stun port.
55 static const int kDefaultStunPort = 3478; 73 static const int kDefaultStunPort = 3478;
56 static const int kDefaultStunTlsPort = 5349; 74 static const int kDefaultStunTlsPort = 5349;
57 static const char kTransport[] = "transport"; 75 static const char kTransport[] = "transport";
58 static const char kUdpTransportType[] = "udp"; 76 static const char kUdpTransportType[] = "udp";
59 static const char kTcpTransportType[] = "tcp"; 77 static const char kTcpTransportType[] = "tcp";
60 78
61 // NOTE: Must be in the same order as the ServiceType enum. 79 // NOTE: Must be in the same order as the ServiceType enum.
62 static const char* kValidIceServiceTypes[] = { 80 static const char* kValidIceServiceTypes[] = {
63 "stun", "stuns", "turn", "turns", "invalid" }; 81 "stun", "stuns", "turn", "turns", "invalid" };
64 82
65 enum ServiceType { 83 enum ServiceType {
66 STUN, // Indicates a STUN server. 84 STUN, // Indicates a STUN server.
67 STUNS, // Indicates a STUN server used with a TLS session. 85 STUNS, // Indicates a STUN server used with a TLS session.
68 TURN, // Indicates a TURN server 86 TURN, // Indicates a TURN server
69 TURNS, // Indicates a TURN server used with a TLS session. 87 TURNS, // Indicates a TURN server used with a TLS session.
70 INVALID, // Unknown. 88 INVALID, // Unknown.
71 }; 89 };
72 90
73 enum { 91 enum {
74 MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0, 92 MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0,
75 MSG_SET_SESSIONDESCRIPTION_FAILED, 93 MSG_SET_SESSIONDESCRIPTION_FAILED,
94 MSG_CREATE_SESSIONDESCRIPTION_FAILED,
76 MSG_GETSTATS, 95 MSG_GETSTATS,
77 }; 96 };
78 97
79 struct SetSessionDescriptionMsg : public rtc::MessageData { 98 struct SetSessionDescriptionMsg : public rtc::MessageData {
80 explicit SetSessionDescriptionMsg( 99 explicit SetSessionDescriptionMsg(
81 webrtc::SetSessionDescriptionObserver* observer) 100 webrtc::SetSessionDescriptionObserver* observer)
82 : observer(observer) { 101 : observer(observer) {
83 } 102 }
84 103
85 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserver> observer; 104 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserver> observer;
86 std::string error; 105 std::string error;
87 }; 106 };
88 107
108 struct CreateSessionDescriptionMsg : public rtc::MessageData {
109 explicit CreateSessionDescriptionMsg(
110 webrtc::CreateSessionDescriptionObserver* observer)
111 : observer(observer) {}
112
113 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer;
114 std::string error;
115 };
116
89 struct GetStatsMsg : public rtc::MessageData { 117 struct GetStatsMsg : public rtc::MessageData {
90 GetStatsMsg(webrtc::StatsObserver* observer, 118 GetStatsMsg(webrtc::StatsObserver* observer,
91 webrtc::MediaStreamTrackInterface* track) 119 webrtc::MediaStreamTrackInterface* track)
92 : observer(observer), track(track) { 120 : observer(observer), track(track) {
93 } 121 }
94 rtc::scoped_refptr<webrtc::StatsObserver> observer; 122 rtc::scoped_refptr<webrtc::StatsObserver> observer;
95 rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track; 123 rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track;
96 }; 124 };
97 125
98 // |in_str| should be of format 126 // |in_str| should be of format
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 return false; 330 return false;
303 } 331 }
304 } else { 332 } else {
305 LOG(WARNING) << "Empty uri."; 333 LOG(WARNING) << "Empty uri.";
306 } 334 }
307 } 335 }
308 return true; 336 return true;
309 } 337 }
310 338
311 // Check if we can send |new_stream| on a PeerConnection. 339 // Check if we can send |new_stream| on a PeerConnection.
312 // Currently only one audio but multiple video track is supported per
313 // PeerConnection.
314 bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams, 340 bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams,
315 webrtc::MediaStreamInterface* new_stream) { 341 webrtc::MediaStreamInterface* new_stream) {
316 if (!new_stream || !current_streams) 342 if (!new_stream || !current_streams) {
317 return false; 343 return false;
318 if (current_streams->find(new_stream->label()) != NULL) { 344 }
345 if (current_streams->find(new_stream->label()) != nullptr) {
319 LOG(LS_ERROR) << "MediaStream with label " << new_stream->label() 346 LOG(LS_ERROR) << "MediaStream with label " << new_stream->label()
320 << " is already added."; 347 << " is already added.";
321 return false; 348 return false;
322 } 349 }
323
324 return true; 350 return true;
325 } 351 }
326 352
353 bool MediaContentDirectionHasSend(cricket::MediaContentDirection dir) {
354 return dir == cricket::MD_SENDONLY || dir == cricket::MD_SENDRECV;
355 }
356
357 bool IsValidOfferToReceiveMedia(int value) {
358 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options;
359 return (value >= Options::kUndefined) &&
360 (value <= Options::kMaxOfferToReceiveMedia);
361 }
362
363 // Add the stream and RTP data channel info to |session_options|.
364 void SetStreams(cricket::MediaSessionOptions* session_options,
365 rtc::scoped_refptr<StreamCollection> streams,
366 const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
367 rtp_data_channels) {
368 session_options->streams.clear();
369 if (streams != nullptr) {
370 for (size_t i = 0; i < streams->count(); ++i) {
371 MediaStreamInterface* stream = streams->at(i);
372 // For each audio track in the stream, add it to the MediaSessionOptions.
373 for (const auto& track : stream->GetAudioTracks()) {
374 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, track->id(),
375 stream->label());
376 }
377 // For each video track in the stream, add it to the MediaSessionOptions.
378 for (const auto& track : stream->GetVideoTracks()) {
379 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, track->id(),
380 stream->label());
381 }
382 }
383 }
384
385 // Check for data channels.
386 for (const auto& kv : rtp_data_channels) {
387 const DataChannel* channel = kv.second;
388 if (channel->state() == DataChannel::kConnecting ||
389 channel->state() == DataChannel::kOpen) {
390 // |streamid| and |sync_label| are both set to the DataChannel label
391 // here so they can be signaled the same way as MediaStreams and Tracks.
392 // For MediaStreams, the sync_label is the MediaStream label and the
393 // track label is the same as |streamid|.
394 const std::string& streamid = channel->label();
395 const std::string& sync_label = channel->label();
396 session_options->AddSendStream(cricket::MEDIA_TYPE_DATA, streamid,
397 sync_label);
398 }
399 }
400 }
401
327 } // namespace 402 } // namespace
328 403
329 namespace webrtc { 404 namespace webrtc {
330 405
406 // Factory class for creating remote MediaStreams and MediaStreamTracks.
407 class RemoteMediaStreamFactory {
408 public:
409 explicit RemoteMediaStreamFactory(rtc::Thread* signaling_thread,
410 cricket::ChannelManager* channel_manager)
411 : signaling_thread_(signaling_thread),
412 channel_manager_(channel_manager) {}
413
414 rtc::scoped_refptr<MediaStreamInterface> CreateMediaStream(
415 const std::string& stream_label) {
416 return MediaStreamProxy::Create(signaling_thread_,
417 MediaStream::Create(stream_label));
418 }
419
420 AudioTrackInterface* AddAudioTrack(webrtc::MediaStreamInterface* stream,
421 const std::string& track_id) {
422 return AddTrack<AudioTrackInterface, AudioTrack, AudioTrackProxy>(
423 stream, track_id, RemoteAudioSource::Create().get());
424 }
425
426 VideoTrackInterface* AddVideoTrack(webrtc::MediaStreamInterface* stream,
427 const std::string& track_id) {
428 return AddTrack<VideoTrackInterface, VideoTrack, VideoTrackProxy>(
429 stream, track_id,
430 VideoSource::Create(channel_manager_, new RemoteVideoCapturer(),
431 nullptr)
432 .get());
433 }
434
435 private:
436 template <typename TI, typename T, typename TP, typename S>
437 TI* AddTrack(MediaStreamInterface* stream,
438 const std::string& track_id,
439 S* source) {
440 rtc::scoped_refptr<TI> track(
441 TP::Create(signaling_thread_, T::Create(track_id, source)));
442 track->set_state(webrtc::MediaStreamTrackInterface::kLive);
443 if (stream->AddTrack(track)) {
444 return track;
445 }
446 return nullptr;
447 }
448
449 rtc::Thread* signaling_thread_;
450 cricket::ChannelManager* channel_manager_;
451 };
452
453 bool ConvertRtcOptionsForOffer(
454 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
455 cricket::MediaSessionOptions* session_options) {
456 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
457 if (!IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) ||
458 !IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video)) {
459 return false;
460 }
461
462 // According to the spec, offer to receive audio/video if the constraint is
463 // not set and there are send streams.
464 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) {
465 session_options->recv_audio =
466 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO);
467 } else {
468 session_options->recv_audio = (rtc_options.offer_to_receive_audio > 0);
469 }
470 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) {
471 session_options->recv_video =
472 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO);
473 } else {
474 session_options->recv_video = (rtc_options.offer_to_receive_video > 0);
475 }
476
477 session_options->vad_enabled = rtc_options.voice_activity_detection;
478 session_options->transport_options.ice_restart = rtc_options.ice_restart;
479 session_options->bundle_enabled =
480 rtc_options.use_rtp_mux &&
481 (session_options->has_audio() || session_options->has_video() ||
482 session_options->has_data());
483
484 return true;
485 }
486
487 bool ParseConstraintsForAnswer(const MediaConstraintsInterface* constraints,
488 cricket::MediaSessionOptions* session_options) {
489 bool value = false;
490 size_t mandatory_constraints_satisfied = 0;
491
492 // kOfferToReceiveAudio defaults to true according to spec.
493 if (!FindConstraint(constraints,
494 MediaConstraintsInterface::kOfferToReceiveAudio, &value,
495 &mandatory_constraints_satisfied) ||
496 value) {
497 session_options->recv_audio = true;
498 }
499
500 // kOfferToReceiveVideo defaults to false according to spec. But
501 // if it is an answer and video is offered, we should still accept video
502 // per default.
503 value = false;
504 if (!FindConstraint(constraints,
505 MediaConstraintsInterface::kOfferToReceiveVideo, &value,
506 &mandatory_constraints_satisfied) ||
507 value) {
508 session_options->recv_video = true;
509 }
510
511 if (FindConstraint(constraints,
512 MediaConstraintsInterface::kVoiceActivityDetection, &value,
513 &mandatory_constraints_satisfied)) {
514 session_options->vad_enabled = value;
515 }
516
517 if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
518 &mandatory_constraints_satisfied)) {
519 session_options->bundle_enabled = value;
520 } else {
521 // kUseRtpMux defaults to true according to spec.
522 session_options->bundle_enabled = true;
523 }
524 session_options->bundle_enabled =
525 session_options->bundle_enabled &&
526 (session_options->has_audio() || session_options->has_video() ||
527 session_options->has_data());
528
529 if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
530 &value, &mandatory_constraints_satisfied)) {
531 session_options->transport_options.ice_restart = value;
532 } else {
533 // kIceRestart defaults to false according to spec.
534 session_options->transport_options.ice_restart = false;
535 }
536
537 if (!constraints) {
538 return true;
539 }
540 return mandatory_constraints_satisfied == constraints->GetMandatory().size();
541 }
542
331 PeerConnection::PeerConnection(PeerConnectionFactory* factory) 543 PeerConnection::PeerConnection(PeerConnectionFactory* factory)
332 : factory_(factory), 544 : factory_(factory),
333 observer_(NULL), 545 observer_(NULL),
334 uma_observer_(NULL), 546 uma_observer_(NULL),
335 signaling_state_(kStable), 547 signaling_state_(kStable),
336 ice_state_(kIceNew), 548 ice_state_(kIceNew),
337 ice_connection_state_(kIceConnectionNew), 549 ice_connection_state_(kIceConnectionNew),
338 ice_gathering_state_(kIceGatheringNew) { 550 ice_gathering_state_(kIceGatheringNew),
339 } 551 local_streams_(StreamCollection::Create()),
552 remote_streams_(StreamCollection::Create()) {}
340 553
341 PeerConnection::~PeerConnection() { 554 PeerConnection::~PeerConnection() {
342 ASSERT(signaling_thread()->IsCurrent()); 555 ASSERT(signaling_thread()->IsCurrent());
343 if (mediastream_signaling_) {
344 mediastream_signaling_->TearDown();
345 }
Taylor Brandstetter 2015/10/07 00:26:19 The stuff previously done in mediastream_signaling
346 // Need to detach RTP senders/receivers from WebRtcSession, 556 // Need to detach RTP senders/receivers from WebRtcSession,
347 // since it's about to be destroyed. 557 // since it's about to be destroyed.
348 for (const auto& sender : senders_) { 558 for (const auto& sender : senders_) {
349 sender->Stop(); 559 sender->Stop();
350 } 560 }
351 for (const auto& receiver : receivers_) { 561 for (const auto& receiver : receivers_) {
352 receiver->Stop(); 562 receiver->Stop();
353 } 563 }
354 } 564 }
355 565
356 bool PeerConnection::Initialize( 566 bool PeerConnection::Initialize(
357 const PeerConnectionInterface::RTCConfiguration& configuration, 567 const PeerConnectionInterface::RTCConfiguration& configuration,
358 const MediaConstraintsInterface* constraints, 568 const MediaConstraintsInterface* constraints,
359 PortAllocatorFactoryInterface* allocator_factory, 569 PortAllocatorFactoryInterface* allocator_factory,
360 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 570 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
361 PeerConnectionObserver* observer) { 571 PeerConnectionObserver* observer) {
362 ASSERT(observer != NULL); 572 ASSERT(observer != nullptr);
363 if (!observer) 573 if (!observer) {
364 return false; 574 return false;
575 }
365 observer_ = observer; 576 observer_ = observer;
366 577
367 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_config; 578 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_config;
368 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_config; 579 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_config;
369 if (!ParseIceServers(configuration.servers, &stun_config, &turn_config)) { 580 if (!ParseIceServers(configuration.servers, &stun_config, &turn_config)) {
370 return false; 581 return false;
371 } 582 }
372 port_allocator_.reset( 583 port_allocator_.reset(
373 allocator_factory->CreatePortAllocator(stun_config, turn_config)); 584 allocator_factory->CreatePortAllocator(stun_config, turn_config));
374 585
375 // To handle both internal and externally created port allocator, we will 586 // To handle both internal and externally created port allocator, we will
376 // enable BUNDLE here. 587 // enable BUNDLE here.
377 int portallocator_flags = port_allocator_->flags(); 588 int portallocator_flags = port_allocator_->flags();
378 portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET | 589 portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
379 cricket::PORTALLOCATOR_ENABLE_IPV6; 590 cricket::PORTALLOCATOR_ENABLE_IPV6;
380 bool value; 591 bool value;
381 // If IPv6 flag was specified, we'll not override it by experiment. 592 // If IPv6 flag was specified, we'll not override it by experiment.
382 if (FindConstraint( 593 if (FindConstraint(constraints, MediaConstraintsInterface::kEnableIPv6,
383 constraints, MediaConstraintsInterface::kEnableIPv6, &value, NULL)) { 594 &value, nullptr)) {
384 if (!value) { 595 if (!value) {
385 portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); 596 portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
386 } 597 }
387 } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") == 598 } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") ==
388 "Disabled") { 599 "Disabled") {
389 portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); 600 portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
390 } 601 }
391 602
392 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) { 603 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
393 portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP; 604 portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
394 LOG(LS_INFO) << "TCP candidates are disabled."; 605 LOG(LS_INFO) << "TCP candidates are disabled.";
395 } 606 }
396 607
397 port_allocator_->set_flags(portallocator_flags); 608 port_allocator_->set_flags(portallocator_flags);
398 // No step delay is used while allocating ports. 609 // No step delay is used while allocating ports.
399 port_allocator_->set_step_delay(cricket::kMinimumStepDelay); 610 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
400 611
401 mediastream_signaling_.reset(new MediaStreamSignaling( 612 remote_stream_factory_.reset(new RemoteMediaStreamFactory(
402 factory_->signaling_thread(), this, factory_->channel_manager())); 613 factory_->signaling_thread(), factory_->channel_manager()));
403 614
404 session_.reset(new WebRtcSession(factory_->channel_manager(), 615 session_.reset(new WebRtcSession(
405 factory_->signaling_thread(), 616 factory_->channel_manager(), factory_->signaling_thread(),
406 factory_->worker_thread(), 617 factory_->worker_thread(), port_allocator_.get()));
407 port_allocator_.get(), 618 stats_.reset(new StatsCollector(this, session_.get()));
408 mediastream_signaling_.get()));
409 stats_.reset(new StatsCollector(session_.get()));
410 619
411 // Initialize the WebRtcSession. It creates transport channels etc. 620 // Initialize the WebRtcSession. It creates transport channels etc.
412 if (!session_->Initialize(factory_->options(), constraints, 621 if (!session_->Initialize(factory_->options(), constraints,
413 dtls_identity_store.Pass(), configuration)) 622 dtls_identity_store.Pass(), configuration)) {
414 return false; 623 return false;
624 }
415 625
416 // Register PeerConnection as receiver of local ice candidates. 626 // Register PeerConnection as receiver of local ice candidates.
417 // All the callbacks will be posted to the application from PeerConnection. 627 // All the callbacks will be posted to the application from PeerConnection.
418 session_->RegisterIceObserver(this); 628 session_->RegisterIceObserver(this);
419 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); 629 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange);
630 session_->SignalVoiceChannelDestroyed.connect(
631 this, &PeerConnection::OnVoiceChannelDestroyed);
632 session_->SignalVideoChannelDestroyed.connect(
633 this, &PeerConnection::OnVideoChannelDestroyed);
634 session_->SignalDataChannelCreated.connect(
635 this, &PeerConnection::OnDataChannelCreated);
636 session_->SignalDataChannelDestroyed.connect(
637 this, &PeerConnection::OnDataChannelDestroyed);
638 session_->SignalDataChannelCreationRequested.connect(
639 this, &PeerConnection::OnDataChannelCreationRequested);
420 return true; 640 return true;
421 } 641 }
422 642
423 rtc::scoped_refptr<StreamCollectionInterface> 643 rtc::scoped_refptr<StreamCollectionInterface>
424 PeerConnection::local_streams() { 644 PeerConnection::local_streams() {
425 return mediastream_signaling_->local_streams(); 645 return local_streams_;
426 } 646 }
427 647
428 rtc::scoped_refptr<StreamCollectionInterface> 648 rtc::scoped_refptr<StreamCollectionInterface>
429 PeerConnection::remote_streams() { 649 PeerConnection::remote_streams() {
430 return mediastream_signaling_->remote_streams(); 650 return remote_streams_;
431 } 651 }
432 652
433 // TODO(deadbeef): Create RtpSenders immediately here, even if local 653 // TODO(deadbeef): Create RtpSenders immediately here, even if local
434 // description hasn't yet been set. 654 // description hasn't yet been set.
435 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { 655 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
436 if (IsClosed()) { 656 if (IsClosed()) {
437 return false; 657 return false;
438 } 658 }
439 if (!CanAddLocalMediaStream(mediastream_signaling_->local_streams(), 659 if (!CanAddLocalMediaStream(local_streams_, local_stream)) {
440 local_stream))
441 return false;
442
443 if (!mediastream_signaling_->AddLocalStream(local_stream)) {
444 return false; 660 return false;
445 } 661 }
662
663 local_streams_->AddStream(local_stream);
664
665 // Find tracks that have already been configured in SDP. This can occur if a
666 // local session description that contains the MSID of these tracks is set
667 // before AddLocalStream is called. It can also occur if the local session
668 // description is not changed and RemoveLocalStream is called and later
669 // AddLocalStream is called again with the same stream.
670 for (const auto& track : local_stream->GetAudioTracks()) {
671 const TrackInfo* track_info =
672 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id());
673 if (track_info) {
674 CreateAudioSender(local_stream, track.get(), track_info->ssrc);
675 }
676 }
677 for (const auto& track : local_stream->GetVideoTracks()) {
678 const TrackInfo* track_info =
679 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id());
680 if (track_info) {
681 CreateVideoSender(local_stream, track.get(), track_info->ssrc);
682 }
683 }
684
446 stats_->AddStream(local_stream); 685 stats_->AddStream(local_stream);
447 observer_->OnRenegotiationNeeded(); 686 observer_->OnRenegotiationNeeded();
448 return true; 687 return true;
449 } 688 }
450 689
690 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around
691 // indefinitely.
451 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { 692 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
452 mediastream_signaling_->RemoveLocalStream(local_stream); 693 for (const auto& track : local_stream->GetAudioTracks()) {
694 const TrackInfo* track_info =
695 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id());
696 if (track_info) {
697 DestroyAudioSender(local_stream, track.get(), track_info->ssrc);
698 }
699 }
700 for (const auto& track : local_stream->GetVideoTracks()) {
701 const TrackInfo* track_info =
702 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id());
703 if (track_info) {
704 DestroyVideoSender(local_stream, track.get());
705 }
706 }
707
708 local_streams_->RemoveStream(local_stream);
709
453 if (IsClosed()) { 710 if (IsClosed()) {
454 return; 711 return;
455 } 712 }
456 observer_->OnRenegotiationNeeded(); 713 observer_->OnRenegotiationNeeded();
457 } 714 }
458 715
459 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( 716 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender(
460 AudioTrackInterface* track) { 717 AudioTrackInterface* track) {
461 if (!track) { 718 if (!track) {
462 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL."; 719 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL.";
463 return NULL; 720 return NULL;
464 } 721 }
465 if (!mediastream_signaling_->local_streams()->FindAudioTrack(track->id())) { 722 if (!local_streams_->FindAudioTrack(track->id())) {
466 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track."; 723 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track.";
467 return NULL; 724 return NULL;
468 } 725 }
469 726
470 rtc::scoped_refptr<DtmfSenderInterface> sender( 727 rtc::scoped_refptr<DtmfSenderInterface> sender(
471 DtmfSender::Create(track, signaling_thread(), session_.get())); 728 DtmfSender::Create(track, signaling_thread(), session_.get()));
472 if (!sender.get()) { 729 if (!sender.get()) {
473 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; 730 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
474 return NULL; 731 return NULL;
475 } 732 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 782
526 PeerConnectionInterface::IceGatheringState 783 PeerConnectionInterface::IceGatheringState
527 PeerConnection::ice_gathering_state() { 784 PeerConnection::ice_gathering_state() {
528 return ice_gathering_state_; 785 return ice_gathering_state_;
529 } 786 }
530 787
531 rtc::scoped_refptr<DataChannelInterface> 788 rtc::scoped_refptr<DataChannelInterface>
532 PeerConnection::CreateDataChannel( 789 PeerConnection::CreateDataChannel(
533 const std::string& label, 790 const std::string& label,
534 const DataChannelInit* config) { 791 const DataChannelInit* config) {
535 bool first_datachannel = !mediastream_signaling_->HasDataChannels(); 792 bool first_datachannel = !HasDataChannels();
536 793
537 rtc::scoped_ptr<InternalDataChannelInit> internal_config; 794 rtc::scoped_ptr<InternalDataChannelInit> internal_config;
538 if (config) { 795 if (config) {
539 internal_config.reset(new InternalDataChannelInit(*config)); 796 internal_config.reset(new InternalDataChannelInit(*config));
540 } 797 }
541 rtc::scoped_refptr<DataChannelInterface> channel( 798 rtc::scoped_refptr<DataChannelInterface> channel(
542 session_->CreateDataChannel(label, internal_config.get())); 799 InternalCreateDataChannel(label, internal_config.get()));
543 if (!channel.get()) 800 if (!channel.get()) {
544 return NULL; 801 return nullptr;
802 }
545 803
546 // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or 804 // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or
547 // the first SCTP DataChannel. 805 // the first SCTP DataChannel.
548 if (session_->data_channel_type() == cricket::DCT_RTP || first_datachannel) { 806 if (session_->data_channel_type() == cricket::DCT_RTP || first_datachannel) {
549 observer_->OnRenegotiationNeeded(); 807 observer_->OnRenegotiationNeeded();
550 } 808 }
551 809
552 return DataChannelProxy::Create(signaling_thread(), channel.get()); 810 return DataChannelProxy::Create(signaling_thread(), channel.get());
553 } 811 }
554 812
555 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, 813 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
556 const MediaConstraintsInterface* constraints) { 814 const MediaConstraintsInterface* constraints) {
557 if (!VERIFY(observer != NULL)) { 815 if (!VERIFY(observer != nullptr)) {
558 LOG(LS_ERROR) << "CreateOffer - observer is NULL."; 816 LOG(LS_ERROR) << "CreateOffer - observer is NULL.";
559 return; 817 return;
560 } 818 }
561 RTCOfferAnswerOptions options; 819 RTCOfferAnswerOptions options;
562 820
563 bool value; 821 bool value;
564 size_t mandatory_constraints = 0; 822 size_t mandatory_constraints = 0;
565 823
566 if (FindConstraint(constraints, 824 if (FindConstraint(constraints,
567 MediaConstraintsInterface::kOfferToReceiveAudio, 825 MediaConstraintsInterface::kOfferToReceiveAudio,
(...skipping 30 matching lines...) Expand all
598 &value, 856 &value,
599 &mandatory_constraints)) { 857 &mandatory_constraints)) {
600 options.use_rtp_mux = value; 858 options.use_rtp_mux = value;
601 } 859 }
602 860
603 CreateOffer(observer, options); 861 CreateOffer(observer, options);
604 } 862 }
605 863
606 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, 864 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
607 const RTCOfferAnswerOptions& options) { 865 const RTCOfferAnswerOptions& options) {
608 if (!VERIFY(observer != NULL)) { 866 if (!VERIFY(observer != nullptr)) {
609 LOG(LS_ERROR) << "CreateOffer - observer is NULL."; 867 LOG(LS_ERROR) << "CreateOffer - observer is NULL.";
610 return; 868 return;
611 } 869 }
612 session_->CreateOffer(observer, options); 870
871 cricket::MediaSessionOptions session_options;
872 if (!GetOptionsForOffer(options, &session_options)) {
873 std::string error = "CreateOffer called with invalid options.";
874 LOG(LS_ERROR) << error;
875 PostCreateSessionDescriptionFailure(observer, error);
876 return;
877 }
878
879 session_->CreateOffer(observer, options, session_options);
613 } 880 }
614 881
615 void PeerConnection::CreateAnswer( 882 void PeerConnection::CreateAnswer(
616 CreateSessionDescriptionObserver* observer, 883 CreateSessionDescriptionObserver* observer,
617 const MediaConstraintsInterface* constraints) { 884 const MediaConstraintsInterface* constraints) {
618 if (!VERIFY(observer != NULL)) { 885 if (!VERIFY(observer != nullptr)) {
619 LOG(LS_ERROR) << "CreateAnswer - observer is NULL."; 886 LOG(LS_ERROR) << "CreateAnswer - observer is NULL.";
620 return; 887 return;
621 } 888 }
622 session_->CreateAnswer(observer, constraints); 889
890 cricket::MediaSessionOptions session_options;
891 if (!GetOptionsForAnswer(constraints, &session_options)) {
892 std::string error = "CreateAnswer called with invalid constraints.";
893 LOG(LS_ERROR) << error;
894 PostCreateSessionDescriptionFailure(observer, error);
895 return;
896 }
897
898 session_->CreateAnswer(observer, constraints, session_options);
623 } 899 }
624 900
625 void PeerConnection::SetLocalDescription( 901 void PeerConnection::SetLocalDescription(
626 SetSessionDescriptionObserver* observer, 902 SetSessionDescriptionObserver* observer,
627 SessionDescriptionInterface* desc) { 903 SessionDescriptionInterface* desc) {
628 if (!VERIFY(observer != NULL)) { 904 if (!VERIFY(observer != nullptr)) {
629 LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; 905 LOG(LS_ERROR) << "SetLocalDescription - observer is NULL.";
630 return; 906 return;
631 } 907 }
632 if (!desc) { 908 if (!desc) {
633 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); 909 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL.");
634 return; 910 return;
635 } 911 }
636 // Update stats here so that we have the most recent stats for tracks and 912 // Update stats here so that we have the most recent stats for tracks and
637 // streams that might be removed by updating the session description. 913 // streams that might be removed by updating the session description.
638 stats_->UpdateStats(kStatsOutputLevelStandard); 914 stats_->UpdateStats(kStatsOutputLevelStandard);
639 std::string error; 915 std::string error;
640 if (!session_->SetLocalDescription(desc, &error)) { 916 if (!session_->SetLocalDescription(desc, &error)) {
641 PostSetSessionDescriptionFailure(observer, error); 917 PostSetSessionDescriptionFailure(observer, error);
642 return; 918 return;
643 } 919 }
644 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); 920
921 // If setting the description decided our SSL role, allocate any necessary
922 // SCTP sids.
923 rtc::SSLRole role;
924 if (session_->data_channel_type() == cricket::DCT_SCTP &&
925 session_->GetSslRole(&role)) {
926 AllocateSctpSids(role);
927 }
928
929 // Update state and SSRC of local MediaStreams and DataChannels based on the
930 // local session description.
931 const cricket::ContentInfo* audio_content =
932 GetFirstAudioContent(desc->description());
933 if (audio_content) {
934 const cricket::AudioContentDescription* audio_desc =
935 static_cast<const cricket::AudioContentDescription*>(
936 audio_content->description);
937 UpdateLocalTracks(audio_desc->streams(), audio_desc->type());
938 }
939
940 const cricket::ContentInfo* video_content =
941 GetFirstVideoContent(desc->description());
942 if (video_content) {
943 const cricket::VideoContentDescription* video_desc =
944 static_cast<const cricket::VideoContentDescription*>(
945 video_content->description);
946 UpdateLocalTracks(video_desc->streams(), video_desc->type());
947 }
948
949 const cricket::ContentInfo* data_content =
950 GetFirstDataContent(desc->description());
951 if (data_content) {
952 const cricket::DataContentDescription* data_desc =
953 static_cast<const cricket::DataContentDescription*>(
954 data_content->description);
955 if (rtc::starts_with(data_desc->protocol().data(),
956 cricket::kMediaProtocolRtpPrefix)) {
957 UpdateLocalRtpDataChannels(data_desc->streams());
958 }
959 }
960
961 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
645 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); 962 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
963
646 // MaybeStartGathering needs to be called after posting 964 // MaybeStartGathering needs to be called after posting
647 // MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates 965 // MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates
648 // before signaling that SetLocalDescription completed. 966 // before signaling that SetLocalDescription completed.
649 session_->MaybeStartGathering(); 967 session_->MaybeStartGathering();
650 } 968 }
651 969
652 void PeerConnection::SetRemoteDescription( 970 void PeerConnection::SetRemoteDescription(
653 SetSessionDescriptionObserver* observer, 971 SetSessionDescriptionObserver* observer,
654 SessionDescriptionInterface* desc) { 972 SessionDescriptionInterface* desc) {
655 if (!VERIFY(observer != NULL)) { 973 if (!VERIFY(observer != nullptr)) {
656 LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; 974 LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL.";
657 return; 975 return;
658 } 976 }
659 if (!desc) { 977 if (!desc) {
660 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); 978 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL.");
661 return; 979 return;
662 } 980 }
663 // Update stats here so that we have the most recent stats for tracks and 981 // Update stats here so that we have the most recent stats for tracks and
664 // streams that might be removed by updating the session description. 982 // streams that might be removed by updating the session description.
665 stats_->UpdateStats(kStatsOutputLevelStandard); 983 stats_->UpdateStats(kStatsOutputLevelStandard);
666 std::string error; 984 std::string error;
667 if (!session_->SetRemoteDescription(desc, &error)) { 985 if (!session_->SetRemoteDescription(desc, &error)) {
668 PostSetSessionDescriptionFailure(observer, error); 986 PostSetSessionDescriptionFailure(observer, error);
669 return; 987 return;
670 } 988 }
671 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); 989
990 // If setting the description decided our SSL role, allocate any necessary
991 // SCTP sids.
992 rtc::SSLRole role;
993 if (session_->data_channel_type() == cricket::DCT_SCTP &&
994 session_->GetSslRole(&role)) {
995 AllocateSctpSids(role);
996 }
997
998 const cricket::SessionDescription* remote_desc = desc->description();
999
1000 // We wait to signal new streams until we finish processing the description,
1001 // since only at that point will new streams have all their tracks.
1002 rtc::scoped_refptr<StreamCollection> new_streams(StreamCollection::Create());
1003
1004 // Find all audio rtp streams and create corresponding remote AudioTracks
1005 // and MediaStreams.
1006 const cricket::ContentInfo* audio_content = GetFirstAudioContent(remote_desc);
1007 if (audio_content) {
1008 const cricket::AudioContentDescription* desc =
1009 static_cast<const cricket::AudioContentDescription*>(
1010 audio_content->description);
1011 UpdateRemoteStreamsList(desc->streams(), desc->type(), new_streams);
1012 remote_info_.default_audio_track_needed =
1013 MediaContentDirectionHasSend(desc->direction()) &&
1014 desc->streams().empty();
1015 }
1016
1017 // Find all video rtp streams and create corresponding remote VideoTracks
1018 // and MediaStreams.
1019 const cricket::ContentInfo* video_content = GetFirstVideoContent(remote_desc);
1020 if (video_content) {
1021 const cricket::VideoContentDescription* desc =
1022 static_cast<const cricket::VideoContentDescription*>(
1023 video_content->description);
1024 UpdateRemoteStreamsList(desc->streams(), desc->type(), new_streams);
1025 remote_info_.default_video_track_needed =
1026 MediaContentDirectionHasSend(desc->direction()) &&
1027 desc->streams().empty();
1028 }
1029
1030 // Update the DataChannels with the information from the remote peer.
1031 const cricket::ContentInfo* data_content = GetFirstDataContent(remote_desc);
1032 if (data_content) {
1033 const cricket::DataContentDescription* data_desc =
1034 static_cast<const cricket::DataContentDescription*>(
1035 data_content->description);
1036 if (rtc::starts_with(data_desc->protocol().data(),
1037 cricket::kMediaProtocolRtpPrefix)) {
1038 UpdateRemoteRtpDataChannels(data_desc->streams());
1039 }
1040 }
1041
1042 // Iterate new_streams and notify the observer about new MediaStreams.
1043 for (size_t i = 0; i < new_streams->count(); ++i) {
1044 MediaStreamInterface* new_stream = new_streams->at(i);
1045 stats_->AddStream(new_stream);
1046 observer_->OnAddStream(new_stream);
1047 }
1048
1049 // Find removed MediaStreams.
1050 if (remote_info_.IsDefaultMediaStreamNeeded() &&
1051 remote_streams_->find(kDefaultStreamLabel) != nullptr) {
1052 // The default media stream already exists. No need to do anything.
1053 } else {
1054 UpdateEndedRemoteMediaStreams();
1055 remote_info_.msid_supported |= remote_streams_->count() > 0;
1056 }
1057 MaybeCreateDefaultStream();
1058
1059 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
672 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); 1060 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
673 } 1061 }
674 1062
675 void PeerConnection::PostSetSessionDescriptionFailure(
676 SetSessionDescriptionObserver* observer,
677 const std::string& error) {
678 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
679 msg->error = error;
680 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
681 }
682
683 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { 1063 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) {
684 if (port_allocator_) { 1064 if (port_allocator_) {
685 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns; 1065 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns;
686 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns; 1066 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns;
687 if (!ParseIceServers(config.servers, &stuns, &turns)) { 1067 if (!ParseIceServers(config.servers, &stuns, &turns)) {
688 return false; 1068 return false;
689 } 1069 }
690 1070
691 std::vector<rtc::SocketAddress> stun_hosts; 1071 std::vector<rtc::SocketAddress> stun_hosts;
692 typedef std::vector<StunConfiguration>::const_iterator StunIt; 1072 typedef std::vector<StunConfiguration>::const_iterator StunIt;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 delete param; 1184 delete param;
805 break; 1185 break;
806 } 1186 }
807 case MSG_SET_SESSIONDESCRIPTION_FAILED: { 1187 case MSG_SET_SESSIONDESCRIPTION_FAILED: {
808 SetSessionDescriptionMsg* param = 1188 SetSessionDescriptionMsg* param =
809 static_cast<SetSessionDescriptionMsg*>(msg->pdata); 1189 static_cast<SetSessionDescriptionMsg*>(msg->pdata);
810 param->observer->OnFailure(param->error); 1190 param->observer->OnFailure(param->error);
811 delete param; 1191 delete param;
812 break; 1192 break;
813 } 1193 }
1194 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: {
1195 CreateSessionDescriptionMsg* param =
1196 static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
1197 param->observer->OnFailure(param->error);
1198 delete param;
1199 break;
1200 }
814 case MSG_GETSTATS: { 1201 case MSG_GETSTATS: {
815 GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata); 1202 GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata);
816 StatsReports reports; 1203 StatsReports reports;
817 stats_->GetStats(param->track, &reports); 1204 stats_->GetStats(param->track, &reports);
818 param->observer->OnComplete(reports); 1205 param->observer->OnComplete(reports);
819 delete param; 1206 delete param;
820 break; 1207 break;
821 } 1208 }
822 default: 1209 default:
823 ASSERT(false && "Not implemented"); 1210 ASSERT(false && "Not implemented");
824 break; 1211 break;
825 } 1212 }
826 } 1213 }
827 1214
828 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { 1215 void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream,
829 stats_->AddStream(stream); 1216 AudioTrackInterface* audio_track,
830 observer_->OnAddStream(stream); 1217 uint32 ssrc) {
831 }
832
833 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) {
834 observer_->OnRemoveStream(stream);
835 }
836
837 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) {
838 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(),
839 data_channel));
840 }
841
842 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream,
843 AudioTrackInterface* audio_track,
844 uint32 ssrc) {
845 receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get())); 1218 receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get()));
846 } 1219 }
847 1220
848 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, 1221 void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream,
849 VideoTrackInterface* video_track, 1222 VideoTrackInterface* video_track,
850 uint32 ssrc) { 1223 uint32 ssrc) {
851 receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get())); 1224 receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get()));
852 } 1225 }
853 1226
854 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote 1227 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
855 // description. 1228 // description.
856 void PeerConnection::OnRemoveRemoteAudioTrack( 1229 void PeerConnection::DestroyAudioReceiver(MediaStreamInterface* stream,
857 MediaStreamInterface* stream, 1230 AudioTrackInterface* audio_track) {
858 AudioTrackInterface* audio_track) {
859 auto it = FindReceiverForTrack(audio_track); 1231 auto it = FindReceiverForTrack(audio_track);
860 if (it == receivers_.end()) { 1232 if (it == receivers_.end()) {
861 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() 1233 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id()
862 << " doesn't exist."; 1234 << " doesn't exist.";
863 } else { 1235 } else {
864 (*it)->Stop(); 1236 (*it)->Stop();
865 receivers_.erase(it); 1237 receivers_.erase(it);
866 } 1238 }
867 } 1239 }
868 1240
869 void PeerConnection::OnRemoveRemoteVideoTrack( 1241 void PeerConnection::DestroyVideoReceiver(MediaStreamInterface* stream,
870 MediaStreamInterface* stream, 1242 VideoTrackInterface* video_track) {
871 VideoTrackInterface* video_track) {
872 auto it = FindReceiverForTrack(video_track); 1243 auto it = FindReceiverForTrack(video_track);
873 if (it == receivers_.end()) { 1244 if (it == receivers_.end()) {
874 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() 1245 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id()
875 << " doesn't exist."; 1246 << " doesn't exist.";
876 } else { 1247 } else {
877 (*it)->Stop(); 1248 (*it)->Stop();
878 receivers_.erase(it); 1249 receivers_.erase(it);
879 } 1250 }
880 } 1251 }
881 1252
882 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, 1253 void PeerConnection::CreateAudioSender(MediaStreamInterface* stream,
883 AudioTrackInterface* audio_track, 1254 AudioTrackInterface* audio_track,
884 uint32 ssrc) { 1255 uint32 ssrc) {
885 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get())); 1256 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get()));
886 stats_->AddLocalAudioTrack(audio_track, ssrc); 1257 stats_->AddLocalAudioTrack(audio_track, ssrc);
887 } 1258 }
888 1259
889 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, 1260 void PeerConnection::CreateVideoSender(MediaStreamInterface* stream,
890 VideoTrackInterface* video_track, 1261 VideoTrackInterface* video_track,
891 uint32 ssrc) { 1262 uint32 ssrc) {
892 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get())); 1263 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get()));
893 } 1264 }
894 1265
895 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local 1266 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local
896 // description. 1267 // description.
897 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, 1268 void PeerConnection::DestroyAudioSender(MediaStreamInterface* stream,
898 AudioTrackInterface* audio_track, 1269 AudioTrackInterface* audio_track,
899 uint32 ssrc) { 1270 uint32 ssrc) {
900 auto it = FindSenderForTrack(audio_track); 1271 auto it = FindSenderForTrack(audio_track);
901 if (it == senders_.end()) { 1272 if (it == senders_.end()) {
902 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id() 1273 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id()
903 << " doesn't exist."; 1274 << " doesn't exist.";
904 return; 1275 return;
905 } else { 1276 } else {
906 (*it)->Stop(); 1277 (*it)->Stop();
907 senders_.erase(it); 1278 senders_.erase(it);
908 } 1279 }
909 stats_->RemoveLocalAudioTrack(audio_track, ssrc); 1280 stats_->RemoveLocalAudioTrack(audio_track, ssrc);
910 } 1281 }
911 1282
912 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, 1283 void PeerConnection::DestroyVideoSender(MediaStreamInterface* stream,
913 VideoTrackInterface* video_track) { 1284 VideoTrackInterface* video_track) {
914 auto it = FindSenderForTrack(video_track); 1285 auto it = FindSenderForTrack(video_track);
915 if (it == senders_.end()) { 1286 if (it == senders_.end()) {
916 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id() 1287 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id()
917 << " doesn't exist."; 1288 << " doesn't exist.";
918 return; 1289 return;
919 } else { 1290 } else {
920 (*it)->Stop(); 1291 (*it)->Stop();
921 senders_.erase(it); 1292 senders_.erase(it);
922 } 1293 }
923 } 1294 }
924 1295
925 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) {
926 }
927
928 void PeerConnection::OnIceConnectionChange( 1296 void PeerConnection::OnIceConnectionChange(
929 PeerConnectionInterface::IceConnectionState new_state) { 1297 PeerConnectionInterface::IceConnectionState new_state) {
930 ASSERT(signaling_thread()->IsCurrent()); 1298 ASSERT(signaling_thread()->IsCurrent());
931 // After transitioning to "closed", ignore any additional states from 1299 // After transitioning to "closed", ignore any additional states from
932 // WebRtcSession (such as "disconnected"). 1300 // WebRtcSession (such as "disconnected").
933 if (ice_connection_state_ == kIceConnectionClosed) { 1301 if (IsClosed()) {
934 return; 1302 return;
935 } 1303 }
936 ice_connection_state_ = new_state; 1304 ice_connection_state_ = new_state;
937 observer_->OnIceConnectionChange(ice_connection_state_); 1305 observer_->OnIceConnectionChange(ice_connection_state_);
938 } 1306 }
939 1307
940 void PeerConnection::OnIceGatheringChange( 1308 void PeerConnection::OnIceGatheringChange(
941 PeerConnectionInterface::IceGatheringState new_state) { 1309 PeerConnectionInterface::IceGatheringState new_state) {
942 ASSERT(signaling_thread()->IsCurrent()); 1310 ASSERT(signaling_thread()->IsCurrent());
943 if (IsClosed()) { 1311 if (IsClosed()) {
(...skipping 26 matching lines...) Expand all
970 observer_->OnIceConnectionChange(ice_connection_state_); 1338 observer_->OnIceConnectionChange(ice_connection_state_);
971 if (ice_gathering_state_ != kIceGatheringComplete) { 1339 if (ice_gathering_state_ != kIceGatheringComplete) {
972 ice_gathering_state_ = kIceGatheringComplete; 1340 ice_gathering_state_ = kIceGatheringComplete;
973 observer_->OnIceGatheringChange(ice_gathering_state_); 1341 observer_->OnIceGatheringChange(ice_gathering_state_);
974 } 1342 }
975 } 1343 }
976 observer_->OnSignalingChange(signaling_state_); 1344 observer_->OnSignalingChange(signaling_state_);
977 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); 1345 observer_->OnStateChange(PeerConnectionObserver::kSignalingState);
978 } 1346 }
979 1347
1348 void PeerConnection::PostSetSessionDescriptionFailure(
1349 SetSessionDescriptionObserver* observer,
1350 const std::string& error) {
1351 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
1352 msg->error = error;
1353 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
1354 }
1355
1356 void PeerConnection::PostCreateSessionDescriptionFailure(
1357 CreateSessionDescriptionObserver* observer,
1358 const std::string& error) {
1359 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
1360 msg->error = error;
1361 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
1362 }
1363
1364 bool PeerConnection::GetOptionsForOffer(
1365 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
1366 cricket::MediaSessionOptions* session_options) {
1367 SetStreams(session_options, local_streams_, rtp_data_channels_);
1368
1369 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) {
1370 return false;
1371 }
1372
1373 if (session_->data_channel_type() == cricket::DCT_SCTP && HasDataChannels()) {
1374 session_options->data_channel_type = cricket::DCT_SCTP;
1375 }
1376 return true;
1377 }
1378
1379 bool PeerConnection::GetOptionsForAnswer(
1380 const MediaConstraintsInterface* constraints,
1381 cricket::MediaSessionOptions* session_options) {
1382 SetStreams(session_options, local_streams_, rtp_data_channels_);
1383 session_options->recv_audio = false;
1384 session_options->recv_video = false;
1385
1386 if (!ParseConstraintsForAnswer(constraints, session_options)) {
1387 return false;
1388 }
1389
1390 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
1391 // are not signaled in the SDP so does not go through that path and must be
1392 // handled here.
1393 if (session_->data_channel_type() == cricket::DCT_SCTP) {
1394 session_options->data_channel_type = cricket::DCT_SCTP;
1395 }
1396 return true;
1397 }
1398
1399 void PeerConnection::UpdateRemoteStreamsList(
1400 const cricket::StreamParamsVec& streams,
1401 cricket::MediaType media_type,
1402 StreamCollection* new_streams) {
1403 TrackInfos* current_tracks = GetRemoteTracks(media_type);
1404
1405 // Find removed tracks. I.e., tracks where the track id or ssrc don't match
1406 // the
1407 // new StreamParam.
1408 auto track_it = current_tracks->begin();
1409 while (track_it != current_tracks->end()) {
1410 const TrackInfo& info = *track_it;
1411 const cricket::StreamParams* params =
1412 cricket::GetStreamBySsrc(streams, info.ssrc);
1413 if (!params || params->id != info.track_id) {
1414 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type);
1415 track_it = current_tracks->erase(track_it);
1416 } else {
1417 ++track_it;
1418 }
1419 }
1420
1421 // Find new and active tracks.
1422 for (const cricket::StreamParams& params : streams) {
1423 // The sync_label is the MediaStream label and the |stream.id| is the
1424 // track id.
1425 const std::string& stream_label = params.sync_label;
1426 const std::string& track_id = params.id;
1427 uint32 ssrc = params.first_ssrc();
1428
1429 rtc::scoped_refptr<MediaStreamInterface> stream =
1430 remote_streams_->find(stream_label);
1431 if (!stream) {
1432 // This is a new MediaStream. Create a new remote MediaStream.
1433 stream = remote_stream_factory_->CreateMediaStream(stream_label);
1434 remote_streams_->AddStream(stream);
1435 new_streams->AddStream(stream);
1436 }
1437
1438 const TrackInfo* track_info =
1439 FindTrackInfo(*current_tracks, stream_label, track_id);
1440 if (!track_info) {
1441 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc));
1442 OnRemoteTrackSeen(stream_label, track_id, ssrc, media_type);
1443 }
1444 }
1445 }
1446
1447 void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label,
1448 const std::string& track_id,
1449 uint32 ssrc,
1450 cricket::MediaType media_type) {
1451 MediaStreamInterface* stream = remote_streams_->find(stream_label);
1452
1453 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
1454 AudioTrackInterface* audio_track =
1455 remote_stream_factory_->AddAudioTrack(stream, track_id);
1456 CreateAudioReceiver(stream, audio_track, ssrc);
1457 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1458 VideoTrackInterface* video_track =
1459 remote_stream_factory_->AddVideoTrack(stream, track_id);
1460 CreateVideoReceiver(stream, video_track, ssrc);
1461 } else {
1462 RTC_DCHECK(false && "Invalid media type");
1463 }
1464 }
1465
1466 void PeerConnection::OnRemoteTrackRemoved(const std::string& stream_label,
1467 const std::string& track_id,
1468 cricket::MediaType media_type) {
1469 MediaStreamInterface* stream = remote_streams_->find(stream_label);
1470
1471 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
1472 rtc::scoped_refptr<AudioTrackInterface> audio_track =
1473 stream->FindAudioTrack(track_id);
1474 if (audio_track) {
1475 audio_track->set_state(webrtc::MediaStreamTrackInterface::kEnded);
1476 stream->RemoveTrack(audio_track);
1477 DestroyAudioReceiver(stream, audio_track);
1478 }
1479 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1480 rtc::scoped_refptr<VideoTrackInterface> video_track =
1481 stream->FindVideoTrack(track_id);
1482 if (video_track) {
1483 video_track->set_state(webrtc::MediaStreamTrackInterface::kEnded);
1484 stream->RemoveTrack(video_track);
1485 DestroyVideoReceiver(stream, video_track);
1486 }
1487 } else {
1488 ASSERT(false && "Invalid media type");
1489 }
1490 }
1491
1492 void PeerConnection::UpdateEndedRemoteMediaStreams() {
1493 std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_to_remove;
1494 for (size_t i = 0; i < remote_streams_->count(); ++i) {
1495 MediaStreamInterface* stream = remote_streams_->at(i);
1496 if (stream->GetAudioTracks().empty() && stream->GetVideoTracks().empty()) {
1497 streams_to_remove.push_back(stream);
1498 }
1499 }
1500
1501 for (const auto& stream : streams_to_remove) {
1502 remote_streams_->RemoveStream(stream);
1503 observer_->OnRemoveStream(stream);
1504 }
1505 }
1506
1507 void PeerConnection::MaybeCreateDefaultStream() {
1508 if (!remote_info_.IsDefaultMediaStreamNeeded()) {
1509 return;
1510 }
1511
1512 bool default_created = false;
1513
1514 rtc::scoped_refptr<MediaStreamInterface> default_remote_stream =
1515 remote_streams_->find(kDefaultStreamLabel);
1516 if (default_remote_stream == nullptr) {
1517 default_created = true;
1518 default_remote_stream =
1519 remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel);
1520 remote_streams_->AddStream(default_remote_stream);
1521 }
1522 if (remote_info_.default_audio_track_needed &&
1523 default_remote_stream->GetAudioTracks().size() == 0) {
1524 remote_audio_tracks_.push_back(
1525 TrackInfo(kDefaultStreamLabel, kDefaultAudioTrackLabel, 0));
1526 OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultAudioTrackLabel, 0,
1527 cricket::MEDIA_TYPE_AUDIO);
1528 }
1529 if (remote_info_.default_video_track_needed &&
1530 default_remote_stream->GetVideoTracks().size() == 0) {
1531 remote_video_tracks_.push_back(
1532 TrackInfo(kDefaultStreamLabel, kDefaultVideoTrackLabel, 0));
1533 OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultVideoTrackLabel, 0,
1534 cricket::MEDIA_TYPE_VIDEO);
1535 }
1536 if (default_created) {
1537 stats_->AddStream(default_remote_stream);
1538 observer_->OnAddStream(default_remote_stream);
1539 }
1540 }
1541
1542 void PeerConnection::RejectRemoteTracks(cricket::MediaType media_type) {
pthatcher1 2015/10/08 05:23:54 Should this be called EndRemoteTracks? All it doe
Taylor Brandstetter 2015/10/09 19:54:09 I agree; done. Funny enough, I think we already ma
1543 TrackInfos* current_tracks = GetRemoteTracks(media_type);
1544 for (TrackInfos::iterator track_it = current_tracks->begin();
1545 track_it != current_tracks->end(); ++track_it) {
1546 const TrackInfo& info = *track_it;
1547 MediaStreamInterface* stream = remote_streams_->find(info.stream_label);
1548 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
1549 AudioTrackInterface* track = stream->FindAudioTrack(info.track_id);
1550 // There's no guarantee the track is still available, e.g. the track may
1551 // have been removed from the stream by javascript.
1552 if (track) {
1553 track->set_state(webrtc::MediaStreamTrackInterface::kEnded);
1554 }
1555 }
1556 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1557 VideoTrackInterface* track = stream->FindVideoTrack(info.track_id);
1558 // There's no guarantee the track is still available, e.g. the track may
1559 // have been removed from the stream by javascript.
1560 if (track) {
1561 track->set_state(webrtc::MediaStreamTrackInterface::kEnded);
1562 }
1563 }
1564 }
1565 }
1566
1567 void PeerConnection::UpdateLocalTracks(
1568 const std::vector<cricket::StreamParams>& streams,
1569 cricket::MediaType media_type) {
1570 TrackInfos* current_tracks = GetLocalTracks(media_type);
1571
1572 // Find removed tracks. I.e., tracks where the track id, stream label or ssrc
1573 // don't match the new StreamParam.
1574 TrackInfos::iterator track_it = current_tracks->begin();
1575 while (track_it != current_tracks->end()) {
1576 const TrackInfo& info = *track_it;
1577 const cricket::StreamParams* params =
1578 cricket::GetStreamBySsrc(streams, info.ssrc);
1579 if (!params || params->id != info.track_id ||
1580 params->sync_label != info.stream_label) {
1581 OnLocalTrackRemoved(info.stream_label, info.track_id, info.ssrc,
1582 media_type);
1583 track_it = current_tracks->erase(track_it);
1584 } else {
1585 ++track_it;
1586 }
1587 }
1588
1589 // Find new and active tracks.
1590 for (const cricket::StreamParams& params : streams) {
1591 // The sync_label is the MediaStream label and the |stream.id| is the
1592 // track id.
1593 const std::string& stream_label = params.sync_label;
1594 const std::string& track_id = params.id;
1595 uint32 ssrc = params.first_ssrc();
1596 const TrackInfo* track_info =
1597 FindTrackInfo(*current_tracks, stream_label, track_id);
1598 if (!track_info) {
1599 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc));
1600 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type);
1601 }
1602 }
1603 }
1604
1605 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label,
1606 const std::string& track_id,
1607 uint32 ssrc,
1608 cricket::MediaType media_type) {
1609 MediaStreamInterface* stream = local_streams_->find(stream_label);
1610 if (!stream) {
1611 LOG(LS_WARNING) << "An unknown local MediaStream with label "
1612 << stream_label << " has been configured.";
1613 return;
1614 }
1615
1616 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
1617 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id);
1618 if (!audio_track) {
1619 LOG(LS_WARNING) << "An unknown local AudioTrack with id , " << track_id
1620 << " has been configured.";
1621 return;
1622 }
1623 CreateAudioSender(stream, audio_track, ssrc);
1624 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1625 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1626 if (!video_track) {
1627 LOG(LS_WARNING) << "An unknown local VideoTrack with id , " << track_id
1628 << " has been configured.";
1629 return;
1630 }
1631 CreateVideoSender(stream, video_track, ssrc);
1632 } else {
1633 RTC_DCHECK(false && "Invalid media type");
1634 }
1635 }
1636
1637 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label,
1638 const std::string& track_id,
1639 uint32 ssrc,
1640 cricket::MediaType media_type) {
1641 MediaStreamInterface* stream = local_streams_->find(stream_label);
1642 if (!stream) {
1643 // This is the normal case. I.e., RemoveLocalStream has been called and the
1644 // SessionDescriptions has been renegotiated.
1645 return;
1646 }
1647 // A track has been removed from the SessionDescription but the MediaStream
1648 // is still associated with PeerConnection. This only occurs if the SDP
1649 // doesn't match with the calls to AddLocalStream and RemoveLocalStream.
1650 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
1651 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id);
1652 if (!audio_track) {
1653 return;
1654 }
1655 DestroyAudioSender(stream, audio_track, ssrc);
1656 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1657 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1658 if (!video_track) {
1659 return;
1660 }
1661 DestroyVideoSender(stream, video_track);
1662 } else {
1663 RTC_DCHECK(false && "Invalid media type.");
1664 }
1665 }
1666
1667 void PeerConnection::UpdateLocalRtpDataChannels(
1668 const cricket::StreamParamsVec& streams) {
1669 std::vector<std::string> existing_channels;
1670
1671 // Find new and active data channels.
1672 for (const cricket::StreamParams& params : streams) {
1673 // |it->sync_label| is actually the data channel label. The reason is that
1674 // we use the same naming of data channels as we do for
1675 // MediaStreams and Tracks.
1676 // For MediaStreams, the sync_label is the MediaStream label and the
1677 // track label is the same as |streamid|.
1678 const std::string& channel_label = params.sync_label;
1679 auto data_channel_it = rtp_data_channels_.find(channel_label);
1680 if (!VERIFY(data_channel_it != rtp_data_channels_.end())) {
1681 continue;
1682 }
1683 // Set the SSRC the data channel should use for sending.
1684 data_channel_it->second->SetSendSsrc(params.first_ssrc());
1685 existing_channels.push_back(data_channel_it->first);
1686 }
1687
1688 UpdateClosingRtpDataChannels(existing_channels, true);
1689 }
1690
1691 void PeerConnection::UpdateRemoteRtpDataChannels(
1692 const cricket::StreamParamsVec& streams) {
1693 std::vector<std::string> existing_channels;
1694
1695 // Find new and active data channels.
1696 for (const cricket::StreamParams& params : streams) {
1697 // The data channel label is either the mslabel or the SSRC if the mslabel
1698 // does not exist. Ex a=ssrc:444330170 mslabel:test1.
1699 std::string label = params.sync_label.empty()
1700 ? rtc::ToString(params.first_ssrc())
1701 : params.sync_label;
1702 auto data_channel_it = rtp_data_channels_.find(label);
1703 if (data_channel_it == rtp_data_channels_.end()) {
1704 // This is a new data channel.
1705 CreateRemoteRtpDataChannel(label, params.first_ssrc());
1706 } else {
1707 data_channel_it->second->SetReceiveSsrc(params.first_ssrc());
1708 }
1709 existing_channels.push_back(label);
1710 }
1711
1712 UpdateClosingRtpDataChannels(existing_channels, false);
1713 }
1714
1715 void PeerConnection::UpdateClosingRtpDataChannels(
1716 const std::vector<std::string>& active_channels,
1717 bool is_local_update) {
1718 auto it = rtp_data_channels_.begin();
1719 while (it != rtp_data_channels_.end()) {
1720 DataChannel* data_channel = it->second;
1721 if (std::find(active_channels.begin(), active_channels.end(),
1722 data_channel->label()) != active_channels.end()) {
1723 ++it;
1724 continue;
1725 }
1726
1727 if (is_local_update) {
1728 data_channel->SetSendSsrc(0);
1729 } else {
1730 data_channel->RemotePeerRequestClose();
1731 }
1732
1733 if (data_channel->state() == DataChannel::kClosed) {
1734 it = rtp_data_channels_.erase(it);
1735 } else {
1736 ++it;
1737 }
1738 }
1739 }
1740
1741 void PeerConnection::CreateRemoteRtpDataChannel(const std::string& label,
1742 uint32 remote_ssrc) {
1743 rtc::scoped_refptr<DataChannel> channel(
1744 InternalCreateDataChannel(label, nullptr));
1745 if (!channel.get()) {
1746 LOG(LS_WARNING) << "Remote peer requested a DataChannel but"
1747 << "CreateDataChannel failed.";
1748 return;
1749 }
1750 channel->SetReceiveSsrc(remote_ssrc);
1751 observer_->OnDataChannel(
1752 DataChannelProxy::Create(signaling_thread(), channel));
1753 }
1754
1755 rtc::scoped_refptr<DataChannel> PeerConnection::InternalCreateDataChannel(
1756 const std::string& label,
1757 const InternalDataChannelInit* config) {
1758 if (IsClosed()) {
1759 return nullptr;
1760 }
1761 if (session_->data_channel_type() == cricket::DCT_NONE) {
1762 LOG(LS_ERROR)
1763 << "InternalCreateDataChannel: Data is not supported in this call.";
1764 return nullptr;
1765 }
1766 InternalDataChannelInit new_config =
1767 config ? (*config) : InternalDataChannelInit();
1768 if (session_->data_channel_type() == cricket::DCT_SCTP) {
1769 if (new_config.id < 0) {
1770 rtc::SSLRole role;
1771 if (session_->GetSslRole(&role) &&
1772 !sid_allocator_.AllocateSctpSid(role, &new_config.id)) {
1773 LOG(LS_ERROR) << "No id can be allocated for the SCTP data channel.";
1774 return nullptr;
1775 }
1776 } else if (!sid_allocator_.ReserveSctpSid(new_config.id)) {
1777 LOG(LS_ERROR) << "Failed to create a SCTP data channel "
1778 << "because the id is already in use or out of range.";
1779 return nullptr;
1780 }
1781 }
1782
1783 rtc::scoped_refptr<DataChannel> channel(DataChannel::Create(
1784 session_.get(), session_->data_channel_type(), label, new_config));
1785 if (!channel) {
1786 sid_allocator_.ReleaseSctpSid(new_config.id);
1787 return nullptr;
1788 }
1789
1790 if (channel->data_channel_type() == cricket::DCT_RTP) {
1791 if (rtp_data_channels_.find(channel->label()) != rtp_data_channels_.end()) {
1792 LOG(LS_ERROR) << "DataChannel with label " << channel->label()
1793 << " already exists.";
1794 return nullptr;
1795 }
1796 rtp_data_channels_[channel->label()] = channel;
1797 } else {
1798 RTC_DCHECK(channel->data_channel_type() == cricket::DCT_SCTP);
1799 sctp_data_channels_.push_back(channel);
1800 channel->SignalClosed.connect(this,
1801 &PeerConnection::OnSctpDataChannelClosed);
1802 }
1803
1804 return channel;
1805 }
1806
1807 bool PeerConnection::HasDataChannels() const {
1808 return !rtp_data_channels_.empty() || !sctp_data_channels_.empty();
1809 }
1810
1811 void PeerConnection::AllocateSctpSids(rtc::SSLRole role) {
1812 for (const auto& channel : sctp_data_channels_) {
1813 if (channel->id() < 0) {
1814 int sid;
1815 if (!sid_allocator_.AllocateSctpSid(role, &sid)) {
1816 LOG(LS_ERROR) << "Failed to allocate SCTP sid.";
1817 continue;
1818 }
1819 channel->SetSctpSid(sid);
1820 }
1821 }
1822 }
1823
1824 void PeerConnection::OnSctpDataChannelClosed(DataChannel* channel) {
1825 for (auto it = sctp_data_channels_.begin(); it != sctp_data_channels_.end();
1826 ++it) {
1827 if (it->get() == channel) {
1828 int sid = channel->id();
1829 RTC_DCHECK(sid >= 0);
1830 sid_allocator_.ReleaseSctpSid(sid);
1831 sctp_data_channels_.erase(it);
1832 return;
1833 }
1834 }
1835 }
1836
1837 void PeerConnection::OnVoiceChannelDestroyed() {
1838 RejectRemoteTracks(cricket::MEDIA_TYPE_AUDIO);
1839 }
1840
1841 void PeerConnection::OnVideoChannelDestroyed() {
1842 RejectRemoteTracks(cricket::MEDIA_TYPE_VIDEO);
1843 }
1844
1845 void PeerConnection::OnDataChannelCreated() {
1846 for (const auto& channel : sctp_data_channels_) {
1847 channel->OnTransportChannelCreated();
1848 }
1849 }
1850
1851 void PeerConnection::OnDataChannelDestroyed() {
1852 // Use a temporary copy of the RTP/SCTP DataChannel list because the
1853 // DataChannel may callback to us and try to modify the list.
1854 std::map<std::string, rtc::scoped_refptr<DataChannel>> temp_rtp_dcs;
1855 temp_rtp_dcs.swap(rtp_data_channels_);
1856 for (const auto& kv : temp_rtp_dcs) {
1857 kv.second->OnDataEngineClose();
pthatcher1 2015/10/08 05:23:54 Can we rename these so they are consistent with on
Taylor Brandstetter 2015/10/09 19:54:09 Well, since the cricket::DataChannel actually IS b
pthatcher1 2015/10/09 21:12:26 Sounds good.
1858 }
1859
1860 std::vector<rtc::scoped_refptr<DataChannel>> temp_sctp_dcs;
1861 temp_sctp_dcs.swap(sctp_data_channels_);
1862 for (const auto& channel : temp_sctp_dcs) {
1863 channel->OnDataEngineClose();
1864 }
1865 }
1866
1867 void PeerConnection::OnDataChannelCreationRequested(
1868 const std::string& label,
1869 const InternalDataChannelInit& config) {
1870 rtc::scoped_refptr<DataChannel> channel(
1871 InternalCreateDataChannel(label, &config));
1872 if (!channel.get()) {
1873 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message.";
1874 return;
1875 }
1876
1877 observer_->OnDataChannel(
1878 DataChannelProxy::Create(signaling_thread(), channel));
1879 }
1880
980 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator 1881 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
981 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { 1882 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) {
982 return std::find_if( 1883 return std::find_if(
983 senders_.begin(), senders_.end(), 1884 senders_.begin(), senders_.end(),
984 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { 1885 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
985 return sender->track() == track; 1886 return sender->track() == track;
986 }); 1887 });
987 } 1888 }
988 1889
989 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator 1890 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
990 PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) { 1891 PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) {
991 return std::find_if( 1892 return std::find_if(
992 receivers_.begin(), receivers_.end(), 1893 receivers_.begin(), receivers_.end(),
993 [track](const rtc::scoped_refptr<RtpReceiverInterface>& receiver) { 1894 [track](const rtc::scoped_refptr<RtpReceiverInterface>& receiver) {
994 return receiver->track() == track; 1895 return receiver->track() == track;
995 }); 1896 });
996 } 1897 }
997 1898
1899 PeerConnection::TrackInfos* PeerConnection::GetRemoteTracks(
1900 cricket::MediaType media_type) {
1901 RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
1902 media_type == cricket::MEDIA_TYPE_VIDEO);
1903 return (media_type == cricket::MEDIA_TYPE_AUDIO) ? &remote_audio_tracks_
1904 : &remote_video_tracks_;
1905 }
1906
1907 PeerConnection::TrackInfos* PeerConnection::GetLocalTracks(
1908 cricket::MediaType media_type) {
1909 RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
1910 media_type == cricket::MEDIA_TYPE_VIDEO);
1911 return (media_type == cricket::MEDIA_TYPE_AUDIO) ? &local_audio_tracks_
1912 : &local_video_tracks_;
1913 }
1914
1915 const PeerConnection::TrackInfo* PeerConnection::FindTrackInfo(
1916 const PeerConnection::TrackInfos& infos,
1917 const std::string& stream_label,
1918 const std::string track_id) const {
1919 for (const TrackInfo& track_info : infos) {
1920 if (track_info.stream_label == stream_label &&
1921 track_info.track_id == track_id) {
1922 return &track_info;
1923 }
1924 }
1925 return nullptr;
1926 }
1927
1928 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
1929 for (const auto& channel : sctp_data_channels_) {
1930 if (channel->id() == sid) {
1931 return channel;
1932 }
1933 }
1934 return nullptr;
1935 }
1936
998 } // namespace webrtc 1937 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698