From 46b707f246f4390afadf75db1eef38bcab4da991 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Thu, 24 Mar 2022 00:23:27 +0100 Subject: [PATCH] Unified & fixed implementation of Group of sources (formerly flatten) Fixed MixingGroup keep&restore when making Session Group Sources. New global feature to Group all sources into one session source. Unused but potentially useful implementation of flatten of mixer session into one new session source. --- ImGuiVisitor.cpp | 2 +- LayerView.cpp | 6 +- MediaPlayer.cpp | 7 +- Mixer.cpp | 202 ++++++++++++++++++++++++++++----------- Mixer.h | 6 +- Session.cpp | 3 + UserInterfaceManager.cpp | 24 +++-- 7 files changed, 176 insertions(+), 74 deletions(-) diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index 62e30e5..2160914 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -675,7 +675,7 @@ void ImGuiVisitor::visit (SessionGroupSource& s) ImGuiToolkit::Icon(s.icon().x, s.icon().y); ImGui::SameLine(0, IMGUI_SAME_LINE); - ImGui::Text("Flat Sesion group"); + ImGui::Text("Session group"); // info ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); diff --git a/LayerView.cpp b/LayerView.cpp index 45cfb79..3c0fd68 100644 --- a/LayerView.cpp +++ b/LayerView.cpp @@ -120,12 +120,12 @@ void LayerView::draw() // special action of Mixing view if (candidate_flatten_group){ - if (ImGui::Selectable( ICON_FA_DOWNLOAD " Flatten" )) { - Mixer::manager().flattenSelection(); + if (ImGui::Selectable( ICON_FA_SIGN_IN_ALT " Group" )) { + Mixer::manager().groupSelection(); } } else { - ImGui::TextDisabled( ICON_FA_DOWNLOAD " Flatten" ); + ImGui::TextDisabled( ICON_FA_SIGN_IN_ALT " Group" ); } ImGui::Separator(); diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index 02dec26..9f1a398 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -36,6 +36,8 @@ #define MEDIA_PLAYER_DEBUG #endif +#define DISCOVER_TIMOUT 15 + std::list MediaPlayer::registered_; MediaPlayer::MediaPlayer() @@ -123,7 +125,7 @@ MediaInfo MediaPlayer::UriDiscoverer(const std::string &uri) #endif MediaInfo video_stream_info; GError *err = NULL; - GstDiscoverer *discoverer = gst_discoverer_new (15 * GST_SECOND, &err); + GstDiscoverer *discoverer = gst_discoverer_new (DISCOVER_TIMOUT * GST_SECOND, &err); /* Instantiate the Discoverer */ if (!discoverer) { @@ -448,7 +450,8 @@ void MediaPlayer::close() if (!opened_) { // wait for loading to finish if (discoverer_.valid()) - discoverer_.wait(); + if ( discoverer_.wait_for(std::chrono::seconds(DISCOVER_TIMOUT)) == std::future_status::timeout ) + failed_ = true; // nothing else to change return; } diff --git a/Mixer.cpp b/Mixer.cpp index 64def71..d837e29 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -661,74 +661,157 @@ void Mixer::deleteSelection() } } -void Mixer::flattenSelection() +void Mixer::groupSelection() { + // obvious cancel if (selection().empty()) return; + // work on non-empty selection of sources + auto _selection = selection().getCopy(); + + // create session group where to transfer sources into SessionGroupSource *sessiongroup = new SessionGroupSource; sessiongroup->setResolution( session_->frame()->resolution() ); - // prepare for new session group attributes + // prepare for new session group name std::string name; - float d = selection().front()->depth(); - - // empty the selection - while ( !selection().empty() ) { - - Source *s = selection().front(); - d = MIN(s->depth(), d); - - // import source into group - if ( sessiongroup->import(s) ) { - name += s->initials(); - // detach & remove element from selection() - detach (s); - // remove source from session - session_->removeSource(s); - } - else - selection().pop_front(); + // prepare for depth to place the group source + float d = _selection.front()->depth(); + // remember groups before emptying the session + std::list allgroups = session_->getMixingGroups(); + std::list selectgroups; + for (auto git = allgroups.begin(); git != allgroups.end(); ++git){ + selectgroups.push_back( intersect( *git, _selection)); } - // set depth at given location - sessiongroup->group(View::LAYER)->translation_.z = d; + // browse the selection + for (auto sit = _selection.begin(); sit != _selection.end(); ++sit) { - // set alpha to full opacity - sessiongroup->group(View::MIXING)->translation_.x = 0.f; - sessiongroup->group(View::MIXING)->translation_.y = 0.f; + // import source into group + if ( sessiongroup->import(*sit) ) { + // find lower depth in _selection + d = MIN( (*sit)->depth(), d); + // generate name from intials of all sources + name += (*sit)->initials(); + // detach & remove element from selection() + detach (*sit); + // remove source from session + session_->removeSource(*sit); + } + } - // Add source to Session - session_->addSource(sessiongroup); + if (sessiongroup->session()->numSource() > 0) { + // recreate groups in session group + for (auto git = selectgroups.begin(); git != selectgroups.end(); ++git) + sessiongroup->session()->link( *git ); - // Attach source to Mixer - attach(sessiongroup); + // set depth at given location + sessiongroup->group(View::LAYER)->translation_.z = d; - // rename and avoid name duplicates - renameSource(sessiongroup, name); + // set alpha to full opacity + sessiongroup->group(View::MIXING)->translation_.x = 0.f; + sessiongroup->group(View::MIXING)->translation_.y = 0.f; - // store in action manager - std::ostringstream info; - info << sessiongroup->name() << " inserted: " << sessiongroup->session()->numSource() << " sources flatten."; - Action::manager().store(info.str()); + // Add source to Session + session_->addSource(sessiongroup); - Log::Notify("Added source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); + // Attach source to Mixer + attach(sessiongroup); - // give the hand to the user - Mixer::manager().setCurrentSource(sessiongroup); + // set name (avoid name duplicates) + renameSource(sessiongroup, name); + + // store in action manager + std::ostringstream info; + info << sessiongroup->name() << " inserted: " << sessiongroup->session()->numSource() << " sources flatten."; + Action::manager().store(info.str()); + + Log::Notify("Added group source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); + + // give the hand to the user + Mixer::manager().setCurrentSource(sessiongroup); + } + else { + delete sessiongroup; + Log::Info("Failed to group selection"); + } } -void Mixer::flatten() +void Mixer::groupAll() { - // + // obvious cancel + if (session_->empty()) + return; + + // create session group where to transfer sources into + SessionGroupSource *sessiongroup = new SessionGroupSource; + sessiongroup->setResolution( session_->frame()->resolution() ); + + // remember groups before emptying the session + std::list allgroups = session_->getMixingGroups(); + + // empty the session (does not delete sources) + for ( Source *s = session_->popSource(); s != nullptr; s = session_->popSource()) { + if ( sessiongroup->import(s) ) + detach(s); + else + break; + } + + if (sessiongroup->session()->numSource() > 0) { + + // recreate groups in session group + for (auto git = allgroups.begin(); git != allgroups.end(); ++git) + sessiongroup->session()->link( *git ); + + // set default depth in workspace for the session-group source + sessiongroup->group(View::LAYER)->translation_.z = LAYER_BACKGROUND + LAYER_STEP; + + // set alpha to full opacity so that rendering is identical after swap + sessiongroup->group(View::MIXING)->translation_.x = 0.f; + sessiongroup->group(View::MIXING)->translation_.y = 0.f; + + // Add the session-group source to Session + session_->addSource(sessiongroup); + + // Attach the session-group source to Mixer + attach(sessiongroup); + + // name the session-group source (avoid name duplicates) + renameSource(sessiongroup, SystemToolkit::base_filename(session_->filename())); + + // store in action manager + std::ostringstream info; + info << sessiongroup->name() << " inserted: " << sessiongroup->session()->numSource() << " sources flatten."; + Action::manager().store(info.str()); + + Log::Notify("Added group source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); + + // give the hand to the user + Mixer::manager().setCurrentSource(sessiongroup); + } + else { + delete sessiongroup; + Log::Info("Failed to group all sources."); + } + +} + +void Mixer::flattenSession() +{ + // new session group containing current session SessionGroupSource *sessiongroup = new SessionGroupSource; sessiongroup->setSession(session_); - // set alpha to full opacity + // set alpha to full opacity so that rendering is identical after swap sessiongroup->group(View::MIXING)->translation_.x = 0.f; sessiongroup->group(View::MIXING)->translation_.y = 0.f; + // set default depth in workspace + sessiongroup->group(View::LAYER)->translation_.z = LAYER_BACKGROUND + LAYER_STEP; + // propose a name to the session group sessiongroup->setName( SystemToolkit::base_filename(session_->filename())); @@ -736,19 +819,24 @@ void Mixer::flatten() Session *futuresession = new Session; futuresession->addSource( sessiongroup ); - // set and swap to futuresession + // set identical filename to future session + futuresession->setFilename( session_->filename() ); + + // set and swap to futuresession (will be done at next update) set(futuresession); - // detatch current session's nodes from views + // detatch current session_'s nodes from views for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++) detach(*source_iter); - // detatch session's mixing group + + // detatch session_'s mixing group for (auto group_iter = session_->beginMixingGroup(); group_iter != session_->endMixingGroup(); group_iter++) (*group_iter)->attachTo(nullptr); + // prevent deletion of session_ (now embedded into session group) session_ = new Session; - Log::Notify("Created source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); + Log::Notify("Created group source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); } void Mixer::renameSource(Source *s, const std::string &newname) @@ -1135,6 +1223,9 @@ void Mixer::merge(Session *session) return; } + // remember groups before emptying the session + std::list allgroups = session->getMixingGroups(); + // import every sources std::ostringstream info; info << session->numSource() << " sources imported from:" << session->filename(); @@ -1149,12 +1240,9 @@ void Mixer::merge(Session *session) attach(s); } - // import and attach session's mixing groups - auto group_iter = session->beginMixingGroup(); - while ( group_iter != session->endMixingGroup() ){ - session_->link((*group_iter)->getCopy(), mixing_.scene.fg()); - group_iter = session->deleteMixingGroup(group_iter); - } + // recreate groups in current session_ + for (auto git = allgroups.begin(); git != allgroups.end(); ++git) + session_->link( *git, mixing_.scene.fg() ); // needs to update ! ++View::need_deep_update_; @@ -1206,6 +1294,9 @@ void Mixer::merge(SessionSource *source) } } + // remember groups before emptying the session + std::list allgroups = session->getMixingGroups(); + // import every sources for ( Source *s = session->popSource(); s != nullptr; s = session->popSource()) { @@ -1236,12 +1327,9 @@ void Mixer::merge(SessionSource *source) attach(s); } - // import and attach session's mixing groups - auto group_iter = session->beginMixingGroup(); - while ( group_iter != session->endMixingGroup() ){ - session_->link((*group_iter)->getCopy(), mixing_.scene.fg()); - group_iter = session->deleteMixingGroup(group_iter); - } + // recreate groups in current session_ + for (auto git = allgroups.begin(); git != allgroups.end(); ++git) + session_->link( *git, mixing_.scene.fg() ); // needs to update ! ++View::need_deep_update_; diff --git a/Mixer.h b/Mixer.h index a0ea8f7..f8e31b3 100644 --- a/Mixer.h +++ b/Mixer.h @@ -66,7 +66,10 @@ public: // operations on selection void deleteSelection (); - void flattenSelection (); + void groupSelection (); + void groupAll (); + + void flattenSession(); // current source Source *currentSource (); @@ -113,7 +116,6 @@ public: void setResolution(glm::vec3 res); bool busy () const { return busy_; } - void flatten(); // operations depending on transition mode void close (bool smooth = false); diff --git a/Session.cpp b/Session.cpp index baf2952..22ab417 100644 --- a/Session.cpp +++ b/Session.cpp @@ -330,6 +330,9 @@ Source *Session::popSource() s = *its; // remove Node from the rendering scene render_.scene.ws()->detach( s->group(View::RENDERING) ); + // inform group + if (s->mixingGroup() != nullptr) + s->mixingGroup()->detach(s); // erase the source from the update list & get next element sources_.erase(its); } diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 36ac233..e3a109f 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -934,10 +934,6 @@ void UserInterface::showMenuFile() ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); ImGui::Combo("Height", &Settings::application.render.res, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) ); - if (ImGui::MenuItem( ICON_FA_FILE_IMPORT " Embed in New file", nullptr, false, Mixer::manager().numSource() > 0)) { - Mixer::manager().flatten(); - } - // FILE OPEN AND SAVE ImGui::Separator(); const std::string currentfilename = Mixer::manager().session()->filename(); @@ -949,11 +945,6 @@ void UserInterface::showMenuFile() selectOpenFilename(); if (ImGui::MenuItem( MENU_REOPEN_FILE, SHORTCUT_REOPEN_FILE, false, currentfileopen)) Mixer::manager().load( currentfilename ); - if (sessionimportdialog && ImGui::MenuItem( ICON_FA_FILE_EXPORT " Import sources" )) { - // launch file dialog to open a session file - sessionimportdialog->open(); - navigator.hidePannel(); - } if (ImGui::MenuItem( MENU_SAVE_FILE, SHORTCUT_SAVE_FILE, false, currentfileopen)) { if (saveOrSaveAs()) navigator.hidePannel(); @@ -963,6 +954,21 @@ void UserInterface::showMenuFile() ImGui::MenuItem( MENU_SAVE_ON_EXIT, nullptr, &Settings::application.recentSessions.save_on_exit); + // IMPORT AND GROUP + ImGui::Separator(); + if (sessionimportdialog && ImGui::MenuItem( ICON_FA_SIGN_OUT_ALT " Import sources" )) { + // launch file dialog to open a session file + sessionimportdialog->open(); + // close pannel to select file + navigator.hidePannel(); + } + if (ImGui::MenuItem( ICON_FA_SIGN_IN_ALT " Group all sources", nullptr, false, Mixer::manager().numSource() > 0)) { + // create a new group session with all sources + Mixer::manager().groupAll(); + // switch pannel to show first source (created) + navigator.showPannelSource(0); + } + // HELP AND QUIT ImGui::Separator(); if (ImGui::MenuItem( IMGUI_TITLE_HELP, SHORTCUT_HELP))