ring_buffer.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef RING_BUFFER
  2. #define RING_BUFFER
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <mutex>
  6. #include <queue>
  7. #include "error_define.h"
  8. #include "log_helper.h"
  9. namespace am {
  10. template<typename T>
  11. struct ring_frame
  12. {
  13. T type;
  14. int len;
  15. };
  16. template<typename T>
  17. class ring_buffer
  18. {
  19. public:
  20. ring_buffer(unsigned int size = 1920 * 1080 * 4 * 10)
  21. {
  22. _size = size;
  23. _head = _tail = 0;
  24. _buf = new uint8_t[size];
  25. }
  26. ~ring_buffer()
  27. {
  28. if (_buf)
  29. delete[] _buf;
  30. }
  31. void put(const void *data, int len, const T &type)
  32. {
  33. std::lock_guard<std::mutex> locker(_lock);
  34. if (_head + len <= _size) {
  35. memcpy(_buf + _head, data, len);
  36. _head += len;
  37. } else if (_head + len > _size) {
  38. int remain = len - (_size - _head);
  39. if (len - remain > 0)
  40. memcpy(_buf + _head, data, len - remain);
  41. if (remain > 0)
  42. memcpy(_buf, (unsigned char *) data + len - remain, remain);
  43. _head = remain;
  44. }
  45. struct ring_frame<T> frame;
  46. frame.len = len;
  47. frame.type = type;
  48. _frames.push(frame);
  49. }
  50. int get(void *data, int len, T &type)
  51. {
  52. std::lock_guard<std::mutex> locker(_lock);
  53. int retLen = 0;
  54. if (_frames.size() <= 0) {
  55. retLen = 0;
  56. return retLen;
  57. }
  58. struct ring_frame<T> frame = _frames.front();
  59. _frames.pop();
  60. if (frame.len > len) {
  61. al_error("ringbuff::get need larger buffer");
  62. return 0;
  63. }
  64. type = frame.type;
  65. retLen = frame.len;
  66. if (_tail + frame.len <= _size) {
  67. memcpy(data, _buf + _tail, frame.len);
  68. _tail += frame.len;
  69. } else {
  70. int remain = frame.len - (_size - _tail);
  71. if (frame.len - remain > 0)
  72. memcpy(data, _buf + _tail, frame.len - remain);
  73. if (remain > 0)
  74. memcpy((unsigned char *) data + frame.len - remain, _buf, remain);
  75. _tail = remain;
  76. }
  77. return retLen;
  78. }
  79. private:
  80. std::queue<ring_frame<T>> _frames;
  81. unsigned int _size, _head, _tail;
  82. uint8_t *_buf;
  83. std::mutex _lock;
  84. };
  85. } // namespace am
  86. #endif