Fixed Recording (timing and UI)

Improved frame grabber timing and fixed UserInterface to show the "saving file" info.
This commit is contained in:
Bruno
2021-08-07 12:34:05 +02:00
parent 2f0e4e3212
commit e47e76962b
3 changed files with 28 additions and 24 deletions

View File

@@ -285,16 +285,17 @@ void FrameGrabber::callback_enough_data (GstAppSrc *, gpointer p)
FrameGrabber *grabber = static_cast<FrameGrabber *>(p); FrameGrabber *grabber = static_cast<FrameGrabber *>(p);
if (grabber) if (grabber)
grabber->accept_buffer_ = false; grabber->accept_buffer_ = false;
} }
GstPadProbeReturn FrameGrabber::callback_event_probe(GstPad *, GstPadProbeInfo * info, gpointer user_data) GstPadProbeReturn FrameGrabber::callback_event_probe(GstPad *, GstPadProbeInfo * info, gpointer p)
{ {
GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info); GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
{ {
FrameGrabber *g = static_cast<FrameGrabber *>(user_data); FrameGrabber *grabber = static_cast<FrameGrabber *>(p);
if (g) if (grabber)
g->finished_ = true; grabber->finished_ = true;
} }
return GST_PAD_PROBE_OK; return GST_PAD_PROBE_OK;
@@ -310,16 +311,15 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt)
if (pipeline_ == nullptr) { if (pipeline_ == nullptr) {
// type specific initialisation // type specific initialisation
init(caps); init(caps);
// generic EOS detector // attach EOS detector
GstPad *pad = gst_element_get_static_pad (gst_bin_get_by_name (GST_BIN (pipeline_), "sink"), "sink"); GstPad *pad = gst_element_get_static_pad (gst_bin_get_by_name (GST_BIN (pipeline_), "sink"), "sink");
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, FrameGrabber::callback_event_probe, this, NULL); gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, FrameGrabber::callback_event_probe, this, NULL);
gst_object_unref (pad); gst_object_unref (pad);
} }
// terminate properly if finished // terminate properly if finished
if (finished_) { if (finished_)
terminate(); terminate();
}
// stop if an incompatilble frame buffer given // stop if an incompatilble frame buffer given
else if ( !gst_caps_is_equal( caps_, caps )) else if ( !gst_caps_is_equal( caps_, caps ))
@@ -329,21 +329,26 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt)
} }
// store a frame if recording is active // store a frame if recording is active
else if (active_) // and if the encoder accepts data
else if (active_ && accept_buffer_)
{ {
// initialize timer GstClockTime t = 0;
// initialize timer on first occurence
if (timer_ == nullptr) { if (timer_ == nullptr) {
timer_ = gst_pipeline_get_clock ( GST_PIPELINE(pipeline_) ); timer_ = gst_pipeline_get_clock ( GST_PIPELINE(pipeline_) );
timer_firstframe_ = gst_clock_get_time(timer_); timer_firstframe_ = gst_clock_get_time(timer_);
} }
else
// time since timer starts (first frame registered)
t = gst_clock_get_time(timer_) - timer_firstframe_;
// time since begin // if time is zero (first frame)
GstClockTime t = gst_clock_get_time(timer_) - timer_firstframe_; // of if delta time is passed one frame duration (with a margin)
t = (t / frame_duration_) * frame_duration_; if ( t == 0 || (t - timestamp_) > (frame_duration_ - 3000) ) {
// if delta time is passed one frame duration (with a margin) // round t to multiple of frame duration
// and if the encoder accepts data t = ( t / frame_duration_) * frame_duration_;
if ( (t - timestamp_) > (frame_duration_ - 3000) && accept_buffer_) {
// set timing of buffer // set timing of buffer
buffer->pts = t; buffer->pts = t;
@@ -356,7 +361,7 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt)
gst_app_src_push_buffer (src_, buffer); gst_app_src_push_buffer (src_, buffer);
// NB: buffer will be unrefed by the appsrc // NB: buffer will be unrefed by the appsrc
// keep timestamp // keep timestamp for next addFrame
timestamp_ = t; timestamp_ = t;
} }
} }

View File

@@ -301,10 +301,11 @@ void VideoRecorder::init(GstCaps *caps)
void VideoRecorder::terminate() void VideoRecorder::terminate()
{ {
active_ = false; active_ = false;
if (expecting_finished_)
Log::Notify("Video Recording %s is ready.", filename_.c_str()); if (!expecting_finished_)
else Log::Warning("Video Recording interrupted (no more disk space?).");
Log::Warning("Recording interrupted (no more disk space?).");
Log::Notify("Video Recording %s is ready.", filename_.c_str());
} }
std::string VideoRecorder::info() const std::string VideoRecorder::info() const

View File

@@ -272,7 +272,7 @@ void UserInterface::handleKeyboard()
// toggle recording // toggle recording
if (video_recorder_) { if (video_recorder_) {
video_recorder_->stop(); video_recorder_->stop();
video_recorder_ = nullptr; // video_recorder_ = nullptr;
} }
else { else {
_video_recorders.emplace_back( std::async(std::launch::async, delayTrigger, new VideoRecorder, std::chrono::seconds(Settings::application.record.delay)) ); _video_recorders.emplace_back( std::async(std::launch::async, delayTrigger, new VideoRecorder, std::chrono::seconds(Settings::application.record.delay)) );
@@ -726,14 +726,13 @@ void UserInterface::Render()
_video_recorders.pop_back(); _video_recorders.pop_back();
} }
} }
// verify the video recorder is valid // verify the video recorder is valid (change to nullptr if invalid)
FrameGrabbing::manager().verify(&video_recorder_); FrameGrabbing::manager().verify(&video_recorder_);
if (video_recorder_ // if there is an ongoing recorder if (video_recorder_ // if there is an ongoing recorder
&& Settings::application.record.timeout < RECORD_MAX_TIMEOUT // and if the timeout is valid && Settings::application.record.timeout < RECORD_MAX_TIMEOUT // and if the timeout is valid
&& video_recorder_->duration() > Settings::application.record.timeout ) // and the timeout is reached && video_recorder_->duration() > Settings::application.record.timeout ) // and the timeout is reached
{ {
video_recorder_->stop(); video_recorder_->stop();
video_recorder_ = nullptr;
} }
#if defined(LINUX) #if defined(LINUX)
@@ -1088,7 +1087,6 @@ void UserInterface::RenderPreview()
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_RECORD, 0.8f)); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_RECORD, 0.8f));
if ( ImGui::MenuItem( ICON_FA_SQUARE " Stop Record", CTRL_MOD "R") ) { if ( ImGui::MenuItem( ICON_FA_SQUARE " Stop Record", CTRL_MOD "R") ) {
video_recorder_->stop(); video_recorder_->stop();
video_recorder_ = nullptr;
} }
ImGui::PopStyleColor(1); ImGui::PopStyleColor(1);
static char dummy_str[512]; static char dummy_str[512];