Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavutil
fifo.c
Go to the documentation of this file.
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 file is part of Libav.
7
*
8
* Libav is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* Libav is distributed in the hope that it will be useful,
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
19
* License along with Libav; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
#include "
common.h
"
23
#include "
fifo.h
"
24
25
AVFifoBuffer
*
av_fifo_alloc
(
unsigned
int
size
)
26
{
27
AVFifoBuffer
*
f
=
av_mallocz
(
sizeof
(
AVFifoBuffer
));
28
if
(!f)
29
return
NULL
;
30
f->
buffer
=
av_malloc
(size);
31
f->
end
= f->
buffer
+
size
;
32
av_fifo_reset
(f);
33
if
(!f->
buffer
)
34
av_freep
(&f);
35
return
f
;
36
}
37
38
void
av_fifo_free
(
AVFifoBuffer
*
f
)
39
{
40
if
(f){
41
av_free
(f->
buffer
);
42
av_free
(f);
43
}
44
}
45
46
void
av_fifo_reset
(
AVFifoBuffer
*
f
)
47
{
48
f->
wptr
= f->
rptr
= f->
buffer
;
49
f->
wndx
= f->
rndx
= 0;
50
}
51
52
int
av_fifo_size
(
AVFifoBuffer
*
f
)
53
{
54
return
(uint32_t)(f->
wndx
- f->
rndx
);
55
}
56
57
int
av_fifo_space
(
AVFifoBuffer
*
f
)
58
{
59
return
f->
end
- f->
buffer
-
av_fifo_size
(f);
60
}
61
62
int
av_fifo_realloc2
(
AVFifoBuffer
*
f
,
unsigned
int
new_size) {
63
unsigned
int
old_size= f->
end
- f->
buffer
;
64
65
if
(old_size < new_size){
66
int
len
=
av_fifo_size
(f);
67
AVFifoBuffer
*f2=
av_fifo_alloc
(new_size);
68
69
if
(!f2)
70
return
-1;
71
av_fifo_generic_read
(f, f2->
buffer
, len,
NULL
);
72
f2->
wptr
+=
len
;
73
f2->
wndx
+=
len
;
74
av_free
(f->
buffer
);
75
*f= *f2;
76
av_free
(f2);
77
}
78
return
0;
79
}
80
81
// src must NOT be const as it can be a context for func that may need updating (like a pointer or byte counter)
82
int
av_fifo_generic_write
(
AVFifoBuffer
*
f
,
void
*src,
int
size
,
int
(*func)(
void
*,
void
*,
int
))
83
{
84
int
total =
size
;
85
do
{
86
int
len
=
FFMIN
(f->
end
- f->
wptr
, size);
87
if
(func) {
88
if
(func(src, f->
wptr
, len) <= 0)
89
break
;
90
}
else
{
91
memcpy(f->
wptr
, src, len);
92
src = (uint8_t*)src + len;
93
}
94
// Write memory barrier needed for SMP here in theory
95
f->
wptr
+=
len
;
96
if
(f->
wptr
>= f->
end
)
97
f->
wptr
= f->
buffer
;
98
f->
wndx
+=
len
;
99
size -=
len
;
100
}
while
(size > 0);
101
return
total -
size
;
102
}
103
104
105
int
av_fifo_generic_read
(
AVFifoBuffer
*f,
void
*dest,
int
buf_size,
void
(*func)(
void
*,
void
*,
int
))
106
{
107
// Read memory barrier needed for SMP here in theory
108
do
{
109
int
len
=
FFMIN
(f->
end
- f->
rptr
, buf_size);
110
if
(func) func(dest, f->
rptr
, len);
111
else
{
112
memcpy(dest, f->
rptr
, len);
113
dest = (uint8_t*)dest + len;
114
}
115
// memory barrier needed for SMP here in theory
116
av_fifo_drain
(f, len);
117
buf_size -=
len
;
118
}
while
(buf_size > 0);
119
return
0;
120
}
121
123
void
av_fifo_drain
(
AVFifoBuffer
*f,
int
size)
124
{
125
f->
rptr
+=
size
;
126
if
(f->
rptr
>= f->
end
)
127
f->
rptr
-= f->
end
- f->
buffer
;
128
f->
rndx
+=
size
;
129
}
130
131
#ifdef TEST
132
133
#undef printf
134
135
int
main
(
void
)
136
{
137
/* create a FIFO buffer */
138
AVFifoBuffer
*fifo =
av_fifo_alloc
(13 *
sizeof
(
int
));
139
int
i, j, n;
140
141
/* fill data */
142
for
(i = 0;
av_fifo_space
(fifo) >=
sizeof
(int); i++)
143
av_fifo_generic_write
(fifo, &i,
sizeof
(
int
),
NULL
);
144
145
/* peek at FIFO */
146
n =
av_fifo_size
(fifo)/
sizeof
(int);
147
for
(i = -n+1; i < n; i++) {
148
int
*
v
= (
int
*)
av_fifo_peek2
(fifo, i*
sizeof
(
int
));
149
printf
(
"%d: %d\n"
, i, *v);
150
}
151
printf
(
"\n"
);
152
153
/* read data */
154
for
(i = 0;
av_fifo_size
(fifo) >=
sizeof
(int); i++) {
155
av_fifo_generic_read
(fifo, &j,
sizeof
(
int
),
NULL
);
156
printf
(
"%d "
, j);
157
}
158
printf
(
"\n"
);
159
160
av_fifo_free
(fifo);
161
162
return
0;
163
}
164
165
#endif