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