From f2799fdbb296fa764384ba085fcb46e19248b09a Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 14 Aug 2018 04:41:15 +0200 Subject: Fix name collision, scons file, final touches --- SConstruct | 4 +- src/GodotCreateSessionDescriptionObserver.cpp | 8 +- src/GodotDataChannelObserver.cpp | 10 +- src/GodotPeerConnectionObserver.cpp | 20 +-- src/GodotSetSessionDescriptionObserver.cpp | 8 +- src/WebRTCLibPeer.cpp | 202 ++++++++++++++++++++++++++ src/WebRTCLibPeer.hpp | 116 +++++++++++++++ src/WebRTCPeer.cpp | 202 -------------------------- src/WebRTCPeer.hpp | 121 --------------- src/init.cpp | 4 +- src/net/WebRTCPeerNative.cpp | 2 +- src/net/WebRTCPeerNative.hpp | 4 +- 12 files changed, 348 insertions(+), 353 deletions(-) create mode 100644 src/WebRTCLibPeer.cpp create mode 100644 src/WebRTCLibPeer.hpp delete mode 100644 src/WebRTCPeer.cpp delete mode 100644 src/WebRTCPeer.hpp diff --git a/SConstruct b/SConstruct index ba8e193..54a06ca 100644 --- a/SConstruct +++ b/SConstruct @@ -111,12 +111,12 @@ elif target_platform == "windows": # Mostly VisualStudio if env["CC"] == "cl": env.Append(CCFLAGS=["/DWEBRTC_WIN", "/DWIN32_LEAN_AND_MEAN", "/DNOMINMAX", "/DRTC_UNUSED=", "/DNO_RETURN="]) - env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in ["secur32", lib_name]]) + env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in ["secur32", "advapi32", "winmm", lib_name]]) env.Append(LIBPATH=[lib_path]) # Mostly "gcc" else: env.Append(CCFLAGS=["-DWINVER=0x0603", "-D_WIN32_WINNT=0x0603", "-DWEBRTC_WIN", "-DWIN32_LEAN_AND_MEAN", "-DNOMINMAX", "-DRTC_UNUSED=", "-DNO_RETURN="]) - env.Append(LIBS=["secur32", lib_name]) + env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in ["secur32", "advapi32", "winmm", lib_name]]) env.Append(LIBPATH=[lib_path]) elif target_platform == "osx": diff --git a/src/GodotCreateSessionDescriptionObserver.cpp b/src/GodotCreateSessionDescriptionObserver.cpp index 1f4b661..77d1308 100644 --- a/src/GodotCreateSessionDescriptionObserver.cpp +++ b/src/GodotCreateSessionDescriptionObserver.cpp @@ -1,16 +1,16 @@ -#include "WebRTCPeer.hpp" +#include "WebRTCLibPeer.hpp" using namespace godot_webrtc; -WebRTCPeer::GodotCSDO::GodotCSDO(WebRTCPeer *parent) { +WebRTCLibPeer::GodotCSDO::GodotCSDO(WebRTCLibPeer *parent) { this->parent = parent; } -void WebRTCPeer::GodotCSDO::OnSuccess(webrtc::SessionDescriptionInterface *desc) { +void WebRTCLibPeer::GodotCSDO::OnSuccess(webrtc::SessionDescriptionInterface *desc) { // serialize this offer and send it to the remote peer: std::string sdp; // sdp = session description protocol desc->ToString(&sdp); parent->queue_signal("offer_created", 2, desc->type().c_str(), sdp.c_str()); }; -void WebRTCPeer::GodotCSDO::OnFailure(const std::string &error){}; +void WebRTCLibPeer::GodotCSDO::OnFailure(const std::string &error){}; diff --git a/src/GodotDataChannelObserver.cpp b/src/GodotDataChannelObserver.cpp index 081c868..7a6cf96 100644 --- a/src/GodotDataChannelObserver.cpp +++ b/src/GodotDataChannelObserver.cpp @@ -1,12 +1,12 @@ -#include "WebRTCPeer.hpp" +#include "WebRTCLibPeer.hpp" using namespace godot_webrtc; -WebRTCPeer::GodotDCO::GodotDCO(WebRTCPeer *parent) { +WebRTCLibPeer::GodotDCO::GodotDCO(WebRTCLibPeer *parent) { this->parent = parent; } -void WebRTCPeer::GodotDCO::OnMessage(const webrtc::DataBuffer &buffer) { +void WebRTCLibPeer::GodotDCO::OnMessage(const webrtc::DataBuffer &buffer) { const uint8_t *data = buffer.data.data(); uint8_t *memory_controlled_buffer = new uint8_t[buffer.data.size()]; @@ -14,6 +14,6 @@ void WebRTCPeer::GodotDCO::OnMessage(const webrtc::DataBuffer &buffer) { parent->queue_packet(memory_controlled_buffer, buffer.data.size()); }; -void WebRTCPeer::GodotDCO::OnStateChange(){}; +void WebRTCLibPeer::GodotDCO::OnStateChange(){}; -void WebRTCPeer::GodotDCO::OnBufferedAmountChange(uint64_t previous_amount){}; +void WebRTCLibPeer::GodotDCO::OnBufferedAmountChange(uint64_t previous_amount){}; diff --git a/src/GodotPeerConnectionObserver.cpp b/src/GodotPeerConnectionObserver.cpp index 572b6d7..298cfcf 100644 --- a/src/GodotPeerConnectionObserver.cpp +++ b/src/GodotPeerConnectionObserver.cpp @@ -1,33 +1,33 @@ -#include "WebRTCPeer.hpp" +#include "WebRTCLibPeer.hpp" using namespace godot_webrtc; -WebRTCPeer::GodotPCO::GodotPCO(WebRTCPeer *parent) { +WebRTCLibPeer::GodotPCO::GodotPCO(WebRTCLibPeer *parent) { this->parent = parent; } -void WebRTCPeer::GodotPCO::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) { +void WebRTCLibPeer::GodotPCO::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) { } -void WebRTCPeer::GodotPCO::OnAddStream(rtc::scoped_refptr stream) { +void WebRTCLibPeer::GodotPCO::OnAddStream(rtc::scoped_refptr stream) { } -void WebRTCPeer::GodotPCO::OnRemoveStream(rtc::scoped_refptr stream) { +void WebRTCLibPeer::GodotPCO::OnRemoveStream(rtc::scoped_refptr stream) { } -void WebRTCPeer::GodotPCO::OnDataChannel(rtc::scoped_refptr data_channel) { +void WebRTCLibPeer::GodotPCO::OnDataChannel(rtc::scoped_refptr data_channel) { } -void WebRTCPeer::GodotPCO::OnRenegotiationNeeded() { +void WebRTCLibPeer::GodotPCO::OnRenegotiationNeeded() { } -void WebRTCPeer::GodotPCO::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) { +void WebRTCLibPeer::GodotPCO::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) { } -void WebRTCPeer::GodotPCO::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) { +void WebRTCLibPeer::GodotPCO::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) { } -void WebRTCPeer::GodotPCO::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) { +void WebRTCLibPeer::GodotPCO::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) { // Serialize the candidate and send it to the remote peer: godot::Dictionary candidateSDP; diff --git a/src/GodotSetSessionDescriptionObserver.cpp b/src/GodotSetSessionDescriptionObserver.cpp index 93b9b8d..52be2af 100644 --- a/src/GodotSetSessionDescriptionObserver.cpp +++ b/src/GodotSetSessionDescriptionObserver.cpp @@ -1,11 +1,11 @@ -#include "WebRTCPeer.hpp" +#include "WebRTCLibPeer.hpp" using namespace godot_webrtc; -WebRTCPeer::GodotSSDO::GodotSSDO(WebRTCPeer *parent) { +WebRTCLibPeer::GodotSSDO::GodotSSDO(WebRTCLibPeer *parent) { this->parent = parent; } -void WebRTCPeer::GodotSSDO::OnSuccess(){}; +void WebRTCLibPeer::GodotSSDO::OnSuccess(){}; -void WebRTCPeer::GodotSSDO::OnFailure(const std::string &error){}; +void WebRTCLibPeer::GodotSSDO::OnFailure(const std::string &error){}; diff --git a/src/WebRTCLibPeer.cpp b/src/WebRTCLibPeer.cpp new file mode 100644 index 0000000..c94cfcd --- /dev/null +++ b/src/WebRTCLibPeer.cpp @@ -0,0 +1,202 @@ +#include "WebRTCLibPeer.hpp" + +using namespace godot_webrtc; + +void WebRTCLibPeer::set_write_mode(godot_int mode) { +} + +godot_int WebRTCLibPeer::get_write_mode() const { + return 0; +} + +bool WebRTCLibPeer::was_string_packet() const { + return false; +} + +godot_int WebRTCLibPeer::get_connection_state() const { + return 0; +} + +godot_error WebRTCLibPeer::create_offer() { + peer_connection->CreateOffer( + ptr_csdo, // CreateSessionDescriptionObserver* observer, + nullptr // webrtc::PeerConnectionInterface::RTCOfferAnswerOptions() // const MediaConstraintsInterface* constraints + ); + return GODOT_OK; +} + +godot_error WebRTCLibPeer::set_remote_description(const char *type, const char *sdp) { + godot_error err = set_description(type, sdp, false); //false meaning !isLocal because it is remote + peer_connection->CreateAnswer(ptr_csdo, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); + return err; +} + +godot_error WebRTCLibPeer::set_local_description(const char *type, const char *sdp) { + return set_description(type, sdp, true); // isLocal == true +} + +godot_error WebRTCLibPeer::add_ice_candidate(const char *sdpMidName, int sdpMlineIndexName, const char *sdpName) { + webrtc::SdpParseError *error = nullptr; + webrtc::IceCandidateInterface *candidate = webrtc::CreateIceCandidate( + sdpMidName, + sdpMlineIndexName, + sdpName, + error); + + // @TODO do something if there's an error (if error, or if !candidate) + if (error || !candidate) + std::cout << "ERROR with creating ICE candidate (" << error << ")\n"; + + if (!peer_connection->AddIceCandidate(candidate)) + ERR_PRINT("Error with adding ICE candidate"); + return GODOT_OK; +} + +godot_error WebRTCLibPeer::poll() { + std::function signal; + while (!signal_queue.empty()) { + mutex_signal_queue->lock(); + signal = signal_queue.front(); + signal_queue.pop(); + mutex_signal_queue->unlock(); + + signal(); + } + return GODOT_OK; +} + +godot_error WebRTCLibPeer::get_packet(const uint8_t **r_buffer, int *r_len) { + if (packet_queue_size == 0) + return GODOT_ERR_UNAVAILABLE; + mutex_packet_queue->lock(); + uint8_t *current_packet = packet_queue.front(); + *r_buffer = current_packet; + *r_len = packet_sizes_queue.front(); + + packet_queue.pop(); + packet_sizes_queue.pop(); + mutex_packet_queue->unlock(); + + --packet_queue_size; + return GODOT_OK; +} + +godot_error WebRTCLibPeer::put_packet(const uint8_t *p_buffer, int p_len) { + webrtc::DataBuffer webrtc_buffer(rtc::CopyOnWriteBuffer(p_buffer, p_len), true); + data_channel->Send(webrtc_buffer); + return GODOT_OK; // @TODO properly return any Error we may get. +} + +godot_int WebRTCLibPeer::get_available_packet_count() const { + return packet_queue_size; +} + +godot_int WebRTCLibPeer::get_max_packet_size() const { + return 1200; +} + +void WebRTCLibPeer::_register_methods() { +} + +void WebRTCLibPeer::_init() { + register_interface(&interface); + + // initialize variables: + mutex_signal_queue = new std::mutex; + mutex_packet_queue = new std::mutex; + packet_queue_size = 0; + + // create a PeerConnectionFactoryInterface: + signaling_thread = new rtc::Thread; + signaling_thread->Start(); + pc_factory = webrtc::CreateModularPeerConnectionFactory( + nullptr, // rtc::Thread* network_thread, + nullptr, // rtc::Thread* worker_thread, + signaling_thread, + nullptr, // std::unique_ptr media_engine, + nullptr, // std::unique_ptr call_factory, + nullptr // std::unique_ptr event_log_factory + ); + if (pc_factory.get() == nullptr) { // PeerConnectionFactory couldn't be created. Fail the method call. + ERR_PRINT("PeerConnectionFactory could not be created"); + // return GODOT_FAILED; + } + + // create PeerConnection configuration and add the ice servers: + webrtc::PeerConnectionInterface::RTCConfiguration configuration; + //webrtc::PeerConnectionInterface::IceServer ice_server; + + //ice_server.uri = "stun:stun.l.google.com:19302"; // @FIXME allow user to input ice servers + //configuration.servers.push_back(ice_server); + + // create a PeerConnection object: + peer_connection = pc_factory->CreatePeerConnection(configuration, nullptr, nullptr, &pco); + if (peer_connection.get() == nullptr) { // PeerConnection couldn't be created. Fail the method call. + ERR_PRINT("PeerConnection could not be created"); + // return GODOT_FAILED; + } + + // create a DataChannel + webrtc::DataChannelInit data_channel_config; + data_channel_config.negotiated = true; // True if the channel has been externally negotiated + data_channel_config.id = 0; + + data_channel = peer_connection->CreateDataChannel("channel", &data_channel_config); + // @TODO (NONESSENTIAL) create data_channel check. fail function call if data_channel isn't created + data_channel->RegisterObserver(&dco); +} + +WebRTCLibPeer::WebRTCLibPeer() : + dco(this), + pco(this), + ptr_csdo(new rtc::RefCountedObject(this)), + ptr_ssdo(new rtc::RefCountedObject(this)) { +} + +WebRTCLibPeer::~WebRTCLibPeer() { + if (_owner) { + register_interface(NULL); + } + delete mutex_signal_queue; + delete mutex_packet_queue; +} + +void WebRTCLibPeer::queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1, const godot::Variant &p_arg2, const godot::Variant &p_arg3) { + mutex_signal_queue->lock(); + signal_queue.push( + [this, p_name, p_argc, p_arg1, p_arg2, p_arg3] { + if (p_argc == 2) + emit_signal(p_name, p_arg1, p_arg2); + else + emit_signal(p_name, p_arg1, p_arg2, p_arg3); + }); + mutex_signal_queue->unlock(); +} + +void WebRTCLibPeer::queue_packet(uint8_t *buffer, int buffer_size) { + mutex_packet_queue->lock(); + packet_queue.push(buffer); + packet_sizes_queue.push(buffer_size); + ++packet_queue_size; + mutex_packet_queue->unlock(); +} + +godot_error WebRTCLibPeer::set_description(const char *type, const char *sdp, bool isLocal) { + // webrtc::SdpType type = (isOffer) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer; + godot::String string_sdp = sdp; + + webrtc::SdpType sdptype = (godot::String(type) == godot::String("offer")) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer; + std::unique_ptr desc = + webrtc::CreateSessionDescription(sdptype, sdp); + + if (isLocal) { + peer_connection->SetLocalDescription( + ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create() + desc.release()); + } else { + peer_connection->SetRemoteDescription( + ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create() + desc.release()); + } + return GODOT_OK; +} diff --git a/src/WebRTCLibPeer.hpp b/src/WebRTCLibPeer.hpp new file mode 100644 index 0000000..437e80a --- /dev/null +++ b/src/WebRTCLibPeer.hpp @@ -0,0 +1,116 @@ +#ifndef WEBRTC_PEER_H +#define WEBRTC_PEER_H + +#include "api/peerconnectioninterface.h" // interface for all things needed from WebRTC +#include "media/base/mediaengine.h" // needed for CreateModularPeerConnectionFactory +#include // std::function +#include // mutex @TODO replace std::mutex with Godot mutex + +#include "net/WebRTCPeerNative.hpp" +#include + +namespace godot_webrtc { + +class WebRTCLibPeer : public WebRTCPeerNative { + GODOT_CLASS(WebRTCLibPeer, WebRTCPeerNative); + +public: + static void _register_methods(); + + void _init(); + + void set_write_mode(godot_int mode); + godot_int get_write_mode() const; + bool was_string_packet() const; + godot_int get_connection_state() const; + + godot_error create_offer(); + godot_error set_remote_description(const char *type, const char *sdp); + godot_error set_local_description(const char *type, const char *sdp); + godot_error add_ice_candidate(const char *sdpMidName, int sdpMlineIndexName, const char *sdpName); + godot_error poll(); + + /* WebRTCPeer */ + virtual godot_error get_packet(const uint8_t **r_buffer, int *r_len); + virtual godot_error put_packet(const uint8_t *p_buffer, int p_len); + virtual godot_int get_available_packet_count() const; + virtual godot_int get_max_packet_size() const; + + WebRTCLibPeer(); + ~WebRTCLibPeer(); + + /* helper functions */ + + void queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1 = godot::Variant(), const godot::Variant &p_arg2 = godot::Variant(), const godot::Variant &p_arg3 = godot::Variant()); + // void queue_signal(godot::StringName p_name, Variant_ARG_LIST); + void queue_packet(uint8_t *, int); + godot_error set_description(const char *type, const char *sdp, bool isLocal); + + /** DataChannelObserver callback functions **/ + class GodotDCO : public webrtc::DataChannelObserver { + public: + WebRTCLibPeer *parent; + + GodotDCO(WebRTCLibPeer *parent); + void OnMessage(const webrtc::DataBuffer &buffer) override; + void OnStateChange() override; // UNUSED + void OnBufferedAmountChange(uint64_t previous_amount) override; // UNUSED + }; + + /** PeerConnectionObserver callback functions **/ + class GodotPCO : public webrtc::PeerConnectionObserver { + public: + WebRTCLibPeer *parent; + + GodotPCO(WebRTCLibPeer *parent); + void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override; + void OnAddStream(rtc::scoped_refptr stream) override; + void OnRemoveStream(rtc::scoped_refptr stream) override; + void OnDataChannel(rtc::scoped_refptr data_channel) override; + void OnRenegotiationNeeded() override; + void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override; + void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override; + void OnIceCandidate(const webrtc::IceCandidateInterface *candidate) override; + }; + + /** CreateSessionDescriptionObserver callback functions **/ + class GodotCSDO : public webrtc::CreateSessionDescriptionObserver { + public: + WebRTCLibPeer *parent; + + GodotCSDO(WebRTCLibPeer *parent); + void OnSuccess(webrtc::SessionDescriptionInterface *desc) override; + void OnFailure(const std::string &error) override; + }; + + /** SetSessionDescriptionObserver callback functions **/ + class GodotSSDO : public webrtc::SetSessionDescriptionObserver { + public: + WebRTCLibPeer *parent; + + GodotSSDO(WebRTCLibPeer *parent); + void OnSuccess() override; + void OnFailure(const std::string &error) override; + }; + + GodotDCO dco; + GodotPCO pco; + rtc::scoped_refptr ptr_ssdo; + rtc::scoped_refptr ptr_csdo; + + std::mutex *mutex_signal_queue; + std::mutex *mutex_packet_queue; + int packet_queue_size; + std::queue packet_queue; + std::queue packet_sizes_queue; + std::queue > signal_queue; + + rtc::Thread *signaling_thread; + rtc::scoped_refptr pc_factory; + rtc::scoped_refptr peer_connection; + rtc::scoped_refptr data_channel; +}; + +} // namespace godot_webrtc + +#endif // WEBRTC_PEER_H diff --git a/src/WebRTCPeer.cpp b/src/WebRTCPeer.cpp deleted file mode 100644 index 00455c0..0000000 --- a/src/WebRTCPeer.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "WebRTCPeer.hpp" - -using namespace godot_webrtc; - -void WebRTCPeer::set_write_mode(godot_int mode) { -} - -godot_int WebRTCPeer::get_write_mode() const { - return 0; -} - -bool WebRTCPeer::was_string_packet() const { - return false; -} - -godot_int WebRTCPeer::get_connection_state() const { - return 0; -} - -godot_error WebRTCPeer::create_offer() { - peer_connection->CreateOffer( - ptr_csdo, // CreateSessionDescriptionObserver* observer, - nullptr // webrtc::PeerConnectionInterface::RTCOfferAnswerOptions() // const MediaConstraintsInterface* constraints - ); - return GODOT_OK; -} - -godot_error WebRTCPeer::set_remote_description(const char *type, const char *sdp) { - godot_error err = set_description(type, sdp, false); //false meaning !isLocal because it is remote - peer_connection->CreateAnswer(ptr_csdo, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); - return err; -} - -godot_error WebRTCPeer::set_local_description(const char *type, const char *sdp) { - return set_description(type, sdp, true); // isLocal == true -} - -godot_error WebRTCPeer::add_ice_candidate(const char *sdpMidName, int sdpMlineIndexName, const char *sdpName) { - webrtc::SdpParseError *error = nullptr; - webrtc::IceCandidateInterface *candidate = webrtc::CreateIceCandidate( - sdpMidName, - sdpMlineIndexName, - sdpName, - error); - - // @TODO do something if there's an error (if error, or if !candidate) - if (error || !candidate) - std::cout << "ERROR with creating ICE candidate (" << error << ")\n"; - - if (!peer_connection->AddIceCandidate(candidate)) - ERR_PRINT("Error with adding ICE candidate"); - return GODOT_OK; -} - -godot_error WebRTCPeer::poll() { - std::function signal; - while (!signal_queue.empty()) { - mutex_signal_queue->lock(); - signal = signal_queue.front(); - signal_queue.pop(); - mutex_signal_queue->unlock(); - - signal(); - } - return GODOT_OK; -} - -godot_error WebRTCPeer::get_packet(const uint8_t **r_buffer, int &r_len) { - if (packet_queue_size == 0) - return GODOT_ERR_UNAVAILABLE; - mutex_packet_queue->lock(); - uint8_t *current_packet = packet_queue.front(); - *r_buffer = current_packet; - r_len = packet_sizes_queue.front(); - - packet_queue.pop(); - packet_sizes_queue.pop(); - mutex_packet_queue->unlock(); - - --packet_queue_size; - return GODOT_OK; -} - -godot_error WebRTCPeer::put_packet(const uint8_t *p_buffer, int p_len) { - webrtc::DataBuffer webrtc_buffer(rtc::CopyOnWriteBuffer(p_buffer, p_len), true); - data_channel->Send(webrtc_buffer); - return GODOT_OK; // @TODO properly return any Error we may get. -} - -godot_int WebRTCPeer::get_available_packet_count() const { - return packet_queue_size; -} - -godot_int WebRTCPeer::get_max_packet_size() const { - return 1200; -} - -void WebRTCPeer::_register_methods() { -} - -void WebRTCPeer::_init() { - register_interface(&interface); - - // initialize variables: - mutex_signal_queue = new std::mutex; - mutex_packet_queue = new std::mutex; - packet_queue_size = 0; - - // create a PeerConnectionFactoryInterface: - signaling_thread = new rtc::Thread; - signaling_thread->Start(); - pc_factory = webrtc::CreateModularPeerConnectionFactory( - nullptr, // rtc::Thread* network_thread, - nullptr, // rtc::Thread* worker_thread, - signaling_thread, - nullptr, // std::unique_ptr media_engine, - nullptr, // std::unique_ptr call_factory, - nullptr // std::unique_ptr event_log_factory - ); - if (pc_factory.get() == nullptr) { // PeerConnectionFactory couldn't be created. Fail the method call. - godot_print_error("PeerConnectionFactory could not be created", "_init", "WebRTCPeer.cpp", 80); - // return GODOT_FAILED; - } - - // create PeerConnection configuration and add the ice servers: - webrtc::PeerConnectionInterface::RTCConfiguration configuration; - //webrtc::PeerConnectionInterface::IceServer ice_server; - - //ice_server.uri = "stun:stun.l.google.com:19302"; // @FIXME allow user to input ice servers - //configuration.servers.push_back(ice_server); - - // create a PeerConnection object: - peer_connection = pc_factory->CreatePeerConnection(configuration, nullptr, nullptr, &pco); - if (peer_connection.get() == nullptr) { // PeerConnection couldn't be created. Fail the method call. - godot_print_error("PeerConnection could not be created", "_init", "WebRTCPeer.cpp", 101); - // return GODOT_FAILED; - } - - // create a DataChannel - webrtc::DataChannelInit data_channel_config; - data_channel_config.negotiated = true; // True if the channel has been externally negotiated - data_channel_config.id = 0; - - data_channel = peer_connection->CreateDataChannel("channel", &data_channel_config); - // @TODO (NONESSENTIAL) create data_channel check. fail function call if data_channel isn't created - data_channel->RegisterObserver(&dco); -} - -WebRTCPeer::WebRTCPeer() : - dco(this), - pco(this), - ptr_csdo(new rtc::RefCountedObject(this)), - ptr_ssdo(new rtc::RefCountedObject(this)) { -} - -WebRTCPeer::~WebRTCPeer() { - if (_owner) { - register_interface(NULL); - } - delete mutex_signal_queue; - delete mutex_packet_queue; -} - -void WebRTCPeer::queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1, const godot::Variant &p_arg2, const godot::Variant &p_arg3) { - mutex_signal_queue->lock(); - signal_queue.push( - [this, p_name, p_argc, p_arg1, p_arg2, p_arg3] { - if (p_argc == 2) - emit_signal(p_name, p_arg1, p_arg2); - else - emit_signal(p_name, p_arg1, p_arg2, p_arg3); - }); - mutex_signal_queue->unlock(); -} - -void WebRTCPeer::queue_packet(uint8_t *buffer, int buffer_size) { - mutex_packet_queue->lock(); - packet_queue.push(buffer); - packet_sizes_queue.push(buffer_size); - ++packet_queue_size; - mutex_packet_queue->unlock(); -} - -godot_error WebRTCPeer::set_description(const char *type, const char *sdp, bool isLocal) { - // webrtc::SdpType type = (isOffer) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer; - godot::String string_sdp = sdp; - - webrtc::SdpType sdptype = (godot::String(type) == godot::String("offer")) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer; - std::unique_ptr desc = - webrtc::CreateSessionDescription(sdptype, sdp); - - if (isLocal) { - peer_connection->SetLocalDescription( - ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create() - desc.release()); - } else { - peer_connection->SetRemoteDescription( - ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create() - desc.release()); - } - return GODOT_OK; -} diff --git a/src/WebRTCPeer.hpp b/src/WebRTCPeer.hpp deleted file mode 100644 index 45a90ec..0000000 --- a/src/WebRTCPeer.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef WEBRTC_PEER_H -#define WEBRTC_PEER_H - -#include "api/peerconnectioninterface.h" // interface for all things needed from WebRTC -#include "media/base/mediaengine.h" // needed for CreateModularPeerConnectionFactory -#ifdef interface -#pragma message("\n 'interface' is defined \n") -#undef interface -#endif // interface - -#include // std::function -#include // mutex @TODO replace std::mutex with Godot mutex - -#include "net/WebRTCPeerNative.hpp" -#include - -namespace godot_webrtc { - -class WebRTCPeer : public WebRTCPeerNative { - GODOT_CLASS(WebRTCPeer, WebRTCPeerNative); - -public: - static void _register_methods(); - - void _init(); - - void set_write_mode(godot_int mode); - godot_int get_write_mode() const; - bool was_string_packet() const; - godot_int get_connection_state() const; - - godot_error create_offer(); - godot_error set_remote_description(const char *type, const char *sdp); - godot_error set_local_description(const char *type, const char *sdp); - godot_error add_ice_candidate(const char *sdpMidName, int sdpMlineIndexName, const char *sdpName); - godot_error poll(); - - /* WebRTCPeer */ - virtual godot_error get_packet(const uint8_t **r_buffer, int &r_len); - virtual godot_error put_packet(const uint8_t *p_buffer, int p_len); - virtual godot_int get_available_packet_count() const; - virtual godot_int get_max_packet_size() const; - - WebRTCPeer(); - ~WebRTCPeer(); - - /* helper functions */ - - void queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1 = godot::Variant(), const godot::Variant &p_arg2 = godot::Variant(), const godot::Variant &p_arg3 = godot::Variant()); - // void queue_signal(godot::StringName p_name, Variant_ARG_LIST); - void queue_packet(uint8_t *, int); - godot_error set_description(const char *type, const char *sdp, bool isLocal); - - /** DataChannelObserver callback functions **/ - class GodotDCO : public webrtc::DataChannelObserver { - public: - WebRTCPeer *parent; - - GodotDCO(WebRTCPeer *parent); - void OnMessage(const webrtc::DataBuffer &buffer) override; - void OnStateChange() override; // UNUSED - void OnBufferedAmountChange(uint64_t previous_amount) override; // UNUSED - }; - - /** PeerConnectionObserver callback functions **/ - class GodotPCO : public webrtc::PeerConnectionObserver { - public: - WebRTCPeer *parent; - - GodotPCO(WebRTCPeer *parent); - void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override; - void OnAddStream(rtc::scoped_refptr stream) override; - void OnRemoveStream(rtc::scoped_refptr stream) override; - void OnDataChannel(rtc::scoped_refptr data_channel) override; - void OnRenegotiationNeeded() override; - void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override; - void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override; - void OnIceCandidate(const webrtc::IceCandidateInterface *candidate) override; - }; - - /** CreateSessionDescriptionObserver callback functions **/ - class GodotCSDO : public webrtc::CreateSessionDescriptionObserver { - public: - WebRTCPeer *parent; - - GodotCSDO(WebRTCPeer *parent); - void OnSuccess(webrtc::SessionDescriptionInterface *desc) override; - void OnFailure(const std::string &error) override; - }; - - /** SetSessionDescriptionObserver callback functions **/ - class GodotSSDO : public webrtc::SetSessionDescriptionObserver { - public: - WebRTCPeer *parent; - - GodotSSDO(WebRTCPeer *parent); - void OnSuccess() override; - void OnFailure(const std::string &error) override; - }; - - GodotDCO dco; - GodotPCO pco; - rtc::scoped_refptr ptr_ssdo; - rtc::scoped_refptr ptr_csdo; - - std::mutex *mutex_signal_queue; - std::mutex *mutex_packet_queue; - int packet_queue_size; - std::queue packet_queue; - std::queue packet_sizes_queue; - std::queue > signal_queue; - - rtc::Thread *signaling_thread; - rtc::scoped_refptr pc_factory; - rtc::scoped_refptr peer_connection; - rtc::scoped_refptr data_channel; -}; - -} // namespace godot_webrtc - -#endif // WEBRTC_PEER_H diff --git a/src/init.cpp b/src/init.cpp index e8e1d0c..ec6998b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,4 +1,4 @@ -#include "WebRTCPeer.hpp" +#include "WebRTCLibPeer.hpp" #include "net/WebRTCPeerNative.hpp" #include @@ -21,5 +21,5 @@ extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_opt extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { godot::Godot::nativescript_init(handle); - godot::register_class(); + godot::register_class(); } diff --git a/src/net/WebRTCPeerNative.cpp b/src/net/WebRTCPeerNative.cpp index d2abcaa..449cca2 100644 --- a/src/net/WebRTCPeerNative.cpp +++ b/src/net/WebRTCPeerNative.cpp @@ -24,7 +24,7 @@ WebRTCPeerNative::~WebRTCPeerNative() { * In this case it forwards calls to our C++ class, but could be plain C, * and you could use void *user for any kind of state struct pointer you have. */ -godot_error get_packet_wp(void *user, const uint8_t **r_buffer, int &r_len) { +godot_error get_packet_wp(void *user, const uint8_t **r_buffer, int *r_len) { return ((WebRTCPeerNative *)user)->get_packet(r_buffer, r_len); } diff --git a/src/net/WebRTCPeerNative.hpp b/src/net/WebRTCPeerNative.hpp index e82f295..90e08b3 100644 --- a/src/net/WebRTCPeerNative.hpp +++ b/src/net/WebRTCPeerNative.hpp @@ -8,7 +8,7 @@ #include /* Forward declare interface functions */ -godot_error get_packet_wp(void *, const uint8_t **, int &); +godot_error get_packet_wp(void *, const uint8_t **, int *); godot_error put_packet_wp(void *, const uint8_t *, int); godot_int get_available_packet_count_wp(const void *); godot_int get_max_packet_size_wp(const void *); @@ -69,7 +69,7 @@ public: virtual godot_error poll() = 0; /* PacketPeer */ - virtual godot_error get_packet(const uint8_t **r_buffer, int &r_len) = 0; + virtual godot_error get_packet(const uint8_t **r_buffer, int *r_len) = 0; virtual godot_error put_packet(const uint8_t *p_buffer, int p_len) = 0; virtual godot_int get_available_packet_count() const = 0; virtual godot_int get_max_packet_size() const = 0; -- cgit v1.2.3