From b16b29780bd0ed2d89a53e6da9766750590c99d0 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Tue, 19 Sep 2023 17:06:00 +0800 Subject: [PATCH] Remote desk client supports MacOS --- .../remote_desk_client/remote_desk_client.cpp | 67 ++++++++++++++----- .../remote_desk_server/remote_desk_server.cpp | 39 +++++++++-- application/remote_desk/xmake.lua | 16 ++++- config/config.ini | 8 ++- src/frame/frame.h | 1 + src/ice/ice_agent.cpp | 26 ++++++- src/ice/ice_agent.h | 12 +++- .../video/decode/ffmpeg/ffmpeg_decoder.h | 2 - .../video/encode/ffmpeg/ffmpeg_encoder.cpp | 44 ++++++++++++ .../video/encode/ffmpeg/ffmpeg_encoder.h | 47 +++++++++++++ src/media/video/encode/nvcodec/nv_encoder.cpp | 6 +- src/media/video/encode/nvcodec/nv_encoder.h | 2 +- src/pc/peer_connection.cpp | 30 +++++++-- src/pc/peer_connection.h | 15 ++++- src/transmission/ice_transmission.cpp | 8 ++- src/transmission/ice_transmission.h | 5 +- thirdparty/sdl2/xmake.lua | 10 +++ thirdparty/xmake.lua | 2 +- xmake.lua | 27 +++++--- 19 files changed, 312 insertions(+), 55 deletions(-) create mode 100644 src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp create mode 100644 src/media/video/encode/ffmpeg/ffmpeg_encoder.h create mode 100644 thirdparty/sdl2/xmake.lua diff --git a/application/remote_desk/remote_desk_client/remote_desk_client.cpp b/application/remote_desk/remote_desk_client/remote_desk_client.cpp index 4cf8f68..25909c4 100644 --- a/application/remote_desk/remote_desk_client/remote_desk_client.cpp +++ b/application/remote_desk/remote_desk_client/remote_desk_client.cpp @@ -1,6 +1,12 @@ #ifdef _WIN32 #include #include +#elif __APPLE__ +#include +#include +#include +#include +#include #endif #include @@ -67,6 +73,18 @@ inline void FreshVideo() { SDL_RenderClear(sdlRenderer); SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); SDL_RenderPresent(sdlRenderer); + + frame_count++; + end_time = SDL_GetTicks(); + elapsed_time = end_time - start_time; + if (elapsed_time >= 1000) { + fps = frame_count / (elapsed_time / 1000); + frame_count = 0; + window_title = "Remote Desk Client FPS [" + std::to_string(fps) + "]"; + // For MacOS, UI frameworks can only be called from the main thread + SDL_SetWindowTitle(screen, window_title.c_str()); + start_time = end_time; + } } inline int ProcessMouseKeyEven(SDL_Event &ev) { @@ -163,16 +181,6 @@ void ReceiveVideoBuffer(const char *data, size_t size, const char *user_id, SDL_Event event; event.type = REFRESH_EVENT; SDL_PushEvent(&event); - frame_count++; - end_time = SDL_GetTicks(); - elapsed_time = end_time - start_time; - if (elapsed_time >= 1000) { - fps = frame_count / (elapsed_time / 1000); - frame_count = 0; - window_title = "Remote Desk Client [FPS " + std::to_string(fps) + "]"; - SDL_SetWindowTitle(screen, window_title.data()); - start_time = end_time; - } } void ReceiveAudioBuffer(const char *data, size_t size, const char *user_id, @@ -187,24 +195,50 @@ void ReceiveDataBuffer(const char *data, size_t size, const char *user_id, << std::endl; } -std::string GetMac() { +std::string GetMac(char *mac_addr) { + int len = 0; +#ifdef _WIN32 IP_ADAPTER_INFO adapterInfo[16]; DWORD bufferSize = sizeof(adapterInfo); - char mac[10]; - int len = 0; DWORD result = GetAdaptersInfo(adapterInfo, &bufferSize); if (result == ERROR_SUCCESS) { PIP_ADAPTER_INFO adapter = adapterInfo; while (adapter) { for (UINT i = 0; i < adapter->AddressLength; i++) { - len += sprintf(mac + len, "%.2X", adapter->Address[i]); + len += sprintf(mac_addr + len, "%.2X", adapter->Address[i]); } break; } } +#else + std::string ifName = "en0"; - return mac; + struct ifaddrs *addrs; + struct ifaddrs *cursor; + const struct sockaddr_dl *dlAddr; + + if (!getifaddrs(&addrs)) { + cursor = addrs; + while (cursor != 0) { + const struct sockaddr_dl *socAddr = + (const struct sockaddr_dl *)cursor->ifa_addr; + if ((cursor->ifa_addr->sa_family == AF_LINK) && + (socAddr->sdl_type == IFT_ETHER) && + strcmp("en0", cursor->ifa_name) == 0) { + dlAddr = (const struct sockaddr_dl *)cursor->ifa_addr; + const unsigned char *base = + (const unsigned char *)&dlAddr->sdl_data[dlAddr->sdl_nlen]; + for (int i = 0; i < dlAddr->sdl_alen; i++) { + len += sprintf(mac_addr + len, "%.2X", base[i]); + } + } + cursor = cursor->ifa_next; + } + freeifaddrs(addrs); + } +#endif + return mac_addr; } int main() { @@ -218,7 +252,8 @@ int main() { params.on_receive_data_buffer = ReceiveDataBuffer; std::string transmission_id = "000001"; - std::string user_id = GetMac(); + char mac_addr[10]; + std::string user_id = "C-" + std::string(GetMac(mac_addr)); peer = CreatePeer(¶ms); JoinConnection(peer, transmission_id.c_str(), user_id.c_str()); diff --git a/application/remote_desk/remote_desk_server/remote_desk_server.cpp b/application/remote_desk/remote_desk_server/remote_desk_server.cpp index b95a68a..8dc8b9b 100644 --- a/application/remote_desk/remote_desk_server/remote_desk_server.cpp +++ b/application/remote_desk/remote_desk_server/remote_desk_server.cpp @@ -127,24 +127,50 @@ void RemoteDeskServer::ReceiveDataBuffer(const char *data, size_t size, } } -std::string GetMac() { +std::string GetMac(char *mac_addr) { + int len = 0; +#ifdef _WIN32 IP_ADAPTER_INFO adapterInfo[16]; DWORD bufferSize = sizeof(adapterInfo); - char mac[10]; - int len = 0; DWORD result = GetAdaptersInfo(adapterInfo, &bufferSize); if (result == ERROR_SUCCESS) { PIP_ADAPTER_INFO adapter = adapterInfo; while (adapter) { for (UINT i = 0; i < adapter->AddressLength; i++) { - len += sprintf(mac + len, "%.2X", adapter->Address[i]); + len += sprintf(mac_addr + len, "%.2X", adapter->Address[i]); } break; } } +#else + std::string ifName = "en0"; - return mac; + struct ifaddrs *addrs; + struct ifaddrs *cursor; + const struct sockaddr_dl *dlAddr; + + if (!getifaddrs(&addrs)) { + cursor = addrs; + while (cursor != 0) { + const struct sockaddr_dl *socAddr = + (const struct sockaddr_dl *)cursor->ifa_addr; + if ((cursor->ifa_addr->sa_family == AF_LINK) && + (socAddr->sdl_type == IFT_ETHER) && + strcmp("en0", cursor->ifa_name) == 0) { + dlAddr = (const struct sockaddr_dl *)cursor->ifa_addr; + const unsigned char *base = + (const unsigned char *)&dlAddr->sdl_data[dlAddr->sdl_nlen]; + for (int i = 0; i < dlAddr->sdl_alen; i++) { + len += sprintf(mac_addr + len, "%.2X", base[i]); + } + } + cursor = cursor->ifa_next; + } + freeifaddrs(addrs); + } +#endif + return mac_addr; } int RemoteDeskServer::Init() { @@ -158,7 +184,8 @@ int RemoteDeskServer::Init() { params.on_receive_data_buffer = ReceiveDataBuffer; std::string transmission_id = "000001"; - std::string user_id = "Server-" + GetMac(); + char mac_addr[10]; + std::string user_id = "S-" + std::string(GetMac(mac_addr)); peer = CreatePeer(¶ms); CreateConnection(peer, transmission_id.c_str(), user_id.c_str()); diff --git a/application/remote_desk/xmake.lua b/application/remote_desk/xmake.lua index 62ec3e7..3cfcb86 100644 --- a/application/remote_desk/xmake.lua +++ b/application/remote_desk/xmake.lua @@ -8,6 +8,8 @@ set_languages("c++17") add_requires("spdlog 1.11.0", {system = false}) add_defines("UNICODE") +add_requires("sdl2", {system = false}) + if is_os("windows") then add_ldflags("/SUBSYSTEM:CONSOLE") add_links("Shell32", "windowsapp", "dwmapi", "User32", "kernel32") @@ -17,6 +19,9 @@ elseif is_os("linux") then add_requires("ffmpeg 5.1.2", {system = false}) add_links("pthread") set_config("cxxflags", "-fPIC") +elseif is_os("macosx") then + add_requires("ffmpeg 5.1.2", {system = false}) + -- add_requires("vcpkg::sdl2 2.28.3", {system = false}) end add_packages("spdlog") @@ -53,13 +58,22 @@ target("remote_desk_client") set_kind("binary") add_deps("projectx") add_packages("log") - add_packages("vcpkg::sdl2") + if is_os("windows") then + add_packages("vcpkg::sdl2") + elseif is_os("macosx") then + -- add_packages("vcpkg::sdl2") + add_packages("sdl2") + add_packages("ffmpeg") + end add_files("remote_desk_client/*.cpp") add_includedirs("../../src/interface") if is_os("windows") then add_links("SDL2-static", "SDL2main", "gdi32", "winmm", "setupapi", "version", "Imm32", "iphlpapi") + elseif is_os("macosx") then + add_links("SDL2") end + -- target("remote_desk") -- set_kind("binary") diff --git a/config/config.ini b/config/config.ini index 1013893..fa3cbef 100644 --- a/config/config.ini +++ b/config/config.ini @@ -4,4 +4,10 @@ port = 9099 [stun server] ip = 120.77.216.215 -port = 3478 \ No newline at end of file +port = 3478 + +[turn server] +ip = 120.77.216.215 +port = 3478 +username = dijunkun +password = dijunkunpw \ No newline at end of file diff --git a/src/frame/frame.h b/src/frame/frame.h index 25cfded..41af760 100644 --- a/src/frame/frame.h +++ b/src/frame/frame.h @@ -2,6 +2,7 @@ #define _FRAME_H_ #include +#include class VideoFrame { public: diff --git a/src/ice/ice_agent.cpp b/src/ice/ice_agent.cpp index ac695ee..9402e10 100644 --- a/src/ice/ice_agent.cpp +++ b/src/ice/ice_agent.cpp @@ -6,7 +6,15 @@ #include "log.h" -IceAgent::IceAgent(std::string &ip, uint16_t port) : ip_(ip), port_(port) {} +IceAgent::IceAgent(std::string &stun_ip, uint16_t stun_port, + std::string &turn_ip, uint16_t turn_port, + std::string &turn_username, std::string &turn_password) + : stun_ip_(stun_ip), + stun_port_(stun_port), + turn_ip_(turn_ip), + turn_port_(turn_port), + turn_username_(turn_username), + turn_password_(turn_password) {} IceAgent::~IceAgent() {} @@ -20,8 +28,20 @@ int IceAgent::CreateIceAgent(juice_cb_state_changed_t on_state_changed, memset(&config, 0, sizeof(config)); // STUN server example - config.stun_server_host = ip_.c_str(); - config.stun_server_port = port_; + config.stun_server_host = stun_ip_.c_str(); + config.stun_server_port = stun_port_; + + if (!turn_ip_.empty() && -1 != turn_port_ && !turn_username_.empty() && + !turn_password_.empty()) { + juice_turn_server_t turn_server; + memset(&turn_server, 0, sizeof(turn_server)); + turn_server.host = turn_ip_.c_str(); + turn_server.port = turn_port_; + turn_server.username = turn_username_.c_str(); + turn_server.password = turn_password_.c_str(); + config.turn_servers = &turn_server; + config.turn_servers_count = 1; + } config.cb_state_changed = on_state_changed; config.cb_candidate = on_candidate; diff --git a/src/ice/ice_agent.h b/src/ice/ice_agent.h index 50989f8..48b7547 100644 --- a/src/ice/ice_agent.h +++ b/src/ice/ice_agent.h @@ -7,7 +7,9 @@ class IceAgent { public: - IceAgent(std::string& ip, uint16_t port); + IceAgent(std::string& stun_ip, uint16_t stun_port, std::string& turn_ip, + uint16_t turn_port, std::string& turn_username, + std::string& turn_password); ~IceAgent(); int CreateIceAgent(juice_cb_state_changed_t on_state_changed, @@ -36,8 +38,12 @@ class IceAgent { int Send(const char* data, size_t size); private: - std::string ip_ = ""; - uint16_t port_ = 0; + std::string stun_ip_ = ""; + uint16_t stun_port_ = 0; + std::string turn_ip_ = ""; + uint16_t turn_port_ = 0; + std::string turn_username_ = ""; + std::string turn_password_ = ""; juice_agent_t* agent_ = nullptr; char local_sdp_[JUICE_MAX_SDP_STRING_LEN]; juice_state_t state_; diff --git a/src/media/video/decode/ffmpeg/ffmpeg_decoder.h b/src/media/video/decode/ffmpeg/ffmpeg_decoder.h index 4760de5..28da5eb 100644 --- a/src/media/video/decode/ffmpeg/ffmpeg_decoder.h +++ b/src/media/video/decode/ffmpeg/ffmpeg_decoder.h @@ -2,12 +2,10 @@ #define _FFMPEG_DECODER_H_ #ifdef _WIN32 -// Windows extern "C" { #include "libavcodec/avcodec.h" }; #else -// Linux... #ifdef __cplusplus extern "C" { #endif diff --git a/src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp b/src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp new file mode 100644 index 0000000..4cfeb9b --- /dev/null +++ b/src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp @@ -0,0 +1,44 @@ +#include "ffmpeg_encoder.h" + +#include + +#include "log.h" + +#define SAVE_ENCODER_STREAM 0 + +VideoEncoder::VideoEncoder() { + if (SAVE_ENCODER_STREAM) { + file_ = fopen("encode_stream.h264", "w+b"); + if (!file_) { + LOG_WARN("Fail to open stream.h264"); + } + } +} +VideoEncoder::~VideoEncoder() { + if (SAVE_ENCODER_STREAM && file_) { + fflush(file_); + fclose(file_); + file_ = nullptr; + } + + if (nv12_data_) { + free(nv12_data_); + nv12_data_ = nullptr; + } +} + +int VideoEncoder::Init() { return 0; } + +int VideoEncoder::Encode( + const uint8_t *pData, int nSize, + std::function on_encoded_image) { + return -1; +} + +int VideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) { + LOG_INFO("output encoded image"); + fwrite(encoded_packets, 1, size, file_); + return 0; +} + +void VideoEncoder::ForceIdr() {} diff --git a/src/media/video/encode/ffmpeg/ffmpeg_encoder.h b/src/media/video/encode/ffmpeg/ffmpeg_encoder.h new file mode 100644 index 0000000..6c9efa2 --- /dev/null +++ b/src/media/video/encode/ffmpeg/ffmpeg_encoder.h @@ -0,0 +1,47 @@ +#ifndef _FFMPEG_ENCODER_H_ +#define _FFMPEG_ENCODER_H_ + +#ifdef _WIN32 +extern "C" { +#include "libavcodec/avcodec.h" +}; +#else +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +}; +#endif +#endif +#include + +class VideoEncoder { + public: + VideoEncoder(); + ~VideoEncoder(); + + int Init(); + int Encode( + const uint8_t* pData, int nSize, + std::function on_encoded_image); + + virtual int OnEncodedImage(char* encoded_packets, size_t size); + + void ForceIdr(); + + private: + int frame_width = 1280; + int frame_height = 720; + int keyFrameInterval_ = 3000; + int maxBitrate_ = 2000; + int max_payload_size_ = 3000; + + std::vector> encoded_packets_; + unsigned char* encoded_image_ = nullptr; + FILE* file_ = nullptr; + unsigned char* nv12_data_ = nullptr; + unsigned int seq_ = 0; +}; + +#endif \ No newline at end of file diff --git a/src/media/video/encode/nvcodec/nv_encoder.cpp b/src/media/video/encode/nvcodec/nv_encoder.cpp index 257310f..4d11db3 100644 --- a/src/media/video/encode/nvcodec/nv_encoder.cpp +++ b/src/media/video/encode/nvcodec/nv_encoder.cpp @@ -60,11 +60,11 @@ int VideoEncoder::Init() { // TO TEST: not tested yet // init_params.encodeConfig->gopLength = NVENC_INFINITE_GOPLENGTH; init_params.encodeConfig->gopLength = keyFrameInterval_; - // Donot use B-frame for realtime application + // Do not use B-frame for realtime application init_params.encodeConfig->frameIntervalP = 1; init_params.encodeConfig->rcParams.rateControlMode = NV_ENC_PARAMS_RC_MODE::NV_ENC_PARAMS_RC_CBR; - init_params.encodeConfig->rcParams.maxBitRate = maxBitrate_ * 1000; + init_params.encodeConfig->rcParams.maxBitRate = maxBitrate_ * 500; init_params.encodeConfig->encodeCodecConfig.h264Config.sliceMode = 1; init_params.encodeConfig->encodeCodecConfig.h264Config.sliceModeData = max_payload_size_; @@ -81,7 +81,7 @@ int VideoEncoder::Encode( return -1; } - if (0 == seq_++ % (30)) { + if (0 == seq_++ % (300)) { ForceIdr(); } diff --git a/src/media/video/encode/nvcodec/nv_encoder.h b/src/media/video/encode/nvcodec/nv_encoder.h index 499fbf4..b33a376 100644 --- a/src/media/video/encode/nvcodec/nv_encoder.h +++ b/src/media/video/encode/nvcodec/nv_encoder.h @@ -28,7 +28,7 @@ class VideoEncoder { int frame_width = 1280; int frame_height = 720; int keyFrameInterval_ = 3000; - int maxBitrate_ = 2000; + int maxBitrate_ = 1000; int max_payload_size_ = 3000; NvEncoder* encoder_ = nullptr; CUcontext cuda_context_ = nullptr; diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index 8a5ef7c..5d2b941 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -29,16 +29,29 @@ int PeerConnection::Init(PeerConnectionParams params, cfg_signal_server_port_ = reader.Get("signal server", "port", "-1"); cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1"); cfg_stun_server_port_ = reader.Get("stun server", "port", "-1"); + cfg_turn_server_ip_ = reader.Get("turn server", "ip", ""); + cfg_turn_server_port_ = reader.Get("turn server", "port", "-1"); + cfg_turn_server_username_ = reader.Get("turn server", "username", ""); + cfg_turn_server_password_ = reader.Get("turn server", "password", ""); std::regex regex("\n"); LOG_INFO("Read config success"); signal_server_port_ = stoi(cfg_signal_server_port_); stun_server_port_ = stoi(cfg_stun_server_port_); + turn_server_port_ = stoi(cfg_turn_server_port_); LOG_INFO("stun server ip [{}] port [{}]", cfg_stun_server_ip_, stun_server_port_); + if (!cfg_turn_server_ip_.empty() && 0 != turn_server_port_ && + !cfg_turn_server_username_.empty() && + !cfg_turn_server_password_.empty()) { + LOG_INFO("turn server ip [{}] port [{}] username [{}] password [{}]", + cfg_turn_server_ip_, turn_server_port_, cfg_turn_server_username_, + cfg_turn_server_password_); + } + on_receive_video_buffer_ = params.on_receive_video_buffer; on_receive_audio_buffer_ = params.on_receive_audio_buffer; on_receive_data_buffer_ = params.on_receive_data_buffer; @@ -74,10 +87,9 @@ int PeerConnection::Init(PeerConnectionParams params, on_ice_status_change_ = [this](std::string ice_status) { if ("JUICE_STATE_COMPLETED" == ice_status) { ice_ready_ = true; - LOG_INFO("Ice connected"); + LOG_INFO("Ice finish"); } else { ice_ready_ = false; - LOG_INFO("Ice not useable"); } }; @@ -135,6 +147,7 @@ void PeerConnection::ProcessSignal(const std::string &signal) { ws_connection_id_ = j["ws_connection_id"].get(); LOG_INFO("Receive local peer websocket connection id [{}]", ws_connection_id_); + std::lock_guard l(signal_status_mutex_); signal_status_ = SignalStatus::Connected; break; } @@ -179,7 +192,9 @@ void PeerConnection::ProcessSignal(const std::string &signal) { on_receive_data_); ice_transmission_list_[remote_user_id]->InitIceTransmission( - cfg_stun_server_ip_, stun_server_port_); + cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_, + turn_server_port_, cfg_turn_server_username_, + cfg_turn_server_password_); ice_transmission_list_[remote_user_id]->JoinTransmission(); } @@ -221,7 +236,9 @@ void PeerConnection::ProcessSignal(const std::string &signal) { on_receive_data_); ice_transmission_list_[remote_user_id]->InitIceTransmission( - cfg_stun_server_ip_, stun_server_port_); + cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_, + turn_server_port_, cfg_turn_server_username_, + cfg_turn_server_password_); ice_transmission_list_[remote_user_id]->SetTransmissionId( transmission_id_); @@ -271,7 +288,10 @@ int PeerConnection::RequestTransmissionMemberList( int PeerConnection::Destroy() { return 0; } -SignalStatus PeerConnection::GetSignalStatus() { return signal_status_; } +SignalStatus PeerConnection::GetSignalStatus() { + std::lock_guard l(signal_status_mutex_); + return signal_status_; +} int PeerConnection::SendVideoData(const char *data, size_t size) { if (!ice_ready_) { diff --git a/src/pc/peer_connection.h b/src/pc/peer_connection.h index fd6a4be..2657880 100644 --- a/src/pc/peer_connection.h +++ b/src/pc/peer_connection.h @@ -3,10 +3,17 @@ #include #include +#include -#include "ffmpeg_decoder.h" #include "ice_transmission.h" +#ifdef _WIN32 +#include "nv_decoder.h" #include "nv_encoder.h" +#else +#include "ffmpeg_decoder.h" +#include "ffmpeg_encoder.h" +#endif + #include "ws_transmission.h" enum SignalStatus { Connecting = 0, Connected, Closed }; @@ -59,8 +66,13 @@ class PeerConnection : public VideoEncoder, VideoDecoder { std::string cfg_signal_server_port_; std::string cfg_stun_server_ip_; std::string cfg_stun_server_port_; + std::string cfg_turn_server_ip_; + std::string cfg_turn_server_port_; + std::string cfg_turn_server_username_; + std::string cfg_turn_server_password_; int signal_server_port_ = 0; int stun_server_port_ = 0; + int turn_server_port_ = 0; private: std::shared_ptr ws_transport_ = nullptr; @@ -70,6 +82,7 @@ class PeerConnection : public VideoEncoder, VideoDecoder { std::string transmission_id_ = ""; std::vector user_id_list_; SignalStatus signal_status_ = SignalStatus::Closed; + std::mutex signal_status_mutex_; private: std::map> diff --git a/src/transmission/ice_transmission.cpp b/src/transmission/ice_transmission.cpp index 97efb53..51a5fce 100644 --- a/src/transmission/ice_transmission.cpp +++ b/src/transmission/ice_transmission.cpp @@ -47,7 +47,10 @@ IceTransmission::~IceTransmission() { } } -int IceTransmission::InitIceTransmission(std::string &ip, int port) { +int IceTransmission::InitIceTransmission(std::string &stun_ip, int stun_port, + std::string &turn_ip, int turn_port, + std::string &turn_username, + std::string &turn_password) { video_rtp_codec_ = std::make_unique(RtpPacket::PAYLOAD_TYPE::H264); data_rtp_codec_ = std::make_unique(RtpPacket::PAYLOAD_TYPE::DATA); @@ -113,7 +116,8 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) { remote_user_id_.size()); }); - ice_agent_ = std::make_unique(ip, port); + ice_agent_ = std::make_unique( + stun_ip, stun_port, turn_ip, turn_port, turn_username, turn_password); ice_agent_->CreateIceAgent( [](juice_agent_t *agent, juice_state_t state, void *user_ptr) { diff --git a/src/transmission/ice_transmission.h b/src/transmission/ice_transmission.h index 80e4feb..f58c454 100644 --- a/src/transmission/ice_transmission.h +++ b/src/transmission/ice_transmission.h @@ -26,7 +26,10 @@ class IceTransmission { ~IceTransmission(); public: - int InitIceTransmission(std::string &ip, int port); + int InitIceTransmission(std::string &stun_ip, int stun_port, + std::string &turn_ip, int turn_port, + std::string &turn_username, + std::string &turn_password); int DestroyIceTransmission(); diff --git a/thirdparty/sdl2/xmake.lua b/thirdparty/sdl2/xmake.lua new file mode 100644 index 0000000..189bb09 --- /dev/null +++ b/thirdparty/sdl2/xmake.lua @@ -0,0 +1,10 @@ +package("sdl2") + add_urls("https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.28.3.tar.gz", {alias = "github"}) + add_versions("github:2.28.3", "c17455d6e0c484bfe634b8de6af4c608e86ee449c28e40af04064aa6643fe382") + + add_deps("cmake") + on_install(function (package) + local configs = {} + import("package.tools.cmake").install(package, configs) + end) +package_end() \ No newline at end of file diff --git a/thirdparty/xmake.lua b/thirdparty/xmake.lua index 7b1cc7d..8e82aaf 100644 --- a/thirdparty/xmake.lua +++ b/thirdparty/xmake.lua @@ -1 +1 @@ -includes("libjuice") \ No newline at end of file +includes("libjuice", "sdl2") \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 2c22413..fa3aed2 100644 --- a/xmake.lua +++ b/xmake.lua @@ -1,5 +1,6 @@ set_project("projectx") set_version("0.0.1") +set_license("GPL-3.0") add_rules("mode.release", "mode.debug") set_languages("c++17") @@ -15,6 +16,9 @@ if is_os("windows") then elseif is_os("linux") then add_requires("ffmpeg 5.1.2", {system = false}) add_packages("ffmpeg") +elseif is_os("macosx") then + add_requires("ffmpeg 5.1.2", {system = false}) + add_packages("ffmpeg") end add_defines("JUICE_STATIC") @@ -98,15 +102,20 @@ target("ws") target("media") set_kind("static") add_deps("log", "frame") - add_packages("cuda") - add_files("src/media/video/encode/nvcodec/*.cpp", - "src/media/video/decode/nvcodec/*.cpp", "src/media/video/decode/ffmpeg/*.cpp") - add_includedirs("src/media/video/encode/nvcodec", - "src/media/video/decode/nvcodec", "src/media/video/decode/ffmpeg", - "thirdparty/nvcodec/Interface", - "thirdparty/nvcodec/Samples", {public = true}) - add_linkdirs("thirdparty/nvcodec/Lib/x64") - add_links("cuda", "nvencodeapi", "nvcuvid") + if is_os("windows") or is_os(("linux")) then + add_packages("cuda") + add_files("src/media/video/encode/nvcodec/*.cpp", + "src/media/video/decode/nvcodec/*.cpp") + add_includedirs("src/media/video/encode/nvcodec", + "src/media/video/decode/nvcodec", "src/media/video/decode/ffmpeg", + "thirdparty/nvcodec/Interface", + "thirdparty/nvcodec/Samples", {public = true}) + add_linkdirs("thirdparty/nvcodec/Lib/x64") + add_links("cuda", "nvencodeapi", "nvcuvid") + elseif is_os("macosx") then + add_files("src/media/video/encode/ffmpeg/*.cpp", "src/media/video/decode/ffmpeg/*.cpp") + add_includedirs("src/media/video/encode/ffmpeg", "src/media/video/decode/ffmpeg", {public = true}) + end target("qos") set_kind("static")