Started Room, publisher negotiation, add RTCRuntime dependencies across webrtc instances

This commit is contained in:
Théo Monnom
2022-09-29 21:34:30 +02:00
parent 32ac92b171
commit 0d34e5a48e
29 changed files with 707 additions and 185 deletions
@@ -10,6 +10,7 @@
#include "api/data_channel_interface.h"
#include "rust/cxx.h"
#include "rust_types.h"
#include "webrtc.h"
namespace livekit {
using NativeDataChannelInit = webrtc::DataChannelInit;
@@ -18,15 +19,18 @@ class NativeDataChannelObserver;
class DataChannel {
public:
explicit DataChannel(
std::shared_ptr<RTCRuntime> rtc_runtime,
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
void register_observer(NativeDataChannelObserver& observer);
void unregister_observer();
bool send(const DataBuffer& buffer);
rust::String label() const;
DataState state() const;
void close();
private:
std::shared_ptr<RTCRuntime> rtc_runtime_;
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel_;
};
@@ -18,7 +18,11 @@ class IceCandidate {
public:
explicit IceCandidate(
std::unique_ptr<webrtc::IceCandidateInterface> ice_candidate);
rust::String sdp_mid() const;
int sdp_mline_index() const;
rust::String candidate() const; // TODO(theomonnom) Return livekit::Candidate instead of rust::String
rust::String stringify() const;
std::unique_ptr<webrtc::IceCandidateInterface> release();
@@ -12,6 +12,7 @@
#include "jsep.h"
#include "rust/cxx.h"
#include "rust_types.h"
#include "webrtc.h"
namespace livekit {
class NativeAddIceCandidateObserver;
@@ -19,6 +20,7 @@ class NativeAddIceCandidateObserver;
class PeerConnection {
public:
explicit PeerConnection(
std::shared_ptr<RTCRuntime> rtc_runtime,
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection);
void create_offer(NativeCreateSdpObserverHandle& observer,
@@ -38,9 +40,11 @@ class PeerConnection {
std::unique_ptr<SessionDescription> remote_description() const;
SignalingState signaling_state() const;
IceGatheringState ice_gathering_state() const;
IceConnectionState ice_connection_state() const;
void close();
private:
std::shared_ptr<RTCRuntime> rtc_runtime_;
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
};
@@ -65,7 +69,7 @@ create_native_add_ice_candidate_observer(
class NativePeerConnectionObserver : public webrtc::PeerConnectionObserver {
public:
explicit NativePeerConnectionObserver(
explicit NativePeerConnectionObserver(std::shared_ptr<RTCRuntime> rtc_runtime,
rust::Box<PeerConnectionObserverWrapper> observer);
void OnSignalingChange(
@@ -126,11 +130,13 @@ class NativePeerConnectionObserver : public webrtc::PeerConnectionObserver {
void OnInterestingUsage(int usage_pattern) override;
private:
std::shared_ptr<RTCRuntime> rtc_runtime_;
rust::Box<PeerConnectionObserverWrapper> observer_;
};
std::unique_ptr<NativePeerConnectionObserver>
create_native_peer_connection_observer(
std::shared_ptr<RTCRuntime> rtc_runtime,
rust::Box<PeerConnectionObserverWrapper> observer);
} // namespace livekit
@@ -8,6 +8,7 @@
#include "api/peer_connection_interface.h"
#include "peer_connection.h"
#include "rust_types.h"
#include "webrtc.h"
namespace livekit {
using NativeRTCConfiguration =
@@ -15,21 +16,19 @@ using NativeRTCConfiguration =
class PeerConnectionFactory {
public:
PeerConnectionFactory();
explicit PeerConnectionFactory(std::shared_ptr<RTCRuntime> rtc_runtime);
~PeerConnectionFactory();
std::unique_ptr<PeerConnection> create_peer_connection(
std::unique_ptr<NativeRTCConfiguration> config,
NativePeerConnectionObserver& observer) const;
private:
std::unique_ptr<rtc::Thread> network_thread_;
std::unique_ptr<rtc::Thread> worker_thread_;
std::unique_ptr<rtc::Thread> signaling_thread_;
std::shared_ptr<RTCRuntime> rtc_runtime_;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_factory_;
};
std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory();
std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory(std::shared_ptr<RTCRuntime> rtc_runtime);
std::unique_ptr<NativeRTCConfiguration> create_rtc_configuration(
RTCConfiguration conf);
} // namespace livekit
@@ -22,6 +22,7 @@ enum class SignalingState;
enum class IceConnectionState;
enum class IceGatheringState;
enum class SdpType;
enum class DataState;
struct SdpParseError;
struct RTCOfferAnswerOptions;
struct RTCError;
@@ -22,13 +22,20 @@ class RTCRuntime {
RTCRuntime(const RTCRuntime&) = delete;
RTCRuntime& operator=(const RTCRuntime&) = delete;
rtc::Thread* network_thread() const;
rtc::Thread* worker_thread() const;
rtc::Thread* signaling_thread() const;
private:
std::unique_ptr<rtc::Thread> network_thread_;
std::unique_ptr<rtc::Thread> worker_thread_;
std::unique_ptr<rtc::Thread> signaling_thread_;
#ifdef WEBRTC_WIN
rtc::WinsockInitializer winsock_;
#endif
};
std::unique_ptr<RTCRuntime> create_rtc_runtime();
std::shared_ptr<RTCRuntime> create_rtc_runtime();
} // namespace livekit
@@ -11,8 +11,9 @@
namespace livekit {
DataChannel::DataChannel(
std::shared_ptr<RTCRuntime> rtc_runtime,
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel)
: data_channel_(std::move(data_channel)) {}
: rtc_runtime_(std::move(rtc_runtime)), data_channel_(std::move(data_channel)) {}
void DataChannel::register_observer(NativeDataChannelObserver& observer) {
data_channel_->RegisterObserver(&observer);
@@ -31,6 +32,10 @@ rust::String DataChannel::label() const {
return data_channel_->label();
}
DataState DataChannel::state() const {
return static_cast<DataState>(data_channel_->state());
}
void DataChannel::close() {
return data_channel_->Close();
}
@@ -69,6 +69,7 @@ pub mod ffi {
fn unregister_observer(self: Pin<&mut DataChannel>);
fn send(self: Pin<&mut DataChannel>, data: &DataBuffer) -> bool;
fn label(self: &DataChannel) -> String;
fn state(self: &DataChannel) -> DataState;
fn close(self: Pin<&mut DataChannel>);
fn create_data_channel_init(init: DataChannelInit) -> UniquePtr<NativeDataChannelInit>;
@@ -12,7 +12,7 @@
namespace livekit {
const std::string& serialize_sdp_error(webrtc::SdpParseError error) {
std::string serialize_sdp_error(webrtc::SdpParseError error) {
std::stringstream ss;
ss << std::hex << std::setfill('0');
ss << std::setw(8) << (uint32_t)error.line.length();
@@ -25,6 +25,18 @@ IceCandidate::IceCandidate(
std::unique_ptr<webrtc::IceCandidateInterface> ice_candidate)
: ice_candidate_(std::move(ice_candidate)) {}
rust::String IceCandidate::sdp_mid() const {
return ice_candidate_->sdp_mid();
}
int IceCandidate::sdp_mline_index() const {
return ice_candidate_->sdp_mline_index();
}
rust::String IceCandidate::candidate() const {
return stringify();
}
rust::String IceCandidate::stringify() const {
std::string str;
ice_candidate_->ToString(&str);
@@ -49,6 +49,9 @@ pub mod ffi {
type NativeSetLocalSdpObserverHandle;
type NativeSetRemoteSdpObserverHandle;
fn sdp_mid(self: &IceCandidate) -> String;
fn sdp_mline_index(self: &IceCandidate) -> i32;
fn candidate(self: &IceCandidate) -> String;
fn stringify(self: &IceCandidate) -> String;
fn stringify(self: &SessionDescription) -> String;
@@ -24,8 +24,10 @@ toNativeOfferAnswerOptions(const RTCOfferAnswerOptions& options) {
}
PeerConnection::PeerConnection(
std::shared_ptr<RTCRuntime> rtc_runtime,
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection)
: peer_connection_(std::move(peer_connection)) {}
: rtc_runtime_(std::move(rtc_runtime)),
peer_connection_(std::move(peer_connection)) {}
void PeerConnection::create_offer(
NativeCreateSdpObserverHandle& observer_handle,
@@ -65,7 +67,7 @@ std::unique_ptr<DataChannel> PeerConnection::create_data_channel(
throw std::runtime_error(serialize_error(to_error(result.error())));
}
return std::make_unique<DataChannel>(result.value());
return std::make_unique<DataChannel>(rtc_runtime_, result.value());
}
void PeerConnection::add_ice_candidate(
@@ -97,14 +99,19 @@ SignalingState PeerConnection::signaling_state() const {
}
IceGatheringState PeerConnection::ice_gathering_state() const {
return static_cast<IceGatheringState>(peer_connection_->ice_gathering_state());
return static_cast<IceGatheringState>(
peer_connection_->ice_gathering_state());
}
IceConnectionState PeerConnection::ice_connection_state() const {
return static_cast<IceConnectionState>(
peer_connection_->ice_connection_state());
}
void PeerConnection::close() {
peer_connection_->Close();
}
// AddIceCandidateObserver
NativeAddIceCandidateObserver::NativeAddIceCandidateObserver(
@@ -124,8 +131,9 @@ create_native_add_ice_candidate_observer(
// PeerConnectionObserver
NativePeerConnectionObserver::NativePeerConnectionObserver(
std::shared_ptr<RTCRuntime> rtc_runtime,
rust::Box<PeerConnectionObserverWrapper> observer)
: observer_(std::move(observer)) {}
: rtc_runtime_(std::move(rtc_runtime)), observer_(std::move(observer)) {}
void NativePeerConnectionObserver::OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state) {
@@ -144,7 +152,7 @@ void NativePeerConnectionObserver::OnRemoveStream(
void NativePeerConnectionObserver::OnDataChannel(
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
observer_->on_data_channel(std::make_unique<DataChannel>(data_channel));
observer_->on_data_channel(std::make_unique<DataChannel>(rtc_runtime_, data_channel));
}
void NativePeerConnectionObserver::OnRenegotiationNeeded() {
@@ -255,7 +263,9 @@ void NativePeerConnectionObserver::OnInterestingUsage(int usage_pattern) {
std::unique_ptr<NativePeerConnectionObserver>
create_native_peer_connection_observer(
std::shared_ptr<RTCRuntime> rtc_runtime,
rust::Box<PeerConnectionObserverWrapper> observer) {
return std::make_unique<NativePeerConnectionObserver>(std::move(observer));
return std::make_unique<NativePeerConnectionObserver>(rtc_runtime,
std::move(observer));
}
} // namespace livekit
@@ -109,6 +109,7 @@ pub mod ffi {
type NativeSetRemoteSdpObserverHandle = crate::jsep::ffi::NativeSetRemoteSdpObserverHandle;
type NativeDataChannelInit = crate::data_channel::ffi::NativeDataChannelInit;
type SessionDescription = crate::jsep::ffi::SessionDescription;
type RTCRuntime = crate::webrtc::ffi::RTCRuntime;
type NativeAddIceCandidateObserver;
type NativePeerConnectionObserver;
@@ -166,9 +167,12 @@ pub mod ffi {
fn ice_gathering_state(self: &PeerConnection) -> IceGatheringState;
fn ice_connection_state(self: &PeerConnection) -> IceConnectionState;
fn close(self: Pin<&mut PeerConnection>);
fn create_native_peer_connection_observer(
rtc_runtime: SharedPtr<RTCRuntime>,
observer: Box<PeerConnectionObserverWrapper>,
) -> UniquePtr<NativePeerConnectionObserver>;
@@ -4,6 +4,8 @@
#include "livekit/peer_connection_factory.h"
#include <utility>
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/rtc_event_log/rtc_event_log_factory.h"
@@ -16,24 +18,15 @@
namespace livekit {
PeerConnectionFactory::PeerConnectionFactory() {
rtc::LogMessage::LogToDebug(rtc::LS_INFO);
PeerConnectionFactory::PeerConnectionFactory(
std::shared_ptr<RTCRuntime> rtc_runtime)
: rtc_runtime_(std::move(rtc_runtime)) {
RTC_LOG(LS_INFO) << "PeerConnectionFactory::PeerConnectionFactory()";
network_thread_ = rtc::Thread::CreateWithSocketServer();
network_thread_->SetName("network_thread", &network_thread_);
network_thread_->Start();
worker_thread_ = rtc::Thread::Create();
worker_thread_->SetName("worker_thread", &worker_thread_);
worker_thread_->Start();
signaling_thread_ = rtc::Thread::Create();
signaling_thread_->SetName("signaling_thread", &signaling_thread_);
signaling_thread_->Start();
webrtc::PeerConnectionFactoryDependencies dependencies;
dependencies.network_thread = network_thread_.get();
dependencies.worker_thread = worker_thread_.get();
dependencies.signaling_thread = signaling_thread_.get();
dependencies.network_thread = rtc_runtime_->network_thread();
dependencies.worker_thread = rtc_runtime_->worker_thread();
dependencies.signaling_thread = rtc_runtime_->signaling_thread();
dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
dependencies.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>(
dependencies.task_queue_factory.get());
@@ -56,6 +49,10 @@ PeerConnectionFactory::PeerConnectionFactory() {
}
}
PeerConnectionFactory::~PeerConnectionFactory() {
RTC_LOG(LS_INFO) << "PeerConnectionFactory::~PeerConnectionFactory()";
}
std::unique_ptr<PeerConnection> PeerConnectionFactory::create_peer_connection(
std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config,
NativePeerConnectionObserver& observer) const {
@@ -67,11 +64,11 @@ std::unique_ptr<PeerConnection> PeerConnectionFactory::create_peer_connection(
throw std::runtime_error(serialize_error(to_error(result.error())));
}
return std::make_unique<PeerConnection>(result.value());
return std::make_unique<PeerConnection>(rtc_runtime_, result.value());
}
std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory() {
return std::make_unique<PeerConnectionFactory>();
std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory(std::shared_ptr<RTCRuntime> rtc_runtime) {
return std::make_unique<PeerConnectionFactory>(std::move(rtc_runtime));
}
std::unique_ptr<NativeRTCConfiguration> create_rtc_configuration(
@@ -43,8 +43,9 @@ pub mod ffi {
crate::peer_connection::ffi::NativePeerConnectionObserver;
type PeerConnectionFactory;
type NativeRTCConfiguration;
type RTCRuntime = crate::webrtc::ffi::RTCRuntime;
fn create_peer_connection_factory() -> UniquePtr<PeerConnectionFactory>;
fn create_peer_connection_factory(runtime: SharedPtr<RTCRuntime>) -> UniquePtr<PeerConnectionFactory>;
fn create_rtc_configuration(conf: RTCConfiguration) -> UniquePtr<NativeRTCConfiguration>;
/// SAFETY
@@ -8,8 +8,19 @@
namespace livekit {
RTCRuntime::RTCRuntime() {
rtc::LogMessage::LogToDebug(rtc::LS_INFO);
RTC_LOG(LS_INFO) << "RTCRuntime()";
RTC_CHECK(rtc::InitializeSSL()) << "Failed to InitializeSSL()";
network_thread_ = rtc::Thread::CreateWithSocketServer();
network_thread_->SetName("network_thread", &network_thread_);
network_thread_->Start();
worker_thread_ = rtc::Thread::Create();
worker_thread_->SetName("worker_thread", &worker_thread_);
worker_thread_->Start();
signaling_thread_ = rtc::Thread::Create();
signaling_thread_->SetName("signaling_thread", &signaling_thread_);
signaling_thread_->Start();
}
RTCRuntime::~RTCRuntime() {
@@ -17,7 +28,19 @@ RTCRuntime::~RTCRuntime() {
RTC_CHECK(rtc::CleanupSSL()) << "Failed to CleanupSSL()";
}
std::unique_ptr<RTCRuntime> create_rtc_runtime() {
return std::make_unique<RTCRuntime>();
rtc::Thread* RTCRuntime::network_thread() const {
return network_thread_.get();
}
rtc::Thread* RTCRuntime::worker_thread() const {
return worker_thread_.get();
}
rtc::Thread* RTCRuntime::signaling_thread() const {
return signaling_thread_.get();
}
std::shared_ptr<RTCRuntime> create_rtc_runtime() {
return std::make_shared<RTCRuntime>();
}
} // namespace livekit
@@ -7,7 +7,7 @@ pub mod ffi {
type RTCRuntime;
fn create_rtc_runtime() -> UniquePtr<RTCRuntime>;
fn create_rtc_runtime() -> SharedPtr<RTCRuntime>;
}
}
+27 -6
View File
@@ -1,11 +1,12 @@
use std::fmt::{Debug, Formatter};
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::sync::{Arc, Mutex};
use cxx::UniquePtr;
use log::trace;
use libwebrtc_sys::data_channel as sys_dc;
pub use sys_dc::ffi::Priority;
pub use sys_dc::ffi::{Priority, DataState};
pub struct DataChannel {
cxx_handle: UniquePtr<sys_dc::ffi::DataChannel>,
@@ -21,6 +22,17 @@ impl Debug for DataChannel {
}
}
#[derive(Debug)]
pub struct DataSendError;
impl Display for DataSendError {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "failed to send data to the DataChannel")
}
}
impl Error for DataSendError { }
impl DataChannel {
pub(crate) fn new(cxx_handle: UniquePtr<sys_dc::ffi::DataChannel>) -> Self {
let mut observer = Box::new(InternalDataChannelObserver::default());
@@ -44,19 +56,28 @@ impl DataChannel {
dc
}
pub fn send(&mut self, data: &[u8], binary: bool) -> bool {
pub fn send(&mut self, data: &[u8], binary: bool) -> Result<(), DataSendError> {
let buffer = sys_dc::ffi::DataBuffer {
ptr: data.as_ptr(),
len: data.len(),
binary,
};
self.cxx_handle.pin_mut().send(&buffer)
self.cxx_handle
.pin_mut()
.send(&buffer)
.then_some(())
.ok_or(DataSendError {})
}
pub fn label(&self) -> String {
self.cxx_handle.label()
}
pub fn state(&self) -> DataState {
self.cxx_handle.state()
}
pub fn close(&mut self) {
self.cxx_handle.pin_mut().close();
}
@@ -69,7 +90,7 @@ impl DataChannel {
*self.observer.on_message_handler.lock().unwrap() = Some(handler);
}
pub fn on_buffer(&mut self, handler: OnBufferedAmountChangeHandler) {
pub fn on_buffered_amount_change(&mut self, handler: OnBufferedAmountChangeHandler) {
*self
.observer
.on_buffered_amount_change_handler
+12
View File
@@ -26,6 +26,18 @@ impl IceCandidate {
pub(crate) fn release(self) -> UniquePtr<sys_jsep::ffi::IceCandidate> {
self.cxx_handle
}
pub fn sdp_mid(&self) -> String {
self.cxx_handle.sdp_mid()
}
pub fn sdp_mline_index(&self) -> i32 {
self.cxx_handle.sdp_mline_index()
}
pub fn candidate(&self) -> String {
self.cxx_handle.candidate()
}
}
impl ToString for IceCandidate {
@@ -25,6 +25,7 @@ pub struct PeerConnection {
observer: Box<InternalObserver>,
// Keep alive for C++
#[allow(unused)]
native_observer: UniquePtr<sys_pc::ffi::NativePeerConnectionObserver>,
}
@@ -174,6 +175,10 @@ impl PeerConnection {
self.cxx_handle.ice_gathering_state()
}
pub fn ice_connection_state(&self) -> IceConnectionState {
self.cxx_handle.ice_connection_state()
}
pub fn close(&mut self) {
self.cxx_handle.pin_mut().close();
}
@@ -8,15 +8,18 @@ pub use sys_factory::ffi::{
use crate::peer_connection::{InternalObserver, PeerConnection};
use crate::rtc_error::RTCError;
use crate::webrtc::RTCRuntime;
pub struct PeerConnectionFactory {
cxx_handle: UniquePtr<sys_factory::ffi::PeerConnectionFactory>,
rtc_runtime: RTCRuntime,
}
impl PeerConnectionFactory {
pub fn new() -> Self {
pub fn new(rtc_runtime: RTCRuntime) -> Self {
Self {
cxx_handle: sys_factory::ffi::create_peer_connection_factory(),
cxx_handle: sys_factory::ffi::create_peer_connection_factory(rtc_runtime.clone().release()),
rtc_runtime,
}
}
@@ -28,8 +31,8 @@ impl PeerConnectionFactory {
unsafe {
let mut observer = Box::new(InternalObserver::default());
let mut native_observer = sys_pc::ffi::create_native_peer_connection_observer(
Box::new(sys_pc::PeerConnectionObserverWrapper::new(&mut *observer)),
let mut native_observer = sys_pc::ffi::create_native_peer_connection_observer(self.rtc_runtime.clone().release(),
Box::new(sys_pc::PeerConnectionObserverWrapper::new(&mut *observer)),
);
let res = self
+7 -2
View File
@@ -1,9 +1,10 @@
use cxx::UniquePtr;
use cxx::{SharedPtr};
use libwebrtc_sys::webrtc as sys_rtc;
#[derive(Clone)]
pub struct RTCRuntime {
cxx_handle: UniquePtr<sys_rtc::ffi::RTCRuntime>,
cxx_handle: SharedPtr<sys_rtc::ffi::RTCRuntime>,
}
impl RTCRuntime {
@@ -12,4 +13,8 @@ impl RTCRuntime {
cxx_handle: sys_rtc::ffi::create_rtc_runtime(),
}
}
pub(crate) fn release(self) -> SharedPtr<sys_rtc::ffi::RTCRuntime> {
self.cxx_handle
}
}