From c06ed70835a2b0866b370234d48bec9b93e244aa Mon Sep 17 00:00:00 2001 From: Steve Anton Date: Tue, 17 Apr 2018 12:53:02 -0700 Subject: [PATCH] Update PeerConnection client example to Unified Plan APIs Bug: webrtc:9154 Change-Id: Icd53cfb57d96325a59c7964efe6276c10a3aebcd Reviewed-on: https://webrtc-review.googlesource.com/70341 Commit-Queue: Steve Anton Reviewed-by: Seth Hampson Reviewed-by: Tommi Cr-Commit-Position: refs/heads/master@{#22912} --- examples/peerconnection/client/conductor.cc | 187 +++++++++----------- examples/peerconnection/client/conductor.h | 20 +-- 2 files changed, 93 insertions(+), 114 deletions(-) diff --git a/examples/peerconnection/client/conductor.cc b/examples/peerconnection/client/conductor.cc index 5e56592cf2..7e36746f37 100644 --- a/examples/peerconnection/client/conductor.cc +++ b/examples/peerconnection/client/conductor.cc @@ -24,8 +24,6 @@ #include "rtc_base/json.h" #include "rtc_base/logging.h" -using webrtc::SdpType; - // Names used for a IceCandidate JSON object. const char kCandidateSdpMidName[] = "sdpMid"; const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex"; @@ -35,9 +33,6 @@ const char kCandidateSdpName[] = "candidate"; const char kSessionDescriptionTypeName[] = "type"; const char kSessionDescriptionSdpName[] = "sdp"; -#define DTLS_ON true -#define DTLS_OFF false - class DummySetSessionDescriptionObserver : public webrtc::SetSessionDescriptionObserver { public: @@ -49,10 +44,6 @@ class DummySetSessionDescriptionObserver virtual void OnFailure(const std::string& error) { RTC_LOG(INFO) << __FUNCTION__ << " " << error; } - - protected: - DummySetSessionDescriptionObserver() {} - ~DummySetSessionDescriptionObserver() {} }; Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd) @@ -65,11 +56,11 @@ Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd) } Conductor::~Conductor() { - RTC_DCHECK(peer_connection_.get() == NULL); + RTC_DCHECK(!peer_connection_); } bool Conductor::connection_active() const { - return peer_connection_.get() != NULL; + return peer_connection_ != nullptr; } void Conductor::Close() { @@ -78,77 +69,73 @@ void Conductor::Close() { } bool Conductor::InitializePeerConnection() { - RTC_DCHECK(peer_connection_factory_.get() == NULL); - RTC_DCHECK(peer_connection_.get() == NULL); + RTC_DCHECK(!peer_connection_factory_); + RTC_DCHECK(!peer_connection_); peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory()); - if (!peer_connection_factory_.get()) { + if (!peer_connection_factory_) { main_wnd_->MessageBox("Error", "Failed to initialize PeerConnectionFactory", true); DeletePeerConnection(); return false; } - if (!CreatePeerConnection(DTLS_ON)) { + if (!CreatePeerConnection(/*dtls=*/true)) { main_wnd_->MessageBox("Error", "CreatePeerConnection failed", true); DeletePeerConnection(); } - AddStreams(); - return peer_connection_.get() != NULL; + + AddTracks(); + + return peer_connection_ != nullptr; } bool Conductor::ReinitializePeerConnectionForLoopback() { loopback_ = true; - rtc::scoped_refptr streams( - peer_connection_->local_streams()); - peer_connection_ = NULL; - if (CreatePeerConnection(DTLS_OFF)) { - for (size_t i = 0; i < streams->count(); ++i) - peer_connection_->AddStream(streams->at(i)); - peer_connection_->CreateOffer(this, NULL); + std::vector> senders = + peer_connection_->GetSenders(); + peer_connection_ = nullptr; + if (CreatePeerConnection(/*dtls=*/false)) { + for (const auto& sender : senders) { + peer_connection_->AddTrack(sender->track(), sender->stream_ids()); + } + peer_connection_->CreateOffer( + this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); } - return peer_connection_.get() != NULL; + return peer_connection_ != nullptr; } bool Conductor::CreatePeerConnection(bool dtls) { - RTC_DCHECK(peer_connection_factory_.get() != NULL); - RTC_DCHECK(peer_connection_.get() == NULL); + RTC_DCHECK(peer_connection_factory_); + RTC_DCHECK(!peer_connection_); webrtc::PeerConnectionInterface::RTCConfiguration config; + config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + config.enable_dtls_srtp = dtls; webrtc::PeerConnectionInterface::IceServer server; server.uri = GetPeerConnectionString(); config.servers.push_back(server); - webrtc::FakeConstraints constraints; - if (dtls) { - constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, - "true"); - } else { - constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, - "false"); - } - peer_connection_ = peer_connection_factory_->CreatePeerConnection( - config, &constraints, NULL, NULL, this); - return peer_connection_.get() != NULL; + config, nullptr, nullptr, this); + return peer_connection_ != nullptr; } void Conductor::DeletePeerConnection() { - peer_connection_ = NULL; - active_streams_.clear(); main_wnd_->StopLocalRenderer(); main_wnd_->StopRemoteRenderer(); - peer_connection_factory_ = NULL; + peer_connection_ = nullptr; + peer_connection_factory_ = nullptr; peer_id_ = -1; loopback_ = false; } void Conductor::EnsureStreamingUI() { - RTC_DCHECK(peer_connection_.get() != NULL); + RTC_DCHECK(peer_connection_); if (main_wnd_->IsWindow()) { if (main_wnd_->current_ui() != MainWindow::STREAMING) main_wnd_->SwitchToStreamingUI(); @@ -159,17 +146,19 @@ void Conductor::EnsureStreamingUI() { // PeerConnectionObserver implementation. // -// Called when a remote stream is added -void Conductor::OnAddStream( - rtc::scoped_refptr stream) { - RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id(); - main_wnd_->QueueUIThreadCallback(NEW_STREAM_ADDED, stream.release()); +void Conductor::OnAddTrack( + rtc::scoped_refptr receiver, + const std::vector>& + streams) { + RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id(); + main_wnd_->QueueUIThreadCallback(NEW_TRACK_ADDED, + receiver->track().release()); } -void Conductor::OnRemoveStream( - rtc::scoped_refptr stream) { - RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id(); - main_wnd_->QueueUIThreadCallback(STREAM_REMOVED, stream.release()); +void Conductor::OnRemoveTrack( + rtc::scoped_refptr receiver) { + RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id(); + main_wnd_->QueueUIThreadCallback(TRACK_REMOVED, receiver->track().release()); } void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { @@ -276,12 +265,13 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) { } return; } - rtc::Optional type_maybe = webrtc::SdpTypeFromString(type_str); + rtc::Optional type_maybe = + webrtc::SdpTypeFromString(type_str); if (!type_maybe) { RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str; return; } - SdpType type = *type_maybe; + webrtc::SdpType type = *type_maybe; std::string sdp; if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName, &sdp)) { @@ -300,10 +290,10 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) { peer_connection_->SetRemoteDescription( DummySetSessionDescriptionObserver::Create(), session_description.release()); - if (type == SdpType::kOffer) { - peer_connection_->CreateAnswer(this, NULL); + if (type == webrtc::SdpType::kOffer) { + peer_connection_->CreateAnswer( + this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); } - return; } else { std::string sdp_mid; int sdp_mlineindex = 0; @@ -329,7 +319,6 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) { return; } RTC_LOG(INFO) << " Received candidate :" << message; - return; } } @@ -339,8 +328,8 @@ void Conductor::OnMessageSent(int err) { } void Conductor::OnServerConnectionFailure() { - main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(), - true); + main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(), + true); } // @@ -371,7 +360,8 @@ void Conductor::ConnectToPeer(int peer_id) { if (InitializePeerConnection()) { peer_id_ = peer_id; - peer_connection_->CreateOffer(this, NULL); + peer_connection_->CreateOffer( + this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); } else { main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true); } @@ -407,41 +397,38 @@ std::unique_ptr Conductor::OpenVideoCaptureDevice() { return capturer; } -void Conductor::AddStreams() { - if (active_streams_.find(kStreamId) != active_streams_.end()) - return; // Already added. +void Conductor::AddTracks() { + if (!peer_connection_->GetSenders().empty()) { + return; // Already added tracks. + } rtc::scoped_refptr audio_track( peer_connection_factory_->CreateAudioTrack( - kAudioLabel, peer_connection_factory_->CreateAudioSource(NULL))); + kAudioLabel, peer_connection_factory_->CreateAudioSource(nullptr))); + auto result_or_error = peer_connection_->AddTrack(audio_track, {kStreamId}); + if (!result_or_error.ok()) { + RTC_LOG(LS_ERROR) << "Failed to add audio track to PeerConnection: " + << result_or_error.error().message(); + } - rtc::scoped_refptr video_track; - auto video_device(OpenVideoCaptureDevice()); + std::unique_ptr video_device = + OpenVideoCaptureDevice(); if (video_device) { - video_track = + rtc::scoped_refptr video_track_( peer_connection_factory_->CreateVideoTrack( - kVideoLabel, - peer_connection_factory_->CreateVideoSource(std::move(video_device), - NULL)); - main_wnd_->StartLocalRenderer(video_track); + kVideoLabel, peer_connection_factory_->CreateVideoSource( + std::move(video_device), nullptr))); + main_wnd_->StartLocalRenderer(video_track_); + + result_or_error = peer_connection_->AddTrack(video_track_, {kStreamId}); + if (!result_or_error.ok()) { + RTC_LOG(LS_ERROR) << "Failed to add video track to PeerConnection: " + << result_or_error.error().message(); + } } else { RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed"; } - rtc::scoped_refptr stream = - peer_connection_factory_->CreateLocalMediaStream(kStreamId); - - stream->AddTrack(audio_track); - if (video_track) - stream->AddTrack(video_track); - - if (!peer_connection_->AddStream(stream)) { - RTC_LOG(LS_ERROR) << "Adding stream to PeerConnection failed"; - } - typedef std::pair > - MediaStreamPair; - active_streams_.insert(MediaStreamPair(stream->id(), stream)); main_wnd_->SwitchToStreamingUI(); } @@ -462,8 +449,6 @@ void Conductor::UIThreadCallback(int msg_id, void* data) { RTC_LOG(INFO) << "PEER_CONNECTION_CLOSED"; DeletePeerConnection(); - RTC_DCHECK(active_streams_.empty()); - if (main_wnd_->IsWindow()) { if (client_->is_connected()) { main_wnd_->SwitchToPeerList(client_->peers()); @@ -502,26 +487,20 @@ void Conductor::UIThreadCallback(int msg_id, void* data) { break; } - case NEW_STREAM_ADDED: { - webrtc::MediaStreamInterface* stream = - reinterpret_cast( - data); - webrtc::VideoTrackVector tracks = stream->GetVideoTracks(); - // Only render the first track. - if (!tracks.empty()) { - webrtc::VideoTrackInterface* track = tracks[0]; - main_wnd_->StartRemoteRenderer(track); + case NEW_TRACK_ADDED: { + auto* track = reinterpret_cast(data); + if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { + auto* video_track = static_cast(track); + main_wnd_->StartRemoteRenderer(video_track); } - stream->Release(); + track->Release(); break; } - case STREAM_REMOVED: { - // Remote peer stopped sending a stream. - webrtc::MediaStreamInterface* stream = - reinterpret_cast( - data); - stream->Release(); + case TRACK_REMOVED: { + // Remote peer stopped sending a track. + auto* track = reinterpret_cast(data); + track->Release(); break; } @@ -542,7 +521,7 @@ void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) { if (loopback_) { // Replace message type from "offer" to "answer" std::unique_ptr session_description = - webrtc::CreateSessionDescription(SdpType::kAnswer, sdp); + webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp); peer_connection_->SetRemoteDescription( DummySetSessionDescriptionObserver::Create(), session_description.release()); diff --git a/examples/peerconnection/client/conductor.h b/examples/peerconnection/client/conductor.h index e42949b762..83d1b73920 100644 --- a/examples/peerconnection/client/conductor.h +++ b/examples/peerconnection/client/conductor.h @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include "api/mediastreaminterface.h" #include "api/peerconnectioninterface.h" @@ -40,8 +40,8 @@ class Conductor MEDIA_CHANNELS_INITIALIZED = 1, PEER_CONNECTION_CLOSED, SEND_MESSAGE_TO_PEER, - NEW_STREAM_ADDED, - STREAM_REMOVED, + NEW_TRACK_ADDED, + TRACK_REMOVED, }; Conductor(PeerConnectionClient* client, MainWindow* main_wnd); @@ -57,7 +57,7 @@ class Conductor bool CreatePeerConnection(bool dtls); void DeletePeerConnection(); void EnsureStreamingUI(); - void AddStreams(); + void AddTracks(); std::unique_ptr OpenVideoCaptureDevice(); // @@ -66,10 +66,12 @@ class Conductor void OnSignalingChange( webrtc::PeerConnectionInterface::SignalingState new_state) override{}; - void OnAddStream( - rtc::scoped_refptr stream) override; - void OnRemoveStream( - rtc::scoped_refptr stream) override; + void OnAddTrack( + rtc::scoped_refptr receiver, + const std::vector>& + streams) override; + void OnRemoveTrack( + rtc::scoped_refptr receiver) override; void OnDataChannel( rtc::scoped_refptr channel) override {} void OnRenegotiationNeeded() override {} @@ -128,8 +130,6 @@ class Conductor PeerConnectionClient* client_; MainWindow* main_wnd_; std::deque pending_messages_; - std::map > - active_streams_; std::string server_; };