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.
This commit is contained in:
Bruno Herbelin
2022-03-24 00:23:27 +01:00
parent e5926a5371
commit 46b707f246
7 changed files with 176 additions and 74 deletions

View File

@@ -675,7 +675,7 @@ void ImGuiVisitor::visit (SessionGroupSource& s)
ImGuiToolkit::Icon(s.icon().x, s.icon().y); ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, IMGUI_SAME_LINE); ImGui::SameLine(0, IMGUI_SAME_LINE);
ImGui::Text("Flat Sesion group"); ImGui::Text("Session group");
// info // info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);

View File

@@ -120,12 +120,12 @@ void LayerView::draw()
// special action of Mixing view // special action of Mixing view
if (candidate_flatten_group){ if (candidate_flatten_group){
if (ImGui::Selectable( ICON_FA_DOWNLOAD " Flatten" )) { if (ImGui::Selectable( ICON_FA_SIGN_IN_ALT " Group" )) {
Mixer::manager().flattenSelection(); Mixer::manager().groupSelection();
} }
} }
else { else {
ImGui::TextDisabled( ICON_FA_DOWNLOAD " Flatten" ); ImGui::TextDisabled( ICON_FA_SIGN_IN_ALT " Group" );
} }
ImGui::Separator(); ImGui::Separator();

View File

@@ -36,6 +36,8 @@
#define MEDIA_PLAYER_DEBUG #define MEDIA_PLAYER_DEBUG
#endif #endif
#define DISCOVER_TIMOUT 15
std::list<MediaPlayer*> MediaPlayer::registered_; std::list<MediaPlayer*> MediaPlayer::registered_;
MediaPlayer::MediaPlayer() MediaPlayer::MediaPlayer()
@@ -123,7 +125,7 @@ MediaInfo MediaPlayer::UriDiscoverer(const std::string &uri)
#endif #endif
MediaInfo video_stream_info; MediaInfo video_stream_info;
GError *err = NULL; 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 */ /* Instantiate the Discoverer */
if (!discoverer) { if (!discoverer) {
@@ -448,7 +450,8 @@ void MediaPlayer::close()
if (!opened_) { if (!opened_) {
// wait for loading to finish // wait for loading to finish
if (discoverer_.valid()) if (discoverer_.valid())
discoverer_.wait(); if ( discoverer_.wait_for(std::chrono::seconds(DISCOVER_TIMOUT)) == std::future_status::timeout )
failed_ = true;
// nothing else to change // nothing else to change
return; return;
} }

158
Mixer.cpp
View File

@@ -661,36 +661,51 @@ void Mixer::deleteSelection()
} }
} }
void Mixer::flattenSelection() void Mixer::groupSelection()
{ {
// obvious cancel
if (selection().empty()) if (selection().empty())
return; return;
// work on non-empty selection of sources
auto _selection = selection().getCopy();
// create session group where to transfer sources into
SessionGroupSource *sessiongroup = new SessionGroupSource; SessionGroupSource *sessiongroup = new SessionGroupSource;
sessiongroup->setResolution( session_->frame()->resolution() ); sessiongroup->setResolution( session_->frame()->resolution() );
// prepare for new session group attributes // prepare for new session group name
std::string name; std::string name;
float d = selection().front()->depth(); // prepare for depth to place the group source
float d = _selection.front()->depth();
// empty the selection // remember groups before emptying the session
while ( !selection().empty() ) { std::list<SourceList> allgroups = session_->getMixingGroups();
std::list<SourceList> selectgroups;
for (auto git = allgroups.begin(); git != allgroups.end(); ++git){
selectgroups.push_back( intersect( *git, _selection));
}
Source *s = selection().front(); // browse the selection
d = MIN(s->depth(), d); for (auto sit = _selection.begin(); sit != _selection.end(); ++sit) {
// import source into group // import source into group
if ( sessiongroup->import(s) ) { if ( sessiongroup->import(*sit) ) {
name += s->initials(); // 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 & remove element from selection()
detach (s); detach (*sit);
// remove source from session // remove source from session
session_->removeSource(s); session_->removeSource(*sit);
}
} }
else
selection().pop_front();
} if (sessiongroup->session()->numSource() > 0) {
// recreate groups in session group
for (auto git = selectgroups.begin(); git != selectgroups.end(); ++git)
sessiongroup->session()->link( *git );
// set depth at given location // set depth at given location
sessiongroup->group(View::LAYER)->translation_.z = d; sessiongroup->group(View::LAYER)->translation_.z = d;
@@ -705,7 +720,7 @@ void Mixer::flattenSelection()
// Attach source to Mixer // Attach source to Mixer
attach(sessiongroup); attach(sessiongroup);
// rename and avoid name duplicates // set name (avoid name duplicates)
renameSource(sessiongroup, name); renameSource(sessiongroup, name);
// store in action manager // store in action manager
@@ -713,22 +728,90 @@ void Mixer::flattenSelection()
info << sessiongroup->name() << " inserted: " << sessiongroup->session()->numSource() << " sources flatten."; info << sessiongroup->name() << " inserted: " << sessiongroup->session()->numSource() << " sources flatten.";
Action::manager().store(info.str()); Action::manager().store(info.str());
Log::Notify("Added source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str()); Log::Notify("Added group source '%s' with %s", sessiongroup->name().c_str(), sessiongroup->info().c_str());
// give the hand to the user // give the hand to the user
Mixer::manager().setCurrentSource(sessiongroup); 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<SourceList> 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; SessionGroupSource *sessiongroup = new SessionGroupSource;
sessiongroup->setSession(session_); 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_.x = 0.f;
sessiongroup->group(View::MIXING)->translation_.y = 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 // propose a name to the session group
sessiongroup->setName( SystemToolkit::base_filename(session_->filename())); sessiongroup->setName( SystemToolkit::base_filename(session_->filename()));
@@ -736,19 +819,24 @@ void Mixer::flatten()
Session *futuresession = new Session; Session *futuresession = new Session;
futuresession->addSource( sessiongroup ); 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); 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++) for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++)
detach(*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++) for (auto group_iter = session_->beginMixingGroup(); group_iter != session_->endMixingGroup(); group_iter++)
(*group_iter)->attachTo(nullptr); (*group_iter)->attachTo(nullptr);
// prevent deletion of session_ (now embedded into session group) // prevent deletion of session_ (now embedded into session group)
session_ = new Session; 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) void Mixer::renameSource(Source *s, const std::string &newname)
@@ -1135,6 +1223,9 @@ void Mixer::merge(Session *session)
return; return;
} }
// remember groups before emptying the session
std::list<SourceList> allgroups = session->getMixingGroups();
// import every sources // import every sources
std::ostringstream info; std::ostringstream info;
info << session->numSource() << " sources imported from:" << session->filename(); info << session->numSource() << " sources imported from:" << session->filename();
@@ -1149,12 +1240,9 @@ void Mixer::merge(Session *session)
attach(s); attach(s);
} }
// import and attach session's mixing groups // recreate groups in current session_
auto group_iter = session->beginMixingGroup(); for (auto git = allgroups.begin(); git != allgroups.end(); ++git)
while ( group_iter != session->endMixingGroup() ){ session_->link( *git, mixing_.scene.fg() );
session_->link((*group_iter)->getCopy(), mixing_.scene.fg());
group_iter = session->deleteMixingGroup(group_iter);
}
// needs to update ! // needs to update !
++View::need_deep_update_; ++View::need_deep_update_;
@@ -1206,6 +1294,9 @@ void Mixer::merge(SessionSource *source)
} }
} }
// remember groups before emptying the session
std::list<SourceList> allgroups = session->getMixingGroups();
// import every sources // import every sources
for ( Source *s = session->popSource(); s != nullptr; s = session->popSource()) { for ( Source *s = session->popSource(); s != nullptr; s = session->popSource()) {
@@ -1236,12 +1327,9 @@ void Mixer::merge(SessionSource *source)
attach(s); attach(s);
} }
// import and attach session's mixing groups // recreate groups in current session_
auto group_iter = session->beginMixingGroup(); for (auto git = allgroups.begin(); git != allgroups.end(); ++git)
while ( group_iter != session->endMixingGroup() ){ session_->link( *git, mixing_.scene.fg() );
session_->link((*group_iter)->getCopy(), mixing_.scene.fg());
group_iter = session->deleteMixingGroup(group_iter);
}
// needs to update ! // needs to update !
++View::need_deep_update_; ++View::need_deep_update_;

