FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavutil
audio_fifo.c
Go to the documentation of this file.
1
/*
2
* Audio FIFO
3
* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
/**
23
* @file
24
* Audio FIFO
25
*/
26
27
#include "
avutil.h
"
28
#include "
audio_fifo.h
"
29
#include "
common.h
"
30
#include "
fifo.h
"
31
#include "
mem.h
"
32
#include "
samplefmt.h
"
33
34
struct
AVAudioFifo
{
35
AVFifoBuffer
**
buf
;
/**< single buffer for interleaved, per-channel buffers for planar */
36
int
nb_buffers
;
/**< number of buffers */
37
int
nb_samples
;
/**< number of samples currently in the FIFO */
38
int
allocated_samples
;
/**< current allocated size, in samples */
39
40
int
channels
;
/**< number of channels */
41
enum
AVSampleFormat
sample_fmt
;
/**< sample format */
42
int
sample_size
;
/**< size, in bytes, of one sample in a buffer */
43
};
44
45
void
av_audio_fifo_free
(
AVAudioFifo
*af)
46
{
47
if
(af) {
48
if
(af->
buf
) {
49
int
i;
50
for
(i = 0; i < af->
nb_buffers
; i++) {
51
if
(af->
buf
[i])
52
av_fifo_free
(af->
buf
[i]);
53
}
54
av_free
(af->
buf
);
55
}
56
av_free
(af);
57
}
58
}
59
60
AVAudioFifo
*
av_audio_fifo_alloc
(
enum
AVSampleFormat
sample_fmt,
int
channels,
61
int
nb_samples)
62
{
63
AVAudioFifo
*af;
64
int
buf_size, i;
65
66
/* get channel buffer size (also validates parameters) */
67
if
(
av_samples_get_buffer_size
(&buf_size, channels, nb_samples, sample_fmt, 1) < 0)
68
return
NULL;
69
70
af =
av_mallocz
(
sizeof
(*af));
71
if
(!af)
72
return
NULL;
73
74
af->
channels
= channels;
75
af->
sample_fmt
= sample_fmt;
76
af->
sample_size
= buf_size / nb_samples;
77
af->
nb_buffers
=
av_sample_fmt_is_planar
(sample_fmt) ? channels : 1;
78
79
af->
buf
=
av_mallocz_array
(af->
nb_buffers
,
sizeof
(*af->
buf
));
80
if
(!af->
buf
)
81
goto
error;
82
83
for
(i = 0; i < af->
nb_buffers
; i++) {
84
af->
buf
[i] =
av_fifo_alloc
(buf_size);
85
if
(!af->
buf
[i])
86
goto
error;
87
}
88
af->
allocated_samples
= nb_samples;
89
90
return
af;
91
92
error:
93
av_audio_fifo_free
(af);
94
return
NULL;
95
}
96
97
int
av_audio_fifo_realloc
(
AVAudioFifo
*af,
int
nb_samples)
98
{
99
int
i,
ret
, buf_size;
100
101
if
((ret =
av_samples_get_buffer_size
(&buf_size, af->
channels
, nb_samples,
102
af->
sample_fmt
, 1)) < 0)
103
return
ret
;
104
105
for
(i = 0; i < af->
nb_buffers
; i++) {
106
if
((ret =
av_fifo_realloc2
(af->
buf
[i], buf_size)) < 0)
107
return
ret
;
108
}
109
af->
allocated_samples
= nb_samples;
110
return
0;
111
}
112
113
int
av_audio_fifo_write
(
AVAudioFifo
*af,
void
**
data
,
int
nb_samples)
114
{
115
int
i,
ret
,
size
;
116
117
/* automatically reallocate buffers if needed */
118
if
(
av_audio_fifo_space
(af) < nb_samples) {
119
int
current_size =
av_audio_fifo_size
(af);
120
/* check for integer overflow in new size calculation */
121
if
(INT_MAX / 2 - current_size < nb_samples)
122
return
AVERROR
(EINVAL);
123
/* reallocate buffers */
124
if
((ret =
av_audio_fifo_realloc
(af, 2 * (current_size + nb_samples))) < 0)
125
return
ret
;
126
}
127
128
size = nb_samples * af->
sample_size
;
129
for
(i = 0; i < af->
nb_buffers
; i++) {
130
ret =
av_fifo_generic_write
(af->
buf
[i], data[i], size, NULL);
131
if
(ret != size)
132
return
AVERROR_BUG
;
133
}
134
af->
nb_samples
+= nb_samples;
135
136
return
nb_samples;
137
}
138
139
int
av_audio_fifo_read
(
AVAudioFifo
*af,
void
**
data
,
int
nb_samples)
140
{
141
int
i,
ret
,
size
;
142
143
if
(nb_samples < 0)
144
return
AVERROR
(EINVAL);
145
nb_samples =
FFMIN
(nb_samples, af->
nb_samples
);
146
if
(!nb_samples)
147
return
0;
148
149
size = nb_samples * af->
sample_size
;
150
for
(i = 0; i < af->
nb_buffers
; i++) {
151
if
((ret =
av_fifo_generic_read
(af->
buf
[i], data[i], size, NULL)) < 0)
152
return
AVERROR_BUG
;
153
}
154
af->
nb_samples
-= nb_samples;
155
156
return
nb_samples;
157
}
158
159
int
av_audio_fifo_drain
(
AVAudioFifo
*af,
int
nb_samples)
160
{
161
int
i,
size
;
162
163
if
(nb_samples < 0)
164
return
AVERROR
(EINVAL);
165
nb_samples =
FFMIN
(nb_samples, af->
nb_samples
);
166
167
if
(nb_samples) {
168
size = nb_samples * af->
sample_size
;
169
for
(i = 0; i < af->
nb_buffers
; i++)
170
av_fifo_drain
(af->
buf
[i], size);
171
af->
nb_samples
-= nb_samples;
172
}
173
return
0;
174
}
175
176
void
av_audio_fifo_reset
(
AVAudioFifo
*af)
177
{
178
int
i;
179
180
for
(i = 0; i < af->
nb_buffers
; i++)
181
av_fifo_reset
(af->
buf
[i]);
182
183
af->
nb_samples
= 0;
184
}
185
186
int
av_audio_fifo_size
(
AVAudioFifo
*af)
187
{
188
return
af->
nb_samples
;
189
}
190
191
int
av_audio_fifo_space
(
AVAudioFifo
*af)
192
{
193
return
af->
allocated_samples
- af->
nb_samples
;
194
}
Generated on Sun Sep 14 2014 18:56:16 for FFmpeg by
1.8.2