ring_buffer.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #ifndef RING_BUFFER
  2. #define RING_BUFFER
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <queue>
  6. #include <mutex>
  7. #include "error_define.h"
  8. #include "log_helper.h"
  9. namespace am {
  10. template <typename T>
  11. struct ring_frame {
  12. T type;
  13. int len;
  14. };
  15. template <typename T>
  16. class ring_buffer
  17. {
  18. public:
  19. ring_buffer(unsigned int size = 1920 * 1080 * 4 * 10)
  20. {
  21. _size = size;
  22. _head = _tail = 0;
  23. _buf = new uint8_t[size];
  24. }
  25. ~ring_buffer()
  26. {
  27. if (_buf)
  28. delete[] _buf;
  29. }
  30. void put(const void *data, int len, const T &type)
  31. {
  32. std::lock_guard<std::mutex> locker(_lock);
  33. if (_head + len <= _size) {
  34. memcpy(_buf + _head, data, len);
  35. _head += len;
  36. }
  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. }
  70. else {
  71. int remain = frame.len - (_size - _tail);
  72. if (frame.len - remain > 0)
  73. memcpy(data, _buf + _tail, frame.len - remain);
  74. if (remain > 0)
  75. memcpy((unsigned char*)data + frame.len - remain, _buf, remain);
  76. _tail = remain;
  77. }
  78. return retLen;
  79. }
  80. private:
  81. std::queue<ring_frame<T>> _frames;
  82. unsigned int _size, _head, _tail;
  83. uint8_t *_buf;
  84. std::mutex _lock;
  85. };
  86. }
  87. #endif