RingBuffer.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #ifndef RINGBUFFER_H
  2. #define RINGBUFFER_H
  3. #pragma once
  4. #include <cmath>
  5. #include <functional>
  6. #include <mutex>
  7. #include <vector>
  8. template<typename T>
  9. class RingBuffer
  10. {
  11. public:
  12. RingBuffer(size_t capacity)
  13. : m_capacity(capacity)
  14. , m_data(capacity)
  15. , m_pts(capacity)
  16. {}
  17. void push(const T& value, double pts)
  18. {
  19. std::unique_lock<std::mutex> lock(m_mutex);
  20. if (m_data[m_writeIndex]) {
  21. // 释放旧帧
  22. if (m_deleter)
  23. m_deleter(m_data[m_writeIndex]);
  24. }
  25. m_data[m_writeIndex] = value;
  26. m_pts[m_writeIndex] = pts;
  27. m_writeIndex = (m_writeIndex + 1) % m_capacity;
  28. if (m_size < m_capacity)
  29. ++m_size;
  30. else
  31. m_readIndex = (m_readIndex + 1) % m_capacity; // 覆盖最旧
  32. }
  33. // 按索引获取
  34. T get(size_t index)
  35. {
  36. std::unique_lock<std::mutex> lock(m_mutex);
  37. if (index >= m_size)
  38. return nullptr;
  39. size_t realIndex = (m_readIndex + index) % m_capacity;
  40. return m_data[realIndex];
  41. }
  42. // 按PTS查找最近帧
  43. size_t getIndexByPts(double pts)
  44. {
  45. std::unique_lock<std::mutex> lock(m_mutex);
  46. if (m_size == 0)
  47. return 0;
  48. size_t best = m_readIndex;
  49. double minDiff = std::abs(m_pts[best] - pts);
  50. for (size_t i = 1; i < m_size; ++i) {
  51. size_t idx = (m_readIndex + i) % m_capacity;
  52. double diff = std::abs(m_pts[idx] - pts);
  53. if (diff < minDiff) {
  54. minDiff = diff;
  55. best = idx;
  56. }
  57. }
  58. if (best >= m_readIndex)
  59. return best - m_readIndex;
  60. else
  61. return m_capacity - m_readIndex + best;
  62. }
  63. size_t size() const { return m_size; }
  64. size_t capacity() const { return m_capacity; }
  65. double firstPts() const { return m_pts[m_readIndex]; }
  66. double lastPts() const { return m_pts[(m_writeIndex + m_capacity - 1) % m_capacity]; }
  67. void setDeleter(std::function<void(T&)> deleter) { m_deleter = deleter; }
  68. void clear()
  69. {
  70. std::unique_lock<std::mutex> lock(m_mutex);
  71. if (m_deleter) {
  72. for (size_t i = 0; i < m_capacity; ++i) {
  73. if (m_data[i])
  74. m_deleter(m_data[i]);
  75. }
  76. }
  77. m_data.assign(m_capacity, nullptr);
  78. m_pts.assign(m_capacity, 0.0);
  79. m_size = 0;
  80. m_readIndex = 0;
  81. m_writeIndex = 0;
  82. }
  83. // 按PTS弹出最近帧
  84. T popNearest(double pts) {
  85. std::unique_lock<std::mutex> lock(m_mutex);
  86. if (m_size == 0) return nullptr;
  87. size_t best = m_readIndex;
  88. double minDiff = std::abs(m_pts[best] - pts);
  89. for (size_t i = 1; i < m_size; ++i) {
  90. size_t idx = (m_readIndex + i) % m_capacity;
  91. double diff = std::abs(m_pts[idx] - pts);
  92. if (diff < minDiff) {
  93. minDiff = diff;
  94. best = idx;
  95. }
  96. }
  97. T result = m_data[best];
  98. m_data[best] = nullptr;
  99. // 移动readIndex和size
  100. if (best == m_readIndex) {
  101. m_readIndex = (m_readIndex + 1) % m_capacity;
  102. --m_size;
  103. } else {
  104. // 只清空,不移动readIndex,保证弹出的是最近帧
  105. }
  106. return result;
  107. }
  108. private:
  109. std::vector<T> m_data;
  110. std::vector<double> m_pts;
  111. size_t m_capacity;
  112. size_t m_size = 0;
  113. size_t m_readIndex = 0;
  114. size_t m_writeIndex = 0;
  115. std::function<void(T&)> m_deleter;
  116. mutable std::mutex m_mutex;
  117. };
  118. #endif // RINGBUFFER_H