OrangePi3588Media/plugins/alarm/frame_ring_buffer.cpp

76 lines
2.3 KiB
C++

#include "frame_ring_buffer.h"
#include <algorithm>
#include <chrono>
namespace rk3588 {
namespace {
uint64_t NowSteadyMs() {
using namespace std::chrono;
return static_cast<uint64_t>(duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count());
}
}
FrameRingBuffer::FrameRingBuffer(int pre_event_sec, int post_event_sec, int fps_hint)
: pre_event_sec_(pre_event_sec), post_event_sec_(post_event_sec), fps_hint_(fps_hint > 0 ? fps_hint : 25) {
const int total_sec = std::max(0, pre_event_sec_) + std::max(0, post_event_sec_) + 2; // +2s margin
max_frames_ = static_cast<size_t>(std::max(1, total_sec) * fps_hint_);
if (max_frames_ < 10) max_frames_ = 10;
}
void FrameRingBuffer::Push(std::shared_ptr<Frame> frame) {
Push(std::move(frame), NowSteadyMs());
}
void FrameRingBuffer::Push(std::shared_ptr<Frame> frame, uint64_t ts_ms) {
if (!frame) return;
if (ts_ms == 0) ts_ms = NowSteadyMs();
std::lock_guard<std::mutex> lock(mutex_);
buffer_.push_back(Entry{ts_ms, std::move(frame)});
last_ts_ms_ = std::max(last_ts_ms_, ts_ms);
while (buffer_.size() > max_frames_) buffer_.pop_front();
}
std::vector<std::shared_ptr<Frame>> FrameRingBuffer::GetFramesInRange(uint64_t start_ts_ms, uint64_t end_ts_ms) const {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<std::shared_ptr<Frame>> out;
for (const auto& e : buffer_) {
if (e.ts_ms < start_ts_ms) continue;
if (e.ts_ms > end_ts_ms) break;
if (e.frame) out.push_back(e.frame);
}
return out;
}
bool FrameRingBuffer::FindTimestampByFrameId(uint64_t frame_id, uint64_t& out_ts_ms) const {
std::lock_guard<std::mutex> lock(mutex_);
for (auto it = buffer_.rbegin(); it != buffer_.rend(); ++it) {
if (!it->frame) continue;
if (it->frame->frame_id == frame_id) {
out_ts_ms = it->ts_ms;
return true;
}
}
return false;
}
uint64_t FrameRingBuffer::LatestTimestampMs() const {
std::lock_guard<std::mutex> lock(mutex_);
return last_ts_ms_;
}
void FrameRingBuffer::Clear() {
std::lock_guard<std::mutex> lock(mutex_);
buffer_.clear();
last_ts_ms_ = 0;
}
size_t FrameRingBuffer::Size() const {
std::lock_guard<std::mutex> lock(mutex_);
return buffer_.size();
}
} // namespace rk3588