Cleanup and improve stability of FrameGrabber

This commit is contained in:
Bruno
2021-08-11 20:48:18 +02:00
parent b37d22ba47
commit fe72c9b829
5 changed files with 22 additions and 31 deletions

View File

@@ -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) if (frame_buffer == nullptr)
return; return;
@@ -188,12 +188,15 @@ void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer, float dt)
// a frame was successfully grabbed // a frame was successfully grabbed
if (buffer != nullptr) { if (buffer != nullptr) {
if ( gst_buffer_get_size(buffer) == 0 )
g_print("Empty buffer");
// give the frame to all recorders // give the frame to all recorders
std::list<FrameGrabber *>::iterator iter = grabbers_.begin(); std::list<FrameGrabber *>::iterator iter = grabbers_.begin();
while (iter != grabbers_.end()) while (iter != grabbers_.end())
{ {
FrameGrabber *rec = *iter; FrameGrabber *rec = *iter;
rec->addFrame(buffer, caps_, dt); rec->addFrame(buffer, caps_);
if (rec->finished()) { if (rec->finished()) {
iter = grabbers_.erase(iter); iter = grabbers_.erase(iter);
@@ -299,7 +302,7 @@ GstPadProbeReturn FrameGrabber::callback_event_probe(GstPad *, GstPadProbeInfo *
return GST_PAD_PROBE_OK; return GST_PAD_PROBE_OK;
} }
void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt) void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps)
{ {
// ignore // ignore
if (buffer == nullptr) if (buffer == nullptr)
@@ -348,26 +351,10 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt)
if (timestamp_on_clock_) if (timestamp_on_clock_)
// set time to actual time // set time to actual time
// & round t to a multiples of frame duration // & round t to a multiples of frame duration
t = duration_; timestamp_ = duration_;
else else
// monotonic time increment to keep fixed FPS // monotonic time increment to keep fixed FPS
t = timestamp_ + frame_duration_; 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;
}
// when buffering is full, refuse buffer every frame // when buffering is full, refuse buffer every frame
if (buffering_full_) 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 // enter buffering_full_ mode if the space left in buffering is for only few frames
// (this prevents filling the buffer entirely) // (this prevents filling the buffer entirely)
if ( buffering_size_ - gst_app_src_get_current_level_bytes(src_) < 3 * gst_buffer_get_size(buffer)) { 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.", 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(gst_app_src_get_current_level_bytes(src_)).c_str(),
BaseToolkit::byte_to_string(buffering_size_).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 // increment ref counter to make sure the frame remains available
gst_buffer_ref(buffer); gst_buffer_ref(buffer);
@@ -406,8 +397,8 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps, float dt)
// de-activate and re-send EOS // de-activate and re-send EOS
stop(); stop();
// inform // inform
Log::Warning("Frame capture : interrupted after %s.", GstToolkit::time_to_string(duration_, GstToolkit::TIME_STRING_READABLE).c_str()); Log::Warning("Frame capture : failed 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::Info("Frame capture: no space left on drive ? / encoding buffer full.");
} }
// terminate properly if finished // terminate properly if finished
else else

View File

@@ -48,7 +48,7 @@ public:
protected: protected:
// only FrameGrabbing manager can add frame // 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 // only addFrame method shall call those
virtual void init(GstCaps *caps) = 0; virtual void init(GstCaps *caps) = 0;
@@ -120,7 +120,7 @@ public:
protected: protected:
// only for friend Session // only for friend Session
void grabFrame(FrameBuffer *frame_buffer, float dt); void grabFrame(FrameBuffer *frame_buffer);
private: private:
std::list<FrameGrabber *> grabbers_; std::list<FrameGrabber *> grabbers_;

View File

@@ -172,7 +172,7 @@ void Mixer::update()
session_->update(dt_); session_->update(dt_);
// grab frames to recorders & streamers // grab frames to recorders & streamers
FrameGrabbing::manager().grabFrame(session_->frame(), dt_); FrameGrabbing::manager().grabFrame(session_->frame());
// delete sources which failed update (one by one) // delete sources which failed update (one by one)
Source *failure = session()->failedSource(); Source *failure = session()->failedSource();

View File

@@ -108,13 +108,13 @@ void PNGRecorder::terminate()
Log::Notify("PNG Capture %s is ready.", filename_.c_str()); 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 : // PNG Recorder specific :
// stop after one frame // stop after one frame
if (timestamp_ > 0) { if (frame_count_ > 0) {
stop(); stop();
} }
} }

View File

@@ -20,7 +20,7 @@ protected:
void init(GstCaps *caps) override; void init(GstCaps *caps) override;
void terminate() override; void terminate() override;
void addFrame(GstBuffer *buffer, GstCaps *caps, float dt) override; void addFrame(GstBuffer *buffer, GstCaps *caps) override;
}; };