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
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 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
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/mathematics.h
"
24
#include "
libavutil/dict.h
"
25
#include "
avformat.h
"
26
#include "
internal.h
"
27
#include "
pcm.h
"
28
#include "
aiff.h
"
29
#include "
isom.h
"
30
#include "
id3v2.h
"
31
#include "
mov_chan.h
"
32
33
#define AIFF 0
34
#define AIFF_C_VERSION1 0xA2805140
35
36
typedef
struct
{
37
int64_t
data_end
;
38
int
block_duration
;
39
}
AIFFInputContext
;
40
41
static
enum
AVCodecID
aiff_codec_get_id
(
int
bps
)
42
{
43
if
(bps <= 8)
44
return
AV_CODEC_ID_PCM_S8
;
45
if
(bps <= 16)
46
return
AV_CODEC_ID_PCM_S16BE
;
47
if
(bps <= 24)
48
return
AV_CODEC_ID_PCM_S24BE
;
49
if
(bps <= 32)
50
return
AV_CODEC_ID_PCM_S32BE
;
51
52
/* bigger than 32 isn't allowed */
53
return
AV_CODEC_ID_NONE
;
54
}
55
56
/* returns the size of the found tag */
57
static
int
get_tag
(
AVIOContext
*pb, uint32_t *
tag
)
58
{
59
int
size
;
60
61
if
(
url_feof
(pb))
62
return
AVERROR
(EIO);
63
64
*tag =
avio_rl32
(pb);
65
size =
avio_rb32
(pb);
66
67
if
(size < 0)
68
size = 0x7fffffff;
69
70
return
size
;
71
}
72
73
/* Metadata string read */
74
static
void
get_meta
(
AVFormatContext
*
s
,
const
char
*key,
int
size
)
75
{
76
uint8_t
*str =
av_malloc
(size+1);
77
78
if
(str) {
79
int
res
=
avio_read
(s->
pb
, str, size);
80
if
(res < 0){
81
av_free
(str);
82
return
;
83
}
84
size += (size&1)-res;
85
str[
res
] = 0;
86
av_dict_set
(&s->
metadata
, key, str,
AV_DICT_DONT_STRDUP_VAL
);
87
}
else
88
size+= size&1;
89
90
avio_skip
(s->
pb
, size);
91
}
92
93
/* Returns the number of sound data frames or negative on error */
94
static
unsigned
int
get_aiff_header
(
AVFormatContext
*
s
,
int
size
,
95
unsigned
version
)
96
{
97
AVIOContext
*pb = s->
pb
;
98
AVCodecContext
*codec = s->
streams
[0]->
codec
;
99
AIFFInputContext
*aiff = s->
priv_data
;
100
int
exp;
101
uint64_t
val
;
102
double
sample_rate
;
103
unsigned
int
num_frames;
104
105
if
(size & 1)
106
size++;
107
codec->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
108
codec->
channels
=
avio_rb16
(pb);
109
num_frames =
avio_rb32
(pb);
110
codec->
bits_per_coded_sample
=
avio_rb16
(pb);
111
112
exp =
avio_rb16
(pb);
113
val =
avio_rb64
(pb);
114
sample_rate = ldexp(val, exp - 16383 - 63);
115
codec->
sample_rate
=
sample_rate
;
116
size -= 18;
117
118
/* get codec id for AIFF-C */
119
if
(version ==
AIFF_C_VERSION1
) {
120
codec->
codec_tag
=
avio_rl32
(pb);
121
codec->
codec_id
=
ff_codec_get_id
(
ff_codec_aiff_tags
, codec->
codec_tag
);
122
size -= 4;
123
}
124
125
if
(version !=
AIFF_C_VERSION1
|| codec->
codec_id
==
AV_CODEC_ID_PCM_S16BE
) {
126
codec->
codec_id
=
aiff_codec_get_id
(codec->
bits_per_coded_sample
);
127
codec->
bits_per_coded_sample
=
av_get_bits_per_sample
(codec->
codec_id
);
128
aiff->
block_duration
= 1;
129
}
else
{
130
switch
(codec->
codec_id
) {
131
case
AV_CODEC_ID_PCM_F32BE
:
132
case
AV_CODEC_ID_PCM_F64BE
:
133
case
AV_CODEC_ID_PCM_S16LE
:
134
case
AV_CODEC_ID_PCM_ALAW
:
135
case
AV_CODEC_ID_PCM_MULAW
:
136
aiff->
block_duration
= 1;
137
break
;
138
case
AV_CODEC_ID_ADPCM_IMA_QT
:
139
codec->
block_align
= 34*codec->
channels
;
140
break
;
141
case
AV_CODEC_ID_MACE3
:
142
codec->
block_align
= 2*codec->
channels
;
143
break
;
144
case
AV_CODEC_ID_ADPCM_G726LE
:
145
codec->
bits_per_coded_sample
= 5;
146
case
AV_CODEC_ID_ADPCM_G722
:
147
case
AV_CODEC_ID_MACE6
:
148
codec->
block_align
= 1*codec->
channels
;
149
break
;
150
case
AV_CODEC_ID_GSM
:
151
codec->
block_align
= 33;
152
break
;
153
default
:
154
aiff->
block_duration
= 1;
155
break
;
156
}
157
if
(codec->
block_align
> 0)
158
aiff->
block_duration
=
av_get_audio_frame_duration
(codec,
159
codec->
block_align
);
160
}
161
162
/* Block align needs to be computed in all cases, as the definition
163
* is specific to applications -> here we use the WAVE format definition */
164
if
(!codec->
block_align
)
165
codec->
block_align
= (
av_get_bits_per_sample
(codec->
codec_id
) * codec->
channels
) >> 3;
166
167
if
(aiff->
block_duration
) {
168
codec->
bit_rate
= codec->
sample_rate
* (codec->
block_align
<< 3) /
169
aiff->
block_duration
;
170
}
171
172
/* Chunk is over */
173
if
(size)
174
avio_skip
(pb, size);
175
176
return
num_frames;
177
}
178
179
static
int
aiff_probe
(
AVProbeData
*p)
180
{
181
/* check file header */
182
if
(p->
buf
[0] ==
'F'
&& p->
buf
[1] ==
'O'
&&
183
p->
buf
[2] ==
'R'
&& p->
buf
[3] ==
'M'
&&
184
p->
buf
[8] ==
'A'
&& p->
buf
[9] ==
'I'
&&
185
p->
buf
[10] ==
'F'
&& (p->
buf
[11] ==
'F'
|| p->
buf
[11] ==
'C'
))
186
return
AVPROBE_SCORE_MAX
;
187
else
188
return
0;
189
}
190
191
/* aiff input */
192
static
int
aiff_read_header
(
AVFormatContext
*
s
)
193
{
194
int
ret
,
size
, filesize;
195
int64_t
offset
= 0, position;
196
uint32_t
tag
;
197
unsigned
version
=
AIFF_C_VERSION1
;
198
AVIOContext
*pb = s->
pb
;
199
AVStream
* st;
200
AIFFInputContext
*aiff = s->
priv_data
;
201
ID3v2ExtraMeta
*id3v2_extra_meta = NULL;
202
203
/* check FORM header */
204
filesize =
get_tag
(pb, &tag);
205
if
(filesize < 0 || tag !=
MKTAG
(
'F'
,
'O'
,
'R'
,
'M'
))
206
return
AVERROR_INVALIDDATA
;
207
208
/* AIFF data type */
209
tag =
avio_rl32
(pb);
210
if
(tag ==
MKTAG
(
'A'
,
'I'
,
'F'
,
'F'
))
/* Got an AIFF file */
211
version =
AIFF
;
212
else
if
(tag !=
MKTAG
(
'A'
,
'I'
,
'F'
,
'C'
))
/* An AIFF-C file then */
213
return
AVERROR_INVALIDDATA
;
214
215
filesize -= 4;
216
217
st =
avformat_new_stream
(s, NULL);
218
if
(!st)
219
return
AVERROR
(ENOMEM);
220
221
while
(filesize > 0) {
222
/* parse different chunks */
223
size =
get_tag
(pb, &tag);
224
if
(size < 0)
225
return
size
;
226
227
filesize -= size + 8;
228
229
switch
(tag) {
230
case
MKTAG
(
'C'
,
'O'
,
'M'
,
'M'
):
/* Common chunk */
231
/* Then for the complete header info */
232
st->
nb_frames
=
get_aiff_header
(s, size, version);
233
if
(st->
nb_frames
< 0)
234
return
st->
nb_frames
;
235
if
(offset > 0)
// COMM is after SSND
236
goto
got_sound;
237
break
;
238
case
MKTAG
(
'I'
,
'D'
,
'3'
,
' '
):
239
position =
avio_tell
(pb);
240
ff_id3v2_read
(s,
ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta);
241
if
(id3v2_extra_meta)
242
if
((ret =
ff_id3v2_parse_apic
(s, &id3v2_extra_meta)) < 0) {
243
ff_id3v2_free_extra_meta
(&id3v2_extra_meta);
244
return
ret
;
245
}
246
ff_id3v2_free_extra_meta
(&id3v2_extra_meta);
247
if
(position + size >
avio_tell
(pb))
248
avio_skip
(pb, position + size -
avio_tell
(pb));
249
break
;
250
case
MKTAG
(
'F'
,
'V'
,
'E'
,
'R'
):
/* Version chunk */
251
version =
avio_rb32
(pb);
252
break
;
253
case
MKTAG
(
'N'
,
'A'
,
'M'
,
'E'
):
/* Sample name chunk */
254
get_meta
(s,
"title"
, size);
255
break
;
256
case
MKTAG
(
'A'
,
'U'
,
'T'
,
'H'
):
/* Author chunk */
257
get_meta
(s,
"author"
, size);
258
break
;
259
case
MKTAG
(
'('
,
'c'
,
')'
,
' '
):
/* Copyright chunk */
260
get_meta
(s,
"copyright"
, size);
261
break
;
262
case
MKTAG
(
'A'
,
'N'
,
'N'
,
'O'
):
/* Annotation chunk */
263
get_meta
(s,
"comment"
, size);
264
break
;
265
case
MKTAG
(
'S'
,
'S'
,
'N'
,
'D'
):
/* Sampled sound chunk */
266
aiff->
data_end
=
avio_tell
(pb) +
size
;
267
offset =
avio_rb32
(pb);
/* Offset of sound data */
268
avio_rb32
(pb);
/* BlockSize... don't care */
269
offset +=
avio_tell
(pb);
/* Compute absolute data offset */
270
if
(st->
codec
->
block_align
&& !pb->
seekable
)
/* Assume COMM already parsed */
271
goto
got_sound;
272
if
(!pb->
seekable
) {
273
av_log
(s,
AV_LOG_ERROR
,
"file is not seekable\n"
);
274
return
-1;
275
}
276
avio_skip
(pb, size - 8);
277
break
;
278
case
MKTAG
(
'w'
,
'a'
,
'v'
,
'e'
):
279
if
((uint64_t)size > (1<<30))
280
return
-1;
281
if
(
ff_get_extradata
(st->
codec
, pb, size) < 0)
282
return
AVERROR
(ENOMEM);
283
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_QDM2
&& size>=12*4 && !st->
codec
->
block_align
) {
284
st->
codec
->
block_align
=
AV_RB32
(st->
codec
->
extradata
+11*4);
285
aiff->
block_duration
=
AV_RB32
(st->
codec
->
extradata
+9*4);
286
}
else
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_QCELP
) {
287
char
rate = 0;
288
if
(size >= 25)
289
rate = st->
codec
->
extradata
[24];
290
switch
(rate) {
291
case
'H'
:
// RATE_HALF
292
st->
codec
->
block_align
= 17;
293
break
;
294
case
'F'
:
// RATE_FULL
295
default
:
296
st->
codec
->
block_align
= 35;
297
}
298
aiff->
block_duration
= 160;
299
st->
codec
->
bit_rate
= st->
codec
->
sample_rate
* (st->
codec
->
block_align
<< 3) /
300
aiff->
block_duration
;
301
}
302
break
;
303
case
MKTAG
(
'C'
,
'H'
,
'A'
,
'N'
):
304
if
(
ff_mov_read_chan
(s, pb, st, size) < 0)
305
return
AVERROR_INVALIDDATA
;
306
break
;
307
default
:
/* Jump */
308
if
(size & 1)
/* Always even aligned */
309
size++;
310
avio_skip
(pb, size);
311
}
312
}
313
314
got_sound:
315
if
(!st->
codec
->
block_align
) {
316
av_log
(s,
AV_LOG_ERROR
,
"could not find COMM tag or invalid block_align value\n"
);
317
return
-1;
318
}
319
320
/* Now positioned, get the sound data start and end */
321
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
322
st->
start_time
= 0;
323
st->
duration
= st->
nb_frames
* aiff->
block_duration
;
324
325
/* Position the stream at the first block */
326
avio_seek
(pb, offset, SEEK_SET);
327
328
return
0;
329
}
330
331
#define MAX_SIZE 4096
332
333
static
int
aiff_read_packet
(
AVFormatContext
*
s
,
334
AVPacket
*
pkt
)
335
{
336
AVStream
*st = s->
streams
[0];
337
AIFFInputContext
*aiff = s->
priv_data
;
338
int64_t max_size;
339
int
res
,
size
;
340
341
/* calculate size of remaining data */
342
max_size = aiff->
data_end
-
avio_tell
(s->
pb
);
343
if
(max_size <= 0)
344
return
AVERROR_EOF
;
345
346
/* Now for that packet */
347
if
(st->
codec
->
block_align
>= 17)
// GSM, QCLP, IMA4
348
size = st->
codec
->
block_align
;
349
else
350
size = (
MAX_SIZE
/ st->
codec
->
block_align
) * st->
codec
->
block_align
;
351
size =
FFMIN
(max_size, size);
352
res =
av_get_packet
(s->
pb
, pkt, size);
353
if
(res < 0)
354
return
res
;
355
356
if
(size >= st->
codec
->
block_align
)
357
pkt->
flags
&= ~
AV_PKT_FLAG_CORRUPT
;
358
/* Only one stream in an AIFF file */
359
pkt->
stream_index
= 0;
360
pkt->
duration
= (res / st->
codec
->
block_align
) * aiff->
block_duration
;
361
return
0;
362
}
363
364
AVInputFormat
ff_aiff_demuxer
= {
365
.
name
=
"aiff"
,
366
.long_name =
NULL_IF_CONFIG_SMALL
(
"Audio IFF"
),
367
.priv_data_size =
sizeof
(
AIFFInputContext
),
368
.
read_probe
=
aiff_probe
,
369
.
read_header
=
aiff_read_header
,
370
.
read_packet
=
aiff_read_packet
,
371
.
read_seek
=
ff_pcm_read_seek
,
372
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_codec_aiff_tags
, 0 },
373
};
Generated on Sun Mar 23 2014 23:50:10 for FFmpeg by
1.8.2