diff --git a/Spitfire.sln b/Spitfire.sln index 83ffef48f..8ef71b3e7 100644 --- a/Spitfire.sln +++ b/Spitfire.sln @@ -5,22 +5,40 @@ VisualStudioVersion = 15.0.26730.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Spitfire", "Spitfire\Spitfire.vcxproj", "{5950B9B8-D486-4B8B-A3A1-53F1738F45ED}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpitfireUtils", "SpitfireUtils\SpitfireUtils.csproj", "{129233EA-CFEE-432B-9CEA-9CC7773C9A02}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Debug|x64.ActiveCfg = Debug|x64 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Debug|x64.Build.0 = Debug|x64 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Debug|x86.ActiveCfg = Debug|Win32 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Debug|x86.Build.0 = Debug|Win32 + {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Release|Any CPU.ActiveCfg = Release|Win32 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Release|x64.ActiveCfg = Release|x64 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Release|x64.Build.0 = Release|x64 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Release|x86.ActiveCfg = Release|Win32 {5950B9B8-D486-4B8B-A3A1-53F1738F45ED}.Release|x86.Build.0 = Release|Win32 + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|Any CPU.Build.0 = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|x64.ActiveCfg = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|x64.Build.0 = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|x86.ActiveCfg = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Debug|x86.Build.0 = Debug|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|Any CPU.ActiveCfg = Release|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|Any CPU.Build.0 = Release|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|x64.ActiveCfg = Release|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|x64.Build.0 = Release|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|x86.ActiveCfg = Release|Any CPU + {129233EA-CFEE-432B-9CEA-9CC7773C9A02}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Spitfire/CreateSessionDescriptionObserver.h b/Spitfire/CreateSessionDescriptionObserver.h index 82b805bfc..6209adfd2 100644 --- a/Spitfire/CreateSessionDescriptionObserver.h +++ b/Spitfire/CreateSessionDescriptionObserver.h @@ -17,16 +17,16 @@ namespace Spitfire { public: - virtual void OnSuccess(webrtc::SessionDescriptionInterface * desc); - virtual void OnFailure(const std::string & error); - CreateSessionDescriptionObserver(RtcConductor* manager); + void OnSuccess(webrtc::SessionDescriptionInterface * desc) override; + void OnFailure(const std::string & error) override; + explicit CreateSessionDescriptionObserver(RtcConductor* manager); ~CreateSessionDescriptionObserver(); - int AddRef() const + int AddRef() const override { return 0; }; - int Release() const + int Release() const override { return 0; }; diff --git a/Spitfire/DataChannelObserver.cpp b/Spitfire/DataChannelObserver.cpp index a280b44ba..d63d402a0 100644 --- a/Spitfire/DataChannelObserver.cpp +++ b/Spitfire/DataChannelObserver.cpp @@ -10,6 +10,14 @@ void Spitfire::Observers::DataChannelObserver::OnStateChange() } } +void Spitfire::Observers::DataChannelObserver::OnBufferedAmountChange(uint64_t previous_amount) +{ + if (_manager->onBufferAmountChange != nullptr) + { + _manager->onBufferAmountChange(previous_amount, dataChannel->buffered_amount(), dataChannel->bytes_sent(), dataChannel->bytes_received()); + } +} + void Spitfire::Observers::DataChannelObserver::OnMessage(const webrtc::DataBuffer & buffer) { if (buffer.binary) diff --git a/Spitfire/DataChannelObserver.h b/Spitfire/DataChannelObserver.h index ca052105a..2245f0f4f 100644 --- a/Spitfire/DataChannelObserver.h +++ b/Spitfire/DataChannelObserver.h @@ -18,16 +18,13 @@ namespace Spitfire { { public: // The data channel state have changed. - virtual void OnStateChange(); + void OnStateChange() override; // A data buffer was successfully received. - virtual void OnMessage(const webrtc::DataBuffer & buffer); + void OnMessage(const webrtc::DataBuffer & buffer) override; // The data channel's buffered_amount has changed. - virtual void OnBufferedAmountChange(uint64_t previous_amount) - { - - } + void OnBufferedAmountChange(uint64_t previous_amount) override; explicit DataChannelObserver(RtcConductor* manager); ~DataChannelObserver(); diff --git a/Spitfire/PeerConnectionObserver.h b/Spitfire/PeerConnectionObserver.h index 0a92d1845..73328aff2 100644 --- a/Spitfire/PeerConnectionObserver.h +++ b/Spitfire/PeerConnectionObserver.h @@ -14,41 +14,41 @@ namespace Spitfire { public: // Triggered when the SignalingState changed. - virtual void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state); + void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override; virtual void OnStateChange(StateType state_changed) { /* Obsolete. Ignore. */ } // Triggered when media is received on a new stream from remote peer. - virtual void OnAddStream(rtc::scoped_refptr stream) + void OnAddStream(rtc::scoped_refptr stream) override { LOG(INFO) << __FUNCTION__ << " "; } - virtual void OnRemoveStream(rtc::scoped_refptr stream) + void OnRemoveStream(rtc::scoped_refptr stream) override { LOG(INFO) << __FUNCTION__ << " "; } // Triggered when a remote peer open a data channel. - virtual void OnDataChannel(rtc::scoped_refptr channel); + void OnDataChannel(rtc::scoped_refptr channel) override; // Triggered when renegotiation is needed, for example the ICE has restarted. - virtual void OnRenegotiationNeeded(); + void OnRenegotiationNeeded() override; // Called any time the IceConnectionState changes - virtual void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state); + void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override; // Called any time the IceGatheringState changes - virtual void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state); + void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override; // New Ice candidate have been found. - virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate); + void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override; virtual void OnIceComplete() { /* Obsolete. Ignore. */ } // Called when the ICE connection receiving status changes. - virtual void OnIceConnectionReceivingChange(bool receiving) { /* Not Implemented */ }; + void OnIceConnectionReceivingChange(bool receiving) override { /* Not Implemented */ }; explicit PeerConnectionObserver(RtcConductor* manager); ~PeerConnectionObserver(); diff --git a/Spitfire/RtcConductor.cpp b/Spitfire/RtcConductor.cpp index 189be5faa..2b3897e4c 100644 --- a/Spitfire/RtcConductor.cpp +++ b/Spitfire/RtcConductor.cpp @@ -56,9 +56,9 @@ namespace Spitfire } serverConfigs.clear(); - // network_thread_->Stop(); - // worker_thread_->Stop(); - // signaling_thread_->Stop(); + network_thread_->Stop(); + worker_thread_->Stop(); + signaling_thread_->Stop(); rtc::Thread::Current()->Stop(); @@ -67,22 +67,20 @@ namespace Spitfire bool RtcConductor::InitializePeerConnection() { - rtc::LogMessage::LogTimestamps(); - rtc::LogMessage::LogThreads(); - rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); - rtc::LogMessage::SetLogToStderr(true); rtc::ThreadManager::Instance()->WrapCurrentThread(); RTC_DCHECK(pc_factory_ == nullptr); RTC_DCHECK(peerObserver->peerConnection == nullptr); - //network_thread_.reset(rtc::Thread::CreateWithSocketServer().release()); - //worker_thread_.reset(rtc::Thread::Create().release()); - //signaling_thread_.reset(rtc::Thread::Create().release()); - //network_thread_->Start(); - // worker_thread_->Start(); - // signaling_thread_->Start(); + network_thread_ = rtc::Thread::CreateWithSocketServer().release(); + worker_thread_ = rtc::Thread::Create().release(); + signaling_thread_ = rtc::Thread::Create().release(); - pc_factory_ = webrtc::CreatePeerConnectionFactory(rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), FakeAudioCaptureModule::Create(), + + network_thread_->Start(); + worker_thread_->Start(); + signaling_thread_->Start(); + + pc_factory_ = webrtc::CreatePeerConnectionFactory(network_thread_, worker_thread_, signaling_thread_, FakeAudioCaptureModule::Create(), new FakeWebRtcVideoEncoderFactory(), new FakeWebRtcVideoDecoderFactory()); diff --git a/Spitfire/RtcConductor.h b/Spitfire/RtcConductor.h index 30d34907f..4545ce7b3 100644 --- a/Spitfire/RtcConductor.h +++ b/Spitfire/RtcConductor.h @@ -19,13 +19,13 @@ namespace Spitfire typedef void(__stdcall *OnErrorCallbackNative)(); typedef void(__stdcall *OnSuccessCallbackNative)(const char * type, const char * sdp); typedef void(__stdcall *OnFailureCallbackNative)(const char * error); - typedef void(__stdcall *OnIceCandidateCallbackNative)(const char * sdp_mid, int sdp_mline_index, const char * sdp); - typedef void(__stdcall *OnRenderCallbackNative)(uint8_t * frame_buffer, uint32_t w, uint32_t h); + typedef void(__stdcall *OnIceCandidateCallbackNative)(const char * sdpMid, int sdpIndex, const char * sdp); + typedef void(__stdcall *OnRenderCallbackNative)(uint8_t * frameBuffer, uint32_t w, uint32_t h); typedef void(__stdcall *OnDataMessageCallbackNative)(const char * msg); typedef void(__stdcall *OnDataBinaryMessageCallbackNative)(const uint8_t * msg, uint32_t size); typedef void(__stdcall *OnIceStateChangeCallbackNative)(webrtc::PeerConnectionInterface::IceConnectionState state); typedef void(__stdcall *OnDataChannelStateCallbackNative)(webrtc::DataChannelInterface::DataState state); - + typedef void(__stdcall *OnBufferAmountCallbackNative)(uint64_t previousAmount, uint64_t currentAmount, uint64_t bytesSent, uint64_t bytesReceived); class RtcConductor { @@ -58,6 +58,7 @@ namespace Spitfire OnIceStateChangeCallbackNative onIceStateChange; OnIceCandidateCallbackNative onIceCandidate; OnDataChannelStateCallbackNative onDataChannelState; + OnBufferAmountCallbackNative onBufferAmountChange; OnDataMessageCallbackNative onDataMessage; OnDataBinaryMessageCallbackNative onDataBinaryMessage; @@ -80,9 +81,9 @@ namespace Spitfire private: - std::unique_ptr worker_thread_; - std::unique_ptr signaling_thread_; - std::unique_ptr network_thread_; + rtc::Thread* worker_thread_; + rtc::Thread* signaling_thread_; + rtc::Thread* network_thread_; bool CreatePeerConnection(bool dtls); diff --git a/Spitfire/RtcUtils.cpp b/Spitfire/RtcUtils.cpp index e2d085bad..fa4df060f 100644 --- a/Spitfire/RtcUtils.cpp +++ b/Spitfire/RtcUtils.cpp @@ -83,8 +83,6 @@ #pragma comment(lib,"common_video.lib") #pragma comment(lib,"congestion_controller.lib") #pragma comment(lib,"create_pc_factory.lib") -#pragma comment(lib,"desktop_capture.lib") -#pragma comment(lib,"desktop_capture_differ_sse2.lib") #pragma comment(lib,"dl.lib") #pragma comment(lib,"event_log_visualizer_utils.lib") #pragma comment(lib,"field_trial_default.lib") @@ -183,12 +181,15 @@ namespace Spitfire void InitializeSSL() { rtc::EnsureWinsockInit(); - rtc::InitializeSSL(NULL); + rtc::InitializeSSL(nullptr); } void EnableLogging() { - + rtc::LogMessage::LogTimestamps(); + rtc::LogMessage::LogThreads(); + rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); + rtc::LogMessage::SetLogToStderr(true); } void CleanupSSL() @@ -199,7 +200,7 @@ namespace Spitfire FILE _iob[] = { *stdin, *stdout, *stderr }; -extern "C" FILE * __cdecl __iob_func(void) +extern "C" FILE * __cdecl __iob_func() { return _iob; } \ No newline at end of file diff --git a/Spitfire/SetSessionDescriptionObserver.h b/Spitfire/SetSessionDescriptionObserver.h index ac95be2e1..10fcd6b5c 100644 --- a/Spitfire/SetSessionDescriptionObserver.h +++ b/Spitfire/SetSessionDescriptionObserver.h @@ -12,16 +12,16 @@ namespace Spitfire { public: ~SetSessionDescriptionObserver(); - SetSessionDescriptionObserver(RtcConductor* manager); + explicit SetSessionDescriptionObserver(RtcConductor* manager); - virtual void OnSuccess(); - virtual void OnFailure(const std::string& error); + void OnSuccess() override; + void OnFailure(const std::string& error) override; - int AddRef() const + int AddRef() const override { return 0; }; - int Release() const + int Release() const override { return 0; }; diff --git a/Spitfire/Spitfire.vcxproj b/Spitfire/Spitfire.vcxproj index 7cc6c5953..a3ed4126c 100644 --- a/Spitfire/Spitfire.vcxproj +++ b/Spitfire/Spitfire.vcxproj @@ -27,20 +27,20 @@ - Application + DynamicLibrary true v141 Unicode - Application + DynamicLibrary false v141 true Unicode - Application + DynamicLibrary true v141 Unicode @@ -74,7 +74,7 @@ true - true + false false @@ -84,45 +84,57 @@ - Use + NotUsing Level3 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;DEBUG;_CONSOLE;WIN32;_CRT_SECURE_NO_WARNINGS;UNICODE;V8_DEPRECATION_WARNINGS;_WINDOWS;NOMINMAX;PSAPI_VERSION=1;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_ATL_NO_OPENGL;_SECURE_ATL;_HAS_EXCEPTIONS=0;_WINSOCK_DEPRECATED_NO_WARNINGS;CHROMIUM_BUILD;CR_CLANG_REVISION=274369-1;COMPONENT_BUILD;USE_AURA=1;USE_DEFAULT_RENDER_THEME=1;USE_LIBJPEG_TURBO=1;ENABLE_WEBRTC=1;ENABLE_MEDIA_ROUTER=1;ENABLE_PEPPER_CDMS;ENABLE_NOTIFICATIONS;FIELDTRIAL_TESTING_ENABLED;NO_TCMALLOC;__STD_C;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;NTDDI_VERSION=0x0A000000;_USING_V110_SDK71_;ENABLE_TASK_MANAGER=1;ENABLE_EXTENSIONS=1;ENABLE_PDF=1;ENABLE_PLUGIN_INSTALLATION=1;ENABLE_PLUGINS=1;ENABLE_SESSION_SERVICE=1;ENABLE_THEMES=1;ENABLE_PRINTING=1;ENABLE_BASIC_PRINTING=1;ENABLE_PRINT_PREVIEW=1;ENABLE_SPELLCHECK=1;ENABLE_CAPTIVE_PORTAL_DETECTION=1;ENABLE_SUPERVISED_USERS=1;ENABLE_MDNS=1;ENABLE_SERVICE_DISCOVERY=1;V8_USE_EXTERNAL_STARTUP_DATA;FULL_SAFE_BROWSING;SAFE_BROWSING_CSD;SAFE_BROWSING_DB_LOCAL;WEBRTC_WIN;USE_LIBPCI=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;DYNAMIC_ANNOTATIONS_ENABLED=1;WTF_USE_DYNAMIC_ANNOTATIONS=1;%(PreprocessorDefinitions) true + $(SolutionDir)/include;%(AdditionalIncludeDirectories) + Default + ProgramDatabase Console true + $(SolutionDir)/libs/lib_x86_debug;%(AdditionalLibraryDirectories) - Use + NotUsing Level3 Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;DEBUG;_CONSOLE;WIN64;_CRT_SECURE_NO_WARNINGS;UNICODE;V8_DEPRECATION_WARNINGS;_WINDOWS;NOMINMAX;PSAPI_VERSION=1;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_ATL_NO_OPENGL;_SECURE_ATL;_HAS_EXCEPTIONS=0;_WINSOCK_DEPRECATED_NO_WARNINGS;CHROMIUM_BUILD;CR_CLANG_REVISION=274369-1;COMPONENT_BUILD;USE_AURA=1;USE_DEFAULT_RENDER_THEME=1;USE_LIBJPEG_TURBO=1;ENABLE_WEBRTC=1;ENABLE_MEDIA_ROUTER=1;ENABLE_PEPPER_CDMS;ENABLE_NOTIFICATIONS;FIELDTRIAL_TESTING_ENABLED;NO_TCMALLOC;__STD_C;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;NTDDI_VERSION=0x0A000000;_USING_V110_SDK71_;ENABLE_TASK_MANAGER=1;ENABLE_EXTENSIONS=1;ENABLE_PDF=1;ENABLE_PLUGIN_INSTALLATION=1;ENABLE_PLUGINS=1;ENABLE_SESSION_SERVICE=1;ENABLE_THEMES=1;ENABLE_PRINTING=1;ENABLE_BASIC_PRINTING=1;ENABLE_PRINT_PREVIEW=1;ENABLE_SPELLCHECK=1;ENABLE_CAPTIVE_PORTAL_DETECTION=1;ENABLE_SUPERVISED_USERS=1;ENABLE_MDNS=1;ENABLE_SERVICE_DISCOVERY=1;V8_USE_EXTERNAL_STARTUP_DATA;FULL_SAFE_BROWSING;SAFE_BROWSING_CSD;SAFE_BROWSING_DB_LOCAL;WEBRTC_WIN;USE_LIBPCI=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;DYNAMIC_ANNOTATIONS_ENABLED=1;WTF_USE_DYNAMIC_ANNOTATIONS=1;%(PreprocessorDefinitions) true + $(SolutionDir)/include;%(AdditionalIncludeDirectories) + Default + ProgramDatabase Console true + $(SolutionDir)\libs\lib_x64_debug;%(AdditionalLibraryDirectories) - Use + NotUsing Level3 MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;UNICODE;V8_DEPRECATION_WARNINGS;_WINDOWS;NOMINMAX;PSAPI_VERSION=1;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_ATL_NO_OPENGL;_SECURE_ATL;_HAS_EXCEPTIONS=0;_WINSOCK_DEPRECATED_NO_WARNINGS;CHROMIUM_BUILD;CR_CLANG_REVISION=274369-1;COMPONENT_BUILD;USE_AURA=1;USE_DEFAULT_RENDER_THEME=1;USE_LIBJPEG_TURBO=1;ENABLE_WEBRTC=1;ENABLE_MEDIA_ROUTER=1;ENABLE_PEPPER_CDMS;ENABLE_NOTIFICATIONS;FIELDTRIAL_TESTING_ENABLED;NO_TCMALLOC;__STD_C;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;NTDDI_VERSION=0x0A000000;_USING_V110_SDK71_;ENABLE_TASK_MANAGER=1;ENABLE_EXTENSIONS=1;ENABLE_PDF=1;ENABLE_PLUGIN_INSTALLATION=1;ENABLE_PLUGINS=1;ENABLE_SESSION_SERVICE=1;ENABLE_THEMES=1;ENABLE_PRINTING=1;ENABLE_BASIC_PRINTING=1;ENABLE_PRINT_PREVIEW=1;ENABLE_SPELLCHECK=1;ENABLE_CAPTIVE_PORTAL_DETECTION=1;ENABLE_SUPERVISED_USERS=1;ENABLE_MDNS=1;ENABLE_SERVICE_DISCOVERY=1;V8_USE_EXTERNAL_STARTUP_DATA;FULL_SAFE_BROWSING;SAFE_BROWSING_CSD;SAFE_BROWSING_DB_LOCAL;WEBRTC_WIN;USE_LIBPCI=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;DYNAMIC_ANNOTATIONS_ENABLED=1;WTF_USE_DYNAMIC_ANNOTATIONS=1;%(PreprocessorDefinitions) true + $(SolutionDir)/include;%(AdditionalIncludeDirectories) + + Console true true true + $(SolutionDir)/libs/lib_x86_release;%(AdditionalLibraryDirectories) @@ -135,13 +147,16 @@ NDEBUG;WIN64;_CRT_SECURE_NO_WARNINGS;UNICODE;V8_DEPRECATION_WARNINGS;_WINDOWS;NOMINMAX;PSAPI_VERSION=1;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_ATL_NO_OPENGL;_SECURE_ATL;_HAS_EXCEPTIONS=0;_WINSOCK_DEPRECATED_NO_WARNINGS;CHROMIUM_BUILD;CR_CLANG_REVISION=274369-1;COMPONENT_BUILD;USE_AURA=1;USE_DEFAULT_RENDER_THEME=1;USE_LIBJPEG_TURBO=1;ENABLE_WEBRTC=1;ENABLE_MEDIA_ROUTER=1;ENABLE_PEPPER_CDMS;ENABLE_NOTIFICATIONS;FIELDTRIAL_TESTING_ENABLED;NO_TCMALLOC;__STD_C;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;NTDDI_VERSION=0x0A000000;_USING_V110_SDK71_;ENABLE_TASK_MANAGER=1;ENABLE_EXTENSIONS=1;ENABLE_PDF=1;ENABLE_PLUGIN_INSTALLATION=1;ENABLE_PLUGINS=1;ENABLE_SESSION_SERVICE=1;ENABLE_THEMES=1;ENABLE_PRINTING=1;ENABLE_BASIC_PRINTING=1;ENABLE_PRINT_PREVIEW=1;ENABLE_SPELLCHECK=1;ENABLE_CAPTIVE_PORTAL_DETECTION=1;ENABLE_SUPERVISED_USERS=1;ENABLE_MDNS=1;ENABLE_SERVICE_DISCOVERY=1;V8_USE_EXTERNAL_STARTUP_DATA;FULL_SAFE_BROWSING;SAFE_BROWSING_CSD;SAFE_BROWSING_DB_LOCAL;WEBRTC_WIN;USE_LIBPCI=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;DYNAMIC_ANNOTATIONS_ENABLED=1;WTF_USE_DYNAMIC_ANNOTATIONS=1;%(PreprocessorDefinitions) true $(SolutionDir)/include;%(AdditionalIncludeDirectories) + + + Speed Console true true true - $(SolutionDir)/libs/lib_x64;%(AdditionalLibraryDirectories) + $(SolutionDir)/libs/lib_x64_release;%(AdditionalLibraryDirectories) @@ -166,6 +181,26 @@ true Async + true + true + true + None + None + false + Async + false + Async + Async + None + None + + + + + + + + diff --git a/Spitfire/SpitfireRtc.cpp b/Spitfire/SpitfireRtc.cpp index e42bea828..8dc39749e 100644 --- a/Spitfire/SpitfireRtc.cpp +++ b/Spitfire/SpitfireRtc.cpp @@ -144,6 +144,10 @@ namespace Spitfire _OnDataChannelStateCallback ^ onDataChannelStateChange; GCHandle ^ onDataChannelStateHandle; + delegate void _OnBufferChangeCallback(uint64_t previousAmount, uint64_t currentAmount, uint64_t bytesSent, uint64_t bytesReceived); + _OnBufferChangeCallback ^ onBufferAmountChange; + GCHandle ^ onBufferAmountChangeHandle; + delegate void _OnIceStateCallback(webrtc::PeerConnectionInterface::IceConnectionState state); _OnIceStateCallback ^ onIceStateChange; @@ -217,6 +221,11 @@ namespace Spitfire OnIceStateChange(managedState); } + void _OnBufferAmountChange(uint64_t previousAmount, uint64_t currentAmount, uint64_t bytesSent, uint64_t bytesReceived) + { + OnBufferAmountChange(previousAmount, currentAmount, bytesSent, bytesReceived); + } + void _OnDataChannelState(webrtc::DataChannelInterface::DataState state) { if (state == webrtc::DataChannelInterface::DataState::kOpen) @@ -266,6 +275,9 @@ namespace Spitfire delegate void IceStateChange(IceConnectionState msg); event IceStateChange ^ OnIceStateChange; + delegate void BufferChange(long previousBufferAmount, long currentBufferAmount, long bytesSent, long bytesReceived); + event BufferChange ^ OnBufferAmountChange; + SpitfireRtc() { m_isDisposed = false; @@ -304,6 +316,11 @@ namespace Spitfire onIceStateChange = gcnew _OnIceStateCallback(this, &SpitfireRtc::_OnIceState); onIceStateCallbackHandle = GCHandle::Alloc(onIceStateChange); _conductor->onIceStateChange = static_cast(Marshal::GetFunctionPointerForDelegate(onIceStateChange).ToPointer()); + + + onBufferAmountChange = gcnew _OnBufferChangeCallback(this, &SpitfireRtc::_OnBufferAmountChange); + onBufferAmountChangeHandle = GCHandle::Alloc(onBufferAmountChange); + _conductor->onBufferAmountChange = static_cast(Marshal::GetFunctionPointerForDelegate(onBufferAmountChange).ToPointer()); } ~SpitfireRtc() @@ -321,6 +338,10 @@ namespace Spitfire FreeGCHandle(onDataMessageHandle); FreeGCHandle(onDataBinaryMessageHandle); FreeGCHandle(onDataChannelStateHandle); + if (_conductor != nullptr) + { + _conductor->DeletePeerConnection(); + } this->!SpitfireRtc(); // call finalizer @@ -386,7 +407,7 @@ namespace Spitfire { _conductor->DataChannelSendText(marshal_as(text)); } - + void DataChannelSendData(array^ array_data) { pin_ptr thePtr = &array_data[0]; diff --git a/SpitfireUtils/DataChannelUtils.cs b/SpitfireUtils/DataChannelUtils.cs new file mode 100644 index 000000000..75bbbfcb7 --- /dev/null +++ b/SpitfireUtils/DataChannelUtils.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SpitfireUtils +{ + public static class DataChannelUtils + { + + /// + /// A memcpy based variant of the Resize function, it is used to copy a segment + /// into a new buffer, usually smaller. + /// + /// + /// + /// + public static unsafe void MemoryResize(ref byte[] source, ref byte[] target, uint count) + { + fixed (byte* pSource = source, pTarget = target) + { + var ps = pSource; + var pt = pTarget; + Native.Copy(pt, ps, count); + } + } + /// + /// Uses memcpy to slice an array into smaller chunks very quickly. + /// + /// + /// + /// + /// + /// + public static unsafe void MemorySlice(ref byte[] source, int sourceOffset, ref byte[] target, int targetOffset, uint count) + { + fixed (byte* pSource = source, pTarget = target) + { + var ps = pSource + sourceOffset; + var pt = pTarget + targetOffset; + Native.Copy(pt, ps, count); + } + } + + /// + /// Copy a segment of data into a new array using pointers. + /// + /// + /// + /// + public static unsafe void Resize(ref byte[] source, ref byte[] target, int count) + { + fixed (byte* pSource = source, pTarget = target) + { + var ps = pSource; + var pt = pTarget; + for (var i = 0; i < count; i++) + { + *pt = *ps; + pt++; + ps++; + } + } + } + /// + /// Slice an array into smaller chunks using pointers. + /// + /// + /// + /// + /// + /// + public static unsafe void Slice(ref byte[] source, int sourceOffset, ref byte[] target, int targetOffset, uint count) + { + fixed (byte* pSource = source, pTarget = target) + { + var ps = pSource + sourceOffset; + var pt = pTarget + targetOffset; + for (var i = 0; i < count; i++) + { + *pt = *ps; + pt++; + ps++; + } + } + } + } +} diff --git a/SpitfireUtils/IceParser.cs b/SpitfireUtils/IceParser.cs new file mode 100644 index 000000000..2a6497196 --- /dev/null +++ b/SpitfireUtils/IceParser.cs @@ -0,0 +1,189 @@ +using System.Collections.Generic; +using System.Net; +using System.Text.RegularExpressions; +namespace SpitfireUtils { + + public enum IceType + { + Host, + Srflx, + Prflx, + Relay, + Unknown + } + + public enum IceTransport + { + Tcp, + Udp, + Unknown + } + /// + /// Contains information on a parse ICE candidate. + /// + public class IceCandidate + { + public string Raw { get; set; } + public ulong Foundation { get; set; } + public uint ComponentId { get; set; } + public IceTransport Transport { get; set; } + public ulong Priority { get; set; } + + public IPAddress LocalIp { get; set; } + + public ushort LocalPort { get; set; } + public IceType Type { get; set; } + + public IPAddress RemoteIp { get; set; } + + public ushort RemotePort { get; set; } + public uint Generation { get; set; } + + public bool Valid => Type != IceType.Unknown; + + public string UFrag { get; set; } + public int NetworkCost { get; set; } + public int NetworkId { get; set; } + } + + public static class IceParser + { + #region static members + + private static readonly Dictionary IceTypeMap = new Dictionary + { + {"host", IceType.Host}, + {"srflx", IceType.Srflx}, + {"prflx", IceType.Prflx}, + {"relay", IceType.Relay} + }; + + private static readonly Dictionary IceTransportMap = + new Dictionary + { + {"udp", IceTransport.Udp}, + {"tcp", IceTransport.Tcp} + }; + + private static readonly Regex TokenRegex = new Regex("[0-9a-zA-Z\\-\\.!\\%\\*_\\+\\`\\\'\\~]+"); + private static readonly Regex IceRegex = new Regex("[a-zA-Z0-9\\+\\/]+"); + private static readonly Regex ComponentIdRegex = new Regex("[0-9]{1,5}"); + private static readonly Regex PriorityRegex = new Regex("[0-9]{1,10}"); + private static readonly Regex Ipv4AddressRegex = new Regex("[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"); + private static readonly Regex Ipv6AdresssRegex = new Regex(":?(?:[0-9a-fA-F]{0,4}:?)+"); + + private static readonly Regex ConnectAddressRegex = + new Regex($"(?:{Ipv4AddressRegex})|(?:{Ipv6AdresssRegex})"); + + private static readonly Regex PortRegex = new Regex("[0-9]{1,5}"); + + private static readonly Regex MasterRegex = + new Regex( + $"(?:a=)?candidate:({IceRegex})\\s({ComponentIdRegex})\\s({TokenRegex})\\s" + + $"({PriorityRegex})\\s({ConnectAddressRegex})\\s({PortRegex})" + + $"\\styp\\s({TokenRegex})(?:\\sraddr\\s({ConnectAddressRegex})\\srport\\s({PortRegex}))?(?:\\sgeneration\\s(\\d+))?(?:\\sufrag\\s({IceRegex}))?(?:\\snetwork-id\\s({PriorityRegex}))?(?:\\snetwork-cost\\s({PriorityRegex}))?") + ; + #endregion + + /// + /// Checks the transport type Dictionary for the connection type. + /// + /// + /// The connection type + private static IceTransport GetTransportType(string transport) + { + transport = transport.ToLower(); + return IceTransportMap.ContainsKey(transport) ? IceTransportMap[transport] : IceTransport.Unknown; + } + + + /// + /// Parse an ice candidate string and extract information on the connection + /// + /// + /// A parse ice candidate + public static IceCandidate Parse(string candidate) + { + var iceCandidate = new IceCandidate(); + var parsed = MasterRegex.Match(candidate); + //we should only ever have 11 results, even if generation is missing. + if (!parsed.Success || parsed.Groups.Count != 14) + { + return null; + } + for (var i = 0; i < parsed.Groups.Count; i++) + { + try + { + var value = parsed.Groups[i].Value; + if (string.IsNullOrWhiteSpace(value)) + { + continue; + } + switch (i) + { + case 0: + iceCandidate.Raw = value; + + break; + case 1: + iceCandidate.Foundation = ulong.Parse(value); + break; + case 2: + iceCandidate.ComponentId = uint.Parse(value); + break; + case 3: + iceCandidate.Transport = GetTransportType(value); + break; + case 4: + iceCandidate.Priority = ulong.Parse(value); + break; + case 5: + iceCandidate.LocalIp = IPAddress.Parse(value); + break; + case 6: + iceCandidate.LocalPort = ushort.Parse(value); + break; + case 7: + iceCandidate.Type = GetIceType(value); + break; + case 8: + iceCandidate.RemoteIp = IPAddress.Parse(value); + break; + case 9: + iceCandidate.RemotePort = ushort.Parse(value); + break; + case 10: + iceCandidate.Generation = uint.Parse(value); + break; + case 11: + iceCandidate.UFrag = value; + break; + case 12: + iceCandidate.NetworkId = int.Parse(value); + break; + case 13: + iceCandidate.NetworkCost = int.Parse(value); + break; + } + } + catch (System.Exception ex) + { + return null; + } + } + return iceCandidate; + } + + /// + /// Checks the ice type against the type Dictionary. + /// + /// + /// The ice type + private static IceType GetIceType(string value) + { + value = value.ToLower(); + return IceTypeMap.ContainsKey(value) ? IceTypeMap[value] : IceType.Unknown; + } + } +} \ No newline at end of file diff --git a/SpitfireUtils/Native.cs b/SpitfireUtils/Native.cs new file mode 100644 index 000000000..130e68039 --- /dev/null +++ b/SpitfireUtils/Native.cs @@ -0,0 +1,34 @@ +using System.Reflection.Emit; + +namespace SpitfireUtils +{ + + internal static class Native + { + public unsafe delegate void MemCpyFunction(void* des, void* src, uint bytes); + + public static MemCpyFunction Copy; + + static Native() + { + var dynamicMethod = new DynamicMethod + ( + "MemCpy", + typeof(void), + new[] { typeof(void*), typeof(void*), typeof(uint) }, + typeof(Native) + ); + + var ilGenerator = dynamicMethod.GetILGenerator(); + + ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(OpCodes.Ldarg_1); + ilGenerator.Emit(OpCodes.Ldarg_2); + + ilGenerator.Emit(OpCodes.Cpblk); + ilGenerator.Emit(OpCodes.Ret); + + Copy = (MemCpyFunction)dynamicMethod.CreateDelegate(typeof(MemCpyFunction)); + } + } +} diff --git a/SpitfireUtils/SpitfireUtils.csproj b/SpitfireUtils/SpitfireUtils.csproj new file mode 100644 index 000000000..b8eadc29a --- /dev/null +++ b/SpitfireUtils/SpitfireUtils.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + true + + + + + + + diff --git a/scripts/build_x64_debug.bat b/scripts/build_x64_debug.bat new file mode 100644 index 000000000..4875c5a3f --- /dev/null +++ b/scripts/build_x64_debug.bat @@ -0,0 +1,4 @@ +cd webrtc-checkout\src\ +call gn gen out/x64/Debug --args="is_debug=true target_cpu=\"x64\" symbol_level=2 enable_nacl=false rtc_enable_sctp=true fatal_linker_warnings=false treat_warnings_as_errors=false" +call ninja -C out/x64/Debug +pause diff --git a/scripts/build_x64_release.bat b/scripts/build_x64_release.bat new file mode 100644 index 000000000..41391f014 --- /dev/null +++ b/scripts/build_x64_release.bat @@ -0,0 +1,4 @@ +cd webrtc-checkout\src\ +call gn gen out/x64/Release --args="is_debug=false target_cpu=\"x64\" symbol_level=0 enable_nacl=false rtc_enable_sctp=true fatal_linker_warnings=false treat_warnings_as_errors=false" +call ninja -C out/x64/Release +pause diff --git a/scripts/build_x86_debug.bat b/scripts/build_x86_debug.bat new file mode 100644 index 000000000..e689ea977 --- /dev/null +++ b/scripts/build_x86_debug.bat @@ -0,0 +1,4 @@ +cd webrtc-checkout\src\ +call gn gen out/x86/Debug --args="is_debug=true target_cpu=\"x86\" symbol_level=2 enable_nacl=false rtc_enable_sctp=true fatal_linker_warnings=false treat_warnings_as_errors=false" +call ninja -C out/x86/Debug +pause diff --git a/scripts/build_x86_release.bat b/scripts/build_x86_release.bat new file mode 100644 index 000000000..499266c84 --- /dev/null +++ b/scripts/build_x86_release.bat @@ -0,0 +1,4 @@ +cd webrtc-checkout\src\ +call gn gen out/x86/Release --args="is_debug=false target_cpu=\"x86\" symbol_level=0 enable_nacl=false rtc_enable_sctp=true fatal_linker_warnings=false treat_warnings_as_errors=false" +call ninja -C out/x86/Release +pause diff --git a/scripts/downloadprep.bat b/scripts/downloadprep.bat new file mode 100644 index 000000000..7e9bf9718 --- /dev/null +++ b/scripts/downloadprep.bat @@ -0,0 +1,10 @@ +rmdir /s/q webrtc-checkout +mkdir webrtc-checkout +cd webrtc-checkout +call fetch --nohooks webrtc +cd src +call git branch -r +call git checkout branch-heads/61 +call gclient sync +Echo 'Please edit the checked out branch to build with the MD flag' +pause diff --git a/scripts/include.bat b/scripts/include.bat new file mode 100644 index 000000000..a1295844d --- /dev/null +++ b/scripts/include.bat @@ -0,0 +1,19 @@ +set "folder=includes" +rmdir /s/q %folder% +mkdir %folder% + +xcopy /s webrtc-checkout\src\webrtc\*.h %folder%\webrtc\ + + +xcopy /s webrtc-checkout\src\third_party\libvpx\*.h %folder%\third_party\libvpx\ + + +xcopy /s webrtc-checkout\src\third_party\libyuv\include\*.h %folder%\third_party\libyuv\include\ + + +xcopy /s webrtc-checkout\src\third_party\jsoncpp\*.h %folder%\third_party\jsoncpp\ + + + +xcopy /s webrtc-checkout\src\third_party\boringssl\*.h %folder%\third_party\boringssl\ + diff --git a/scripts/link_x64_debug.bat b/scripts/link_x64_debug.bat new file mode 100644 index 000000000..457482777 --- /dev/null +++ b/scripts/link_x64_debug.bat @@ -0,0 +1,7 @@ +set "folder=link" +rmdir /s/q %folder%\Libx64\Debug + +For /f %%b In ('Dir webrtc-checkout\src\out\x64\Debug\ /b /s /a:d') Do ( + Robocopy %%b %folder%\Libx64\Debug\ *.lib /xx /np + ) +pause diff --git a/scripts/link_x64_release.bat b/scripts/link_x64_release.bat new file mode 100644 index 000000000..a44e1fd96 --- /dev/null +++ b/scripts/link_x64_release.bat @@ -0,0 +1,7 @@ +set "folder=link" +rmdir /s/q %folder%\Libx64\Release + +For /f %%b In ('Dir webrtc-checkout\src\out\x64\Release\ /b /s /a:d') Do ( + Robocopy %%b %folder%\Libx64\Release\ *.lib /xx /np + ) +pause diff --git a/scripts/link_x86_debug.bat b/scripts/link_x86_debug.bat new file mode 100644 index 000000000..60208c815 --- /dev/null +++ b/scripts/link_x86_debug.bat @@ -0,0 +1,7 @@ +set "folder=link" +rmdir /s/q %folder%\Libx86\Debug + +For /f %%b In ('Dir webrtc-checkout\src\out\x86\Debug\ /b /s /a:d') Do ( + Robocopy %%b %folder%\Libx86\Debug\ *.lib /xx /np + ) +pause diff --git a/scripts/link_x86_release.bat b/scripts/link_x86_release.bat new file mode 100644 index 000000000..0383eeccf --- /dev/null +++ b/scripts/link_x86_release.bat @@ -0,0 +1,7 @@ +set "folder=link" +rmdir /s/q %folder%\Libx86\Release + +For /f %%b In ('Dir webrtc-checkout\src\out\x86\Release\ /b /s /a:d') Do ( + Robocopy %%b %folder%\Libx86\Release\ *.lib /xx /np + ) +pause