Preliminary implementation of recording 'save & continue'

This commit is contained in:
Bruno Herbelin
2021-12-01 23:05:41 +01:00
parent 73d4f7c1ea
commit 66f445997d
3 changed files with 54 additions and 3 deletions

View File

@@ -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<FrameGrabber *, FrameGrabber *>::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);
}

View File

@@ -3,6 +3,7 @@
#include <atomic>
#include <list>
#include <map>
#include <string>
#include <gst/gst.h>
@@ -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<FrameGrabber *> grabbers_;
std::map<FrameGrabber *, FrameGrabber *> grabbers_chain_;
guint pbo_[2];
guint pbo_index_;
guint pbo_next_index_;

View File

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