#ifndef RINGBUFFER_H #define RINGBUFFER_H #pragma once #include #include #include #include template class RingBuffer { public: RingBuffer(size_t capacity) : m_capacity(capacity) , m_data(capacity) , m_pts(capacity) {} void push(const T& value, double pts) { std::unique_lock lock(m_mutex); if (m_data[m_writeIndex]) { // 释放旧帧 if (m_deleter) m_deleter(m_data[m_writeIndex]); } m_data[m_writeIndex] = value; m_pts[m_writeIndex] = pts; m_writeIndex = (m_writeIndex + 1) % m_capacity; if (m_size < m_capacity) ++m_size; else m_readIndex = (m_readIndex + 1) % m_capacity; // 覆盖最旧 } // 按索引获取 T get(size_t index) { std::unique_lock lock(m_mutex); if (index >= m_size) return nullptr; size_t realIndex = (m_readIndex + index) % m_capacity; return m_data[realIndex]; } // 按PTS查找最近帧 size_t getIndexByPts(double pts) { std::unique_lock lock(m_mutex); if (m_size == 0) return 0; size_t best = m_readIndex; double minDiff = std::abs(m_pts[best] - pts); for (size_t i = 1; i < m_size; ++i) { size_t idx = (m_readIndex + i) % m_capacity; double diff = std::abs(m_pts[idx] - pts); if (diff < minDiff) { minDiff = diff; best = idx; } } if (best >= m_readIndex) return best - m_readIndex; else return m_capacity - m_readIndex + best; } size_t size() const { return m_size; } size_t capacity() const { return m_capacity; } double firstPts() const { return m_pts[m_readIndex]; } double lastPts() const { return m_pts[(m_writeIndex + m_capacity - 1) % m_capacity]; } void setDeleter(std::function deleter) { m_deleter = deleter; } void clear() { std::unique_lock lock(m_mutex); if (m_deleter) { for (size_t i = 0; i < m_capacity; ++i) { if (m_data[i]) m_deleter(m_data[i]); } } m_data.assign(m_capacity, nullptr); m_pts.assign(m_capacity, 0.0); m_size = 0; m_readIndex = 0; m_writeIndex = 0; } // 按PTS弹出最近帧 T popNearest(double pts) { std::unique_lock lock(m_mutex); if (m_size == 0) return nullptr; size_t best = m_readIndex; double minDiff = std::abs(m_pts[best] - pts); for (size_t i = 1; i < m_size; ++i) { size_t idx = (m_readIndex + i) % m_capacity; double diff = std::abs(m_pts[idx] - pts); if (diff < minDiff) { minDiff = diff; best = idx; } } T result = m_data[best]; m_data[best] = nullptr; // 移动readIndex和size if (best == m_readIndex) { m_readIndex = (m_readIndex + 1) % m_capacity; --m_size; } else { // 只清空,不移动readIndex,保证弹出的是最近帧 } return result; } private: std::vector m_data; std::vector m_pts; size_t m_capacity; size_t m_size = 0; size_t m_readIndex = 0; size_t m_writeIndex = 0; std::function m_deleter; mutable std::mutex m_mutex; }; #endif // RINGBUFFER_H