Index: webrtc/api/peerconnection.cc |
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc |
index ee359271c2fc2573b2f209d9af2c365ed6a5970c..2ba64688d16887d68271ecbdabdae13d6bcf4e86 100644 |
--- a/webrtc/api/peerconnection.cc |
+++ b/webrtc/api/peerconnection.cc |
@@ -19,7 +19,6 @@ |
#include "webrtc/api/dtmfsender.h" |
#include "webrtc/api/jsepicecandidate.h" |
#include "webrtc/api/jsepsessiondescription.h" |
-#include "webrtc/api/mediaconstraintsinterface.h" |
#include "webrtc/api/mediastream.h" |
#include "webrtc/api/mediastreamobserver.h" |
#include "webrtc/api/mediastreamproxy.h" |
@@ -540,6 +539,94 @@ bool ParseIceServers(const PeerConnectionInterface::IceServers& servers, |
return true; |
} |
+class PeerConnection::StoredConstraints : public MediaConstraintsInterface { |
+ public: |
+ explicit StoredConstraints(const MediaConstraintsInterface* constraints) { |
+ if (constraints) { |
+ mandatory_ = constraints->GetMandatory(); |
+ optional_ = constraints->GetOptional(); |
+ } |
+ } |
+ ~StoredConstraints() override {} |
+ |
+ const MediaConstraintsInterface::Constraints& |
+ GetMandatory() const override { return mandatory_; } |
+ const MediaConstraintsInterface::Constraints& |
+ GetOptional() const override { return optional_; } |
+ private: |
+ MediaConstraintsInterface::Constraints mandatory_; |
+ MediaConstraintsInterface::Constraints optional_; |
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(StoredConstraints); |
+}; |
+ |
+class PeerConnection::LiveSession { |
pthatcher1
2016/02/26 21:51:20
What is a LiveSession? It appears to be a random
the sun
2016/02/29 15:58:22
Indeed. Great suggestion! Look at the current solu
|
+ public: |
+ LiveSession(PeerConnection* pc, |
+ PeerConnectionFactory* factory, |
+ cricket::PortAllocator* port_allocator, |
+ const cricket::MediaConfig& media_config, |
+ const PeerConnectionInterface::RTCConfiguration& configuration, |
+ const MediaConstraintsInterface* constraints, |
+ rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store) { |
+ RTC_DCHECK(pc); |
+ RTC_DCHECK(factory); |
+ RTC_DCHECK(port_allocator); |
+ RTC_DCHECK(constraints); |
+ media_controller_.reset(factory->CreateMediaController(media_config)); |
+ remote_stream_factory_.reset(new RemoteMediaStreamFactory( |
+ factory->signaling_thread(), media_controller_->channel_manager())); |
+ session_.reset( |
+ new WebRtcSession(media_controller_.get(), factory->signaling_thread(), |
+ factory->worker_thread(), port_allocator)); |
+ stats_.reset(new StatsCollector(pc)); |
+ |
+ // Initialize the WebRtcSession. It creates transport channels etc. |
+ RTC_CHECK(session_->Initialize(factory->options(), constraints, |
+ std::move(dtls_identity_store), configuration)); |
+ |
+ // Register PeerConnection as receiver of local ice candidates. |
+ // All the callbacks will be posted to the application from PeerConnection. |
+ session_->RegisterIceObserver(pc); |
+ session_->SignalState.connect(pc, &PeerConnection::OnSessionStateChange); |
+ session_->SignalVoiceChannelDestroyed.connect( |
+ pc, &PeerConnection::OnVoiceChannelDestroyed); |
+ session_->SignalVideoChannelDestroyed.connect( |
+ pc, &PeerConnection::OnVideoChannelDestroyed); |
+ session_->SignalDataChannelCreated.connect( |
+ pc, &PeerConnection::OnDataChannelCreated); |
+ session_->SignalDataChannelDestroyed.connect( |
+ pc, &PeerConnection::OnDataChannelDestroyed); |
+ session_->SignalDataChannelOpenMessage.connect( |
+ pc, &PeerConnection::OnDataChannelOpenMessage); |
+ } |
+ |
+ ~LiveSession() { |
+ // TODO(solenberg): Disconnect signals. Kill kill kill. |
+ } |
+ |
+ RemoteMediaStreamFactory* remote_stream_factory() { |
+ return remote_stream_factory_.get(); |
+ } |
+ WebRtcSession* session() { |
+ return session_.get(); |
+ } |
+ StatsCollector* stats() { |
+ return stats_.get(); |
+ } |
+ |
+ private: |
+ rtc::scoped_ptr<MediaControllerInterface> media_controller_; |
+ rtc::scoped_ptr<RemoteMediaStreamFactory> remote_stream_factory_; |
+ // The session_ scoped_ptr is declared at the bottom of PeerConnection |
+ // because its destruction fires signals (such as VoiceChannelDestroyed) |
+ // which will trigger some final actions in PeerConnection... |
+ rtc::scoped_ptr<WebRtcSession> session_; |
+ // ... But stats_ depends on session_ so it should be destroyed even earlier. |
+ rtc::scoped_ptr<StatsCollector> stats_; |
+ |
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LiveSession); |
+}; |
+ |
PeerConnection::PeerConnection(PeerConnectionFactory* factory) |
: factory_(factory), |
observer_(NULL), |
@@ -554,14 +641,7 @@ PeerConnection::PeerConnection(PeerConnectionFactory* factory) |
PeerConnection::~PeerConnection() { |
TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection"); |
RTC_DCHECK(signaling_thread()->IsCurrent()); |
- // Need to detach RTP senders/receivers from WebRtcSession, |
- // since it's about to be destroyed. |
- for (const auto& sender : senders_) { |
- sender->Stop(); |
- } |
- for (const auto& receiver : receivers_) { |
- receiver->Stop(); |
- } |
+ DestroyLiveSession(); |
} |
bool PeerConnection::Initialize( |
@@ -613,48 +693,19 @@ bool PeerConnection::Initialize( |
port_allocator_->set_step_delay(cricket::kMinimumStepDelay); |
// We rely on default values when constraints aren't found. |
- cricket::MediaConfig media_config; |
- |
- media_config.disable_prerenderer_smoothing = |
+ media_config_.disable_prerenderer_smoothing = |
configuration.disable_prerenderer_smoothing; |
// Find DSCP constraint. |
FindConstraint(constraints, MediaConstraintsInterface::kEnableDscp, |
- &media_config.enable_dscp, NULL); |
+ &media_config_.enable_dscp, NULL); |
// Find constraints for cpu overuse detection. |
FindConstraint(constraints, MediaConstraintsInterface::kCpuOveruseDetection, |
- &media_config.enable_cpu_overuse_detection, NULL); |
- |
- media_controller_.reset(factory_->CreateMediaController(media_config)); |
+ &media_config_.enable_cpu_overuse_detection, NULL); |
- remote_stream_factory_.reset(new RemoteMediaStreamFactory( |
- factory_->signaling_thread(), media_controller_->channel_manager())); |
- |
- session_.reset( |
- new WebRtcSession(media_controller_.get(), factory_->signaling_thread(), |
- factory_->worker_thread(), port_allocator_.get())); |
- stats_.reset(new StatsCollector(this)); |
- |
- // Initialize the WebRtcSession. It creates transport channels etc. |
- if (!session_->Initialize(factory_->options(), constraints, |
- std::move(dtls_identity_store), configuration)) { |
- return false; |
- } |
- |
- // Register PeerConnection as receiver of local ice candidates. |
- // All the callbacks will be posted to the application from PeerConnection. |
- session_->RegisterIceObserver(this); |
- session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); |
- session_->SignalVoiceChannelDestroyed.connect( |
- this, &PeerConnection::OnVoiceChannelDestroyed); |
- session_->SignalVideoChannelDestroyed.connect( |
- this, &PeerConnection::OnVideoChannelDestroyed); |
- session_->SignalDataChannelCreated.connect( |
- this, &PeerConnection::OnDataChannelCreated); |
- session_->SignalDataChannelDestroyed.connect( |
- this, &PeerConnection::OnDataChannelDestroyed); |
- session_->SignalDataChannelOpenMessage.connect( |
- this, &PeerConnection::OnDataChannelOpenMessage); |
+ configuration_ = configuration; |
+ constraints_.reset(new StoredConstraints(constraints)); |
+ dtls_identity_store_ = std::move(dtls_identity_store); |
return true; |
} |
@@ -696,7 +747,7 @@ bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
OnVideoTrackAdded(track.get(), local_stream); |
} |
- stats_->AddStream(local_stream); |
+ stats()->AddStream(local_stream); |
observer_->OnRenegotiationNeeded(); |
return true; |
} |
@@ -738,6 +789,7 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::AddTrack( |
<< "Adding a track with two streams is not currently supported."; |
return nullptr; |
} |
+ |
// TODO(deadbeef): Support adding a track to two different senders. |
if (FindSenderForTrack(track) != senders_.end()) { |
LOG(LS_ERROR) << "Sender for track " << track->id() << " already exists."; |
@@ -749,8 +801,8 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::AddTrack( |
if (track->kind() == MediaStreamTrackInterface::kAudioKind) { |
new_sender = RtpSenderProxy::Create( |
signaling_thread(), |
- new AudioRtpSender(static_cast<AudioTrackInterface*>(track), |
- session_.get(), stats_.get())); |
+ new AudioRtpSender(static_cast<AudioTrackInterface*>(track), session(), |
+ stats())); |
if (!streams.empty()) { |
new_sender->set_stream_id(streams[0]->label()); |
} |
@@ -763,7 +815,7 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::AddTrack( |
new_sender = RtpSenderProxy::Create( |
signaling_thread(), |
new VideoRtpSender(static_cast<VideoTrackInterface*>(track), |
- session_.get())); |
+ session())); |
if (!streams.empty()) { |
new_sender->set_stream_id(streams[0]->label()); |
} |
@@ -800,6 +852,11 @@ bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) { |
return true; |
} |
+WebRtcSession* PeerConnection::session() { |
+ CreateLiveSession(); |
+ return live_session_->session(); |
+} |
+ |
rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( |
AudioTrackInterface* track) { |
TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); |
@@ -813,7 +870,7 @@ rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( |
} |
rtc::scoped_refptr<DtmfSenderInterface> sender( |
- DtmfSender::Create(track, signaling_thread(), session_.get())); |
+ DtmfSender::Create(track, signaling_thread(), session())); |
if (!sender.get()) { |
LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; |
return NULL; |
@@ -828,10 +885,10 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( |
rtc::scoped_refptr<RtpSenderInterface> new_sender; |
if (kind == MediaStreamTrackInterface::kAudioKind) { |
new_sender = RtpSenderProxy::Create( |
- signaling_thread(), new AudioRtpSender(session_.get(), stats_.get())); |
+ signaling_thread(), new AudioRtpSender(session(), stats())); |
} else if (kind == MediaStreamTrackInterface::kVideoKind) { |
new_sender = RtpSenderProxy::Create(signaling_thread(), |
- new VideoRtpSender(session_.get())); |
+ new VideoRtpSender(session())); |
} else { |
LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind; |
return new_sender; |
@@ -863,7 +920,7 @@ bool PeerConnection::GetStats(StatsObserver* observer, |
return false; |
} |
- stats_->UpdateStats(level); |
+ stats()->UpdateStats(level); |
signaling_thread()->Post(this, MSG_GETSTATS, |
new GetStatsMsg(observer, track)); |
return true; |
@@ -906,7 +963,7 @@ PeerConnection::CreateDataChannel( |
// Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or |
// the first SCTP DataChannel. |
- if (session_->data_channel_type() == cricket::DCT_RTP || first_datachannel) { |
+ if (session()->data_channel_type() == cricket::DCT_RTP || first_datachannel) { |
observer_->OnRenegotiationNeeded(); |
} |
@@ -981,7 +1038,7 @@ void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, |
return; |
} |
- session_->CreateOffer(observer, options, session_options); |
+ session()->CreateOffer(observer, options, session_options); |
} |
void PeerConnection::CreateAnswer( |
@@ -1001,7 +1058,7 @@ void PeerConnection::CreateAnswer( |
return; |
} |
- session_->CreateAnswer(observer, constraints, session_options); |
+ session()->CreateAnswer(observer, constraints, session_options); |
} |
void PeerConnection::SetLocalDescription( |
@@ -1018,9 +1075,9 @@ void PeerConnection::SetLocalDescription( |
} |
// Update stats here so that we have the most recent stats for tracks and |
// streams that might be removed by updating the session description. |
- stats_->UpdateStats(kStatsOutputLevelStandard); |
+ stats()->UpdateStats(kStatsOutputLevelStandard); |
std::string error; |
- if (!session_->SetLocalDescription(desc, &error)) { |
+ if (!session()->SetLocalDescription(desc, &error)) { |
PostSetSessionDescriptionFailure(observer, error); |
return; |
} |
@@ -1028,8 +1085,8 @@ void PeerConnection::SetLocalDescription( |
// If setting the description decided our SSL role, allocate any necessary |
// SCTP sids. |
rtc::SSLRole role; |
- if (session_->data_channel_type() == cricket::DCT_SCTP && |
- session_->GetSslRole(session_->data_channel(), &role)) { |
+ if (session()->data_channel_type() == cricket::DCT_SCTP && |
+ session()->GetSslRole(session()->data_channel(), &role)) { |
AllocateSctpSids(role); |
} |
@@ -1079,7 +1136,7 @@ void PeerConnection::SetLocalDescription( |
// MaybeStartGathering needs to be called after posting |
// MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates |
// before signaling that SetLocalDescription completed. |
- session_->MaybeStartGathering(); |
+ session()->MaybeStartGathering(); |
} |
void PeerConnection::SetRemoteDescription( |
@@ -1096,9 +1153,9 @@ void PeerConnection::SetRemoteDescription( |
} |
// Update stats here so that we have the most recent stats for tracks and |
// streams that might be removed by updating the session description. |
- stats_->UpdateStats(kStatsOutputLevelStandard); |
+ stats()->UpdateStats(kStatsOutputLevelStandard); |
std::string error; |
- if (!session_->SetRemoteDescription(desc, &error)) { |
+ if (!session()->SetRemoteDescription(desc, &error)) { |
PostSetSessionDescriptionFailure(observer, error); |
return; |
} |
@@ -1106,8 +1163,8 @@ void PeerConnection::SetRemoteDescription( |
// If setting the description decided our SSL role, allocate any necessary |
// SCTP sids. |
rtc::SSLRole role; |
- if (session_->data_channel_type() == cricket::DCT_SCTP && |
- session_->GetSslRole(session_->data_channel(), &role)) { |
+ if (session()->data_channel_type() == cricket::DCT_SCTP && |
+ session()->GetSslRole(session()->data_channel(), &role)) { |
AllocateSctpSids(role); |
} |
@@ -1174,7 +1231,7 @@ void PeerConnection::SetRemoteDescription( |
// Iterate new_streams and notify the observer about new MediaStreams. |
for (size_t i = 0; i < new_streams->count(); ++i) { |
MediaStreamInterface* new_stream = new_streams->at(i); |
- stats_->AddStream(new_stream); |
+ stats()->AddStream(new_stream); |
observer_->OnAddStream(new_stream); |
} |
@@ -1194,22 +1251,22 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { |
} |
port_allocator_->SetIceServers(stun_servers, turn_servers); |
} |
- session_->SetIceConfig(session_->ParseIceConfig(config)); |
- return session_->SetIceTransports(config.type); |
+ session()->SetIceConfig(session()->ParseIceConfig(config)); |
+ return session()->SetIceTransports(config.type); |
} |
bool PeerConnection::AddIceCandidate( |
const IceCandidateInterface* ice_candidate) { |
TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); |
- return session_->ProcessIceMessage(ice_candidate); |
+ return session()->ProcessIceMessage(ice_candidate); |
} |
void PeerConnection::RegisterUMAObserver(UMAObserver* observer) { |
TRACE_EVENT0("webrtc", "PeerConnection::RegisterUmaObserver"); |
uma_observer_ = observer; |
- if (session_) { |
- session_->set_metrics_observer(uma_observer_); |
+ if (live_session_) { |
+ session()->set_metrics_observer(uma_observer_); |
} |
// Send information about IPv4/IPv6 status. |
@@ -1227,20 +1284,20 @@ void PeerConnection::RegisterUMAObserver(UMAObserver* observer) { |
} |
const SessionDescriptionInterface* PeerConnection::local_description() const { |
- return session_->local_description(); |
+ return session()->local_description(); |
} |
const SessionDescriptionInterface* PeerConnection::remote_description() const { |
- return session_->remote_description(); |
+ return session()->remote_description(); |
} |
void PeerConnection::Close() { |
TRACE_EVENT0("webrtc", "PeerConnection::Close"); |
// Update stats here so that we have the most recent stats for tracks and |
// streams before the channels are closed. |
- stats_->UpdateStats(kStatsOutputLevelStandard); |
- |
- session_->Close(); |
+ stats()->UpdateStats(kStatsOutputLevelStandard); |
+ session()->Close(); |
+ DestroyLiveSession(); |
} |
void PeerConnection::OnSessionStateChange(WebRtcSession* /*session*/, |
@@ -1298,7 +1355,7 @@ void PeerConnection::OnMessage(rtc::Message* msg) { |
case MSG_GETSTATS: { |
GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata); |
StatsReports reports; |
- stats_->GetStats(param->track, &reports); |
+ stats()->GetStats(param->track, &reports); |
param->observer->OnComplete(reports); |
delete param; |
break; |
@@ -1318,7 +1375,7 @@ void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream, |
uint32_t ssrc) { |
receivers_.push_back(RtpReceiverProxy::Create( |
signaling_thread(), |
- new AudioRtpReceiver(audio_track, ssrc, session_.get()))); |
+ new AudioRtpReceiver(audio_track, ssrc, session()))); |
} |
void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream, |
@@ -1326,7 +1383,7 @@ void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream, |
uint32_t ssrc) { |
receivers_.push_back(RtpReceiverProxy::Create( |
signaling_thread(), |
- new VideoRtpReceiver(video_track, ssrc, session_.get()))); |
+ new VideoRtpReceiver(video_track, ssrc, session()))); |
} |
// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote |
@@ -1414,7 +1471,7 @@ void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, |
// Normal case; we've never seen this track before. |
rtc::scoped_refptr<RtpSenderInterface> new_sender = RtpSenderProxy::Create( |
signaling_thread(), |
- new AudioRtpSender(track, stream->label(), session_.get(), stats_.get())); |
+ new AudioRtpSender(track, stream->label(), session(), stats())); |
senders_.push_back(new_sender); |
// If the sender has already been configured in SDP, we call SetSsrc, |
// which will connect the sender to the underlying transport. This can |
@@ -1456,7 +1513,7 @@ void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, |
// Normal case; we've never seen this track before. |
rtc::scoped_refptr<RtpSenderInterface> new_sender = RtpSenderProxy::Create( |
signaling_thread(), |
- new VideoRtpSender(track, stream->label(), session_.get())); |
+ new VideoRtpSender(track, stream->label(), session())); |
senders_.push_back(new_sender); |
const TrackInfo* track_info = |
FindTrackInfo(local_video_tracks_, stream->label(), track->id()); |
@@ -1498,9 +1555,9 @@ bool PeerConnection::GetOptionsForOffer( |
cricket::MediaSessionOptions* session_options) { |
// TODO(deadbeef): Once we have transceivers, enumerate them here instead of |
// ContentInfos. |
- if (session_->local_description()) { |
+ if (session()->local_description()) { |
for (const cricket::ContentInfo& content : |
- session_->local_description()->description()->contents()) { |
+ session()->local_description()->description()->contents()) { |
session_options->transport_options[content.name] = |
cricket::TransportOptions(); |
} |
@@ -1527,7 +1584,8 @@ bool PeerConnection::GetOptionsForOffer( |
(session_options->has_audio() || session_options->has_video() || |
session_options->has_data()); |
- if (session_->data_channel_type() == cricket::DCT_SCTP && HasDataChannels()) { |
+ if (session()->data_channel_type() == cricket::DCT_SCTP && |
+ HasDataChannels()) { |
session_options->data_channel_type = cricket::DCT_SCTP; |
} |
return true; |
@@ -1540,10 +1598,10 @@ bool PeerConnection::GetOptionsForAnswer( |
session_options->recv_video = false; |
// TODO(deadbeef): Once we have transceivers, enumerate them here instead of |
// ContentInfos. |
- if (session_->remote_description()) { |
+ if (session()->remote_description()) { |
// Initialize the transport_options map. |
for (const cricket::ContentInfo& content : |
- session_->remote_description()->description()->contents()) { |
+ session()->remote_description()->description()->contents()) { |
session_options->transport_options[content.name] = |
cricket::TransportOptions(); |
} |
@@ -1561,7 +1619,7 @@ bool PeerConnection::GetOptionsForAnswer( |
// RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams |
// are not signaled in the SDP so does not go through that path and must be |
// handled here. |
- if (session_->data_channel_type() == cricket::DCT_SCTP) { |
+ if (session()->data_channel_type() == cricket::DCT_SCTP) { |
session_options->data_channel_type = cricket::DCT_SCTP; |
} |
return true; |
@@ -1610,7 +1668,7 @@ void PeerConnection::UpdateRemoteStreamsList( |
remote_streams_->find(stream_label); |
if (!stream) { |
// This is a new MediaStream. Create a new remote MediaStream. |
- stream = remote_stream_factory_->CreateMediaStream(stream_label); |
+ stream = remote_stream_factory()->CreateMediaStream(stream_label); |
remote_streams_->AddStream(stream); |
new_streams->AddStream(stream); |
} |
@@ -1630,7 +1688,7 @@ void PeerConnection::UpdateRemoteStreamsList( |
if (!default_stream) { |
// Create the new default MediaStream. |
default_stream = |
- remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel); |
+ remote_stream_factory()->CreateMediaStream(kDefaultStreamLabel); |
remote_streams_->AddStream(default_stream); |
new_streams->AddStream(default_stream); |
} |
@@ -1654,12 +1712,12 @@ void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, |
MediaStreamInterface* stream = remote_streams_->find(stream_label); |
if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
- AudioTrackInterface* audio_track = remote_stream_factory_->AddAudioTrack( |
- ssrc, session_.get(), stream, track_id); |
+ AudioTrackInterface* audio_track = remote_stream_factory()->AddAudioTrack( |
+ ssrc, session(), stream, track_id); |
CreateAudioReceiver(stream, audio_track, ssrc); |
} else if (media_type == cricket::MEDIA_TYPE_VIDEO) { |
VideoTrackInterface* video_track = |
- remote_stream_factory_->AddVideoTrack(stream, track_id); |
+ remote_stream_factory()->AddVideoTrack(stream, track_id); |
CreateVideoReceiver(stream, video_track, ssrc); |
} else { |
RTC_DCHECK(false && "Invalid media type"); |
@@ -1909,17 +1967,17 @@ rtc::scoped_refptr<DataChannel> PeerConnection::InternalCreateDataChannel( |
if (IsClosed()) { |
return nullptr; |
} |
- if (session_->data_channel_type() == cricket::DCT_NONE) { |
+ if (session()->data_channel_type() == cricket::DCT_NONE) { |
LOG(LS_ERROR) |
<< "InternalCreateDataChannel: Data is not supported in this call."; |
return nullptr; |
} |
InternalDataChannelInit new_config = |
config ? (*config) : InternalDataChannelInit(); |
- if (session_->data_channel_type() == cricket::DCT_SCTP) { |
+ if (session()->data_channel_type() == cricket::DCT_SCTP) { |
if (new_config.id < 0) { |
rtc::SSLRole role; |
- if ((session_->GetSslRole(session_->data_channel(), &role)) && |
+ if ((session()->GetSslRole(session()->data_channel(), &role)) && |
!sid_allocator_.AllocateSid(role, &new_config.id)) { |
LOG(LS_ERROR) << "No id can be allocated for the SCTP data channel."; |
return nullptr; |
@@ -1932,7 +1990,7 @@ rtc::scoped_refptr<DataChannel> PeerConnection::InternalCreateDataChannel( |
} |
rtc::scoped_refptr<DataChannel> channel(DataChannel::Create( |
- session_.get(), session_->data_channel_type(), label, new_config)); |
+ session(), session()->data_channel_type(), label, new_config)); |
if (!channel) { |
sid_allocator_.ReleaseSid(new_config.id); |
return nullptr; |
@@ -2099,4 +2157,40 @@ DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { |
return nullptr; |
} |
+void PeerConnection::CreateLiveSession() { |
+ if (!live_session_) { |
+ live_session_.reset(new LiveSession(this, factory_.get(), |
+ port_allocator_.get(), media_config_, configuration_, |
+ constraints_.get(), std::move(dtls_identity_store_))); |
+ session()->set_metrics_observer(uma_observer_); |
+ } |
+} |
+ |
+void PeerConnection::DestroyLiveSession() { |
+ // Need to detach RTP senders/receivers from WebRtcSession, |
+ // since it's about to be destroyed. |
+ for (const auto& sender : senders_) { |
+ sender->Stop(); |
+ } |
+ for (const auto& receiver : receivers_) { |
+ receiver->Stop(); |
+ } |
+ live_session_.reset(nullptr); |
+} |
+ |
+const WebRtcSession* PeerConnection::session() const { |
+ const_cast<PeerConnection*>(this)->CreateLiveSession(); |
+ return live_session_->session(); |
+} |
+ |
+RemoteMediaStreamFactory* PeerConnection::remote_stream_factory() { |
+ CreateLiveSession(); |
+ return live_session_->remote_stream_factory(); |
+} |
+ |
+StatsCollector* PeerConnection::stats() { |
+ CreateLiveSession(); |
+ return live_session_->stats(); |
+} |
+ |
} // namespace webrtc |