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_alloc_extradata
(st->
codec
, size))
282
return
AVERROR
(ENOMEM);
283
avio_read
(pb, st->
codec
->
extradata
, size);
284
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_QDM2
&& size>=12*4 && !st->
codec
->
block_align
) {
285
st->
codec
->
block_align
=
AV_RB32
(st->
codec
->
extradata
+11*4);
286
aiff->
block_duration
=
AV_RB32
(st->
codec
->
extradata
+9*4);
287
}
else
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_QCELP
) {
288
char
rate = 0;
289
if
(size >= 25)
290
rate = st->
codec
->
extradata
[24];
291
switch
(rate) {
292
case
'H'
:
// RATE_HALF
293
st->
codec
->
block_align
= 17;
294
break
;
295
case
'F'
:
// RATE_FULL
296
default
:
297
st->
codec
->
block_align
= 35;
298
}
299
aiff->
block_duration
= 160;
300
st->
codec
->
bit_rate
= st->
codec
->
sample_rate
* (st->
codec
->
block_align
<< 3) /
301
aiff->
block_duration
;
302
}
303
break
;
304
case
MKTAG
(
'C'
,
'H'
,
'A'
,
'N'
):
305
if
(
ff_mov_read_chan
(s, pb, st, size) < 0)
306
return
AVERROR_INVALIDDATA
;
307
break
;
308
default
:
/* Jump */
309
if
(size & 1)
/* Always even aligned */
310
size++;
311
avio_skip
(pb, size);
312
}
313
}
314
315
got_sound:
316
if
(!st->
codec
->
block_align
) {
317
av_log
(s,
AV_LOG_ERROR
,
"could not find COMM tag or invalid block_align value\n"
);
318
return
-1;
319
}
320
321
/* Now positioned, get the sound data start and end */
322
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
323
st->
start_time
= 0;
324
st->
duration
= st->
nb_frames
* aiff->
block_duration
;
325
326
/* Position the stream at the first block */
327
avio_seek
(pb, offset, SEEK_SET);
328
329
return
0;
330
}
331
332
#define MAX_SIZE 4096
333
334
static
int
aiff_read_packet
(
AVFormatContext
*
s
,
335
AVPacket
*
pkt
)
336
{
337
AVStream
*st = s->
streams
[0];
338
AIFFInputContext
*aiff = s->
priv_data
;
339
int64_t max_size;
340
int
res
,
size
;
341
342
/* calculate size of remaining data */
343
max_size = aiff->
data_end
-
avio_tell
(s->
pb
);
344
if
(max_size <= 0)
345
return
AVERROR_EOF
;
346
347
/* Now for that packet */
348
if
(st->
codec
->
block_align
>= 17)
// GSM, QCLP, IMA4
349
size = st->
codec
->
block_align
;
350
else
351
size = (
MAX_SIZE
/ st->
codec
->
block_align
) * st->
codec
->
block_align
;
352
size =
FFMIN
(max_size, size);
353
res =
av_get_packet
(s->
pb
, pkt, size);
354
if
(res < 0)
355
return
res
;
356
357
if
(size >= st->
codec
->
block_align
)
358
pkt->
flags
&= ~
AV_PKT_FLAG_CORRUPT
;
359
/* Only one stream in an AIFF file */
360
pkt->
stream_index
= 0;
361
pkt->
duration
= (res / st->
codec
->
block_align
) * aiff->
block_duration
;
362
return
0;
363
}
364
365
AVInputFormat
ff_aiff_demuxer
= {
366
.
name
=
"aiff"
,
367
.long_name =
NULL_IF_CONFIG_SMALL
(
"Audio IFF"
),
368
.priv_data_size =
sizeof
(
AIFFInputContext
),
369
.
read_probe
=
aiff_probe
,
370
.
read_header
=
aiff_read_header
,
371
.
read_packet
=
aiff_read_packet
,
372
.
read_seek
=
ff_pcm_read_seek
,
373
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_codec_aiff_tags
, 0 },
374
};
Generated on Sat Jan 25 2014 19:52:01 for FFmpeg by
1.8.2