From 700fb2ec149a08c58ac87cbe44f8df4dd487bb8b Mon Sep 17 00:00:00 2001 From: dijunkun Date: Mon, 14 Apr 2025 16:12:55 +0800 Subject: [PATCH] [feat] send server resolution before sending first frame --- src/device_controller/device_controller.h | 2 + .../linux/screen_capturer_x11.h | 11 +- .../screen_capturer_kit/screen_capturer_sck.h | 11 +- src/screen_capturer/screen_capturer.h | 2 - .../windows/screen_capturer_wgc.h | 9 +- src/single_window/render.cpp | 31 ++++-- src/single_window/render.h | 6 ++ src/single_window/render_callback_func.cpp | 100 +++++++++--------- thirdparty/projectx | 2 +- 9 files changed, 96 insertions(+), 78 deletions(-) diff --git a/src/device_controller/device_controller.h b/src/device_controller/device_controller.h index f063108..5e87fda 100644 --- a/src/device_controller/device_controller.h +++ b/src/device_controller/device_controller.h @@ -31,6 +31,8 @@ typedef struct { typedef struct { char host_name[64]; size_t host_name_size; + size_t origin_display_width; + size_t origin_display_height; } HostInfo; typedef struct { diff --git a/src/screen_capturer/linux/screen_capturer_x11.h b/src/screen_capturer/linux/screen_capturer_x11.h index 401d702..9d68d9b 100644 --- a/src/screen_capturer/linux/screen_capturer_x11.h +++ b/src/screen_capturer/linux/screen_capturer_x11.h @@ -26,13 +26,10 @@ class ScreenCapturerX11 : public ScreenCapturer { public: virtual int Init(const RECORD_DESKTOP_RECT &rect, const int fps, - cb_desktop_data cb); - - virtual int Destroy(); - - virtual int Start(); - - virtual int Stop(); + cb_desktop_data cb) override; + virtual int Destroy() override; + virtual int Start() override; + virtual int Stop() override; int Pause(); int Resume(); diff --git a/src/screen_capturer/macosx/screen_capturer_kit/screen_capturer_sck.h b/src/screen_capturer/macosx/screen_capturer_kit/screen_capturer_sck.h index 392a892..a662bef 100644 --- a/src/screen_capturer/macosx/screen_capturer_kit/screen_capturer_sck.h +++ b/src/screen_capturer/macosx/screen_capturer_kit/screen_capturer_sck.h @@ -22,13 +22,10 @@ class ScreenCapturerSck : public ScreenCapturer { ~ScreenCapturerSck(); public: - virtual int Init(const int fps, cb_desktop_data cb); - - virtual int Destroy(); - - virtual int Start(); - - virtual int Stop(); + virtual int Init(const int fps, cb_desktop_data cb) override; + virtual int Destroy() override; + virtual int Start() override; + virtual int Stop() override; int Pause(); diff --git a/src/screen_capturer/screen_capturer.h b/src/screen_capturer/screen_capturer.h index a07158e..ece553b 100644 --- a/src/screen_capturer/screen_capturer.h +++ b/src/screen_capturer/screen_capturer.h @@ -19,9 +19,7 @@ class ScreenCapturer { public: virtual int Init(const int fps, cb_desktop_data cb) = 0; virtual int Destroy() = 0; - virtual int Start() = 0; - virtual int Stop() = 0; }; diff --git a/src/screen_capturer/windows/screen_capturer_wgc.h b/src/screen_capturer/windows/screen_capturer_wgc.h index 2d394d6..464c1f6 100644 --- a/src/screen_capturer/windows/screen_capturer_wgc.h +++ b/src/screen_capturer/windows/screen_capturer_wgc.h @@ -19,14 +19,13 @@ class ScreenCapturerWgc : public ScreenCapturer, public: bool IsWgcSupported(); - virtual int Init(const int fps, cb_desktop_data cb); - virtual int Destroy(); - - virtual int Start(); + virtual int Init(const int fps, cb_desktop_data cb) override; + virtual int Destroy() override; + virtual int Start() override; + virtual int Stop() override; int Pause(); int Resume(); - virtual int Stop(); void OnFrame(const WgcSession::wgc_session_frame &frame); diff --git a/src/single_window/render.cpp b/src/single_window/render.cpp index e34766a..f5fd6d2 100644 --- a/src/single_window/render.cpp +++ b/src/single_window/render.cpp @@ -194,6 +194,24 @@ int Render::StartScreenCapturer() { int screen_capturer_init_ret = screen_capturer_->Init( 60, [this](unsigned char* data, int size, int width, int height) -> void { + if (!hostname_sent_ && width > 0 && height > 0) { + original_display_width_ = width; + original_display_height_ = height; + std::string host_name = GetHostName(); + RemoteAction remote_action; + remote_action.type = ControlType::host_infomation; + memcpy(&remote_action.i.host_name, host_name.data(), + host_name.size()); + remote_action.i.host_name_size = host_name.size(); + remote_action.i.origin_display_height = original_display_height_; + remote_action.i.origin_display_width = original_display_width_; + int ret = SendDataFrame(peer_, (const char*)&remote_action, + sizeof(remote_action)); + if (0 == ret) { + hostname_sent_ = true; + } + } + auto now_time = std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()) .count(); @@ -1046,10 +1064,11 @@ void Render::ProcessSdlEvent() { stream_window_width_ = (float)stream_window_width; stream_window_height_ = (float)stream_window_height; - float video_ratio = - (float)props->video_width_ / (float)props->video_height_; + float video_ratio = (float)props->original_display_width_ / + (float)props->original_display_height_; float video_ratio_reverse = - (float)props->video_height_ / (float)props->video_width_; + (float)props->original_display_height_ / + (float)props->original_display_width_; float render_area_width = stream_window_width_; float render_area_height = @@ -1139,11 +1158,7 @@ void Render::ProcessSdlEvent() { case SDL_MOUSEBUTTONUP: case SDL_MOUSEWHEEL: if (foucs_on_stream_window_) { - for (auto& [_, props] : client_properties_) { - if (props->control_mouse_) { - ProcessMouseEvent(event); - } - } + ProcessMouseEvent(event); } break; diff --git a/src/single_window/render.h b/src/single_window/render.h index 20fb1bd..6c8cb4d 100644 --- a/src/single_window/render.h +++ b/src/single_window/render.h @@ -83,6 +83,8 @@ class Render { std::string mouse_control_button_label_ = "Mouse Control"; std::string audio_capture_button_label_ = "Audio Capture"; std::string remote_host_name_ = ""; + int original_display_width_ = 0; + int original_display_height_ = 0; SDL_Texture *stream_texture_ = nullptr; SDL_Rect stream_render_rect_; SDL_Rect stream_render_rect_last_; @@ -303,6 +305,10 @@ class Render { bool audio_buffer_fresh_ = false; bool need_to_rejoin_ = false; bool just_created_ = false; + std::string controlled_remote_id_ = ""; + int original_display_width_ = 0; + int original_display_height_ = 0; + bool hostname_sent_ = false; // stream window render SDL_Window *stream_window_ = nullptr; diff --git a/src/single_window/render_callback_func.cpp b/src/single_window/render_callback_func.cpp index d6fb356..72bac8c 100644 --- a/src/single_window/render_callback_func.cpp +++ b/src/single_window/render_callback_func.cpp @@ -23,31 +23,46 @@ int Render::SendKeyCommand(int key_code, bool is_down) { } remote_action.k.key_value = key_code; - SendDataFrame(peer_, (const char *)&remote_action, sizeof(remote_action)); + if (!controlled_remote_id_.empty()) { + if (client_properties_.find(controlled_remote_id_) != + client_properties_.end()) { + auto props = client_properties_[controlled_remote_id_]; + if (props->connection_status_ == ConnectionStatus::Connected) { + SendDataFrame(props->peer_, (const char *)&remote_action, + sizeof(remote_action)); + } + } + } return 0; } int Render::ProcessMouseEvent(SDL_Event &event) { - std::string remote_id = ""; + controlled_remote_id_ = ""; int video_width, video_height = 0; int render_width, render_height = 0; for (auto &it : client_properties_) { auto props = it.second; + if (!props->control_mouse_) { + continue; + } + if (event.button.x >= props->stream_render_rect_.x && event.button.x <= props->stream_render_rect_.x + props->stream_render_rect_.w && event.button.y >= props->stream_render_rect_.y && event.button.y <= props->stream_render_rect_.y + props->stream_render_rect_.h) { - remote_id = it.first; + controlled_remote_id_ = it.first; video_width = props->video_width_; video_height = props->video_height_; render_width = props->stream_render_rect_.w; render_height = props->stream_render_rect_.h; - float ratio_x = (float)video_width / (float)render_width; - float ratio_y = (float)video_height / (float)render_height; + float ratio_x = + (float)props->original_display_width_ / (float)render_width; + float ratio_y = + (float)props->original_display_height_ / (float)render_height; RemoteAction remote_action; remote_action.m.x = (size_t)(event.button.x * ratio_x); @@ -60,8 +75,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) { } else if (SDL_BUTTON_RIGHT == event.button.button) { remote_action.m.flag = MouseFlag::right_down; } - remote_action.m.flag = MouseFlag::move; - SendDataFrame(peer_, (const char *)&remote_action, + SendDataFrame(props->peer_, (const char *)&remote_action, sizeof(remote_action)); } else if (SDL_MOUSEBUTTONUP == event.type) { remote_action.type = ControlType::mouse; @@ -70,13 +84,12 @@ int Render::ProcessMouseEvent(SDL_Event &event) { } else if (SDL_BUTTON_RIGHT == event.button.button) { remote_action.m.flag = MouseFlag::right_up; } - remote_action.m.flag = MouseFlag::move; - SendDataFrame(peer_, (const char *)&remote_action, + SendDataFrame(props->peer_, (const char *)&remote_action, sizeof(remote_action)); } else if (SDL_MOUSEMOTION == event.type) { remote_action.type = ControlType::mouse; remote_action.m.flag = MouseFlag::move; - SendDataFrame(peer_, (const char *)&remote_action, + SendDataFrame(props->peer_, (const char *)&remote_action, sizeof(remote_action)); } } @@ -197,35 +210,39 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, return; } - std::string remote_id(user_id, user_id_size); - if (render->client_properties_.find(remote_id) == - render->client_properties_.end()) { - return; - } - auto props = render->client_properties_.find(remote_id)->second; - RemoteAction remote_action; memcpy(&remote_action, data, size); - if (ControlType::mouse == remote_action.type && render->mouse_controller_) { - render->mouse_controller_->SendMouseCommand(remote_action); - } else if (ControlType::audio_capture == remote_action.type) { - if (remote_action.a) { - render->StartSpeakerCapturer(); - render->audio_capture_ = true; - } else { - render->StopSpeakerCapturer(); - render->audio_capture_ = false; + std::string remote_id(user_id, user_id_size); + if (render->client_properties_.find(remote_id) != + render->client_properties_.end()) { + auto props = render->client_properties_.find(remote_id)->second; + if (ControlType::host_infomation == remote_action.type) { + props->remote_host_name_ = std::string(remote_action.i.host_name, + remote_action.i.host_name_size); + props->original_display_width_ = remote_action.i.origin_display_width; + props->original_display_height_ = remote_action.i.origin_display_height; + LOG_INFO("Remote hostname: [{}], resolution: [{}x{}]", + props->remote_host_name_, remote_action.i.origin_display_width, + remote_action.i.origin_display_height); + } + } else { + if (ControlType::mouse == remote_action.type && render->mouse_controller_) { + render->mouse_controller_->SendMouseCommand(remote_action); + } else if (ControlType::audio_capture == remote_action.type) { + if (remote_action.a) { + render->StartSpeakerCapturer(); + render->audio_capture_ = true; + } else { + render->StopSpeakerCapturer(); + render->audio_capture_ = false; + } + } else if (ControlType::keyboard == remote_action.type && + render->keyboard_capturer_) { + render->keyboard_capturer_->SendKeyboardCommand( + (int)remote_action.k.key_value, + remote_action.k.flag == KeyFlag::key_down); } - } else if (ControlType::keyboard == remote_action.type && - render->keyboard_capturer_) { - render->keyboard_capturer_->SendKeyboardCommand( - (int)remote_action.k.key_value, - remote_action.k.flag == KeyFlag::key_down); - } else if (ControlType::host_infomation == remote_action.type) { - props->remote_host_name_ = - std::string(remote_action.i.host_name, remote_action.i.host_name_size); - LOG_INFO("Remote hostname: [{}]", props->remote_host_name_); } } @@ -317,19 +334,6 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, } props->connection_established_ = true; - if (!props->hostname_sent_) { - // TODO: self and remote hostname - std::string host_name = GetHostName(); - RemoteAction remote_action; - remote_action.type = ControlType::host_infomation; - memcpy(&remote_action.i.host_name, host_name.data(), host_name.size()); - remote_action.i.host_name_size = host_name.size(); - int ret = SendDataFrame(render->peer_, (const char *)&remote_action, - sizeof(remote_action)); - if (0 == ret) { - props->hostname_sent_ = true; - } - } if (!is_server) { props->stream_render_rect_.x = 0; diff --git a/thirdparty/projectx b/thirdparty/projectx index bc3dd68..df6f432 160000 --- a/thirdparty/projectx +++ b/thirdparty/projectx @@ -1 +1 @@ -Subproject commit bc3dd680f9ab9a7370348c6fcde0c83bd3e73eb2 +Subproject commit df6f4321e8a936114877c1a33398c8dce1abe42a