From f6e4701d6b8630769e279a114d25cd3a1cb25708 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Fri, 27 Oct 2023 19:29:39 +0200 Subject: [PATCH] BugFix Storing Play status of source in XML Undo and restore play status of Source. Fix reload / restore play speed. --- src/MediaPlayer.cpp | 19 ++++++++++------- src/MediaPlayer.h | 1 + src/SessionCreator.cpp | 24 ++++++++++++++-------- src/SessionVisitor.cpp | 1 - src/SourceCallback.cpp | 2 +- src/SourceControlWindow.cpp | 41 ++++++++++++++++++++++++++++--------- 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/MediaPlayer.cpp b/src/MediaPlayer.cpp index 3a2e5db..38cf170 100644 --- a/src/MediaPlayer.cpp +++ b/src/MediaPlayer.cpp @@ -302,7 +302,7 @@ void MediaPlayer::open (const std::string & filename, const std::string &uri) void MediaPlayer::reopen() { // re-openning is meaningfull only if it was already open - if (pipeline_ != nullptr) { + if (pipeline_ != nullptr && opened_) { // reload : terminate pipeline and re-create it close(); execute_open(); @@ -1348,7 +1348,7 @@ void MediaPlayer::execute_seek_command(GstClockTime target, bool force) #endif } else - Log::Warning("MediaPlayer %s Seek failed", std::to_string(id_).c_str()); + Log::Info("MediaPlayer %s Seek failed", std::to_string(id_).c_str()); // Force update if (force) { @@ -1359,6 +1359,15 @@ void MediaPlayer::execute_seek_command(GstClockTime target, bool force) } +void MediaPlayer::setRate(double s) +{ + // bound to interval [-MAX_PLAY_SPEED MAX_PLAY_SPEED] + rate_ = CLAMP(s, -MAX_PLAY_SPEED, MAX_PLAY_SPEED); + // skip interval [-MIN_PLAY_SPEED MIN_PLAY_SPEED] + if (ABS(rate_) < MIN_PLAY_SPEED) + rate_ = SIGN(rate_) * MIN_PLAY_SPEED; + +} void MediaPlayer::setPlaySpeed(double s) { @@ -1367,11 +1376,7 @@ void MediaPlayer::setPlaySpeed(double s) #endif // Set rate to requested value (may be executed later) - // bound to interval [-MAX_PLAY_SPEED MAX_PLAY_SPEED] - rate_ = CLAMP(s, -MAX_PLAY_SPEED, MAX_PLAY_SPEED); - // skip interval [-MIN_PLAY_SPEED MIN_PLAY_SPEED] - if (ABS(rate_) < MIN_PLAY_SPEED) - rate_ = SIGN(rate_) * MIN_PLAY_SPEED; + setRate(s); // discard if too early or not possible if (pipeline_ == nullptr || !media_.seekable) diff --git a/src/MediaPlayer.h b/src/MediaPlayer.h index 266c8ca..f7e525c 100644 --- a/src/MediaPlayer.h +++ b/src/MediaPlayer.h @@ -142,6 +142,7 @@ public: * Set the speed factor for playing * Can be negative. * */ + void setRate(double s); void setPlaySpeed(double s); /** * Loop Mode: Behavior when reaching an extremity diff --git a/src/SessionCreator.cpp b/src/SessionCreator.cpp index c7c3322..b88988c 100644 --- a/src/SessionCreator.cpp +++ b/src/SessionCreator.cpp @@ -894,17 +894,22 @@ void SessionLoader::visit(MediaPlayer &n) n.setTimeline(tl); } + // change play rate: will be activated in SessionLoader::visit (MediaSource& s) + double speed = 1.0; + mediaplayerNode->QueryDoubleAttribute("speed", &speed); + n.setRate(speed); + + // change video effect only if effect given is different + const char *pFilter = mediaplayerNode->Attribute("video_effect"); + if (pFilter) { + if (n.videoEffect().compare(pFilter) != 0) { + n.setVideoEffect(pFilter); + } + } + // change play status only if different id (e.g. new media player) if ( n.id() != id__ ) { - const char *pFilter = mediaplayerNode->Attribute("video_effect"); - if (pFilter) - n.setVideoEffect(std::string(pFilter)); - - double speed = 1.0; - mediaplayerNode->QueryDoubleAttribute("speed", &speed); - n.setPlaySpeed(speed); - int loop = 1; mediaplayerNode->QueryIntAttribute("loop", &loop); n.setLoop( (MediaPlayer::LoopMode) loop); @@ -921,13 +926,14 @@ void SessionLoader::visit(MediaPlayer &n) mediaplayerNode->QueryIntAttribute("sync_to_metronome", &sync_to_metronome); n.setSyncToMetronome( (Metronome::Synchronicity) sync_to_metronome); + /// obsolete // only read media player play attribute if the source has no play attribute (backward compatibility) if ( !xmlCurrent_->Attribute( "play" ) ) { bool play = true; mediaplayerNode->QueryBoolAttribute("play", &play); n.play(play); } - } + } } } diff --git a/src/SessionVisitor.cpp b/src/SessionVisitor.cpp index 81affad..d5718a0 100644 --- a/src/SessionVisitor.cpp +++ b/src/SessionVisitor.cpp @@ -424,7 +424,6 @@ void SessionVisitor::visit(MediaPlayer &n) newelement->SetAttribute("id", n.id()); if (!n.singleFrame()) { - newelement->SetAttribute("play", n.isPlaying()); newelement->SetAttribute("loop", (int) n.loop()); newelement->SetAttribute("speed", n.playSpeed()); newelement->SetAttribute("video_effect", n.videoEffect().c_str()); diff --git a/src/SourceCallback.cpp b/src/SourceCallback.cpp index 215d935..147704c 100644 --- a/src/SourceCallback.cpp +++ b/src/SourceCallback.cpp @@ -551,7 +551,7 @@ void PlaySpeed::writeValue(Source *s, float val) { // access media player if target source is a media source MediaSource *ms = dynamic_cast(s); - if (ms != nullptr) { + if (ms != nullptr && ms->ready()) { ms->mediaplayer()->setPlaySpeed((double) val); } } diff --git a/src/SourceControlWindow.cpp b/src/SourceControlWindow.cpp index bc4c104..db531fd 100644 --- a/src/SourceControlWindow.cpp +++ b/src/SourceControlWindow.cpp @@ -131,6 +131,7 @@ void SourceControlWindow::Update() for (auto source = selectedsources.begin(); source != selectedsources.end(); ++source) (*source)->play( n_play < n_source ); + Action::manager().store( n_play < n_source ? "Sources Play" : "Sources Pause" ); play_toggle_request_ = false; } @@ -393,6 +394,7 @@ void SourceControlWindow::Render() mediaplayer_timeline_zoom_ = 1.f; mediaplayer_active_->timeline()->clearFading(); mediaplayer_active_->timeline()->clearGaps(); + mediaplayer_active_->setVideoEffect(""); std::ostringstream oss; oss << SystemToolkit::base_filename( mediaplayer_active_->filename() ); oss << ": Reset timeline"; @@ -419,7 +421,8 @@ void SourceControlWindow::Render() ImGui::Separator(); if (ImGuiToolkit::MenuItemIcon(16, 16, "Gstreamer effect", nullptr, - false, mediaplayer_active_->videoEffectAvailable()) ) + !mediaplayer_active_->videoEffect().empty(), + mediaplayer_active_->videoEffectAvailable()) ) mediaplayer_edit_pipeline_ = true; ImGui::EndMenu(); @@ -685,8 +688,10 @@ void SourceControlWindow::RenderSelection(size_t i) ImVec2 image_top = ImGui::GetCursorPos(); const ImVec2 framesize(1.5f * timeline_height_ * (*source)->frame()->aspectRatio(), 1.5f * timeline_height_); int action = SourceButton(*source, framesize); - if (action > 1) + if (action > 1) { (*source)->play( ! (*source)->playing() ); + Action::manager().store((*source)->playing() ? "Source Play" : "Source Pause" ); + } else if (action > 0) UserInterface::manager().showSourceEditor(*source); @@ -840,8 +845,10 @@ void SourceControlWindow::RenderSelection(size_t i) /// const ImVec2 framesize(1.5f * timeline_height_ * (*source)->frame()->aspectRatio(), 1.5f * timeline_height_); int action = SourceButton(*source, framesize); - if (action > 1) - (*source)->play( ! (*source)->playing() ); + if (action > 1) { + (*source)->play( ! (*source)->playing() ); + Action::manager().store((*source)->playing() ? "Source Play" : "Source Pause" ); + } else if (action > 0) UserInterface::manager().showSourceEditor(*source); @@ -1240,8 +1247,10 @@ void SourceControlWindow::RenderSelectedSources() ImVec2 image_top = ImGui::GetCursorPos(); ImVec2 framesize(widthcolumn, widthcolumn / (*source)->frame()->aspectRatio()); int action = SourceButton(*source, framesize); - if (action > 1) - (*source)->play( ! (*source)->playing() ); + if (action > 1) { + (*source)->play( ! (*source)->playing() ); + Action::manager().store((*source)->playing() ? "Source Play" : "Source Pause" ); + } else if (action > 0) UserInterface::manager().showSourceEditor(*source); @@ -1702,8 +1711,11 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms) // display buttons Play/Stop depending on current playing mode ImGui::SameLine(0, h_space_); if (mediaplayer_mode_) { - if (ImGui::Button(ICON_FA_PAUSE)) + if (ImGui::Button(ICON_FA_PAUSE)){ mediaplayer_mode_ = false; + oss << ": Pause"; + Action::manager().store(oss.str()); + } ImGui::SameLine(0, h_space_); ImGui::PushButtonRepeat(true); @@ -1712,8 +1724,11 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms) ImGui::PopButtonRepeat(); } else { - if (ImGui::Button(ICON_FA_PLAY)) + if (ImGui::Button(ICON_FA_PLAY)) { mediaplayer_mode_ = true; + oss << ": Play"; + Action::manager().store(oss.str()); + } ImGui::SameLine(0, h_space_); ImGui::PushButtonRepeat(true); @@ -1926,7 +1941,7 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms) _effect_description = mediaplayer_active_->videoEffect(); _effect_description_changed = true; } - const ImVec2 mpp_dialog_size(buttons_width_ * 3.f, buttons_height_ * 6); + const ImVec2 mpp_dialog_size(buttons_width_ * 3.f, buttons_height_ * 6.2f); ImGui::SetNextWindowSize(mpp_dialog_size, ImGuiCond_Always); const ImVec2 mpp_dialog_pos = top + rendersize * 0.5f - mpp_dialog_size * 0.5f; ImGui::SetNextWindowPos(mpp_dialog_pos, ImGuiCond_Always); @@ -2028,7 +2043,7 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms) if (_status > 1) { // On Error ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0, 0.2, 0.2, 0.95f)); - ImGui::Text("Error - %s", _status_message.c_str()); + ImGui::TextWrapped("Error - %s", _status_message.c_str()); ImGui::PopStyleColor(1); } else if (_status > 0) { @@ -2052,6 +2067,8 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms) // apply to pipeline mediaplayer_active_->setVideoEffect(_effect_description); + oss << " gst effect"; + Action::manager().store(oss.str()); } ImGui::PopStyleColor(1); } @@ -2160,12 +2177,14 @@ void SourceControlWindow::DrawButtonBar(ImVec2 bottom, float width) if (ImGui::Button(ICON_FA_PAUSE) && enabled) { for (auto source = selection_.begin(); source != selection_.end(); ++source) (*source)->play(false); + Action::manager().store("Sources Pause"); } } else { if (ImGui::Button(ICON_FA_PLAY) && enabled){ for (auto source = selection_.begin(); source != selection_.end(); ++source) (*source)->play(true); + Action::manager().store("Sources Play"); } } } @@ -2174,11 +2193,13 @@ void SourceControlWindow::DrawButtonBar(ImVec2 bottom, float width) if (ImGui::Button(ICON_FA_PLAY) && enabled) { for (auto source = selection_.begin(); source != selection_.end(); ++source) (*source)->play(true); + Action::manager().store("Sources Play"); } ImGui::SameLine(0, h_space_); if (ImGui::Button(ICON_FA_PAUSE) && enabled) { for (auto source = selection_.begin(); source != selection_.end(); ++source) (*source)->play(false); + Action::manager().store("Sources Pause"); } } ImGui::SameLine(0, h_space_);