From 66f445997d5caa7ba010b02d9cfd925b6689e189 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Wed, 1 Dec 2021 23:05:41 +0100 Subject: [PATCH] Preliminary implementation of recording 'save & continue' --- FrameGrabber.cpp | 35 ++++++++++++++++++++++++++++++++++- FrameGrabber.h | 3 +++ UserInterfaceManager.cpp | 19 +++++++++++++++++-- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/FrameGrabber.cpp b/FrameGrabber.cpp index 70d55f7..c3717b3 100644 --- a/FrameGrabber.cpp +++ b/FrameGrabber.cpp @@ -60,9 +60,22 @@ void FrameGrabbing::add(FrameGrabber *rec) grabbers_.push_back(rec); } +void FrameGrabbing::chain(FrameGrabber *rec, FrameGrabber *next_rec) +{ + if (rec != nullptr && next_rec != nullptr) + { + // add grabber if not yet + if ( std::find(grabbers_.begin(), grabbers_.end(), rec) == grabbers_.end() ) + grabbers_.push_back(rec); + + grabbers_chain_[next_rec] = rec; + } +} + void FrameGrabbing::verify(FrameGrabber **rec) { - if ( std::find(grabbers_.begin(), grabbers_.end(), *rec) == grabbers_.end() ) + if ( std::find(grabbers_.begin(), grabbers_.end(), *rec) == grabbers_.end() && + grabbers_chain_.find(*rec) == grabbers_chain_.end() ) *rec = nullptr; } @@ -214,6 +227,7 @@ void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer) FrameGrabber *rec = *iter; rec->addFrame(buffer, caps_); + // remove finished recorders if (rec->finished()) { iter = grabbers_.erase(iter); delete rec; @@ -222,6 +236,25 @@ void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer) ++iter; } + // manage the list of chainned recorder + std::map::iterator chain = grabbers_chain_.begin(); + while (chain != grabbers_chain_.end()) { + // update frame grabber of chain list + chain->first->addFrame(buffer, caps_); + // if the chained recorder is now active + if (chain->first->active_ && chain->first->accept_buffer_){ + // add it to main grabbers, + grabbers_.push_back(chain->first); + // stop the replaced grabber + chain->second->stop(); + // loop in chain list: done with this chain + chain = grabbers_chain_.erase(chain); + } + else + // loop in chain list + ++chain; + } + // unref / free the frame gst_buffer_unref(buffer); } diff --git a/FrameGrabber.h b/FrameGrabber.h index 716166b..44dc397 100644 --- a/FrameGrabber.h +++ b/FrameGrabber.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -111,6 +112,7 @@ public: inline uint height() const { return height_; } void add(FrameGrabber *rec); + void chain(FrameGrabber *rec, FrameGrabber *new_rec); void verify(FrameGrabber **rec); FrameGrabber *front(); FrameGrabber *get(uint64_t id); @@ -124,6 +126,7 @@ protected: private: std::list grabbers_; + std::map grabbers_chain_; guint pbo_[2]; guint pbo_index_; guint pbo_next_index_; diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 223978a..b05f265 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -326,8 +326,15 @@ void UserInterface::handleKeyboard() else { // toggle recording if (video_recorder_) { - video_recorder_->stop(); -// video_recorder_ = nullptr; + // allow 'save & continue' for Ctrl+Alt+R if no timeout for recording + if (alt_modifier_active && Settings::application.record.timeout == RECORD_MAX_TIMEOUT) { + VideoRecorder *rec = new VideoRecorder; + FrameGrabbing::manager().chain(video_recorder_, rec); + video_recorder_ = rec; + } + // normal case: Ctrl+R stop recording + else + video_recorder_->stop(); } else { _video_recorders.emplace_back( std::async(std::launch::async, delayTrigger, new VideoRecorder, @@ -1334,6 +1341,14 @@ void UserInterface::RenderPreview() if ( ImGui::MenuItem( ICON_FA_SQUARE " Stop Record", CTRL_MOD "R") ) { video_recorder_->stop(); } + // offer the 'save & continue' recording for undefined duration + if (Settings::application.record.timeout == RECORD_MAX_TIMEOUT) { + if ( ImGui::MenuItem( ICON_FA_ARROW_ALT_CIRCLE_DOWN " Save & continue", CTRL_MOD "Alt+R") ) { + VideoRecorder *rec = new VideoRecorder; + FrameGrabbing::manager().chain(video_recorder_, rec); + video_recorder_ = rec; + } + } ImGui::PopStyleColor(1); } // start recording