mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	[feat] send server resolution before sending first frame
This commit is contained in:
		| @@ -31,6 +31,8 @@ typedef struct { | |||||||
| typedef struct { | typedef struct { | ||||||
|   char host_name[64]; |   char host_name[64]; | ||||||
|   size_t host_name_size; |   size_t host_name_size; | ||||||
|  |   size_t origin_display_width; | ||||||
|  |   size_t origin_display_height; | ||||||
| } HostInfo; | } HostInfo; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|   | |||||||
| @@ -26,13 +26,10 @@ class ScreenCapturerX11 : public ScreenCapturer { | |||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   virtual int Init(const RECORD_DESKTOP_RECT &rect, const int fps, |   virtual int Init(const RECORD_DESKTOP_RECT &rect, const int fps, | ||||||
|                    cb_desktop_data cb); |                    cb_desktop_data cb) override; | ||||||
|  |   virtual int Destroy() override; | ||||||
|   virtual int Destroy(); |   virtual int Start() override; | ||||||
|  |   virtual int Stop() override; | ||||||
|   virtual int Start(); |  | ||||||
|  |  | ||||||
|   virtual int Stop(); |  | ||||||
|  |  | ||||||
|   int Pause(); |   int Pause(); | ||||||
|   int Resume(); |   int Resume(); | ||||||
|   | |||||||
| @@ -22,13 +22,10 @@ class ScreenCapturerSck : public ScreenCapturer { | |||||||
|   ~ScreenCapturerSck(); |   ~ScreenCapturerSck(); | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   virtual int Init(const int fps, cb_desktop_data cb); |   virtual int Init(const int fps, cb_desktop_data cb) override; | ||||||
|  |   virtual int Destroy() override; | ||||||
|   virtual int Destroy(); |   virtual int Start() override; | ||||||
|  |   virtual int Stop() override; | ||||||
|   virtual int Start(); |  | ||||||
|  |  | ||||||
|   virtual int Stop(); |  | ||||||
|  |  | ||||||
|   int Pause(); |   int Pause(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,9 +19,7 @@ class ScreenCapturer { | |||||||
|  public: |  public: | ||||||
|   virtual int Init(const int fps, cb_desktop_data cb) = 0; |   virtual int Init(const int fps, cb_desktop_data cb) = 0; | ||||||
|   virtual int Destroy() = 0; |   virtual int Destroy() = 0; | ||||||
|  |  | ||||||
|   virtual int Start() = 0; |   virtual int Start() = 0; | ||||||
|  |  | ||||||
|   virtual int Stop() = 0; |   virtual int Stop() = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,14 +19,13 @@ class ScreenCapturerWgc : public ScreenCapturer, | |||||||
|  public: |  public: | ||||||
|   bool IsWgcSupported(); |   bool IsWgcSupported(); | ||||||
|  |  | ||||||
|   virtual int Init(const int fps, cb_desktop_data cb); |   virtual int Init(const int fps, cb_desktop_data cb) override; | ||||||
|   virtual int Destroy(); |   virtual int Destroy() override; | ||||||
|  |   virtual int Start() override; | ||||||
|   virtual int Start(); |   virtual int Stop() override; | ||||||
|  |  | ||||||
|   int Pause(); |   int Pause(); | ||||||
|   int Resume(); |   int Resume(); | ||||||
|   virtual int Stop(); |  | ||||||
|  |  | ||||||
|   void OnFrame(const WgcSession::wgc_session_frame &frame); |   void OnFrame(const WgcSession::wgc_session_frame &frame); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -194,6 +194,24 @@ int Render::StartScreenCapturer() { | |||||||
|  |  | ||||||
|   int screen_capturer_init_ret = screen_capturer_->Init( |   int screen_capturer_init_ret = screen_capturer_->Init( | ||||||
|       60, [this](unsigned char* data, int size, int width, int height) -> void { |       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::milliseconds>( |         auto now_time = std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
|                             std::chrono::steady_clock::now().time_since_epoch()) |                             std::chrono::steady_clock::now().time_since_epoch()) | ||||||
|                             .count(); |                             .count(); | ||||||
| @@ -1046,10 +1064,11 @@ void Render::ProcessSdlEvent() { | |||||||
|               stream_window_width_ = (float)stream_window_width; |               stream_window_width_ = (float)stream_window_width; | ||||||
|               stream_window_height_ = (float)stream_window_height; |               stream_window_height_ = (float)stream_window_height; | ||||||
|  |  | ||||||
|               float video_ratio = |               float video_ratio = (float)props->original_display_width_ / | ||||||
|                   (float)props->video_width_ / (float)props->video_height_; |                                   (float)props->original_display_height_; | ||||||
|               float video_ratio_reverse = |               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_width = stream_window_width_; | ||||||
|               float render_area_height = |               float render_area_height = | ||||||
| @@ -1139,11 +1158,7 @@ void Render::ProcessSdlEvent() { | |||||||
|       case SDL_MOUSEBUTTONUP: |       case SDL_MOUSEBUTTONUP: | ||||||
|       case SDL_MOUSEWHEEL: |       case SDL_MOUSEWHEEL: | ||||||
|         if (foucs_on_stream_window_) { |         if (foucs_on_stream_window_) { | ||||||
|           for (auto& [_, props] : client_properties_) { |           ProcessMouseEvent(event); | ||||||
|             if (props->control_mouse_) { |  | ||||||
|               ProcessMouseEvent(event); |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -83,6 +83,8 @@ class Render { | |||||||
|     std::string mouse_control_button_label_ = "Mouse Control"; |     std::string mouse_control_button_label_ = "Mouse Control"; | ||||||
|     std::string audio_capture_button_label_ = "Audio Capture"; |     std::string audio_capture_button_label_ = "Audio Capture"; | ||||||
|     std::string remote_host_name_ = ""; |     std::string remote_host_name_ = ""; | ||||||
|  |     int original_display_width_ = 0; | ||||||
|  |     int original_display_height_ = 0; | ||||||
|     SDL_Texture *stream_texture_ = nullptr; |     SDL_Texture *stream_texture_ = nullptr; | ||||||
|     SDL_Rect stream_render_rect_; |     SDL_Rect stream_render_rect_; | ||||||
|     SDL_Rect stream_render_rect_last_; |     SDL_Rect stream_render_rect_last_; | ||||||
| @@ -303,6 +305,10 @@ class Render { | |||||||
|   bool audio_buffer_fresh_ = false; |   bool audio_buffer_fresh_ = false; | ||||||
|   bool need_to_rejoin_ = false; |   bool need_to_rejoin_ = false; | ||||||
|   bool just_created_ = 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 |   // stream window render | ||||||
|   SDL_Window *stream_window_ = nullptr; |   SDL_Window *stream_window_ = nullptr; | ||||||
|   | |||||||
| @@ -23,31 +23,46 @@ int Render::SendKeyCommand(int key_code, bool is_down) { | |||||||
|   } |   } | ||||||
|   remote_action.k.key_value = key_code; |   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; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int Render::ProcessMouseEvent(SDL_Event &event) { | int Render::ProcessMouseEvent(SDL_Event &event) { | ||||||
|   std::string remote_id = ""; |   controlled_remote_id_ = ""; | ||||||
|   int video_width, video_height = 0; |   int video_width, video_height = 0; | ||||||
|   int render_width, render_height = 0; |   int render_width, render_height = 0; | ||||||
|   for (auto &it : client_properties_) { |   for (auto &it : client_properties_) { | ||||||
|     auto props = it.second; |     auto props = it.second; | ||||||
|  |     if (!props->control_mouse_) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (event.button.x >= props->stream_render_rect_.x && |     if (event.button.x >= props->stream_render_rect_.x && | ||||||
|         event.button.x <= |         event.button.x <= | ||||||
|             props->stream_render_rect_.x + props->stream_render_rect_.w && |             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 && | ||||||
|         event.button.y <= |         event.button.y <= | ||||||
|             props->stream_render_rect_.y + props->stream_render_rect_.h) { |             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_width = props->video_width_; | ||||||
|       video_height = props->video_height_; |       video_height = props->video_height_; | ||||||
|       render_width = props->stream_render_rect_.w; |       render_width = props->stream_render_rect_.w; | ||||||
|       render_height = props->stream_render_rect_.h; |       render_height = props->stream_render_rect_.h; | ||||||
|  |  | ||||||
|       float ratio_x = (float)video_width / (float)render_width; |       float ratio_x = | ||||||
|       float ratio_y = (float)video_height / (float)render_height; |           (float)props->original_display_width_ / (float)render_width; | ||||||
|  |       float ratio_y = | ||||||
|  |           (float)props->original_display_height_ / (float)render_height; | ||||||
|  |  | ||||||
|       RemoteAction remote_action; |       RemoteAction remote_action; | ||||||
|       remote_action.m.x = (size_t)(event.button.x * ratio_x); |       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) { |         } else if (SDL_BUTTON_RIGHT == event.button.button) { | ||||||
|           remote_action.m.flag = MouseFlag::right_down; |           remote_action.m.flag = MouseFlag::right_down; | ||||||
|         } |         } | ||||||
|         remote_action.m.flag = MouseFlag::move; |         SendDataFrame(props->peer_, (const char *)&remote_action, | ||||||
|         SendDataFrame(peer_, (const char *)&remote_action, |  | ||||||
|                       sizeof(remote_action)); |                       sizeof(remote_action)); | ||||||
|       } else if (SDL_MOUSEBUTTONUP == event.type) { |       } else if (SDL_MOUSEBUTTONUP == event.type) { | ||||||
|         remote_action.type = ControlType::mouse; |         remote_action.type = ControlType::mouse; | ||||||
| @@ -70,13 +84,12 @@ int Render::ProcessMouseEvent(SDL_Event &event) { | |||||||
|         } else if (SDL_BUTTON_RIGHT == event.button.button) { |         } else if (SDL_BUTTON_RIGHT == event.button.button) { | ||||||
|           remote_action.m.flag = MouseFlag::right_up; |           remote_action.m.flag = MouseFlag::right_up; | ||||||
|         } |         } | ||||||
|         remote_action.m.flag = MouseFlag::move; |         SendDataFrame(props->peer_, (const char *)&remote_action, | ||||||
|         SendDataFrame(peer_, (const char *)&remote_action, |  | ||||||
|                       sizeof(remote_action)); |                       sizeof(remote_action)); | ||||||
|       } else if (SDL_MOUSEMOTION == event.type) { |       } else if (SDL_MOUSEMOTION == event.type) { | ||||||
|         remote_action.type = ControlType::mouse; |         remote_action.type = ControlType::mouse; | ||||||
|         remote_action.m.flag = MouseFlag::move; |         remote_action.m.flag = MouseFlag::move; | ||||||
|         SendDataFrame(peer_, (const char *)&remote_action, |         SendDataFrame(props->peer_, (const char *)&remote_action, | ||||||
|                       sizeof(remote_action)); |                       sizeof(remote_action)); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -197,35 +210,39 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, | |||||||
|     return; |     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; |   RemoteAction remote_action; | ||||||
|   memcpy(&remote_action, data, size); |   memcpy(&remote_action, data, size); | ||||||
|  |  | ||||||
|   if (ControlType::mouse == remote_action.type && render->mouse_controller_) { |   std::string remote_id(user_id, user_id_size); | ||||||
|     render->mouse_controller_->SendMouseCommand(remote_action); |   if (render->client_properties_.find(remote_id) != | ||||||
|   } else if (ControlType::audio_capture == remote_action.type) { |       render->client_properties_.end()) { | ||||||
|     if (remote_action.a) { |     auto props = render->client_properties_.find(remote_id)->second; | ||||||
|       render->StartSpeakerCapturer(); |     if (ControlType::host_infomation == remote_action.type) { | ||||||
|       render->audio_capture_ = true; |       props->remote_host_name_ = std::string(remote_action.i.host_name, | ||||||
|     } else { |                                              remote_action.i.host_name_size); | ||||||
|       render->StopSpeakerCapturer(); |       props->original_display_width_ = remote_action.i.origin_display_width; | ||||||
|       render->audio_capture_ = false; |       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; |     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) { |     if (!is_server) { | ||||||
|       props->stream_render_rect_.x = 0; |       props->stream_render_rect_.x = 0; | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								thirdparty/projectx
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								thirdparty/projectx
									
									
									
									
										vendored
									
									
								
							 Submodule thirdparty/projectx updated: bc3dd680f9...df6f4321e8
									
								
							
		Reference in New Issue
	
	Block a user