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_G722
:
145
case
AV_CODEC_ID_MACE6
:
146
codec->
block_align
= 1*codec->
channels
;
147
break
;
148
case
AV_CODEC_ID_GSM
:
149
codec->
block_align
= 33;
150
break
;
151
default
:
152
aiff->
block_duration
= 1;
153
break
;
154
}
155
if
(codec->
block_align
> 0)
156
aiff->
block_duration
=
av_get_audio_frame_duration
(codec,
157
codec->
block_align
);
158
}
159
160
/* Block align needs to be computed in all cases, as the definition
161
* is specific to applications -> here we use the WAVE format definition */
162
if
(!codec->
block_align
)
163
codec->
block_align
= (
av_get_bits_per_sample
(codec->
codec_id
) * codec->
channels
) >> 3;
164
165
if
(aiff->
block_duration
) {
166
codec->
bit_rate
= codec->
sample_rate
* (codec->
block_align
<< 3) /
167
aiff->
block_duration
;
168
}
169
170
/* Chunk is over */
171
if
(size)
172
avio_skip
(pb, size);
173
174
return
num_frames;
175
}
176
177
static
int
aiff_probe
(
AVProbeData
*p)
178
{
179
/* check file header */
180
if
(p->
buf
[0] ==
'F'
&& p->
buf
[1] ==
'O'
&&
181
p->
buf
[2] ==
'R'
&& p->
buf
[3] ==
'M'
&&
182
p->
buf
[8] ==
'A'
&& p->
buf
[9] ==
'I'
&&
183
p->
buf
[10] ==
'F'
&& (p->
buf
[11] ==
'F'
|| p->
buf
[11] ==
'C'
))
184
return
AVPROBE_SCORE_MAX
;
185
else
186
return
0;
187
}
188
189
/* aiff input */
190
static
int
aiff_read_header
(
AVFormatContext
*
s
)
191
{
192
int
ret
,
size
, filesize;
193
int64_t
offset
= 0, position;
194
uint32_t
tag
;
195
unsigned
version
=
AIFF_C_VERSION1
;
196
AVIOContext
*pb = s->
pb
;
197
AVStream
* st;
198
AIFFInputContext
*aiff = s->
priv_data
;
199
ID3v2ExtraMeta
*id3v2_extra_meta = NULL;
200
201
/* check FORM header */
202
filesize =
get_tag
(pb, &tag);
203
if
(filesize < 0 || tag !=
MKTAG
(
'F'
,
'O'
,
'R'
,
'M'
))
204
return
AVERROR_INVALIDDATA
;
205
206
/* AIFF data type */
207
tag =
avio_rl32
(pb);
208
if
(tag ==
MKTAG
(
'A'
,
'I'
,
'F'
,
'F'
))
/* Got an AIFF file */
209
version =
AIFF
;
210
else
if
(tag !=
MKTAG
(
'A'
,
'I'
,
'F'
,
'C'
))
/* An AIFF-C file then */
211
return
AVERROR_INVALIDDATA
;
212
213
filesize -= 4;
214
215
st =
avformat_new_stream
(s, NULL);
216
if
(!st)
217
return
AVERROR
(ENOMEM);
218
219
while
(filesize > 0) {
220
/* parse different chunks */
221
size =
get_tag
(pb, &tag);
222
if
(size < 0)
223
return
size
;
224
225
filesize -= size + 8;
226
227
switch
(tag) {
228
case
MKTAG
(
'C'
,
'O'
,
'M'
,
'M'
):
/* Common chunk */
229
/* Then for the complete header info */
230
st->
nb_frames
=
get_aiff_header
(s, size, version);
231
if
(st->
nb_frames
< 0)
232
return
st->
nb_frames
;
233
if
(offset > 0)
// COMM is after SSND
234
goto
got_sound;
235
break
;
236
case
MKTAG
(
'I'
,
'D'
,
'3'
,
' '
):
237
position =
avio_tell
(pb);
238
ff_id3v2_read
(s,
ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta);
239
if
(id3v2_extra_meta)
240
if
((ret =
ff_id3v2_parse_apic
(s, &id3v2_extra_meta)) < 0) {
241
ff_id3v2_free_extra_meta
(&id3v2_extra_meta);
242
return
ret
;
243
}
244
ff_id3v2_free_extra_meta
(&id3v2_extra_meta);
245
if
(position + size >
avio_tell
(pb))
246
avio_skip
(pb, position + size -
avio_tell
(pb));
247
break
;
248
case
MKTAG
(
'F'
,
'V'
,
'E'
,
'R'
):
/* Version chunk */
249
version =
avio_rb32
(pb);
250
break
;
251
case
MKTAG
(
'N'
,
'A'
,
'M'
,
'E'
):
/* Sample name chunk */
252
get_meta
(s,
"title"
, size);
253
break
;
254
case
MKTAG
(
'A'
,
'U'
,
'T'
,
'H'
):
/* Author chunk */
255
get_meta
(s,
"author"
, size);
256
break
;
257
case
MKTAG
(
'('
,
'c'
,
')'
,
' '
):
/* Copyright chunk */
258
get_meta
(s,
"copyright"
, size);
259
break
;
260
case
MKTAG
(
'A'
,
'N'
,
'N'
,
'O'
):
/* Annotation chunk */
261
get_meta
(s,
"comment"
, size);
262
break
;
263
case
MKTAG
(
'S'
,
'S'
,
'N'
,
'D'
):
/* Sampled sound chunk */
264
aiff->
data_end
=
avio_tell
(pb) +
size
;
265
offset =
avio_rb32
(pb);
/* Offset of sound data */
266
avio_rb32
(pb);
/* BlockSize... don't care */
267
offset +=
avio_tell
(pb);
/* Compute absolute data offset */
268
if
(st->
codec
->
block_align
&& !pb->
seekable
)
/* Assume COMM already parsed */
269
goto
got_sound;
270
if
(!pb->
seekable
) {
271
av_log
(s,
AV_LOG_ERROR
,
"file is not seekable\n"
);
272
return
-1;
273
}
274
avio_skip
(pb, size - 8);
275
break
;
276
case
MKTAG
(
'w'
,
'a'
,
'v'
,
'e'
):
277
if
((uint64_t)size > (1<<30))
278
return
-1;
279
st->
codec
->
extradata
=
av_mallocz
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
280
if
(!st->
codec
->
extradata
)
281
return
AVERROR
(ENOMEM);
282
st->
codec
->
extradata_size
=
size
;
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 Wed Jul 10 2013 23:48:11 for FFmpeg by
1.8.2