From fe72c9b8298d99eefbf4bd86fbfdc78e5867b7bb Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 11 Aug 2021 20:48:18 +0200 Subject: [PATCH] Cleanup and improve stability of FrameGrabber --- FrameGrabber.cpp | 39 +++++++++++++++------------------------ FrameGrabber.h | 4 ++-- Mixer.cpp | 2 +- Recorder.cpp | 6 +++--- Recorder.h | 2 +- 5 files changed, 22 insertions(+), 31 deletions(-) diff --git a/FrameGrabber.cpp b/FrameGrabber.cpp index ea025fc..2101cc7 100644 --- a/FrameGrabber.cpp +++ b/FrameGrabber.cpp @@ -97,7 +97,7 @@ void FrameGrabbing::clearAll() } -void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer, float dt) +void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer) { if (frame_buffer == nullptr) return; @@ -188,12 +188,15 @@ void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer, float dt) // a frame was successfully grabbed if (buffer != nullptr) { + if ( gst_buffer_get_size(buffer) == 0 ) + g_print("Empty buffer"); + // give the frame to all recorders std::list::iterator iter = grabbers_.begin(); while (iter != grabbers_.end()) { FrameGrabber *rec = *iter; - rec->addFrame(buffer, caps_, dt); + rec->addFrame(buffer, caps_); if (rec->finished()) { iter = grabbers_.erase(iter); @@ -299,7 +302,7 @@ GstPadProbeReturn FrameGrabber::callback_event_probe(GstPad *, GstPadProbeInfo * return GST_PAD_PROBE_OK; } -void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) +void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps) { // ignore if (buffer == nullptr) @@ -348,26 +351,10 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) if (timestamp_on_clock_) // set time to actual time // & round t to a multiples of frame duration - t = duration_; + timestamp_ = duration_; else // monotonic time increment to keep fixed FPS - t = timestamp_ + frame_duration_; - - // set frame presentation time stamp - buffer->pts = t; - buffer->duration = frame_duration_; - - // if time since last timestamp is more than 1 frame - if (t - timestamp_ > frame_duration_) { - // timestamp for next addFrame will be one frame later (skip a frame) - timestamp_ = t + frame_duration_; - } - // normal case (not delayed) - else - { - // keep timestamp for next addFrame - timestamp_ = t; - } + timestamp_ += frame_duration_; // when buffering is full, refuse buffer every frame if (buffering_full_) @@ -377,7 +364,7 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) // enter buffering_full_ mode if the space left in buffering is for only few frames // (this prevents filling the buffer entirely) if ( buffering_size_ - gst_app_src_get_current_level_bytes(src_) < 3 * gst_buffer_get_size(buffer)) { -#ifndef NDEBUG +#ifndef _NDEBUG Log::Info("Frame capture : Using %s of %s Buffer.", BaseToolkit::byte_to_string(gst_app_src_get_current_level_bytes(src_)).c_str(), BaseToolkit::byte_to_string(buffering_size_).c_str()); @@ -386,6 +373,10 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) } } + // set frame presentation time stamp + buffer->pts = timestamp_; + buffer->duration = frame_duration_; + // increment ref counter to make sure the frame remains available gst_buffer_ref(buffer); @@ -406,8 +397,8 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) // de-activate and re-send EOS stop(); // inform - Log::Warning("Frame capture : interrupted after %s.", GstToolkit::time_to_string(duration_, GstToolkit::TIME_STRING_READABLE).c_str()); - Log::Info("Frame capture: not space left on drive / encoding buffer full."); + Log::Warning("Frame capture : failed after %s.", GstToolkit::time_to_string(duration_, GstToolkit::TIME_STRING_READABLE).c_str()); + Log::Info("Frame capture: no space left on drive ? / encoding buffer full."); } // terminate properly if finished else diff --git a/FrameGrabber.h b/FrameGrabber.h index ae3b496..716166b 100644 --- a/FrameGrabber.h +++ b/FrameGrabber.h @@ -48,7 +48,7 @@ public: protected: // only FrameGrabbing manager can add frame - virtual void addFrame(GstBuffer *buffer, GstCaps *caps, float dt); + virtual void addFrame(GstBuffer *buffer, GstCaps *caps); // only addFrame method shall call those virtual void init(GstCaps *caps) = 0; @@ -120,7 +120,7 @@ public: protected: // only for friend Session - void grabFrame(FrameBuffer *frame_buffer, float dt); + void grabFrame(FrameBuffer *frame_buffer); private: std::list grabbers_; diff --git a/Mixer.cpp b/Mixer.cpp index 6547861..1a95530 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -172,7 +172,7 @@ void Mixer::update() session_->update(dt_); // grab frames to recorders & streamers - FrameGrabbing::manager().grabFrame(session_->frame(), dt_); + FrameGrabbing::manager().grabFrame(session_->frame()); // delete sources which failed update (one by one) Source *failure = session()->failedSource(); diff --git a/Recorder.cpp b/Recorder.cpp index d395b98..0ef807f 100644 --- a/Recorder.cpp +++ b/Recorder.cpp @@ -108,13 +108,13 @@ void PNGRecorder::terminate() Log::Notify("PNG Capture %s is ready.", filename_.c_str()); } -void PNGRecorder::addFrame(GstBuffer *buffer, GstCaps *caps, float dt) +void PNGRecorder::addFrame(GstBuffer *buffer, GstCaps *caps) { - FrameGrabber::addFrame(buffer, caps, dt); + FrameGrabber::addFrame(buffer, caps); // PNG Recorder specific : // stop after one frame - if (timestamp_ > 0) { + if (frame_count_ > 0) { stop(); } } diff --git a/Recorder.h b/Recorder.h index d1f1595..22b1d8e 100644 --- a/Recorder.h +++ b/Recorder.h @@ -20,7 +20,7 @@ protected: void init(GstCaps *caps) override; void terminate() override; - void addFrame(GstBuffer *buffer, GstCaps *caps, float dt) override; + void addFrame(GstBuffer *buffer, GstCaps *caps) override; };