From 1a0c5e8b4210c8d73752f8716860b7ecad3ebbec Mon Sep 17 00:00:00 2001 From: dijunkun Date: Tue, 3 Dec 2024 17:22:15 +0800 Subject: [PATCH] [feat] use client_properties_ and server_properties_ to store streams properties --- .../connection_status_window.cpp | 19 +- src/single_window/control_bar.cpp | 136 ++++---- src/single_window/control_window.cpp | 309 +++++++++--------- src/single_window/main_window.cpp | 2 +- src/single_window/recent_connections.cpp | 9 +- src/single_window/remote_peer_window.cpp | 60 ++-- src/single_window/render.cpp | 233 +++++++------ src/single_window/render.h | 48 ++- src/single_window/render_callback_func.cpp | 157 +++++---- src/single_window/setting_window.cpp | 6 +- src/single_window/stream_window.cpp | 2 +- src/single_window/thumbnail.cpp | 2 - thirdparty/projectx | 2 +- 13 files changed, 546 insertions(+), 439 deletions(-) diff --git a/src/single_window/connection_status_window.cpp b/src/single_window/connection_status_window.cpp index c29c8a2..5cf9587 100644 --- a/src/single_window/connection_status_window.cpp +++ b/src/single_window/connection_status_window.cpp @@ -3,7 +3,8 @@ #include "rd_log.h" #include "render.h" -int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { +int Render::ConnectionStatusWindow( + std::shared_ptr &properties) { if (show_connection_status_window_) { const ImGuiViewport *viewport = ImGui::GetMainViewport(); @@ -33,11 +34,11 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { ImGui::SetWindowFontScale(0.5f); std::string text; - if (ConnectionStatus::Connecting == properties.connection_status_) { + if (ConnectionStatus::Connecting == properties->connection_status_) { text = localization::p2p_connecting[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); - } else if (ConnectionStatus::Connected == properties.connection_status_) { + } else if (ConnectionStatus::Connected == properties->connection_status_) { text = localization::p2p_connected[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); @@ -49,7 +50,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { show_connection_status_window_ = false; } } else if (ConnectionStatus::Disconnected == - properties.connection_status_) { + properties->connection_status_) { text = localization::p2p_disconnected[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); @@ -60,7 +61,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { ImGui::IsKeyPressed(ImGuiKey_Escape)) { show_connection_status_window_ = false; } - } else if (ConnectionStatus::Failed == properties.connection_status_) { + } else if (ConnectionStatus::Failed == properties->connection_status_) { text = localization::p2p_failed[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); @@ -71,7 +72,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { ImGui::IsKeyPressed(ImGuiKey_Escape)) { show_connection_status_window_ = false; } - } else if (ConnectionStatus::Closed == properties.connection_status_) { + } else if (ConnectionStatus::Closed == properties->connection_status_) { text = localization::p2p_closed[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); @@ -83,7 +84,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { show_connection_status_window_ = false; } } else if (ConnectionStatus::IncorrectPassword == - properties.connection_status_) { + properties->connection_status_) { if (!password_validating_) { if (password_validating_time_ == 1) { text = localization::input_password[localization_language_index_]; @@ -117,7 +118,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { ImGui::Checkbox( localization::remember_password[localization_language_index_] .c_str(), - &remember_password_); + &(properties->remember_password_)); ImGui::SetWindowFontScale(0.5f); ImGui::PopStyleVar(); @@ -148,7 +149,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); } } else if (ConnectionStatus::NoSuchTransmissionId == - properties.connection_status_) { + properties->connection_status_) { text = localization::no_such_id[localization_language_index_]; ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); diff --git a/src/single_window/control_bar.cpp b/src/single_window/control_bar.cpp index 8b192e9..31d9376 100644 --- a/src/single_window/control_bar.cpp +++ b/src/single_window/control_bar.cpp @@ -29,46 +29,45 @@ int LossRateDisplay(float loss_rate) { return 0; } -int Render::ControlBar(SubStreamWindowProperties& properties) { +int Render::ControlBar(std::shared_ptr& properties) { ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); ImVec2 mouse_button_pos = ImVec2(0, 0); - if (properties.control_bar_expand_) { - ImGui::SetCursorPosX(properties.is_control_bar_in_left_ - ? (properties.control_window_width_ + 5.0f) + if (properties->control_bar_expand_) { + ImGui::SetCursorPosX(properties->is_control_bar_in_left_ + ? (properties->control_window_width_ + 5.0f) : 38.0f); // mouse control button ImDrawList* draw_list = ImGui::GetWindowDrawList(); - if (properties.is_control_bar_in_left_) { + if (properties->is_control_bar_in_left_) { draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, ImGui::GetCursorScreenPos().y - 7.0f), ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, ImGui::GetCursorScreenPos().y - 7.0f + - properties.control_window_height_), + properties->control_window_height_), IM_COL32(178, 178, 178, 255), 1.0f); } mouse_button_pos = ImGui::GetCursorScreenPos(); float disable_mouse_x = ImGui::GetCursorScreenPos().x + 4.0f; float disable_mouse_y = ImGui::GetCursorScreenPos().y + 4.0f; - std::string mouse = properties.mouse_control_button_pressed_ + std::string mouse = properties->mouse_control_button_pressed_ ? ICON_FA_COMPUTER_MOUSE : ICON_FA_COMPUTER_MOUSE; if (ImGui::Button(mouse.c_str(), ImVec2(25, 25))) { - if (properties.connection_established_) { - properties.control_mouse_ = !properties.control_mouse_; - properties.start_keyboard_capturer_ = - !properties.start_keyboard_capturer_; - properties.mouse_control_button_pressed_ = - !properties.mouse_control_button_pressed_; - properties.mouse_control_button_label_ = - properties.mouse_control_button_pressed_ + if (properties->connection_established_) { + control_mouse_ = !control_mouse_; + start_keyboard_capturer_ = !start_keyboard_capturer_; + properties->mouse_control_button_pressed_ = + !properties->mouse_control_button_pressed_; + properties->mouse_control_button_label_ = + properties->mouse_control_button_pressed_ ? localization::release_mouse[localization_language_index_] : localization::control_mouse[localization_language_index_]; } } - if (!properties.mouse_control_button_pressed_) { + if (!properties->mouse_control_button_pressed_) { draw_list->AddLine( ImVec2(disable_mouse_x, disable_mouse_y), ImVec2(disable_mouse_x + 16.0f, disable_mouse_y + 14.2f), @@ -87,27 +86,26 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f; // std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH // : ICON_FA_VOLUME_XMARK; - std::string audio = properties.audio_capture_button_pressed_ + std::string audio = properties->audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH : ICON_FA_VOLUME_HIGH; if (ImGui::Button(audio.c_str(), ImVec2(25, 25))) { - if (properties.connection_established_) { - properties.audio_capture_ = !properties.audio_capture_; - properties.audio_capture_button_pressed_ = - !properties.audio_capture_button_pressed_; - properties.audio_capture_button_label_ = - properties.audio_capture_button_pressed_ + if (properties->connection_established_) { + properties->audio_capture_button_pressed_ = + !properties->audio_capture_button_pressed_; + properties->audio_capture_button_label_ = + properties->audio_capture_button_pressed_ ? localization::audio_capture[localization_language_index_] : localization::mute[localization_language_index_]; RemoteAction remote_action; remote_action.type = ControlType::audio_capture; - remote_action.a = properties.audio_capture_button_pressed_; + remote_action.a = properties->audio_capture_button_pressed_; SendDataFrame(peer_, (const char*)&remote_action, sizeof(remote_action)); } } - if (!properties.audio_capture_button_pressed_) { + if (!properties->audio_capture_button_pressed_) { draw_list->AddLine( ImVec2(disable_audio_x, disable_audio_y), ImVec2(disable_audio_x + 16.0f, disable_audio_y + 14.2f), @@ -123,19 +121,19 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { ImGui::SameLine(); // net traffic stats button bool button_color_style_pushed = false; - if (properties.net_traffic_stats_button_pressed_) { + if (properties->net_traffic_stats_button_pressed_) { ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(66 / 255.0f, 150 / 255.0f, 250 / 255.0f, 1.0f)); button_color_style_pushed = true; } std::string net_traffic_stats = ICON_FA_SIGNAL; if (ImGui::Button(net_traffic_stats.c_str(), ImVec2(25, 25))) { - properties.net_traffic_stats_button_pressed_ = - !properties.net_traffic_stats_button_pressed_; - properties.control_window_height_is_changing_ = true; - properties.net_traffic_stats_button_pressed_time_ = ImGui::GetTime(); - properties.net_traffic_stats_button_label_ = - properties.net_traffic_stats_button_pressed_ + properties->net_traffic_stats_button_pressed_ = + !properties->net_traffic_stats_button_pressed_; + properties->control_window_height_is_changing_ = true; + properties->net_traffic_stats_button_pressed_time_ = ImGui::GetTime(); + properties->net_traffic_stats_button_label_ = + properties->net_traffic_stats_button_pressed_ ? localization::hide_net_traffic_stats [localization_language_index_] : localization::show_net_traffic_stats @@ -152,7 +150,7 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { fullscreen_button_pressed_ ? ICON_FA_COMPRESS : ICON_FA_EXPAND; if (ImGui::Button(fullscreen.c_str(), ImVec2(25, 25))) { fullscreen_button_pressed_ = !fullscreen_button_pressed_; - properties.fullscreen_button_label_ = + properties->fullscreen_button_label_ = fullscreen_button_pressed_ ? localization::exit_fullscreen[localization_language_index_] : localization::fullscreen[localization_language_index_]; @@ -162,7 +160,7 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { } else { SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); } - properties.reset_control_bar_pos_ = true; + properties->reset_control_bar_pos_ = true; } ImGui::SameLine(); @@ -176,39 +174,39 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { ImGui::SameLine(); - if (!properties.is_control_bar_in_left_) { + if (!properties->is_control_bar_in_left_) { draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, ImGui::GetCursorScreenPos().y - 7.0f), ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, ImGui::GetCursorScreenPos().y - 7.0f + - properties.control_window_height_), + properties->control_window_height_), IM_COL32(178, 178, 178, 255), 1.0f); } } - ImGui::SetCursorPosX(properties.is_control_bar_in_left_ - ? (properties.control_window_width_ * 2 - 20.0f) + ImGui::SetCursorPosX(properties->is_control_bar_in_left_ + ? (properties->control_window_width_ * 2 - 20.0f) : 5.0f); std::string control_bar = - properties.control_bar_expand_ - ? (properties.is_control_bar_in_left_ ? ICON_FA_ANGLE_LEFT - : ICON_FA_ANGLE_RIGHT) - : (properties.is_control_bar_in_left_ ? ICON_FA_ANGLE_RIGHT - : ICON_FA_ANGLE_LEFT); + properties->control_bar_expand_ + ? (properties->is_control_bar_in_left_ ? ICON_FA_ANGLE_LEFT + : ICON_FA_ANGLE_RIGHT) + : (properties->is_control_bar_in_left_ ? ICON_FA_ANGLE_RIGHT + : ICON_FA_ANGLE_LEFT); if (ImGui::Button(control_bar.c_str(), ImVec2(15, 25))) { - properties.control_bar_expand_ = !properties.control_bar_expand_; - properties.control_bar_button_pressed_time_ = ImGui::GetTime(); - properties.control_window_width_is_changing_ = true; + properties->control_bar_expand_ = !properties->control_bar_expand_; + properties->control_bar_button_pressed_time_ = ImGui::GetTime(); + properties->control_window_width_is_changing_ = true; - if (!properties.control_bar_expand_) { - properties.control_window_height_ = 40; - properties.net_traffic_stats_button_pressed_ = false; + if (!properties->control_bar_expand_) { + properties->control_window_height_ = 40; + properties->net_traffic_stats_button_pressed_ = false; } } - if (properties.net_traffic_stats_button_pressed_ && - properties.control_bar_expand_) { + if (properties->net_traffic_stats_button_pressed_ && + properties->control_bar_expand_) { NetTrafficStats(properties); } @@ -217,16 +215,17 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { return 0; } -int Render::NetTrafficStats(SubStreamWindowProperties& properties) { - ImGui::SetCursorPos(ImVec2(properties.is_control_bar_in_left_ - ? (properties.control_window_width_ + 5.0f) +int Render::NetTrafficStats( + std::shared_ptr& properties) { + ImGui::SetCursorPos(ImVec2(properties->is_control_bar_in_left_ + ? (properties->control_window_width_ + 5.0f) : 5.0f, 40.0f)); if (ImGui::BeginTable( "NetTrafficStats", 4, ImGuiTableFlags_BordersH, - ImVec2(properties.control_window_max_width_ - 10.0f, - properties.control_window_max_height_ - 40.0f))) { + ImVec2(properties->control_window_max_width_ - 10.0f, + properties->control_window_max_height_ - 40.0f))) { ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); @@ -248,13 +247,13 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { localization::video[localization_language_index_].c_str()); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.video_inbound_stats.bitrate); + (int)properties->net_traffic_stats_.video_inbound_stats.bitrate); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.video_outbound_stats.bitrate); + (int)properties->net_traffic_stats_.video_outbound_stats.bitrate); ImGui::TableNextColumn(); LossRateDisplay( - properties.net_traffic_stats_.video_inbound_stats.loss_rate); + properties->net_traffic_stats_.video_inbound_stats.loss_rate); ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -262,25 +261,26 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { localization::audio[localization_language_index_].c_str()); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.audio_inbound_stats.bitrate); + (int)properties->net_traffic_stats_.audio_inbound_stats.bitrate); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.audio_outbound_stats.bitrate); + (int)properties->net_traffic_stats_.audio_outbound_stats.bitrate); ImGui::TableNextColumn(); LossRateDisplay( - properties.net_traffic_stats_.audio_inbound_stats.loss_rate); + properties->net_traffic_stats_.audio_inbound_stats.loss_rate); ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("%s", localization::data[localization_language_index_].c_str()); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.data_inbound_stats.bitrate); + (int)properties->net_traffic_stats_.data_inbound_stats.bitrate); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.data_outbound_stats.bitrate); + (int)properties->net_traffic_stats_.data_outbound_stats.bitrate); ImGui::TableNextColumn(); - LossRateDisplay(properties.net_traffic_stats_.data_inbound_stats.loss_rate); + LossRateDisplay( + properties->net_traffic_stats_.data_inbound_stats.loss_rate); ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -288,13 +288,13 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { localization::total[localization_language_index_].c_str()); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.total_inbound_stats.bitrate); + (int)properties->net_traffic_stats_.total_inbound_stats.bitrate); ImGui::TableNextColumn(); BitrateDisplay( - (int)properties.net_traffic_stats_.total_outbound_stats.bitrate); + (int)properties->net_traffic_stats_.total_outbound_stats.bitrate); ImGui::TableNextColumn(); LossRateDisplay( - properties.net_traffic_stats_.total_inbound_stats.loss_rate); + properties->net_traffic_stats_.total_inbound_stats.loss_rate); ImGui::EndTable(); } diff --git a/src/single_window/control_window.cpp b/src/single_window/control_window.cpp index c3a2199..9a23c7c 100644 --- a/src/single_window/control_window.cpp +++ b/src/single_window/control_window.cpp @@ -1,41 +1,42 @@ #include "rd_log.h" #include "render.h" -int Render::ControlWindow(SubStreamWindowProperties &properties) { +int Render::ControlWindow( + std::shared_ptr &properties) { double time_duration = - ImGui::GetTime() - properties.control_bar_button_pressed_time_; - if (properties.control_window_width_is_changing_) { - if (properties.control_bar_expand_) { - properties.control_window_width_ = - (float)(properties.control_window_min_width_ + - (properties.control_window_max_width_ - - properties.control_window_min_width_) * + ImGui::GetTime() - properties->control_bar_button_pressed_time_; + if (properties->control_window_width_is_changing_) { + if (properties->control_bar_expand_) { + properties->control_window_width_ = + (float)(properties->control_window_min_width_ + + (properties->control_window_max_width_ - + properties->control_window_min_width_) * 4 * time_duration); } else { - properties.control_window_width_ = - (float)(properties.control_window_max_width_ - - (properties.control_window_max_width_ - - properties.control_window_min_width_) * + properties->control_window_width_ = + (float)(properties->control_window_max_width_ - + (properties->control_window_max_width_ - + properties->control_window_min_width_) * 4 * time_duration); } } time_duration = - ImGui::GetTime() - properties.net_traffic_stats_button_pressed_time_; - if (properties.control_window_height_is_changing_) { - if (properties.control_bar_expand_ && - properties.net_traffic_stats_button_pressed_) { - properties.control_window_height_ = - (float)(properties.control_window_min_height_ + - (properties.control_window_max_height_ - - properties.control_window_min_height_) * + ImGui::GetTime() - properties->net_traffic_stats_button_pressed_time_; + if (properties->control_window_height_is_changing_) { + if (properties->control_bar_expand_ && + properties->net_traffic_stats_button_pressed_) { + properties->control_window_height_ = + (float)(properties->control_window_min_height_ + + (properties->control_window_max_height_ - + properties->control_window_min_height_) * 4 * time_duration); - } else if (properties.control_bar_expand_ && - !properties.net_traffic_stats_button_pressed_) { - properties.control_window_height_ = - (float)(properties.control_window_max_height_ - - (properties.control_window_max_height_ - - properties.control_window_min_height_) * + } else if (properties->control_bar_expand_ && + !properties->net_traffic_stats_button_pressed_) { + properties->control_window_height_ = + (float)(properties->control_window_max_height_ - + (properties->control_window_max_height_ - + properties->control_window_min_height_) * 4 * time_duration); } } @@ -47,189 +48,189 @@ int Render::ControlWindow(SubStreamWindowProperties &properties) { ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(properties.control_window_width_, - properties.control_window_height_), + ImGui::SetNextWindowSize(ImVec2(properties->control_window_width_, + properties->control_window_height_), ImGuiCond_Always); - if (0 == properties.control_winodw_pos_.x && - 0 == properties.control_winodw_pos_.y) { + if (0 == properties->control_winodw_pos_.x && + 0 == properties->control_winodw_pos_.y) { ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_ + 1), ImGuiCond_Once); } - if (properties.reset_control_bar_pos_) { + if (properties->reset_control_bar_pos_) { float new_control_window_pos_x, new_control_window_pos_y, new_cursor_pos_x, new_cursor_pos_y; // set control window pos - new_control_window_pos_x = properties.control_winodw_pos_.x; - if (properties.control_winodw_pos_.y < - properties.stream_render_rect_last_.y) { - new_control_window_pos_y = properties.stream_render_rect_.y - - (properties.stream_render_rect_last_.y - - properties.control_winodw_pos_.y); + new_control_window_pos_x = properties->control_winodw_pos_.x; + if (properties->control_winodw_pos_.y < + properties->stream_render_rect_last_.y) { + new_control_window_pos_y = properties->stream_render_rect_.y - + (properties->stream_render_rect_last_.y - + properties->control_winodw_pos_.y); if (fullscreen_button_pressed_ && new_control_window_pos_y < 0) { new_control_window_pos_y = 0; } else if (!fullscreen_button_pressed_ && new_control_window_pos_y < (title_bar_height_ + 1)) { new_control_window_pos_y = title_bar_height_ + 1; } - } else if (properties.control_winodw_pos_.y + - properties.control_window_height_ > - properties.stream_render_rect_last_.y + - properties.stream_render_rect_last_.h) { - new_control_window_pos_y = properties.stream_render_rect_.y + - properties.stream_render_rect_.h + - (properties.control_winodw_pos_.y - - properties.stream_render_rect_last_.y - - properties.stream_render_rect_last_.h); - if (new_control_window_pos_y > properties.sub_stream_window_height_ - - properties.control_window_height_) { - new_control_window_pos_y = properties.sub_stream_window_height_ - - properties.control_window_height_; + } else if (properties->control_winodw_pos_.y + + properties->control_window_height_ > + properties->stream_render_rect_last_.y + + properties->stream_render_rect_last_.h) { + new_control_window_pos_y = properties->stream_render_rect_.y + + properties->stream_render_rect_.h + + (properties->control_winodw_pos_.y - + properties->stream_render_rect_last_.y - + properties->stream_render_rect_last_.h); + if (new_control_window_pos_y > properties->sub_stream_window_height_ - + properties->control_window_height_) { + new_control_window_pos_y = properties->sub_stream_window_height_ - + properties->control_window_height_; } - } else if (properties.control_winodw_pos_.y + - properties.control_window_height_ == - properties.stream_render_rect_last_.y + - properties.stream_render_rect_last_.h) { - new_control_window_pos_y = properties.stream_render_rect_.y + - properties.stream_render_rect_.h - - properties.control_window_height_; + } else if (properties->control_winodw_pos_.y + + properties->control_window_height_ == + properties->stream_render_rect_last_.y + + properties->stream_render_rect_last_.h) { + new_control_window_pos_y = properties->stream_render_rect_.y + + properties->stream_render_rect_.h - + properties->control_window_height_; } else { new_control_window_pos_y = - (properties.control_winodw_pos_.y - - properties.stream_render_rect_last_.y) / - (float)(properties.stream_render_rect_last_.h) * - properties.stream_render_rect_.h + - properties.stream_render_rect_.y; + (properties->control_winodw_pos_.y - + properties->stream_render_rect_last_.y) / + (float)(properties->stream_render_rect_last_.h) * + properties->stream_render_rect_.h + + properties->stream_render_rect_.y; } ImGui::SetNextWindowPos( ImVec2(new_control_window_pos_x, new_control_window_pos_y), ImGuiCond_Always); - if (0 != properties.mouse_diff_control_bar_pos_x_ && - 0 != properties.mouse_diff_control_bar_pos_y_) { + if (0 != properties->mouse_diff_control_bar_pos_x_ && + 0 != properties->mouse_diff_control_bar_pos_y_) { // set cursor pos new_cursor_pos_x = - new_control_window_pos_x + properties.mouse_diff_control_bar_pos_x_; + new_control_window_pos_x + properties->mouse_diff_control_bar_pos_x_; new_cursor_pos_y = - new_control_window_pos_y + properties.mouse_diff_control_bar_pos_y_; + new_control_window_pos_y + properties->mouse_diff_control_bar_pos_y_; SDL_WarpMouseInWindow(stream_window_, (int)new_cursor_pos_x, (int)new_cursor_pos_y); } - properties.reset_control_bar_pos_ = false; - } else if (!properties.reset_control_bar_pos_ && + properties->reset_control_bar_pos_ = false; + } else if (!properties->reset_control_bar_pos_ && ImGui::IsMouseReleased(ImGuiPopupFlags_MouseButtonLeft) || - properties.control_window_width_is_changing_) { - if (properties.control_winodw_pos_.x <= - properties.sub_stream_window_width_ / 2) { + properties->control_window_width_is_changing_) { + if (properties->control_winodw_pos_.x <= + properties->sub_stream_window_width_ / 2) { float pos_x = 0; float pos_y = - (properties.control_winodw_pos_.y >= + (properties->control_winodw_pos_.y >= (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && - properties.control_winodw_pos_.y <= - properties.sub_stream_window_height_ - - properties.control_window_height_) - ? properties.control_winodw_pos_.y - : (properties.control_winodw_pos_.y < + properties->control_winodw_pos_.y <= + properties->sub_stream_window_height_ - + properties->control_window_height_) + ? properties->control_winodw_pos_.y + : (properties->control_winodw_pos_.y < (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) ? (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) - : (properties.sub_stream_window_height_ - - properties.control_window_height_)); + : (properties->sub_stream_window_height_ - + properties->control_window_height_)); - if (properties.control_bar_expand_) { - if (properties.control_window_width_ >= - properties.control_window_max_width_) { - properties.control_window_width_ = - properties.control_window_max_width_; - properties.control_window_width_is_changing_ = false; + if (properties->control_bar_expand_) { + if (properties->control_window_width_ >= + properties->control_window_max_width_) { + properties->control_window_width_ = + properties->control_window_max_width_; + properties->control_window_width_is_changing_ = false; } else { - properties.control_window_width_is_changing_ = true; + properties->control_window_width_is_changing_ = true; } } else { - if (properties.control_window_width_ <= - properties.control_window_min_width_) { - properties.control_window_width_ = - properties.control_window_min_width_; - properties.control_window_width_is_changing_ = false; + if (properties->control_window_width_ <= + properties->control_window_min_width_) { + properties->control_window_width_ = + properties->control_window_min_width_; + properties->control_window_width_is_changing_ = false; } else { - properties.control_window_width_is_changing_ = true; + properties->control_window_width_is_changing_ = true; } } ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); - properties.is_control_bar_in_left_ = true; - } else if (properties.control_winodw_pos_.x > - properties.sub_stream_window_width_ / 2) { + properties->is_control_bar_in_left_ = true; + } else if (properties->control_winodw_pos_.x > + properties->sub_stream_window_width_ / 2) { float pos_x = 0; float pos_y = - (properties.control_winodw_pos_.y >= + (properties->control_winodw_pos_.y >= (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && - properties.control_winodw_pos_.y <= - properties.sub_stream_window_height_ - - properties.control_window_height_) - ? properties.control_winodw_pos_.y - : (properties.control_winodw_pos_.y < + properties->control_winodw_pos_.y <= + properties->sub_stream_window_height_ - + properties->control_window_height_) + ? properties->control_winodw_pos_.y + : (properties->control_winodw_pos_.y < (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) ? (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) - : (properties.sub_stream_window_height_ - - properties.control_window_height_)); + : (properties->sub_stream_window_height_ - + properties->control_window_height_)); - if (properties.control_bar_expand_) { - if (properties.control_window_width_ >= - properties.control_window_max_width_) { - properties.control_window_width_ = - properties.control_window_max_width_; - properties.control_window_width_is_changing_ = false; - pos_x = properties.sub_stream_window_width_ - - properties.control_window_max_width_; + if (properties->control_bar_expand_) { + if (properties->control_window_width_ >= + properties->control_window_max_width_) { + properties->control_window_width_ = + properties->control_window_max_width_; + properties->control_window_width_is_changing_ = false; + pos_x = properties->sub_stream_window_width_ - + properties->control_window_max_width_; } else { - properties.control_window_width_is_changing_ = true; - pos_x = properties.sub_stream_window_width_ - - properties.control_window_width_; + properties->control_window_width_is_changing_ = true; + pos_x = properties->sub_stream_window_width_ - + properties->control_window_width_; } } else { - if (properties.control_window_width_ <= - properties.control_window_min_width_) { - properties.control_window_width_ = - properties.control_window_min_width_; - properties.control_window_width_is_changing_ = false; - pos_x = properties.sub_stream_window_width_ - - properties.control_window_min_width_; + if (properties->control_window_width_ <= + properties->control_window_min_width_) { + properties->control_window_width_ = + properties->control_window_min_width_; + properties->control_window_width_is_changing_ = false; + pos_x = properties->sub_stream_window_width_ - + properties->control_window_min_width_; } else { - properties.control_window_width_is_changing_ = true; - pos_x = properties.sub_stream_window_width_ - - properties.control_window_width_; + properties->control_window_width_is_changing_ = true; + pos_x = properties->sub_stream_window_width_ - + properties->control_window_width_; } } ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); - properties.is_control_bar_in_left_ = false; + properties->is_control_bar_in_left_ = false; } } - if (properties.control_bar_expand_ && - properties.control_window_height_is_changing_) { - if (properties.net_traffic_stats_button_pressed_) { - if (properties.control_window_height_ >= - properties.control_window_max_height_) { - properties.control_window_height_ = - properties.control_window_max_height_; - properties.control_window_height_is_changing_ = false; + if (properties->control_bar_expand_ && + properties->control_window_height_is_changing_) { + if (properties->net_traffic_stats_button_pressed_) { + if (properties->control_window_height_ >= + properties->control_window_max_height_) { + properties->control_window_height_ = + properties->control_window_max_height_; + properties->control_window_height_is_changing_ = false; } else { - properties.control_window_height_is_changing_ = true; + properties->control_window_height_is_changing_ = true; } } else { - if (properties.control_window_height_ <= - properties.control_window_min_height_) { - properties.control_window_height_ = - properties.control_window_min_height_; - properties.control_window_height_is_changing_ = false; + if (properties->control_window_height_ <= + properties->control_window_min_height_) { + properties->control_window_height_ = + properties->control_window_min_height_; + properties->control_window_height_is_changing_ = false; } else { - properties.control_window_height_is_changing_ = true; + properties->control_window_height_is_changing_ = true; } } } @@ -239,32 +240,32 @@ int Render::ControlWindow(SubStreamWindowProperties &properties) { ImGuiWindowFlags_NoScrollbar); ImGui::PopStyleVar(); - properties.control_winodw_pos_ = ImGui::GetWindowPos(); - SDL_GetMouseState(&properties.mouse_pos_x_, &properties.mouse_pos_y_); - properties.mouse_diff_control_bar_pos_x_ = - properties.mouse_pos_x_ - properties.control_winodw_pos_.x; - properties.mouse_diff_control_bar_pos_y_ = - properties.mouse_pos_y_ - properties.control_winodw_pos_.y; + properties->control_winodw_pos_ = ImGui::GetWindowPos(); + SDL_GetMouseState(&properties->mouse_pos_x_, &properties->mouse_pos_y_); + properties->mouse_diff_control_bar_pos_x_ = + properties->mouse_pos_x_ - properties->control_winodw_pos_.x; + properties->mouse_diff_control_bar_pos_y_ = + properties->mouse_pos_y_ - properties->control_winodw_pos_.y; ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); static bool a, b, c, d, e; - ImGui::SetNextWindowPos(ImVec2(properties.is_control_bar_in_left_ - ? properties.control_winodw_pos_.x - - properties.control_window_width_ - : properties.control_winodw_pos_.x, - properties.control_winodw_pos_.y), + ImGui::SetNextWindowPos(ImVec2(properties->is_control_bar_in_left_ + ? properties->control_winodw_pos_.x - + properties->control_window_width_ + : properties->control_winodw_pos_.x, + properties->control_winodw_pos_.y), ImGuiCond_Always); ImGui::SetWindowFontScale(0.5f); ImGui::BeginChild("ControlBar", - ImVec2(properties.control_window_width_ * 2, - properties.control_window_height_), + ImVec2(properties->control_window_width_ * 2, + properties->control_window_height_), ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration); ImGui::SetWindowFontScale(1.0f); ImGui::PopStyleColor(); ControlBar(properties); - properties.control_bar_hovered_ = ImGui::IsWindowHovered(); + properties->control_bar_hovered_ = ImGui::IsWindowHovered(); ImGui::EndChild(); ImGui::End(); diff --git a/src/single_window/main_window.cpp b/src/single_window/main_window.cpp index 88c2468..cbd749c 100644 --- a/src/single_window/main_window.cpp +++ b/src/single_window/main_window.cpp @@ -29,7 +29,7 @@ int Render::MainWindow() { RecentConnectionsWindow(); StatusBar(); - for (auto& properties : connection_properties_) { + for (auto& properties : client_properties_) { ConnectionStatusWindow(properties.second); } diff --git a/src/single_window/recent_connections.cpp b/src/single_window/recent_connections.cpp index 22717ea..56b7cac 100644 --- a/src/single_window/recent_connections.cpp +++ b/src/single_window/recent_connections.cpp @@ -177,11 +177,14 @@ int Render::ShowRecentConnections() { if (ImGui::Button(connect_to_this_connection_button_name.c_str(), ImVec2(button_width, button_height))) { remote_id_ = remote_id; + + bool remember_password_flag = false; if (!password.empty() && password.size() == 6) { - remember_password_ = true; + remember_password_flag = true; + memcpy(remote_password_, password.c_str(), 6); } - memcpy(remote_password_, password.c_str(), 6); - ConnectTo(); + + ConnectTo(remote_id, remote_password_, remember_password_flag); } } ImGui::SetWindowFontScale(1.0f); diff --git a/src/single_window/remote_peer_window.cpp b/src/single_window/remote_peer_window.cpp index c18a303..dfa8935 100644 --- a/src/single_window/remote_peer_window.cpp +++ b/src/single_window/remote_peer_window.cpp @@ -75,11 +75,12 @@ int Render::RemoteWindow() { remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(), static_cast(&isspace)), remote_id_.end()); - ConnectTo(); + ConnectTo(remote_id_, remote_password_, false); } if (rejoin_) { - ConnectTo(); + ConnectTo(remote_id_, remote_password_, + client_properties_[remote_id_]->remember_password_); } } ImGui::EndChild(); @@ -102,33 +103,44 @@ static int InputTextCallback(ImGuiInputTextCallbackData *data) { return 0; } -int Render::ConnectTo() { - // connection_status_ = ConnectionStatus::Connecting; +int Render::ConnectTo(const std::string &host_name, const char *password, + bool remember_password) { + LOG_INFO("Connect to [{}]", host_name); + if (client_properties_.find(host_name) == client_properties_.end()) { + client_properties_[host_name] = + std::make_shared(); + } + + auto props = client_properties_[host_name]; + props->connection_status_ = ConnectionStatus::Connecting; + props->remember_password_ = remember_password; + memcpy(props->remote_password_, password, 6); + int ret = -1; if (signal_connected_) { - // if (!connection_established_) { - if (0 == strcmp(remote_id_.c_str(), client_id_) && !peer_reserved_) { - peer_reserved_ = CreatePeer(¶ms_); - if (peer_reserved_) { - LOG_INFO("Create peer[reserved] instance successful"); - std::string client_id = "C-"; - client_id += client_id_; - Init(peer_reserved_, client_id.c_str()); - LOG_INFO("Peer[reserved] init finish"); + if (!props->connection_established_) { + if (0 == strcmp(host_name.c_str(), client_id_) && !peer_reserved_) { + peer_reserved_ = CreatePeer(¶ms_); + if (peer_reserved_) { + LOG_INFO("Create peer[reserved] instance successful"); + std::string client_id = "C-"; + client_id += client_id_; + Init(peer_reserved_, client_id.c_str()); + LOG_INFO("Peer[reserved] init finish"); + } else { + LOG_INFO("Create peer[reserved] instance failed"); + } + } + + ret = JoinConnection(peer_reserved_ ? peer_reserved_ : peer_, + host_name.c_str(), password); + if (0 == ret) { + is_client_mode_ = true; + rejoin_ = false; } else { - LOG_INFO("Create peer[reserved] instance failed"); + rejoin_ = true; } } - - ret = JoinConnection(peer_reserved_ ? peer_reserved_ : peer_, - remote_id_.c_str(), remote_password_); - if (0 == ret) { - is_client_mode_ = true; - rejoin_ = false; - } else { - rejoin_ = true; - } - // } } return 0; diff --git a/src/single_window/render.cpp b/src/single_window/render.cpp index 31ce4e0..18a83cf 100644 --- a/src/single_window/render.cpp +++ b/src/single_window/render.cpp @@ -15,12 +15,12 @@ #include "rd_log.h" #include "screen_capturer_factory.h" -// Refresh Event -#define REFRESH_EVENT (SDL_USEREVENT + 1) #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 #define MOUSE_GRAB_PADDING 5 +const Uint32 STREAM_FRASH = SDL_RegisterEvents(29); + SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, const SDL_Point* area, void* data) { Render* render = (Render*)data; @@ -40,9 +40,9 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, return SDL_HITTEST_DRAGGABLE; } - if (!render->streaming_) { - return SDL_HITTEST_NORMAL; - } + // if (!render->streaming_) { + // return SDL_HITTEST_NORMAL; + // } if (area->y < MOUSE_GRAB_PADDING) { if (area->x < MOUSE_GRAB_PADDING) { @@ -69,7 +69,7 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, return SDL_HITTEST_NORMAL; } -Render::Render() { memset(&net_traffic_stats_, 0, sizeof(net_traffic_stats_)); } +Render::Render() {} Render::~Render() {} @@ -198,7 +198,7 @@ int Render::StartScreenCapturer() { std::chrono::steady_clock::now().time_since_epoch()) .count(); auto duration = now_time - last_frame_time_; - if (duration >= 0 && connection_established_) { + if (duration >= 0) { XVideoFrame frame; frame.data = (const char*)data; frame.size = size; @@ -238,9 +238,7 @@ int Render::StartSpeakerCapturer() { speaker_capturer_ = (SpeakerCapturer*)speaker_capturer_factory_->Create(); int speaker_capturer_init_ret = speaker_capturer_->Init( [this](unsigned char* data, size_t size) -> void { - if (connection_established_) { - SendAudioFrame(peer_, (const char*)data, size); - } + SendAudioFrame(peer_, (const char*)data, size); }); if (0 != speaker_capturer_init_ret) { @@ -518,16 +516,16 @@ int Render::CreateStreamWindow() { } stream_pixformat_ = SDL_PIXELFORMAT_NV12; - stream_texture_ = SDL_CreateTexture(stream_renderer_, stream_pixformat_, - SDL_TEXTUREACCESS_STREAMING, - texture_width_, texture_height_); + // stream_texture_ = SDL_CreateTexture(stream_renderer_, stream_pixformat_, + // SDL_TEXTUREACCESS_STREAMING, + // texture_width_, texture_height_); SDL_SetWindowResizable(stream_window_, SDL_TRUE); // for window region action SDL_SetWindowHitTest(stream_window_, HitTestCallback, this); - // change stream_render_rect_ + // change props->stream_render_rect_ SDL_Event event; event.type = SDL_WINDOWEVENT; event.window.windowID = SDL_GetWindowID(stream_window_); @@ -733,7 +731,12 @@ int Render::DrawStreamWindow() { // Rendering ImGui::Render(); SDL_RenderClear(stream_renderer_); - SDL_RenderCopy(stream_renderer_, stream_texture_, NULL, &stream_render_rect_); + + for (auto& it : client_properties_) { + auto props = it.second; + SDL_RenderCopy(stream_renderer_, props->stream_texture_, NULL, + &(props->stream_render_rect_)); + } ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); SDL_RenderPresent(stream_renderer_); @@ -766,11 +769,6 @@ int Render::Run() { screen_width_ = DM.w; screen_height_ = DM.h; - stream_render_rect_.x = 0; - stream_render_rect_.y = (int)title_bar_height_; - stream_render_rect_.w = (int)stream_window_width_; - stream_render_rect_.h = (int)(stream_window_height_ - title_bar_height_); - // use linear filtering to render textures otherwise the graphics will be // blurry SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); @@ -842,40 +840,47 @@ int Render::Run() { ImGui_ImplSDL2_ProcessEvent(&event); } if (event.type == SDL_QUIT) { - if (streaming_) { + if (stream_window_inited_) { LOG_INFO("Destroy stream window"); SDL_SetWindowGrab(stream_window_, SDL_FALSE); DestroyStreamWindow(); DestroyStreamWindowContext(); - if (dst_buffer_) { - thumbnail_->SaveToThumbnail( - (char*)dst_buffer_, video_width_, video_height_, remote_id_, - remote_host_name_, remember_password_ ? remote_password_ : ""); - recent_connection_image_save_time_ = SDL_GetTicks(); - } + for (auto& it : client_properties_) { + auto props = it.second; + if (props->dst_buffer_) { + thumbnail_->SaveToThumbnail( + (char*)props->dst_buffer_, props->video_width_, + props->video_height_, it.first, props->remote_host_name_, + props->remember_password_ ? props->remote_password_ : ""); + } - LOG_INFO("[{}] Leave connection [{}]", client_id_, remote_id_); - LeaveConnection(peer_reserved_ ? peer_reserved_ : peer_, - remote_id_.c_str()); - if (peer_reserved_) { - LOG_INFO("Destroy peer[reserved]"); - DestroyPeer(&peer_reserved_); - } + LOG_INFO("[{}] Leave connection [{}]", client_id_, it.first); + LeaveConnection(peer_reserved_ ? peer_reserved_ : peer_, + it.first.c_str()); + if (peer_reserved_) { + LOG_INFO("Destroy peer[reserved]"); + DestroyPeer(&peer_reserved_); + } + + props->streaming_ = false; + props->remember_password_ = false; + props->connection_established_ = false; + props->audio_capture_button_pressed_ = false; + + memset(&props->net_traffic_stats_, 0, + sizeof(props->net_traffic_stats_)); + SDL_SetWindowFullscreen(main_window_, SDL_FALSE); + SDL_DestroyTexture(props->stream_texture_); + memset(audio_buffer_, 0, 720); + } + client_properties_.clear(); - streaming_ = false; rejoin_ = false; - connection_established_ = false; is_client_mode_ = false; - audio_capture_button_pressed_ = false; - fullscreen_button_pressed_ = false; reload_recent_connections_ = true; - remember_password_ = false; - - memset(&net_traffic_stats_, 0, sizeof(net_traffic_stats_)); - SDL_SetWindowFullscreen(main_window_, SDL_FALSE); - memset(audio_buffer_, 0, 720); - + fullscreen_button_pressed_ = false; + recent_connection_image_save_time_ = SDL_GetTicks(); continue; } else { LOG_INFO("Quit program"); @@ -888,73 +893,101 @@ int Render::Run() { } else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED && stream_window_created_ && event.window.windowID == SDL_GetWindowID(stream_window_)) { - // to prevent cursor relocation - if (!reset_control_bar_pos_) { - mouse_diff_control_bar_pos_x_ = 0; - mouse_diff_control_bar_pos_y_ = 0; - } + for (auto& it : client_properties_) { + auto props = it.second; - reset_control_bar_pos_ = true; - int stream_window_width, stream_window_height; - SDL_GetWindowSize(stream_window_, &stream_window_width, - &stream_window_height); - stream_window_width_ = (float)stream_window_width; - stream_window_height_ = (float)stream_window_height; + // to prevent cursor relocation + if (!props->reset_control_bar_pos_) { + props->mouse_diff_control_bar_pos_x_ = 0; + props->mouse_diff_control_bar_pos_y_ = 0; + } - float video_ratio = (float)video_width_ / (float)video_height_; - float video_ratio_reverse = (float)video_height_ / (float)video_width_; + props->reset_control_bar_pos_ = true; + int stream_window_width, stream_window_height; + SDL_GetWindowSize(stream_window_, &stream_window_width, + &stream_window_height); + stream_window_width_ = (float)stream_window_width; + stream_window_height_ = (float)stream_window_height; - float render_area_width = stream_window_width_; - float render_area_height = - stream_window_height_ - - (fullscreen_button_pressed_ ? 0 : title_bar_height_); + float video_ratio = + (float)props->video_width_ / (float)props->video_height_; + float video_ratio_reverse = + (float)props->video_height_ / (float)props->video_width_; - stream_render_rect_last_ = stream_render_rect_; - if (render_area_width < render_area_height * video_ratio) { - stream_render_rect_.x = 0; - stream_render_rect_.y = - (int)(abs(render_area_height - - render_area_width * video_ratio_reverse) / - 2 + - (fullscreen_button_pressed_ ? 0 : title_bar_height_)); - stream_render_rect_.w = (int)render_area_width; - stream_render_rect_.h = - (int)(render_area_width * video_ratio_reverse); - } else if (render_area_width > render_area_height * video_ratio) { - stream_render_rect_.x = - (int)abs(render_area_width - render_area_height * video_ratio) / - 2; - stream_render_rect_.y = - fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; - stream_render_rect_.w = (int)(render_area_height * video_ratio); - stream_render_rect_.h = (int)render_area_height; - } else { - stream_render_rect_.x = 0; - stream_render_rect_.y = - fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; - stream_render_rect_.w = (int)render_area_width; - stream_render_rect_.h = (int)render_area_height; + float render_area_width = stream_window_width_; + float render_area_height = + stream_window_height_ - + (fullscreen_button_pressed_ ? 0 : title_bar_height_); + + props->stream_render_rect_last_ = props->stream_render_rect_; + if (render_area_width < render_area_height * video_ratio) { + props->stream_render_rect_.x = 0; + props->stream_render_rect_.y = + (int)(abs(render_area_height - + render_area_width * video_ratio_reverse) / + 2 + + (fullscreen_button_pressed_ ? 0 : title_bar_height_)); + props->stream_render_rect_.w = (int)render_area_width; + props->stream_render_rect_.h = + (int)(render_area_width * video_ratio_reverse); + } else if (render_area_width > render_area_height * video_ratio) { + props->stream_render_rect_.x = + (int)abs(render_area_width - render_area_height * video_ratio) / + 2; + props->stream_render_rect_.y = + fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; + props->stream_render_rect_.w = + (int)(render_area_height * video_ratio); + props->stream_render_rect_.h = (int)render_area_height; + } else { + props->stream_render_rect_.x = 0; + props->stream_render_rect_.y = + fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; + props->stream_render_rect_.w = (int)render_area_width; + props->stream_render_rect_.h = (int)render_area_height; + } } } else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) { - if (connection_established_) { + if (event.window.windowID == SDL_GetWindowID(stream_window_)) { continue; } else { exit_ = true; } - } else if (event.type == REFRESH_EVENT) { - if (stream_texture_) - if (video_width_ != texture_width_ || - video_height_ != texture_height_) { - texture_width_ = video_width_; - texture_height_ = video_height_; + } else if (event.type == STREAM_FRASH) { + SubStreamWindowProperties* props = + static_cast(event.user.data1); + if (!props) { + LOG_ERROR("Invalid stream window properties"); + continue; + } - SDL_DestroyTexture(stream_texture_); - stream_texture_ = SDL_CreateTexture( + if (props->stream_texture_) { + if (props->video_width_ != props->texture_width_ || + props->video_height_ != props->texture_height_) { + props->texture_width_ = props->video_width_; + props->texture_height_ = props->video_height_; + + SDL_DestroyTexture(props->stream_texture_); + props->stream_texture_ = SDL_CreateTexture( stream_renderer_, stream_pixformat_, - SDL_TEXTUREACCESS_STREAMING, texture_width_, texture_height_); + SDL_TEXTUREACCESS_STREAMING, props->texture_width_, + props->texture_height_); } - SDL_UpdateTexture(stream_texture_, NULL, dst_buffer_, texture_width_); + } else { + if (props->video_width_ != props->texture_width_ || + props->video_height_ != props->texture_height_) { + props->texture_width_ = props->video_width_; + props->texture_height_ = props->video_height_; + } + + props->stream_texture_ = SDL_CreateTexture( + stream_renderer_, stream_pixformat_, SDL_TEXTUREACCESS_STREAMING, + props->texture_width_, props->texture_height_); + } + + SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_, + props->texture_width_); } } @@ -965,6 +998,7 @@ int Render::Run() { int ret = thumbnail_->LoadThumbnail( main_renderer_, recent_connection_textures_, &recent_connection_image_width_, &recent_connection_image_height_); + LOG_INFO("1 Load recent connection thumbnails"); if (!ret) { LOG_INFO("Load recent connection thumbnails"); } @@ -972,10 +1006,13 @@ int Render::Run() { } } - if (connection_established_ && streaming_) { + if (need_to_create_stream_window_) { CreateStreamWindow(); SetupStreamWindow(); + need_to_create_stream_window_ = false; + } + if (stream_window_inited_) { if (!stream_window_grabbed_ && control_mouse_) { SDL_SetWindowGrab(stream_window_, SDL_TRUE); stream_window_grabbed_ = true; diff --git a/src/single_window/render.h b/src/single_window/render.h index 536518c..c2222a2 100644 --- a/src/single_window/render.h +++ b/src/single_window/render.h @@ -25,6 +25,8 @@ #include "speaker_capturer_factory.h" #include "thumbnail.h" +extern const Uint32 STREAM_FRASH; + class Render { public: struct SubStreamWindowProperties { @@ -34,14 +36,6 @@ class Render { bool mouse_control_button_pressed_ = false; bool mouse_controller_is_started_ = false; bool audio_capture_button_pressed_ = false; - bool audio_capture_ = true; - bool start_screen_capturer_ = false; - bool screen_capturer_is_started_ = false; - bool start_keyboard_capturer_ = false; - bool keyboard_capturer_is_started_ = false; - bool control_mouse_ = false; - bool stream_window_grabbed_ = false; - bool window_maximized_ = false; bool streaming_ = false; bool is_control_bar_in_left_ = true; bool control_bar_hovered_ = false; @@ -50,6 +44,9 @@ class Render { bool control_window_width_is_changing_ = false; bool control_window_height_is_changing_ = false; bool p2p_mode_ = true; + bool hostname_sent_ = false; + bool remember_password_ = false; + char remote_password_[7] = ""; float sub_stream_window_width_ = 1280; float sub_stream_window_height_ = 720; float control_window_min_width_ = 20; @@ -80,6 +77,7 @@ class Render { std::string mouse_control_button_label_ = "Mouse Control"; std::string audio_capture_button_label_ = "Audio Capture"; std::string remote_host_name_ = ""; + SDL_Texture *stream_texture_ = nullptr; SDL_Rect stream_render_rect_; SDL_Rect stream_render_rect_last_; ImVec2 control_winodw_pos_; @@ -104,17 +102,19 @@ class Render { int RemoteWindow(); int RecentConnectionsWindow(); int SettingWindow(); - int ControlWindow(SubStreamWindowProperties &properties); - int ControlBar(SubStreamWindowProperties &properties); + int ControlWindow(std::shared_ptr &properties); + int ControlBar(std::shared_ptr &properties); int AboutWindow(); int StatusBar(); - int ConnectionStatusWindow(SubStreamWindowProperties &properties); + int ConnectionStatusWindow( + std::shared_ptr &properties); int LoadRecentConnections(); int ShowRecentConnections(); private: int CreateRtcConnection(); - int ConnectTo(); + int ConnectTo(const std::string &host_name, const char *password, + bool remember_password); int CreateMainWindow(); int DestroyMainWindow(); int CreateStreamWindow(); @@ -127,7 +127,7 @@ class Render { int DrawMainWindow(); int DrawStreamWindow(); int ConfirmDeleteConnection(); - int NetTrafficStats(SubStreamWindowProperties &properties); + int NetTrafficStats(std::shared_ptr &properties); public: static void OnReceiveVideoBufferCb(const XVideoFrame *video_frame, @@ -150,6 +150,7 @@ class Render { static void NetStatusReport(const char *client_id, size_t client_id_size, TraversalMode mode, const XNetTrafficStats *net_traffic_stats, + const char *user_id, const size_t user_id_size, void *user_data); static SDL_HitTestResult HitTestCallback(SDL_Window *window, @@ -228,8 +229,16 @@ class Render { SDL_Window *main_window_ = nullptr; SDL_Renderer *main_renderer_ = nullptr; ImGuiContext *main_ctx_ = nullptr; + bool exit_ = false; // main window properties + bool start_mouse_controller_ = false; + bool mouse_controller_is_started_ = false; + bool start_screen_capturer_ = false; + bool screen_capturer_is_started_ = false; + bool start_keyboard_capturer_ = false; + bool keyboard_capturer_is_started_ = false; + bool audio_capture_ = false; int main_window_width_real_ = 720; int main_window_height_real_ = 540; float main_window_dpi_scaling_w_ = 1.0f; @@ -279,8 +288,12 @@ class Render { ImGuiContext *stream_ctx_ = nullptr; // stream window properties + bool need_to_create_stream_window_ = false; bool stream_window_created_ = false; bool stream_window_inited_ = false; + bool window_maximized_ = false; + bool stream_window_grabbed_ = false; + bool control_mouse_ = false; int stream_window_width_default_ = 1280; int stream_window_height_default_ = 720; float stream_window_width_ = 1280; @@ -309,10 +322,8 @@ class Render { bool focus_on_input_widget_ = true; bool is_client_mode_ = false; bool reload_recent_connections_ = true; - bool hostname_sent_ = false; bool show_confirm_delete_connection_ = false; bool delete_connection_ = false; - bool remember_password_ = false; bool re_enter_remote_id_ = false; double copy_start_time_ = 0; double regenerate_password_start_time_ = 0; @@ -350,9 +361,12 @@ class Render { /* ------ main window property end ------ */ /* ------ sub stream window property start ------ */ - std::unordered_map - connection_properties_; + std::unordered_map> + client_properties_; /* ------ stream window property end ------ */ + + std::unordered_map> + server_properties_; }; #endif \ No newline at end of file diff --git a/src/single_window/render_callback_func.cpp b/src/single_window/render_callback_func.cpp index c2e14c1..a0d7d7a 100644 --- a/src/single_window/render_callback_func.cpp +++ b/src/single_window/render_callback_func.cpp @@ -4,8 +4,6 @@ #include "rd_log.h" #include "render.h" -// Refresh Event -#define REFRESH_EVENT (SDL_USEREVENT + 1) #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 #ifdef REMOTE_DESK_DEBUG @@ -80,41 +78,50 @@ void Render::SdlCaptureAudioOut([[maybe_unused]] void *userdata, } void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame, - [[maybe_unused]] const char *user_id, - [[maybe_unused]] size_t user_id_size, + const char *user_id, size_t user_id_size, void *user_data) { Render *render = (Render *)user_data; if (!render) { return; } - if (render->connection_established_) { - if (!render->dst_buffer_) { - render->dst_buffer_capacity_ = video_frame->size; - render->dst_buffer_ = new unsigned char[video_frame->size]; + std::string remote_id(user_id, user_id_size); + if (render->client_properties_.find(remote_id) == + render->client_properties_.end()) { + return; + } + SubStreamWindowProperties *props = + render->client_properties_.find(remote_id)->second.get(); + + if (props->connection_established_) { + if (!props->dst_buffer_) { + props->dst_buffer_capacity_ = video_frame->size; + props->dst_buffer_ = new unsigned char[video_frame->size]; } - if (render->dst_buffer_capacity_ < video_frame->size) { - delete render->dst_buffer_; - render->dst_buffer_capacity_ = video_frame->size; - render->dst_buffer_ = new unsigned char[video_frame->size]; + if (props->dst_buffer_capacity_ < video_frame->size) { + delete props->dst_buffer_; + props->dst_buffer_capacity_ = video_frame->size; + props->dst_buffer_ = new unsigned char[video_frame->size]; } - memcpy(render->dst_buffer_, video_frame->data, video_frame->size); - render->video_width_ = video_frame->width; - render->video_height_ = video_frame->height; - render->video_size_ = video_frame->size; + memcpy(props->dst_buffer_, video_frame->data, video_frame->size); + props->video_width_ = video_frame->width; + props->video_height_ = video_frame->height; + props->video_size_ = video_frame->size; SDL_Event event; - event.type = REFRESH_EVENT; + event.type = STREAM_FRASH; + event.user.type = STREAM_FRASH; + event.user.data1 = props; SDL_PushEvent(&event); - render->streaming_ = true; + + props->streaming_ = true; } } void Render::OnReceiveAudioBufferCb(const char *data, size_t size, - [[maybe_unused]] const char *user_id, - [[maybe_unused]] size_t user_id_size, + const char *user_id, size_t user_id_size, void *user_data) { Render *render = (Render *)user_data; if (!render) { @@ -130,12 +137,16 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, void *user_data) { Render *render = (Render *)user_data; if (!render) { - LOG_ERROR("??????????????????"); return; } - std::string user(user_id, user_id_size); - LOG_INFO("Receive data from: {}", user); + 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); @@ -144,18 +155,18 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, } 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->ProcessKeyEvent((int)remote_action.k.key_value, remote_action.k.flag == KeyFlag::key_down); } else if (ControlType::host_infomation == remote_action.type) { - render->remote_host_name_ = + props->remote_host_name_ = std::string(remote_action.i.host_name, remote_action.i.host_name_size); - LOG_INFO("Remote hostname: [{}]", render->remote_host_name_); - } else { - LOG_ERROR("Unknown control type: {}", (int)remote_action.type); + LOG_INFO("Remote hostname: [{}]", props->remote_host_name_); } } @@ -188,31 +199,44 @@ void Render::OnSignalStatusCb(SignalStatus status, void *user_data) { } } -void Render::OnConnectionStatusCb(ConnectionStatus status, - [[maybe_unused]] const char *user_id, - [[maybe_unused]] const size_t user_id_size, - void *user_data) { +void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, + const size_t user_id_size, void *user_data) { Render *render = (Render *)user_data; if (!render) { return; } - render->connection_status_ = status; + bool is_server = false; + std::shared_ptr props; + + std::string remote_id(user_id, user_id_size); + if (render->client_properties_.find(remote_id) != + render->client_properties_.end()) { + props = render->client_properties_.find(remote_id)->second; + } else { + if (render->server_properties_.find(remote_id) == + render->server_properties_.end()) { + render->server_properties_[remote_id] = + std::make_shared(); + } + props = render->server_properties_.find(remote_id)->second; + is_server = true; + } + + props->connection_status_ = status; render->show_connection_status_window_ = true; if (ConnectionStatus::Connecting == status) { render->connection_status_str_ = "Connecting"; } else if (ConnectionStatus::Gathering == status) { render->connection_status_str_ = "Gathering"; } else if (ConnectionStatus::Connected == status) { - std::string remote_id(user_id, user_id_size); - render->connection_properties_[remote_id] = SubStreamWindowProperties(); render->connection_status_str_ = "Connected"; - render->connection_established_ = true; - if (render->peer_reserved_ || !render->is_client_mode_) { - render->start_screen_capturer_ = true; - render->start_mouse_controller_ = true; + if (!render->need_to_create_stream_window_) { + render->need_to_create_stream_window_ = true; } - if (!render->hostname_sent_) { + + props->connection_established_ = true; + if (!props->hostname_sent_) { // TODO: self and remote hostname std::string host_name = GetHostName(); RemoteAction remote_action; @@ -222,11 +246,21 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, int ret = SendDataFrame(render->peer_, (const char *)&remote_action, sizeof(remote_action)); if (0 == ret) { - render->hostname_sent_ = true; + props->hostname_sent_ = true; } - LOG_ERROR("1111111111111111 [{}|{}]", ret, host_name); - } else { - LOG_ERROR("2222222222222222"); + } + + if (!is_server) { + props->stream_render_rect_.x = 0; + props->stream_render_rect_.y = (int)render->title_bar_height_; + props->stream_render_rect_.w = (int)render->stream_window_width_; + props->stream_render_rect_.h = + (int)(render->stream_window_height_ - render->title_bar_height_); + } + + if (render->peer_reserved_ || !render->is_client_mode_) { + render->start_screen_capturer_ = true; + render->start_mouse_controller_ = true; } } else if (ConnectionStatus::Disconnected == status) { render->connection_status_str_ = "Disconnected"; @@ -239,30 +273,29 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, render->password_validating_time_ = 0; render->start_screen_capturer_ = false; render->start_mouse_controller_ = false; - render->connection_established_ = false; - render->control_mouse_ = false; - render->mouse_control_button_pressed_ = false; render->start_keyboard_capturer_ = false; - render->hostname_sent_ = false; + render->control_mouse_ = false; + props->connection_established_ = false; + props->mouse_control_button_pressed_ = false; + props->hostname_sent_ = false; if (render->audio_capture_) { render->StopSpeakerCapturer(); render->audio_capture_ = false; - render->audio_capture_button_pressed_ = false; } if (!render->rejoin_) { memset(render->remote_password_, 0, sizeof(render->remote_password_)); } - if (render->dst_buffer_) { - memset(render->dst_buffer_, 0, render->dst_buffer_capacity_); - SDL_UpdateTexture(render->stream_texture_, NULL, render->dst_buffer_, - render->texture_width_); + if (props->dst_buffer_) { + memset(props->dst_buffer_, 0, props->dst_buffer_capacity_); + SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_, + props->texture_width_); } } else if (ConnectionStatus::IncorrectPassword == status) { render->connection_status_str_ = "Incorrect password"; render->password_validating_ = false; render->password_validating_time_++; if (render->connect_button_pressed_) { - render->connection_established_ = false; + props->connection_established_ = false; render->connect_button_label_ = render->connect_button_pressed_ ? localization::disconnect[render->localization_language_index_] @@ -271,7 +304,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, } else if (ConnectionStatus::NoSuchTransmissionId == status) { render->connection_status_str_ = "No such transmission id"; if (render->connect_button_pressed_) { - render->connection_established_ = false; + props->connection_established_ = false; render->connect_button_label_ = render->connect_button_pressed_ ? localization::disconnect[render->localization_language_index_] @@ -283,21 +316,29 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, void Render::NetStatusReport(const char *client_id, size_t client_id_size, TraversalMode mode, const XNetTrafficStats *net_traffic_stats, + const char *user_id, const size_t user_id_size, void *user_data) { Render *render = (Render *)user_data; if (!render) { 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; + if (0 == strcmp(render->client_id_, "")) { memset(&render->client_id_, 0, sizeof(render->client_id_)); memcpy(render->client_id_, client_id, client_id_size); LOG_INFO("Use client id [{}] and save id into cache file", client_id); render->SaveSettingsIntoCacheFile(); } - if (render->traversal_mode_ != mode) { - render->traversal_mode_ = mode; - LOG_INFO("Net mode: [{}]", int(render->traversal_mode_)); + if (props->traversal_mode_ != mode) { + props->traversal_mode_ = mode; + LOG_INFO("Net mode: [{}]", int(props->traversal_mode_)); } if (!net_traffic_stats) { @@ -306,6 +347,6 @@ void Render::NetStatusReport(const char *client_id, size_t client_id_size, // only display client side net status if connected to itself if (!(render->peer_reserved_ && !strstr(client_id, "C-"))) { - render->net_traffic_stats_ = *net_traffic_stats; + props->net_traffic_stats_ = *net_traffic_stats; } } \ No newline at end of file diff --git a/src/single_window/setting_window.cpp b/src/single_window/setting_window.cpp index c075dcb..42bb8d0 100644 --- a/src/single_window/setting_window.cpp +++ b/src/single_window/setting_window.cpp @@ -70,7 +70,7 @@ int Render::SettingWindow() { ImGui::Separator(); - if (streaming_) { + if (stream_window_inited_) { ImGui::BeginDisabled(); } @@ -161,7 +161,7 @@ int Render::SettingWindow() { ImGui::Checkbox("##enable_turn", &enable_turn_); } - if (streaming_) { + if (stream_window_inited_) { ImGui::EndDisabled(); } @@ -234,7 +234,7 @@ int Render::SettingWindow() { LoadSettingsFromCacheFile(); // Recreate peer instance - if (!streaming_) { + if (!stream_window_inited_) { LOG_INFO("Recreate peer instance"); DestroyPeer(&peer_); is_create_connection_ = false; diff --git a/src/single_window/stream_window.cpp b/src/single_window/stream_window.cpp index a6b4dfc..2251f61 100644 --- a/src/single_window/stream_window.cpp +++ b/src/single_window/stream_window.cpp @@ -18,7 +18,7 @@ int Render::StreamWindow() { ImGuiWindowFlags_NoBringToFrontOnFocus); ImGui::PopStyleColor(2); - for (auto &properties : connection_properties_) { + for (auto &properties : client_properties_) { ControlWindow(properties.second); } diff --git a/src/single_window/thumbnail.cpp b/src/single_window/thumbnail.cpp index d98de06..9abfb28 100644 --- a/src/single_window/thumbnail.cpp +++ b/src/single_window/thumbnail.cpp @@ -96,7 +96,6 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height, image_name = remote_id + 'Y' + password + host_name; } - LOG_ERROR("1 image_path: [{}]", image_name); std::string ciphertext = AES_encrypt(image_name, aes128_key_, aes128_iv_); std::string file_path = image_path_ + ciphertext; stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4, @@ -219,7 +218,6 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer, AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_); std::string image_path = image_path_ + cipher_image_name; textures[original_image_name] = nullptr; - LOG_ERROR("2 image_path: [{}]", original_image_name); LoadTextureFromFile(image_path.c_str(), renderer, &(textures[original_image_name]), width, height); } diff --git a/thirdparty/projectx b/thirdparty/projectx index 49d6307..6e3c8c4 160000 --- a/thirdparty/projectx +++ b/thirdparty/projectx @@ -1 +1 @@ -Subproject commit 49d63071544421ad45f7b764eb9cabd8290fe42c +Subproject commit 6e3c8c488d16a12e25c548c42edb39a518baa329