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
(
avio_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, size);
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
switch
(st->
codec
->
codec_id
) {
348
case
AV_CODEC_ID_ADPCM_IMA_QT
:
349
case
AV_CODEC_ID_GSM
:
350
case
AV_CODEC_ID_QDM2
:
351
case
AV_CODEC_ID_QCELP
:
352
size = st->
codec
->
block_align
;
353
break
;
354
default
:
355
size = (
MAX_SIZE
/ st->
codec
->
block_align
) * st->
codec
->
block_align
;
356
}
357
size =
FFMIN
(max_size, size);
358
res =
av_get_packet
(s->
pb
, pkt, size);
359
if
(res < 0)
360
return
res;
361
362
if
(size >= st->
codec
->
block_align
)
363
pkt->
flags
&= ~
AV_PKT_FLAG_CORRUPT
;
364
/* Only one stream in an AIFF file */
365
pkt->
stream_index
= 0;
366
pkt->
duration
= (res / st->
codec
->
block_align
) * aiff->
block_duration
;
367
return
0;
368
}
369
370
AVInputFormat
ff_aiff_demuxer
= {
371
.
name
=
"aiff"
,
372
.long_name =
NULL_IF_CONFIG_SMALL
(
"Audio IFF"
),
373
.priv_data_size =
sizeof
(
AIFFInputContext
),
374
.
read_probe
=
aiff_probe
,
375
.
read_header
=
aiff_read_header
,
376
.
read_packet
=
aiff_read_packet
,
377
.
read_seek
=
ff_pcm_read_seek
,
378
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_codec_aiff_tags
, 0 },
379
};
Generated on Fri Dec 5 2014 04:42:10 for FFmpeg by
1.8.2