From 6b7f4477b0473bd5508ca02f6d3d8c775af3af21 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sun, 9 Nov 2025 22:47:17 +0100 Subject: [PATCH] Refactor Broadcast manager methods to use FrameGrabber type instead of ID, forcing the use of singletons. Update OutputPreviewWindow to reflect these changes and remove unused variables. --- src/ControlManager.cpp | 2 +- src/FrameGrabber.cpp | 38 +++++++---------------- src/FrameGrabber.h | 11 +++---- src/OutputPreviewWindow.cpp | 61 +++++++++++++++++++------------------ src/OutputPreviewWindow.h | 3 -- 5 files changed, 48 insertions(+), 67 deletions(-) diff --git a/src/ControlManager.cpp b/src/ControlManager.cpp index 506032c..d6195a9 100644 --- a/src/ControlManager.cpp +++ b/src/ControlManager.cpp @@ -611,7 +611,7 @@ bool Control::receiveOutputAttribute(const std::string &attribute, // if argument is given, it is the connection port if (!arguments.Eos()) arguments >> f >> osc::EndMessage; - Broadcast::manager().start( new VideoBroadcast((int) f), true); + Broadcast::manager().start( new VideoBroadcast((int) f)); } else if ( attribute.compare(OSC_OUTPUT_SRT_STOP) == 0) { Broadcast::manager().stop(FrameGrabber::GRABBER_BROADCAST); diff --git a/src/FrameGrabber.cpp b/src/FrameGrabber.cpp index 083a594..02e901b 100644 --- a/src/FrameGrabber.cpp +++ b/src/FrameGrabber.cpp @@ -659,54 +659,38 @@ guint64 FrameGrabber::frames() const } -uint64_t Broadcast::start(FrameGrabber *ptr, bool singleton) +void Broadcast::start(FrameGrabber *ptr) { - if (singleton) - stop( ptr->type() ); - - uint64_t b = ptr->id(); + stop( ptr->type() ); FrameGrabbing::manager().add(ptr); - return b; } -bool Broadcast::enabled(uint64_t b) +bool Broadcast::busy(FrameGrabber::Type T) { - return ( FrameGrabbing::manager().get(b) != nullptr); -} - -bool Broadcast::busy(uint64_t b) -{ - FrameGrabber *ptr = FrameGrabbing::manager().get(b); + FrameGrabber *ptr = FrameGrabbing::manager().get( T ); if (ptr != nullptr) return ptr->busy(); return false; } -std::string Broadcast::info(uint64_t b, bool extended) +std::string Broadcast::info(FrameGrabber::Type T, bool extended) { - FrameGrabber *ptr = FrameGrabbing::manager().get(b); + FrameGrabber *ptr = FrameGrabbing::manager().get( T ); if (ptr != nullptr) return ptr->info(extended); return "Disabled"; } -void Broadcast::stop(uint64_t b) +bool Broadcast::enabled(FrameGrabber::Type T) { - FrameGrabber *ptr = FrameGrabbing::manager().get(b); - if (ptr != nullptr) - ptr->stop(); - + return ( FrameGrabbing::manager().get( T ) != nullptr); } void Broadcast::stop(FrameGrabber::Type T) { - FrameGrabber *prev = nullptr; - do { - prev = FrameGrabbing::manager().get( T ); - if (prev != nullptr) - prev->stop(); - } - while (prev != nullptr); + FrameGrabber *prev = FrameGrabbing::manager().get( T ); + if (prev != nullptr) + prev->stop(); } diff --git a/src/FrameGrabber.h b/src/FrameGrabber.h index ec2a2fa..2954230 100644 --- a/src/FrameGrabber.h +++ b/src/FrameGrabber.h @@ -173,7 +173,7 @@ private: * * FrameGrabbers can terminate (normal behavior or failure) and the FrameGrabber * is deleted automatically; pointer is then invalid and cannot be accessed. To avoid this, - * the Broadcast::manager() gives access to FrameGrabbers by id. + * the Broadcast::manager() gives access to FrameGrabbers by type (single instance). * * Singleton mechanism also allows starting a unique instance of each FrameGrabber::Type */ @@ -193,11 +193,10 @@ public: return _instance; } - uint64_t start(FrameGrabber *ptr, bool singleton = false); - bool enabled(uint64_t); - bool busy(uint64_t); - std::string info(uint64_t, bool extended = false); - void stop(uint64_t); + void start(FrameGrabber *ptr); + bool enabled(FrameGrabber::Type); + bool busy(FrameGrabber::Type); + std::string info(FrameGrabber::Type, bool extended = false); void stop(FrameGrabber::Type); }; diff --git a/src/OutputPreviewWindow.cpp b/src/OutputPreviewWindow.cpp index 7c662b0..0ab820c 100644 --- a/src/OutputPreviewWindow.cpp +++ b/src/OutputPreviewWindow.cpp @@ -41,7 +41,7 @@ OutputPreviewWindow::OutputPreviewWindow() : WorkspaceWindow("OutputPreview"), - video_recorder_(nullptr), srt_(0), shm_(0), loopback_(0), + video_recorder_(nullptr), magnifying_glass(false) { @@ -135,19 +135,19 @@ void OutputPreviewWindow::ToggleRecordPause() void OutputPreviewWindow::ToggleVideoBroadcast() { - if (Broadcast::manager().enabled(srt_) ) - Broadcast::manager().stop(srt_); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_BROADCAST ) ) + Broadcast::manager().stop( FrameGrabber::GRABBER_BROADCAST ); else { if (Settings::application.broadcast_port<1000) Settings::application.broadcast_port = BROADCAST_DEFAULT_PORT; - srt_ = Broadcast::manager().start( new VideoBroadcast(Settings::application.broadcast_port), true); + Broadcast::manager().start( new VideoBroadcast(Settings::application.broadcast_port)); } } void OutputPreviewWindow::ToggleSharedMemory() { - if (Broadcast::manager().enabled(shm_) ) - Broadcast::manager().stop(shm_); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_SHM ) ) + Broadcast::manager().stop( FrameGrabber::GRABBER_SHM ); else { // find a folder to put the socket for shm std::string _shm_socket_file = Settings::application.shm_socket_path; @@ -156,22 +156,22 @@ void OutputPreviewWindow::ToggleSharedMemory() _shm_socket_file = SystemToolkit::full_filename(_shm_socket_file, ".shm_vimix" + std::to_string(Settings::application.instance_id)); // create shhmdata broadcaster with method - shm_ = Broadcast::manager().start( new ShmdataBroadcast( (ShmdataBroadcast::Method) Settings::application.shm_method, _shm_socket_file), true); + Broadcast::manager().start( new ShmdataBroadcast( (ShmdataBroadcast::Method) Settings::application.shm_method, _shm_socket_file)); } } bool OutputPreviewWindow::ToggleLoopbackCamera() { bool need_initialization = false; - if (Broadcast::manager().enabled(loopback_)) - Broadcast::manager().stop(loopback_); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_LOOPBACK )) + Broadcast::manager().stop( FrameGrabber::GRABBER_LOOPBACK ); else { if (Settings::application.loopback_camera < 1) Settings::application.loopback_camera = LOOPBACK_DEFAULT_DEVICE; Settings::application.loopback_camera += Settings::application.instance_id; try { - loopback_ = Broadcast::manager().start( new Loopback(Settings::application.loopback_camera), true ); + Broadcast::manager().start( new Loopback(Settings::application.loopback_camera) ); } catch (const std::runtime_error &e) { need_initialization = true; @@ -389,27 +389,28 @@ void OutputPreviewWindow::Render() // Broadcasting menu ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.9f)); if (VideoBroadcast::available()) { - if ( ImGui::MenuItem( ICON_FA_GLOBE " SRT Broadcast", NULL, Broadcast::manager().enabled(srt_) ) ) + if ( ImGui::MenuItem( ICON_FA_GLOBE " SRT Broadcast", NULL, Broadcast::manager().enabled( FrameGrabber::GRABBER_BROADCAST ) ) ) ToggleVideoBroadcast(); } // Shared Memory menu if (ShmdataBroadcast::available()) { - if ( ImGui::MenuItem( ICON_FA_MEMORY " SHM Shared Memory", NULL, Broadcast::manager().enabled(shm_) ) ) + if ( ImGui::MenuItem( ICON_FA_MEMORY " SHM Shared Memory", NULL, Broadcast::manager().enabled( FrameGrabber::GRABBER_SHM ) ) ) ToggleSharedMemory(); } // Loopback camera menu if (Loopback::available()) { - if ( ImGui::MenuItem( ICON_FA_VIDEO " Loopback Camera", NULL, Broadcast::manager().enabled(loopback_)) ) + if ( ImGui::MenuItem( ICON_FA_VIDEO " Loopback Camera", NULL, Broadcast::manager().enabled( FrameGrabber::GRABBER_LOOPBACK )) ) openInitializeSystemLoopback = ToggleLoopbackCamera(); } ImGui::PopStyleColor(1); // Display list of active stream - if (ls.size()>0 || Broadcast::manager().enabled(srt_) || - Broadcast::manager().enabled(shm_) || Broadcast::manager().enabled(loopback_)) { + if (ls.size()>0 || Broadcast::manager().enabled( FrameGrabber::GRABBER_BROADCAST ) || + Broadcast::manager().enabled( FrameGrabber::GRABBER_SHM ) || + Broadcast::manager().enabled( FrameGrabber::GRABBER_LOOPBACK )) { ImGui::Separator(); ImGui::MenuItem("Active streams:", nullptr, false, false); @@ -418,36 +419,36 @@ void OutputPreviewWindow::Render() ImGui::Text(" %s ", (*it).c_str() ); // SRT broadcast description - if (Broadcast::manager().enabled(srt_)) { - ImGui::Text(" %s ", Broadcast::manager().info(srt_).c_str()); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_BROADCAST )) { + ImGui::Text(" %s ", Broadcast::manager().info( FrameGrabber::GRABBER_BROADCAST ).c_str()); // copy text icon to give user the srt link to connect to ImVec2 draw_pos = ImGui::GetCursorPos(); ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) ); - std::string moreinfo = Broadcast::manager().info(srt_, true); + std::string moreinfo = Broadcast::manager().info( FrameGrabber::GRABBER_BROADCAST , true); if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str())) ImGui::SetClipboardText(moreinfo.c_str()); ImGui::SetCursorPos(draw_pos); } // Shared memory broadcast description - if (Broadcast::manager().enabled(shm_)) { - ImGui::Text(" %s ", Broadcast::manager().info(shm_).c_str()); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_SHM )) { + ImGui::Text(" %s ", Broadcast::manager().info( FrameGrabber::GRABBER_SHM ).c_str()); // copy text icon to give user the socket path to connect to ImVec2 draw_pos = ImGui::GetCursorPos(); ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) ); - std::string moreinfo = Broadcast::manager().info(shm_, true); + std::string moreinfo = Broadcast::manager().info( FrameGrabber::GRABBER_SHM , true); if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str())) ImGui::SetClipboardText(moreinfo.c_str()); ImGui::SetCursorPos(draw_pos); } // Loopback camera description - if (Broadcast::manager().enabled(loopback_)) { - ImGui::Text(" %s ", Broadcast::manager().info(loopback_).c_str()); + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_LOOPBACK )) { + ImGui::Text(" %s ", Broadcast::manager().info( FrameGrabber::GRABBER_LOOPBACK ).c_str()); // copy text icon to give user the device path to connect to ImVec2 draw_pos = ImGui::GetCursorPos(); ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) ); - std::string moreinfo = Broadcast::manager().info(loopback_, true); + std::string moreinfo = Broadcast::manager().info( FrameGrabber::GRABBER_LOOPBACK , true); if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str())) ImGui::SetClipboardText(moreinfo.c_str()); ImGui::SetCursorPos(draw_pos); @@ -549,10 +550,10 @@ void OutputPreviewWindow::Render() } // broadcast indicator float vertical = r; - if (Broadcast::manager().enabled(srt_)) + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_BROADCAST )) { ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical)); - if (Broadcast::manager().busy(srt_)) + if (Broadcast::manager().busy( FrameGrabber::GRABBER_BROADCAST )) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f)); else ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f)); @@ -561,10 +562,10 @@ void OutputPreviewWindow::Render() vertical += 2.f * r; } // shmdata indicator - if (Broadcast::manager().enabled(shm_)) + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_SHM )) { ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical)); - if (Broadcast::manager().busy(shm_)) + if (Broadcast::manager().busy( FrameGrabber::GRABBER_SHM )) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f)); else ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f)); @@ -573,10 +574,10 @@ void OutputPreviewWindow::Render() vertical += 2.f * r; } // loopback camera indicator - if (Broadcast::manager().enabled(loopback_)) + if (Broadcast::manager().enabled( FrameGrabber::GRABBER_LOOPBACK )) { ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical)); - if (Broadcast::manager().busy(loopback_)) + if (Broadcast::manager().busy( FrameGrabber::GRABBER_LOOPBACK )) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f)); else ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f)); diff --git a/src/OutputPreviewWindow.h b/src/OutputPreviewWindow.h index 75b15bb..41a4448 100644 --- a/src/OutputPreviewWindow.h +++ b/src/OutputPreviewWindow.h @@ -12,9 +12,6 @@ class OutputPreviewWindow : public WorkspaceWindow { // frame grabbers VideoRecorder *video_recorder_; - uint64_t srt_; - uint64_t shm_; - uint64_t loopback_; // delayed trigger for recording std::vector< std::future > _video_recorders;