#include "frame_ring_buffer.h" #include #include namespace rk3588 { namespace { uint64_t NowSteadyMs() { using namespace std::chrono; return static_cast(duration_cast(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(std::max(1, total_sec) * fps_hint_); if (max_frames_ < 10) max_frames_ = 10; } void FrameRingBuffer::Push(std::shared_ptr frame) { Push(std::move(frame), NowSteadyMs()); } void FrameRingBuffer::Push(std::shared_ptr frame, uint64_t ts_ms) { if (!frame) return; if (ts_ms == 0) ts_ms = NowSteadyMs(); std::lock_guard 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> FrameRingBuffer::GetFramesInRange(uint64_t start_ts_ms, uint64_t end_ts_ms) const { std::lock_guard lock(mutex_); std::vector> 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 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 lock(mutex_); return last_ts_ms_; } void FrameRingBuffer::Clear() { std::lock_guard lock(mutex_); buffer_.clear(); last_ts_ms_ = 0; } size_t FrameRingBuffer::Size() const { std::lock_guard lock(mutex_); return buffer_.size(); } } // namespace rk3588