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}
This commit is contained in:
@ -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<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 @@ void Conductor::EnsureStreamingUI() {
|
||||
// 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 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) {
|
||||
}
|
||||
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 @@ 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<cricket::VideoCapturer> 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<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 @@ 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<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 @@ void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) {
|
||||
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());
|
||||
|
||||
@ -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 @@ 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<cricket::VideoCapturer> OpenVideoCaptureDevice();
|
||||
|
||||
//
|
||||
@ -66,10 +66,12 @@ class Conductor
|
||||
|
||||
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 @@ class Conductor
|
||||
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_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user