Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
aiffdec.c
Go to the documentation of this file.
1
/*
2
* AIFF/AIFF-C demuxer
3
* Copyright (c) 2006 Patrick Guimond
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
libavutil/mathematics.h
"
23
#include "
libavutil/dict.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
#include "
pcm.h
"
27
#include "
aiff.h
"
28
29
#define AIFF 0
30
#define AIFF_C_VERSION1 0xA2805140
31
32
typedef
struct
{
33
int64_t
data_end
;
34
}
AIFFInputContext
;
35
36
static
enum
CodecID
aiff_codec_get_id
(
int
bps
)
37
{
38
if
(bps <= 8)
39
return
CODEC_ID_PCM_S8
;
40
if
(bps <= 16)
41
return
CODEC_ID_PCM_S16BE
;
42
if
(bps <= 24)
43
return
CODEC_ID_PCM_S24BE
;
44
if
(bps <= 32)
45
return
CODEC_ID_PCM_S32BE
;
46
47
/* bigger than 32 isn't allowed */
48
return
CODEC_ID_NONE
;
49
}
50
51
/* returns the size of the found tag */
52
static
int
get_tag
(
AVIOContext
*pb, uint32_t *
tag
)
53
{
54
int
size
;
55
56
if
(pb->
eof_reached
)
57
return
AVERROR
(EIO);
58
59
*tag =
avio_rl32
(pb);
60
size =
avio_rb32
(pb);
61
62
if
(size < 0)
63
size = 0x7fffffff;
64
65
return
size
;
66
}
67
68
/* Metadata string read */
69
static
void
get_meta
(
AVFormatContext
*s,
const
char
*key,
int
size
)
70
{
71
uint8_t *str =
av_malloc
(size+1);
72
int
res;
73
74
if
(!str) {
75
avio_skip
(s->
pb
, size);
76
return
;
77
}
78
79
res =
avio_read
(s->
pb
, str, size);
80
if
(res < 0)
81
return
;
82
83
str[res] = 0;
84
av_dict_set
(&s->
metadata
, key, str,
AV_DICT_DONT_STRDUP_VAL
);
85
}
86
87
/* Returns the number of sound data frames or negative on error */
88
static
unsigned
int
get_aiff_header
(
AVIOContext
*pb,
AVCodecContext
*codec,
89
int
size
,
unsigned
version
)
90
{
91
int
exp;
92
uint64_t val;
93
double
sample_rate;
94
unsigned
int
num_frames;
95
96
if
(size & 1)
97
size++;
98
codec->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
99
codec->
channels
=
avio_rb16
(pb);
100
num_frames =
avio_rb32
(pb);
101
codec->
bits_per_coded_sample
=
avio_rb16
(pb);
102
103
exp =
avio_rb16
(pb);
104
val =
avio_rb64
(pb);
105
sample_rate = ldexp(val, exp - 16383 - 63);
106
codec->
sample_rate
= sample_rate;
107
size -= 18;
108
109
/* Got an AIFF-C? */
110
if
(version ==
AIFF_C_VERSION1
) {
111
codec->
codec_tag
=
avio_rl32
(pb);
112
codec->
codec_id
=
ff_codec_get_id
(
ff_codec_aiff_tags
, codec->
codec_tag
);
113
114
switch
(codec->
codec_id
) {
115
case
CODEC_ID_PCM_S16BE
:
116
codec->
codec_id
=
aiff_codec_get_id
(codec->
bits_per_coded_sample
);
117
codec->
bits_per_coded_sample
=
av_get_bits_per_sample
(codec->
codec_id
);
118
break
;
119
case
CODEC_ID_ADPCM_IMA_QT
:
120
codec->
block_align
= 34*codec->
channels
;
121
codec->
frame_size
= 64;
122
break
;
123
case
CODEC_ID_MACE3
:
124
codec->
block_align
= 2*codec->
channels
;
125
codec->
frame_size
= 6;
126
break
;
127
case
CODEC_ID_MACE6
:
128
codec->
block_align
= 1*codec->
channels
;
129
codec->
frame_size
= 6;
130
break
;
131
case
CODEC_ID_GSM
:
132
codec->
block_align
= 33;
133
codec->
frame_size
= 160;
134
break
;
135
case
CODEC_ID_QCELP
:
136
codec->
block_align
= 35;
137
codec->
frame_size
= 160;
138
break
;
139
default
:
140
break
;
141
}
142
size -= 4;
143
}
else
{
144
/* Need the codec type */
145
codec->
codec_id
=
aiff_codec_get_id
(codec->
bits_per_coded_sample
);
146
codec->
bits_per_coded_sample
=
av_get_bits_per_sample
(codec->
codec_id
);
147
}
148
149
/* Block align needs to be computed in all cases, as the definition
150
* is specific to applications -> here we use the WAVE format definition */
151
if
(!codec->
block_align
)
152
codec->
block_align
= (codec->
bits_per_coded_sample
* codec->
channels
) >> 3;
153
154
codec->
bit_rate
= (codec->
frame_size
? codec->
sample_rate
/codec->
frame_size
:
155
codec->
sample_rate
) * (codec->
block_align
<< 3);
156
157
/* Chunk is over */
158
if
(size)
159
avio_skip
(pb, size);
160
161
return
num_frames;
162
}
163
164
static
int
aiff_probe
(
AVProbeData
*p)
165
{
166
/* check file header */
167
if
(p->
buf
[0] ==
'F'
&& p->
buf
[1] ==
'O'
&&
168
p->
buf
[2] ==
'R'
&& p->
buf
[3] ==
'M'
&&
169
p->
buf
[8] ==
'A'
&& p->
buf
[9] ==
'I'
&&
170
p->
buf
[10] ==
'F'
&& (p->
buf
[11] ==
'F'
|| p->
buf
[11] ==
'C'
))
171
return
AVPROBE_SCORE_MAX
;
172
else
173
return
0;
174
}
175
176
/* aiff input */
177
static
int
aiff_read_header
(
AVFormatContext
*s,
178
AVFormatParameters
*ap)
179
{
180
int
size
, filesize;
181
int64_t offset = 0;
182
uint32_t
tag
;
183
unsigned
version
=
AIFF_C_VERSION1
;
184
AVIOContext
*pb = s->
pb
;
185
AVStream
* st;
186
AIFFInputContext
*aiff = s->
priv_data
;
187
188
/* check FORM header */
189
filesize =
get_tag
(pb, &tag);
190
if
(filesize < 0 || tag !=
MKTAG
(
'F'
,
'O'
,
'R'
,
'M'
))
191
return
AVERROR_INVALIDDATA
;
192
193
/* AIFF data type */
194
tag =
avio_rl32
(pb);
195
if
(tag ==
MKTAG
(
'A'
,
'I'
,
'F'
,
'F'
))
/* Got an AIFF file */
196
version =
AIFF
;
197
else
if
(tag !=
MKTAG
(
'A'
,
'I'
,
'F'
,
'C'
))
/* An AIFF-C file then */
198
return
AVERROR_INVALIDDATA
;
199
200
filesize -= 4;
201
202
st =
avformat_new_stream
(s,
NULL
);
203
if
(!st)
204
return
AVERROR
(ENOMEM);
205
206
while
(filesize > 0) {
207
/* parse different chunks */
208
size =
get_tag
(pb, &tag);
209
if
(size < 0)
210
return
size
;
211
212
filesize -= size + 8;
213
214
switch
(tag) {
215
case
MKTAG
(
'C'
,
'O'
,
'M'
,
'M'
):
/* Common chunk */
216
/* Then for the complete header info */
217
st->
nb_frames
=
get_aiff_header
(pb, st->
codec
, size, version);
218
if
(st->
nb_frames
< 0)
219
return
st->
nb_frames
;
220
if
(offset > 0)
// COMM is after SSND
221
goto
got_sound;
222
break
;
223
case
MKTAG
(
'F'
,
'V'
,
'E'
,
'R'
):
/* Version chunk */
224
version =
avio_rb32
(pb);
225
break
;
226
case
MKTAG
(
'N'
,
'A'
,
'M'
,
'E'
):
/* Sample name chunk */
227
get_meta
(s,
"title"
, size);
228
break
;
229
case
MKTAG
(
'A'
,
'U'
,
'T'
,
'H'
):
/* Author chunk */
230
get_meta
(s,
"author"
, size);
231
break
;
232
case
MKTAG
(
'('
,
'c'
,
')'
,
' '
):
/* Copyright chunk */
233
get_meta
(s,
"copyright"
, size);
234
break
;
235
case
MKTAG
(
'A'
,
'N'
,
'N'
,
'O'
):
/* Annotation chunk */
236
get_meta
(s,
"comment"
, size);
237
break
;
238
case
MKTAG
(
'S'
,
'S'
,
'N'
,
'D'
):
/* Sampled sound chunk */
239
aiff->
data_end
=
avio_tell
(pb) +
size
;
240
offset =
avio_rb32
(pb);
/* Offset of sound data */
241
avio_rb32
(pb);
/* BlockSize... don't care */
242
offset +=
avio_tell
(pb);
/* Compute absolute data offset */
243
if
(st->
codec
->
block_align
)
/* Assume COMM already parsed */
244
goto
got_sound;
245
if
(!pb->
seekable
) {
246
av_log
(s,
AV_LOG_ERROR
,
"file is not seekable\n"
);
247
return
-1;
248
}
249
avio_skip
(pb, size - 8);
250
break
;
251
case
MKTAG
(
'w'
,
'a'
,
'v'
,
'e'
):
252
if
((uint64_t)size > (1<<30))
253
return
-1;
254
st->
codec
->
extradata
=
av_mallocz
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
255
if
(!st->
codec
->
extradata
)
256
return
AVERROR
(ENOMEM);
257
st->
codec
->
extradata_size
=
size
;
258
avio_read
(pb, st->
codec
->
extradata
, size);
259
break
;
260
default
:
/* Jump */
261
if
(size & 1)
/* Always even aligned */
262
size++;
263
avio_skip
(pb, size);
264
}
265
}
266
267
got_sound:
268
if
(!st->
codec
->
block_align
) {
269
av_log
(s,
AV_LOG_ERROR
,
"could not find COMM tag or invalid block_align value\n"
);
270
return
-1;
271
}
272
273
/* Now positioned, get the sound data start and end */
274
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
275
st->
start_time
= 0;
276
st->
duration
= st->
codec
->
frame_size
?
277
st->
nb_frames
* st->
codec
->
frame_size
: st->
nb_frames
;
278
279
/* Position the stream at the first block */
280
avio_seek
(pb, offset, SEEK_SET);
281
282
return
0;
283
}
284
285
#define MAX_SIZE 4096
286
287
static
int
aiff_read_packet
(
AVFormatContext
*s,
288
AVPacket
*pkt)
289
{
290
AVStream
*st = s->
streams
[0];
291
AIFFInputContext
*aiff = s->
priv_data
;
292
int64_t max_size;
293
int
res,
size
;
294
295
/* calculate size of remaining data */
296
max_size = aiff->
data_end
-
avio_tell
(s->
pb
);
297
if
(max_size <= 0)
298
return
AVERROR_EOF
;
299
300
/* Now for that packet */
301
if
(st->
codec
->
block_align
>= 33)
// GSM, QCLP, IMA4
302
size = st->
codec
->
block_align
;
303
else
304
size = (
MAX_SIZE
/ st->
codec
->
block_align
) * st->
codec
->
block_align
;
305
size =
FFMIN
(max_size, size);
306
res =
av_get_packet
(s->
pb
, pkt, size);
307
if
(res < 0)
308
return
res;
309
310
/* Only one stream in an AIFF file */
311
pkt->
stream_index
= 0;
312
return
0;
313
}
314
315
AVInputFormat
ff_aiff_demuxer
= {
316
.
name
=
"aiff"
,
317
.long_name =
NULL_IF_CONFIG_SMALL
(
"Audio IFF"
),
318
.priv_data_size =
sizeof
(
AIFFInputContext
),
319
.
read_probe
=
aiff_probe
,
320
.
read_header
=
aiff_read_header
,
321
.
read_packet
=
aiff_read_packet
,
322
.
read_seek
=
pcm_read_seek
,
323
.codec_tag= (
const
AVCodecTag
*
const
[]){
ff_codec_aiff_tags
, 0},
324
};