mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 18:59:59 +01:00
Cleanup and improve stability of FrameGrabber
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user