diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc new file mode 100644 index 0000000000..cd02e7118a --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "rtc_tools/data_channel_benchmark/peer_connection_client.h" + +#include <memory> +#include <string> +#include <utility> + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/create_peerconnection_factory.h" +#include "api/jsep.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/scoped_refptr.h" +#include "api/set_remote_description_observer_interface.h" +#include "api/video_codecs/builtin_video_decoder_factory.h" +#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "rtc_base/logging.h" +#include "rtc_base/thread.h" + +namespace { + +constexpr char kStunServer[] = "stun:stun.l.google.com:19302"; + +class SetLocalDescriptionObserverAdapter + : public webrtc::SetLocalDescriptionObserverInterface { + public: + using Callback = std::function<void(webrtc::RTCError)>; + static rtc::scoped_refptr<SetLocalDescriptionObserverAdapter> Create( + Callback callback) { + return rtc::scoped_refptr<SetLocalDescriptionObserverAdapter>( + new rtc::RefCountedObject<SetLocalDescriptionObserverAdapter>( + std::move(callback))); + } + + explicit SetLocalDescriptionObserverAdapter(Callback callback) + : callback_(std::move(callback)) {} + ~SetLocalDescriptionObserverAdapter() override = default; + + private: + void OnSetLocalDescriptionComplete(webrtc::RTCError error) override { + callback_(std::move(error)); + } + + Callback callback_; +}; + +class SetRemoteDescriptionObserverAdapter + : public webrtc::SetRemoteDescriptionObserverInterface { + public: + using Callback = std::function<void(webrtc::RTCError)>; + static rtc::scoped_refptr<SetRemoteDescriptionObserverAdapter> Create( + Callback callback) { + return rtc::scoped_refptr<SetRemoteDescriptionObserverAdapter>( + new rtc::RefCountedObject<SetRemoteDescriptionObserverAdapter>( + std::move(callback))); + } + + explicit SetRemoteDescriptionObserverAdapter(Callback callback) + : callback_(std::move(callback)) {} + ~SetRemoteDescriptionObserverAdapter() override = default; + + private: + void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override { + callback_(std::move(error)); + } + + Callback callback_; +}; + +class CreateSessionDescriptionObserverAdapter + : public webrtc::CreateSessionDescriptionObserver { + public: + using Success = std::function<void(webrtc::SessionDescriptionInterface*)>; + using Failure = std::function<void(webrtc::RTCError)>; + + static rtc::scoped_refptr<CreateSessionDescriptionObserverAdapter> Create( + Success success, + Failure failure) { + return rtc::scoped_refptr<CreateSessionDescriptionObserverAdapter>( + new rtc::RefCountedObject<CreateSessionDescriptionObserverAdapter>( + std::move(success), std::move(failure))); + } + + CreateSessionDescriptionObserverAdapter(Success success, Failure failure) + : success_(std::move(success)), failure_(std::move(failure)) {} + ~CreateSessionDescriptionObserverAdapter() override = default; + + private: + void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { + success_(desc); + } + + void OnFailure(webrtc::RTCError error) override { + failure_(std::move(error)); + } + + Success success_; + Failure failure_; +}; + +} // namespace + +namespace webrtc { + +PeerConnectionClient::PeerConnectionClient( + webrtc::PeerConnectionFactoryInterface* factory, + webrtc::SignalingInterface* signaling) + : signaling_(signaling) { + signaling_->OnIceCandidate( + [&](std::unique_ptr<webrtc::IceCandidateInterface> candidate) { + AddIceCandidate(std::move(candidate)); + }); + signaling_->OnRemoteDescription( + [&](std::unique_ptr<webrtc::SessionDescriptionInterface> sdp) { + SetRemoteDescription(std::move(sdp)); + }); + InitializePeerConnection(factory); +} + +PeerConnectionClient::~PeerConnectionClient() { + Disconnect(); +} + +rtc::scoped_refptr<PeerConnectionFactoryInterface> +PeerConnectionClient::CreateDefaultFactory(rtc::Thread* signaling_thread) { + auto factory = webrtc::CreatePeerConnectionFactory( + /*network_thread=*/nullptr, /*worker_thread=*/nullptr, + /*signaling_thread*/ signaling_thread, + /*default_adm=*/nullptr, webrtc::CreateBuiltinAudioEncoderFactory(), + webrtc::CreateBuiltinAudioDecoderFactory(), + webrtc::CreateBuiltinVideoEncoderFactory(), + webrtc::CreateBuiltinVideoDecoderFactory(), + /*audio_mixer=*/nullptr, /*audio_processing=*/nullptr); + + if (!factory) { + RTC_LOG(LS_ERROR) << "Failed to initialize PeerConnectionFactory"; + return nullptr; + } + + return factory; +} + +bool PeerConnectionClient::InitializePeerConnection( + webrtc::PeerConnectionFactoryInterface* factory) { + RTC_CHECK(factory) + << "Must call InitializeFactory before InitializePeerConnection"; + + webrtc::PeerConnectionInterface::RTCConfiguration config; + webrtc::PeerConnectionInterface::IceServer server; + server.urls.push_back(kStunServer); + config.servers.push_back(server); + config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + + webrtc::PeerConnectionDependencies dependencies(this); + auto result = + factory->CreatePeerConnectionOrError(config, std::move(dependencies)); + + if (!result.ok()) { + RTC_LOG(LS_ERROR) << "Failed to create PeerConnection: " + << result.error().message(); + DeletePeerConnection(); + return false; + } + peer_connection_ = result.MoveValue(); + RTC_LOG(LS_INFO) << "PeerConnection created successfully"; + return true; +} + +bool PeerConnectionClient::StartPeerConnection() { + RTC_LOG(LS_INFO) << "Creating offer"; + + peer_connection_->SetLocalDescription( + SetLocalDescriptionObserverAdapter::Create([this]( + webrtc::RTCError error) { + if (error.ok()) + signaling_->SendDescription(peer_connection_->local_description()); + })); + + return true; +} + +bool PeerConnectionClient::IsConnected() { + return peer_connection_->peer_connection_state() == + webrtc::PeerConnectionInterface::PeerConnectionState::kConnected; +} + +// Disconnect from the call. +void PeerConnectionClient::Disconnect() { + for (auto& data_channel : data_channels_) { + data_channel->Close(); + data_channel.release(); + } + data_channels_.clear(); + DeletePeerConnection(); +} + +// Delete the WebRTC PeerConnection. +void PeerConnectionClient::DeletePeerConnection() { + RTC_LOG(LS_INFO); + + if (peer_connection_) { + peer_connection_->Close(); + } + peer_connection_.release(); +} + +void PeerConnectionClient::OnIceConnectionChange( + webrtc::PeerConnectionInterface::IceConnectionState new_state) { + if (new_state == webrtc::PeerConnectionInterface::IceConnectionState:: + kIceConnectionCompleted) { + RTC_LOG(LS_INFO) << "State is updating to connected"; + } else if (new_state == webrtc::PeerConnectionInterface::IceConnectionState:: + kIceConnectionDisconnected) { + RTC_LOG(LS_INFO) << "Disconnecting from peer"; + Disconnect(); + } +} + +void PeerConnectionClient::OnIceGatheringChange( + webrtc::PeerConnectionInterface::IceGatheringState new_state) { + if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) { + RTC_LOG(LS_INFO) << "Client is ready to receive remote SDP"; + } +} + +void PeerConnectionClient::OnIceCandidate( + const webrtc::IceCandidateInterface* candidate) { + signaling_->SendIceCandidate(candidate); +} + +void PeerConnectionClient::OnDataChannel( + rtc::scoped_refptr<webrtc::DataChannelInterface> channel) { + RTC_LOG(LS_INFO) << __FUNCTION__ << " remote datachannel created"; + if (on_data_channel_callback_) + on_data_channel_callback_(channel); + data_channels_.push_back(channel); +} + +void PeerConnectionClient::SetOnDataChannel( + std::function<void(rtc::scoped_refptr<webrtc::DataChannelInterface>)> + callback) { + on_data_channel_callback_ = callback; +} + +void PeerConnectionClient::OnNegotiationNeededEvent(uint32_t event_id) { + RTC_LOG(LS_INFO) << "OnNegotiationNeededEvent"; + + peer_connection_->SetLocalDescription( + SetLocalDescriptionObserverAdapter::Create([this]( + webrtc::RTCError error) { + if (error.ok()) + signaling_->SendDescription(peer_connection_->local_description()); + })); +} + +bool PeerConnectionClient::SetRemoteDescription( + std::unique_ptr<webrtc::SessionDescriptionInterface> desc) { + RTC_LOG(LS_INFO) << "SetRemoteDescription"; + auto type = desc->GetType(); + + peer_connection_->SetRemoteDescription( + std::move(desc), + SetRemoteDescriptionObserverAdapter::Create([&](webrtc::RTCError) { + RTC_LOG(LS_INFO) << "SetRemoteDescription done"; + + if (type == webrtc::SdpType::kOffer) { + // Got an offer from the remote, need to set an answer and send it. + peer_connection_->SetLocalDescription( + SetLocalDescriptionObserverAdapter::Create( + [this](webrtc::RTCError error) { + if (error.ok()) + signaling_->SendDescription( + peer_connection_->local_description()); + })); + } + })); + + return true; +} + +void PeerConnectionClient::AddIceCandidate( + std::unique_ptr<webrtc::IceCandidateInterface> candidate) { + RTC_LOG(LS_INFO) << "AddIceCandidate"; + + peer_connection_->AddIceCandidate( + std::move(candidate), [](const webrtc::RTCError& error) { + RTC_LOG(LS_INFO) << "Failed to add candidate: " << error.message(); + }); +} + +} // namespace webrtc |