View File

@@ -66,7 +66,10 @@ public:
// operations on selection // operations on selection
void deleteSelection (); void deleteSelection ();
void flattenSelection (); void groupSelection ();
void groupAll ();
void flattenSession();
// current source // current source
Source *currentSource (); Source *currentSource ();
@@ -113,7 +116,6 @@ public:
void setResolution(glm::vec3 res); void setResolution(glm::vec3 res);
bool busy () const { return busy_; } bool busy () const { return busy_; }
void flatten();
// operations depending on transition mode // operations depending on transition mode
void close (bool smooth = false); void close (bool smooth = false);

View File

@@ -330,6 +330,9 @@ Source *Session::popSource()
s = *its; s = *its;
// remove Node from the rendering scene // remove Node from the rendering scene
render_.scene.ws()->detach( s->group(View::RENDERING) ); 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 // erase the source from the update list & get next element
sources_.erase(its); sources_.erase(its);
} }

View File

@@ -934,10 +934,6 @@ void UserInterface::showMenuFile()
ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f);
ImGui::Combo("Height", &Settings::application.render.res, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) ); 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 // FILE OPEN AND SAVE
ImGui::Separator(); ImGui::Separator();
const std::string currentfilename = Mixer::manager().session()->filename(); const std::string currentfilename = Mixer::manager().session()->filename();
@@ -949,11 +945,6 @@ void UserInterface::showMenuFile()
selectOpenFilename(); selectOpenFilename();
if (ImGui::MenuItem( MENU_REOPEN_FILE, SHORTCUT_REOPEN_FILE, false, currentfileopen)) if (ImGui::MenuItem( MENU_REOPEN_FILE, SHORTCUT_REOPEN_FILE, false, currentfileopen))
Mixer::manager().load( currentfilename ); 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 (ImGui::MenuItem( MENU_SAVE_FILE, SHORTCUT_SAVE_FILE, false, currentfileopen)) {
if (saveOrSaveAs()) if (saveOrSaveAs())
navigator.hidePannel(); navigator.hidePannel();
@@ -963,6 +954,21 @@ void UserInterface::showMenuFile()
ImGui::MenuItem( MENU_SAVE_ON_EXIT, nullptr, &Settings::application.recentSessions.save_on_exit); 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 // HELP AND QUIT
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem( IMGUI_TITLE_HELP, SHORTCUT_HELP)) if (ImGui::MenuItem( IMGUI_TITLE_HELP, SHORTCUT_HELP))