jcsyshc 2 роки тому
батько
коміт
14be6f02c2

+ 1 - 1
CMakeLists.txt

@@ -3,7 +3,7 @@ project(RemoteAR3)
 
 set(CMAKE_CXX_STANDARD 20)
 
-add_executable(RemoteAR3 src/main.cpp
+add_executable(${PROJECT_NAME} src/main.cpp
         src/main_ext.cpp
         src/frame_encoder/encoder_base.cpp
         src/frame_sender/sender_base.cpp

+ 1 - 1
src/cuda_helper.hpp

@@ -17,7 +17,7 @@ inline bool check_cuda_api_call(CUresult api_ret, unsigned int line_number,
     if (ret != CUDA_SUCCESS) [[unlikely]] error_name = "Unknown";
     ret = cuGetErrorString(api_ret, &error_str);
     if (ret != CUDA_SUCCESS) [[unlikely]] error_str = "Unknown";
-    SPDLOG_ERROR("CUDA driver api call {} failed at {}:{} with error 0x{:x}:{}, {}.",
+    SPDLOG_ERROR("CUDA driver api call {} failed at {}:{} with error 0x{:x}({}):{}.",
                  api_call_str, file_name, line_number,
                  (int) api_ret, error_name, error_str);
     RET_ERROR_B;

+ 1 - 1
src/frame_sender/sender_base.cpp

@@ -58,7 +58,6 @@ struct sender_base::impl {
             if (mq().query_variable<bool>(SENDER_SHOULD_STOP)) {
                 q_this->close_connection();
                 ctx->stop();
-                SPDLOG_INFO("Frame sender stopped.");
                 return;
             }
 
@@ -112,4 +111,5 @@ void sender_base::run() {
 
     SPDLOG_INFO("Frame sender started.");
     pimpl->ctx->run();
+    SPDLOG_INFO("Frame sender stopped.");
 }

+ 1 - 0
src/frame_sender/sender_base.h

@@ -9,6 +9,7 @@
 
 enum sender_type {
     SENDER_TCP,
+    SENDER_UDP,
     SENDER_UDP_FEC
 };
 

+ 9 - 7
src/frame_sender/sender_tcp.cpp

@@ -31,23 +31,25 @@ struct sender_tcp::impl {
 
     void close_connection() {
         if (socket == nullptr) return;
-        auto remote_ep = socket->remote_endpoint();
-        SPDLOG_INFO("Client {}:{} left.",
-                    remote_ep.address().to_string(), remote_ep.port());
-        socket.reset();
+        // TODO: log client exit
+//        if (socket->is_open()) {
+//            auto remote_ep = socket->remote_endpoint();
+//            SPDLOG_INFO("Client {}:{} left.",
+//                        remote_ep.address().to_string(), remote_ep.port());
+//        }
+        socket = std::make_unique<tcp::socket>(*q_this->get_ctx());
         mq().update_variable(SENDER_CONNECTED, false);
     }
 
     void send_frame(frame_ptr_type &&frame) {
-        if (socket == nullptr) return;
+        if (!socket->is_open()) return;
 
         out_buf.create(frame->length + sizeof(frame->length));
         auto ptr = write_binary_number(out_buf.ptr, frame->length);
         memcpy(ptr, frame->ptr, frame->length);
 
-        assert(socket->is_open());
         error_code err;
-        write(*socket, buffer(out_buf.ptr, out_buf.length), err);
+        write(*socket, buffer(out_buf.ptr, out_buf.length), err); // TODO: change to async operation
         if (err) {
             SPDLOG_WARN("Error while sending frame: {}", err.to_string());
             close_connection();

+ 69 - 33
src/main_ext.cpp

@@ -57,6 +57,25 @@ using boost::iostreams::mapped_file;
 
 log_timer global_timer;
 
+// utility
+struct imgui_disable_guard {
+    explicit imgui_disable_guard(bool enable = true) {
+        is_disabled = enable;
+        if (is_disabled) {
+            ImGui::BeginDisabled();
+        }
+    }
+
+    ~imgui_disable_guard() {
+        if (is_disabled) {
+            ImGui::EndDisabled();
+        }
+    }
+
+private:
+    bool is_disabled;
+};
+
 // global variable definition
 CUcontext cuda_ctx = nullptr;
 int main_window_width = -1, main_window_height = -1;
@@ -759,9 +778,10 @@ void prepare_imgui_frame() {
                 ImGui::RadioButton("Right", &preview_camera_index, 1);
 
                 ImGui::SeparatorText("Infos");
-                ImGui::BeginDisabled();
-                ImGui::DragFloat("Process Frame Rate (fps)", &process_frame_rate, 0, 0, 60, "%.01f");
-                ImGui::EndDisabled();
+                {
+                    auto guard = imgui_disable_guard{};
+                    ImGui::DragFloat("Process Frame Rate (fps)", &process_frame_rate, 0, 0, 60, "%.01f");
+                }
 
                 // auto save raw config
 //                ImGui::SeparatorText("Auto Shoot");
@@ -858,18 +878,20 @@ void prepare_imgui_frame() {
             ImGui::PushID("Encoder");
 
             ImGui::SeparatorText("Method");
-            if (is_encoding()) {
-                ImGui::BeginDisabled();
-            }
-            if (ImGui::RadioButton("NvEnc", chosen_encoder == ENCODER_NVENC)) {
-                simple_eq.emplace([] { chosen_encoder = ENCODER_NVENC; });
-            }
-            ImGui::SameLine();
-            if (ImGui::RadioButton("nvJPEG", chosen_encoder == ENCODER_JPEG)) {
-                simple_eq.emplace([] { chosen_encoder = ENCODER_JPEG; });
-            }
-            if (is_encoding()) {
-                ImGui::EndDisabled();
+            {
+                auto guard = imgui_disable_guard{is_encoding()};
+                if (ImGui::RadioButton("NvEnc", chosen_encoder == ENCODER_NVENC)) {
+                    simple_eq.emplace([] {
+                        chosen_encoder = ENCODER_NVENC;
+                        if (chosen_sender == SENDER_UDP) { // NvEnc cannot be used with UDP
+                            chosen_sender = SENDER_TCP;
+                        }
+                    });
+                }
+                ImGui::SameLine();
+                if (ImGui::RadioButton("nvJPEG", chosen_encoder == ENCODER_JPEG)) {
+                    simple_eq.emplace([] { chosen_encoder = ENCODER_JPEG; });
+                }
             }
 
             ImGui::SeparatorText("Actions");
@@ -902,18 +924,15 @@ void prepare_imgui_frame() {
                     RET_ERROR;
                 }
             }
-            if (is_encoding()) {
-                ImGui::BeginDisabled();
-            }
-            ImGui::Checkbox("Full Resolution", &output_full_frame);
-            ImGui::SameLine();
-            ImGui::Checkbox("Save Video", &encoder_save_file);
-            if (encoder_save_file) {
+            {
+                auto guard = imgui_disable_guard{is_encoding()};
+                ImGui::Checkbox("Full Resolution", &output_full_frame);
                 ImGui::SameLine();
-                ImGui::Checkbox("Save Frame Length", &encoder_save_length);
-            }
-            if (is_encoding()) {
-                ImGui::EndDisabled();
+                ImGui::Checkbox("Save Video", &encoder_save_file);
+                if (encoder_save_file) {
+                    ImGui::SameLine();
+                    ImGui::Checkbox("Save Frame Length", &encoder_save_length);
+                }
             }
 
             ImGui::PopID();
@@ -923,6 +942,24 @@ void prepare_imgui_frame() {
         if (ImGui::CollapsingHeader("Frame Sender")) {
             ImGui::PushID("Sender");
 
+            ImGui::SeparatorText("Method");
+            {
+                auto guard = imgui_disable_guard{is_sending()};
+                if (ImGui::RadioButton("TCP", chosen_sender == SENDER_TCP)) {
+                    simple_eq.emplace([] { chosen_sender = SENDER_TCP; });
+                }
+                if (chosen_encoder != ENCODER_NVENC) {
+                    ImGui::SameLine();
+                    if (ImGui::RadioButton("UDP", chosen_sender == SENDER_UDP)) {
+                        simple_eq.emplace([] { chosen_sender = SENDER_UDP; });
+                    }
+                }
+                ImGui::SameLine();
+                if (ImGui::RadioButton("UDP (FEC)", chosen_sender == SENDER_UDP_FEC)) {
+                    simple_eq.emplace([] { chosen_sender = SENDER_UDP_FEC; });
+                }
+            }
+
             ImGui::SeparatorText("Actions");
             if (!is_sending()) {
                 if (ImGui::Button("Start")) {
@@ -935,13 +972,12 @@ void prepare_imgui_frame() {
             }
 
             ImGui::SeparatorText("Configs");
-            if (is_sending()) {
-                ImGui::BeginDisabled();
-            }
-            ImGui::InputInt("Listen Port", &sender_listen_port);
-            ImGui::DragFloat("Parity Rate", &sender_parity_rate, 0.01, 0, 2, "%.02f");
-            if (is_sending()) {
-                ImGui::EndDisabled();
+            {
+                auto guard = imgui_disable_guard{is_sending()};
+                ImGui::InputInt("Listen Port", &sender_listen_port);
+                if (chosen_sender == SENDER_UDP_FEC) {
+                    ImGui::DragFloat("Parity Rate", &sender_parity_rate, 0.01, 0, 2, "%.02f");
+                }
             }
 
             ImGui::PopID();

+ 0 - 14
src/simple_opengl.cpp

@@ -148,7 +148,6 @@ struct simple_render::impl {
     void create_program() {
         auto simple_vert_shader = glCreateShader(GL_VERTEX_SHADER);
         auto simple_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
-        auto remap_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
         compile_shader(simple_vert_shader, simple_vert_shader_source, "simple_vertex");
         compile_shader(simple_frag_shader, simple_frag_shader_source, "simple_fragment");
 
@@ -160,7 +159,6 @@ struct simple_render::impl {
 
         glDeleteShader(simple_vert_shader);
         glDeleteShader(simple_frag_shader);
-        glDeleteShader(remap_frag_shader);
 
         // create buffers
         glGenBuffers(1, &vbo);
@@ -390,15 +388,3 @@ void smart_texture::create(GLenum format, cv::Size size, GLint min_filter, GLint
 cv::Size smart_texture::size() const {
     return pimpl->last_size;
 }
-
-void upload_remap_data(smart_texture *tex, const cv::Mat &data) {
-    // allocate texture
-    assert(data.type() == CV_32FC2);
-    tex->create(GL_RG32F, data.size());
-
-    // copy data to texture
-    glBindTexture(GL_TEXTURE_2D, tex->id);
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
-                    data.cols, data.rows, GL_RG, GL_FLOAT, data.data);
-    glBindTexture(GL_TEXTURE_2D, 0);
-}

+ 0 - 2
src/simple_opengl.h

@@ -32,8 +32,6 @@ private:
     std::unique_ptr<impl> pimpl;
 };
 
-void upload_remap_data(smart_texture *tex, const cv::Mat &data);
-
 class simple_render {
 public:
     simple_render();