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