Libav
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
{
64
unsigned
int
old_size = f->
end
- f->
buffer
;
65
66
if
(old_size < new_size) {
67
int
len
=
av_fifo_size
(f);
68
AVFifoBuffer
*f2 =
av_fifo_alloc
(new_size);
69
70
if
(!f2)
71
return
-1;
72
av_fifo_generic_read
(f, f2->
buffer
, len,
NULL
);
73
f2->
wptr
+=
len
;
74
f2->
wndx
+=
len
;
75
av_free
(f->
buffer
);
76
*f = *f2;
77
av_free
(f2);
78
}
79
return
0;
80
}
81
82
/* src must NOT be const as it can be a context for func that may need
83
* updating (like a pointer or byte counter) */
84
int
av_fifo_generic_write
(
AVFifoBuffer
*f,
void
*src,
int
size
,
85
int
(*func)(
void
*,
void
*,
int
))
86
{
87
int
total =
size
;
88
do
{
89
int
len
=
FFMIN
(f->
end
- f->
wptr
, size);
90
if
(func) {
91
if
(func(src, f->
wptr
, len) <= 0)
92
break
;
93
}
else
{
94
memcpy(f->
wptr
, src, len);
95
src = (
uint8_t
*)src + len;
96
}
97
// Write memory barrier needed for SMP here in theory
98
f->
wptr
+=
len
;
99
if
(f->
wptr
>= f->
end
)
100
f->
wptr
= f->
buffer
;
101
f->
wndx
+=
len
;
102
size -=
len
;
103
}
while
(size > 0);
104
return
total -
size
;
105
}
106
107
int
av_fifo_generic_read
(
AVFifoBuffer
*f,
void
*dest,
int
buf_size,
108
void
(*func)(
void
*,
void
*,
int
))
109
{
110
// Read memory barrier needed for SMP here in theory
111
do
{
112
int
len
=
FFMIN
(f->
end
- f->
rptr
, buf_size);
113
if
(func)
114
func(dest, f->
rptr
, len);
115
else
{
116
memcpy(dest, f->
rptr
, len);
117
dest = (
uint8_t
*)dest + len;
118
}
119
// memory barrier needed for SMP here in theory
120
av_fifo_drain
(f, len);
121
buf_size -=
len
;
122
}
while
(buf_size > 0);
123
return
0;
124
}
125
127
void
av_fifo_drain
(
AVFifoBuffer
*f,
int
size)
128
{
129
f->
rptr
+=
size
;
130
if
(f->
rptr
>= f->
end
)
131
f->
rptr
-= f->
end
- f->
buffer
;
132
f->
rndx
+=
size
;
133
}
134
135
#ifdef TEST
136
137
int
main
(
void
)
138
{
139
/* create a FIFO buffer */
140
AVFifoBuffer
*fifo =
av_fifo_alloc
(13 *
sizeof
(
int
));
141
int
i, j, n;
142
143
/* fill data */
144
for
(i = 0;
av_fifo_space
(fifo) >=
sizeof
(int); i++)
145
av_fifo_generic_write
(fifo, &i,
sizeof
(
int
),
NULL
);
146
147
/* peek at FIFO */
148
n =
av_fifo_size
(fifo) /
sizeof
(int);
149
for
(i = -n + 1; i < n; i++) {
150
int
*v = (
int
*)
av_fifo_peek2
(fifo, i *
sizeof
(
int
));
151
printf(
"%d: %d\n"
, i, *v);
152
}
153
printf(
"\n"
);
154
155
/* read data */
156
for
(i = 0;
av_fifo_size
(fifo) >=
sizeof
(int); i++) {
157
av_fifo_generic_read
(fifo, &j,
sizeof
(
int
),
NULL
);
158
printf(
"%d "
, j);
159
}
160
printf(
"\n"
);
161
162
av_fifo_free
(fifo);
163
164
return
0;
165
}
166
167
#endif
Generated on Thu Sep 30 2021 23:03:18 for Libav by
1.8.1.2