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.

This commit is contained in:
brunoherbelin
2025-11-09 22:47:17 +01:00
parent ec9a4ef88a
commit 6b7f4477b0
5 changed files with 48 additions and 67 deletions

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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));

View File

@@ -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<VideoRecorder *> > _video_recorders;