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 <steveanton@webrtc.org>
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22912}
diff --git a/examples/peerconnection/client/conductor.cc b/examples/peerconnection/client/conductor.cc
index 5e56592..7e36746 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 kSessionDescriptionTypeName[] = "type";
const char kSessionDescriptionSdpName[] = "sdp";
-#define DTLS_ON true
-#define DTLS_OFF false
-
class DummySetSessionDescriptionObserver
: public webrtc::SetSessionDescriptionObserver {
public:
@@ -49,10 +44,6 @@
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() {
- 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 @@
}
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<webrtc::StreamCollectionInterface> 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<rtc::scoped_refptr<webrtc::RtpSenderInterface>> 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 @@
// PeerConnectionObserver implementation.
//
-// Called when a remote stream is added
-void Conductor::OnAddStream(
- rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
- RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id();
- main_wnd_->QueueUIThreadCallback(NEW_STREAM_ADDED, stream.release());
+void Conductor::OnAddTrack(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
+ streams) {
+ RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id();
+ main_wnd_->QueueUIThreadCallback(NEW_TRACK_ADDED,
+ receiver->track().release());
}
-void Conductor::OnRemoveStream(
- rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
- RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id();
- main_wnd_->QueueUIThreadCallback(STREAM_REMOVED, stream.release());
+void Conductor::OnRemoveTrack(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> 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 @@
}
return;
}
- rtc::Optional<SdpType> type_maybe = webrtc::SdpTypeFromString(type_str);
+ rtc::Optional<webrtc::SdpType> 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 @@
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 @@
return;
}
RTC_LOG(INFO) << " Received candidate :" << message;
- return;
}
}
@@ -339,8 +328,8 @@
}
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 @@
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 @@
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<webrtc::AudioTrackInterface> 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<webrtc::VideoTrackInterface> video_track;
- auto video_device(OpenVideoCaptureDevice());
+ std::unique_ptr<cricket::VideoCapturer> video_device =
+ OpenVideoCaptureDevice();
if (video_device) {
- video_track =
+ rtc::scoped_refptr<webrtc::VideoTrackInterface> 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<webrtc::MediaStreamInterface> 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<std::string,
- rtc::scoped_refptr<webrtc::MediaStreamInterface> >
- MediaStreamPair;
- active_streams_.insert(MediaStreamPair(stream->id(), stream));
main_wnd_->SwitchToStreamingUI();
}
@@ -462,8 +449,6 @@
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 @@
break;
}
- case NEW_STREAM_ADDED: {
- webrtc::MediaStreamInterface* stream =
- reinterpret_cast<webrtc::MediaStreamInterface*>(
- 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<webrtc::MediaStreamTrackInterface*>(data);
+ if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
+ auto* video_track = static_cast<webrtc::VideoTrackInterface*>(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<webrtc::MediaStreamInterface*>(
- data);
- stream->Release();
+ case TRACK_REMOVED: {
+ // Remote peer stopped sending a track.
+ auto* track = reinterpret_cast<webrtc::MediaStreamTrackInterface*>(data);
+ track->Release();
break;
}
@@ -542,7 +521,7 @@
if (loopback_) {
// Replace message type from "offer" to "answer"
std::unique_ptr<webrtc::SessionDescriptionInterface> 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 e42949b..83d1b73 100644
--- a/examples/peerconnection/client/conductor.h
+++ b/examples/peerconnection/client/conductor.h
@@ -14,8 +14,8 @@
#include <deque>
#include <map>
#include <memory>
-#include <set>
#include <string>
+#include <vector>
#include "api/mediastreaminterface.h"
#include "api/peerconnectioninterface.h"
@@ -40,8 +40,8 @@
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 @@
bool CreatePeerConnection(bool dtls);
void DeletePeerConnection();
void EnsureStreamingUI();
- void AddStreams();
+ void AddTracks();
std::unique_ptr<cricket::VideoCapturer> OpenVideoCaptureDevice();
//
@@ -66,10 +66,12 @@
void OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state) override{};
- void OnAddStream(
- rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override;
- void OnRemoveStream(
- rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override;
+ void OnAddTrack(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
+ streams) override;
+ void OnRemoveTrack(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
void OnDataChannel(
rtc::scoped_refptr<webrtc::DataChannelInterface> channel) override {}
void OnRenegotiationNeeded() override {}
@@ -128,8 +130,6 @@
PeerConnectionClient* client_;
MainWindow* main_wnd_;
std::deque<std::string*> pending_messages_;
- std::map<std::string, rtc::scoped_refptr<webrtc::MediaStreamInterface> >
- active_streams_;
std::string server_;
};