You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.4KB

  1. /*
  2. * A very simple circular buffer FIFO implementation
  3. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  4. * Copyright (c) 2006 Roman Shaposhnik
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "common.h"
  21. #include "fifo.h"
  22. int av_fifo_init(AVFifoBuffer *f, int size)
  23. {
  24. f->buffer = av_malloc(size);
  25. if (!f->buffer)
  26. return -1;
  27. f->end = f->buffer + size;
  28. f->wptr = f->rptr = f->buffer;
  29. return 0;
  30. }
  31. void av_fifo_free(AVFifoBuffer *f)
  32. {
  33. av_free(f->buffer);
  34. }
  35. int av_fifo_size(AVFifoBuffer *f)
  36. {
  37. int size = f->wptr - f->rptr;
  38. if (size < 0)
  39. size += f->end - f->buffer;
  40. return size;
  41. }
  42. /**
  43. * Get data from the fifo (returns -1 if not enough data).
  44. */
  45. int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size)
  46. {
  47. int len;
  48. int size = f->wptr - f->rptr;
  49. if (size < 0)
  50. size += f->end - f->buffer;
  51. if (size < buf_size)
  52. return -1;
  53. while (buf_size > 0) {
  54. len = FFMIN(f->end - f->rptr, buf_size);
  55. memcpy(buf, f->rptr, len);
  56. buf += len;
  57. f->rptr += len;
  58. if (f->rptr >= f->end)
  59. f->rptr = f->buffer;
  60. buf_size -= len;
  61. }
  62. return 0;
  63. }
  64. /**
  65. * Resizes a FIFO.
  66. */
  67. void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) {
  68. unsigned int old_size= f->end - f->buffer;
  69. if(old_size < new_size){
  70. uint8_t *old= f->buffer;
  71. f->buffer= av_realloc(f->buffer, new_size);
  72. f->rptr += f->buffer - old;
  73. f->wptr += f->buffer - old;
  74. if(f->wptr < f->rptr){
  75. memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
  76. f->rptr += new_size - old_size;
  77. }
  78. f->end= f->buffer + new_size;
  79. }
  80. }
  81. void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size)
  82. {
  83. int len;
  84. while (size > 0) {
  85. len = FFMIN(f->end - f->wptr, size);
  86. memcpy(f->wptr, buf, len);
  87. f->wptr += len;
  88. if (f->wptr >= f->end)
  89. f->wptr = f->buffer;
  90. buf += len;
  91. size -= len;
  92. }
  93. }
  94. /* get data from the fifo (return -1 if not enough data) */
  95. int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest)
  96. {
  97. int len;
  98. int size = f->wptr - f->rptr;
  99. if (size < 0)
  100. size += f->end - f->buffer;
  101. if (size < buf_size)
  102. return -1;
  103. while (buf_size > 0) {
  104. len = FFMIN(f->end - f->rptr, buf_size);
  105. func(dest, f->rptr, len);
  106. f->rptr += len;
  107. if (f->rptr >= f->end)
  108. f->rptr = f->buffer;
  109. buf_size -= len;
  110. }
  111. return 0;
  112. }
  113. /* discard data from the fifo */
  114. void av_fifo_drain(AVFifoBuffer *f, int size)
  115. {
  116. f->rptr += size;
  117. if (f->rptr >= f->end)
  118. f->rptr -= f->end - f->buffer;
  119. }