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 | { | |
0726982c | 27 | f->wptr = f->rptr = |
f5a478f6 | 28 | f->buffer = av_malloc(size); |
4497712f | 29 | f->end = f->buffer + size; |
f5a478f6 RS |
30 | if (!f->buffer) |
31 | return -1; | |
f5a478f6 RS |
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 | { | |
765d4f3b | 53 | return av_fifo_generic_read(f, buf_size, NULL, buf); |
f5a478f6 RS |
54 | } |
55 | ||
56 | /** | |
57 | * Resizes a FIFO. | |
58 | */ | |
59 | void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) { | |
60 | unsigned int old_size= f->end - f->buffer; | |
61 | ||
62 | if(old_size < new_size){ | |
96e39edc MN |
63 | int len= av_fifo_size(f); |
64 | AVFifoBuffer f2; | |
f5a478f6 | 65 | |
96e39edc MN |
66 | av_fifo_init(&f2, new_size); |
67 | av_fifo_read(f, f2.buffer, len); | |
68 | f2.wptr += len; | |
69 | av_free(f->buffer); | |
70 | *f= f2; | |
f5a478f6 RS |
71 | } |
72 | } | |
73 | ||
74 | void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size) | |
75 | { | |
49cec199 BA |
76 | av_fifo_generic_write(f, (void *)buf, size, NULL); |
77 | } | |
78 | ||
79 | int av_fifo_generic_write(AVFifoBuffer *f, void *buf, int size, int (*func)(void*, void*, int)) | |
80 | { | |
81 | int total = size; | |
50b44685 | 82 | do { |
870a12d1 | 83 | int len = FFMIN(f->end - f->wptr, size); |
49cec199 BA |
84 | if(func) { |
85 | if(func(buf, f->wptr, len) <= 0) | |
86 | break; | |
87 | } else { | |
f5a478f6 | 88 | memcpy(f->wptr, buf, len); |
49cec199 BA |
89 | buf = (uint8_t*)buf + len; |
90 | } | |
f5a478f6 RS |
91 | f->wptr += len; |
92 | if (f->wptr >= f->end) | |
93 | f->wptr = f->buffer; | |
f5a478f6 | 94 | size -= len; |
50b44685 | 95 | } while (size > 0); |
49cec199 | 96 | return total - size; |
f5a478f6 RS |
97 | } |
98 | ||
99 | ||
be65b41f | 100 | /** get data from the fifo (return -1 if not enough data) */ |
f5a478f6 RS |
101 | int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest) |
102 | { | |
870a12d1 | 103 | int size = av_fifo_size(f); |
f5a478f6 RS |
104 | |
105 | if (size < buf_size) | |
106 | return -1; | |
50b44685 | 107 | do { |
870a12d1 | 108 | int len = FFMIN(f->end - f->rptr, buf_size); |
765d4f3b MN |
109 | if(func) func(dest, f->rptr, len); |
110 | else{ | |
111 | memcpy(dest, f->rptr, len); | |
112 | dest = (uint8_t*)dest + len; | |
113 | } | |
3da97cfd | 114 | av_fifo_drain(f, len); |
f5a478f6 | 115 | buf_size -= len; |
50b44685 | 116 | } while (buf_size > 0); |
f5a478f6 RS |
117 | return 0; |
118 | } | |
119 | ||
be65b41f | 120 | /** discard data from the fifo */ |
f5a478f6 RS |
121 | void av_fifo_drain(AVFifoBuffer *f, int size) |
122 | { | |
123 | f->rptr += size; | |
124 | if (f->rptr >= f->end) | |
125 | f->rptr -= f->end - f->buffer; | |
126 | } |