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
cafenc.c
Go to the documentation of this file.
1
/*
2
* Core Audio Format muxer
3
* Copyright (c) 2011 Carl Eugen Hoyos
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 "
avformat.h
"
23
#include "
caf.h
"
24
#include "
isom.h
"
25
#include "
avio_internal.h
"
26
#include "
libavutil/intfloat.h
"
27
#include "
libavutil/dict.h
"
28
29
typedef
struct
{
30
int64_t
data
;
31
uint8_t
*
pkt_sizes
;
32
int
size_buffer_size
;
33
int
size_entries_used
;
34
int
packets
;
35
}
CAFContext
;
36
37
static
uint32_t
codec_flags
(
enum
AVCodecID
codec_id
) {
38
switch
(codec_id) {
39
case
AV_CODEC_ID_PCM_F32BE
:
40
case
AV_CODEC_ID_PCM_F64BE
:
41
return
1;
//< kCAFLinearPCMFormatFlagIsFloat
42
case
AV_CODEC_ID_PCM_S16LE
:
43
case
AV_CODEC_ID_PCM_S24LE
:
44
case
AV_CODEC_ID_PCM_S32LE
:
45
return
2;
//< kCAFLinearPCMFormatFlagIsLittleEndian
46
case
AV_CODEC_ID_PCM_F32LE
:
47
case
AV_CODEC_ID_PCM_F64LE
:
48
return
3;
//< kCAFLinearPCMFormatFlagIsFloat | kCAFLinearPCMFormatFlagIsLittleEndian
49
default
:
50
return
0;
51
}
52
}
53
54
static
uint32_t
samples_per_packet
(
enum
AVCodecID
codec_id
,
int
channels) {
55
switch
(codec_id) {
56
case
AV_CODEC_ID_PCM_S8
:
57
case
AV_CODEC_ID_PCM_S16LE
:
58
case
AV_CODEC_ID_PCM_S16BE
:
59
case
AV_CODEC_ID_PCM_S24LE
:
60
case
AV_CODEC_ID_PCM_S24BE
:
61
case
AV_CODEC_ID_PCM_S32LE
:
62
case
AV_CODEC_ID_PCM_S32BE
:
63
case
AV_CODEC_ID_PCM_F32LE
:
64
case
AV_CODEC_ID_PCM_F32BE
:
65
case
AV_CODEC_ID_PCM_F64LE
:
66
case
AV_CODEC_ID_PCM_F64BE
:
67
case
AV_CODEC_ID_PCM_ALAW
:
68
case
AV_CODEC_ID_PCM_MULAW
:
69
return
1;
70
case
AV_CODEC_ID_MACE3
:
71
case
AV_CODEC_ID_MACE6
:
72
return
6;
73
case
AV_CODEC_ID_ADPCM_IMA_QT
:
74
return
64;
75
case
AV_CODEC_ID_AMR_NB
:
76
case
AV_CODEC_ID_GSM
:
77
case
AV_CODEC_ID_ILBC
:
78
case
AV_CODEC_ID_QCELP
:
79
return
160;
80
case
AV_CODEC_ID_GSM_MS
:
81
return
320;
82
case
AV_CODEC_ID_MP1
:
83
return
384;
84
case
AV_CODEC_ID_MP2
:
85
case
AV_CODEC_ID_MP3
:
86
return
1152;
87
case
AV_CODEC_ID_AC3
:
88
return
1536;
89
case
AV_CODEC_ID_QDM2
:
90
return
2048 * channels;
91
case
AV_CODEC_ID_ALAC
:
92
return
4096;
93
case
AV_CODEC_ID_ADPCM_IMA_WAV
:
94
return
(1024 - 4 * channels) * 8 / (4 * channels) + 1;
95
case
AV_CODEC_ID_ADPCM_MS
:
96
return
(1024 - 7 * channels) * 2 / channels + 2;
97
default
:
98
return
0;
99
}
100
}
101
102
static
int
caf_write_header
(
AVFormatContext
*
s
)
103
{
104
AVIOContext
*pb = s->
pb
;
105
AVCodecContext
*enc = s->
streams
[0]->
codec
;
106
CAFContext
*caf = s->
priv_data
;
107
AVDictionaryEntry
*
t
= NULL;
108
unsigned
int
codec_tag =
ff_codec_get_tag
(
ff_codec_caf_tags
, enc->
codec_id
);
109
int64_t chunk_size = 0;
110
111
switch
(enc->
codec_id
) {
112
case
AV_CODEC_ID_AAC
:
113
case
AV_CODEC_ID_AC3
:
114
av_log
(s,
AV_LOG_ERROR
,
"muxing codec currently unsupported\n"
);
115
return
AVERROR_PATCHWELCOME
;
116
}
117
118
switch
(enc->
codec_id
) {
119
case
AV_CODEC_ID_PCM_S8
:
120
case
AV_CODEC_ID_PCM_S16LE
:
121
case
AV_CODEC_ID_PCM_S16BE
:
122
case
AV_CODEC_ID_PCM_S24LE
:
123
case
AV_CODEC_ID_PCM_S24BE
:
124
case
AV_CODEC_ID_PCM_S32LE
:
125
case
AV_CODEC_ID_PCM_S32BE
:
126
case
AV_CODEC_ID_PCM_F32LE
:
127
case
AV_CODEC_ID_PCM_F32BE
:
128
case
AV_CODEC_ID_PCM_F64LE
:
129
case
AV_CODEC_ID_PCM_F64BE
:
130
case
AV_CODEC_ID_PCM_ALAW
:
131
case
AV_CODEC_ID_PCM_MULAW
:
132
codec_tag =
MKTAG
(
'l'
,
'p'
,
'c'
,
'm'
);
133
}
134
135
if
(!codec_tag) {
136
av_log
(s,
AV_LOG_ERROR
,
"unsupported codec\n"
);
137
return
AVERROR_INVALIDDATA
;
138
}
139
140
if
(!enc->
block_align
&& !pb->
seekable
) {
141
av_log
(s,
AV_LOG_ERROR
,
"Muxing variable packet size not supported on non seekable output\n"
);
142
return
AVERROR_INVALIDDATA
;
143
}
144
145
ffio_wfourcc
(pb,
"caff"
);
//< mFileType
146
avio_wb16
(pb, 1);
//< mFileVersion
147
avio_wb16
(pb, 0);
//< mFileFlags
148
149
ffio_wfourcc
(pb,
"desc"
);
//< Audio Description chunk
150
avio_wb64
(pb, 32);
//< mChunkSize
151
avio_wb64
(pb,
av_double2int
(enc->
sample_rate
));
//< mSampleRate
152
avio_wl32
(pb, codec_tag);
//< mFormatID
153
avio_wb32
(pb,
codec_flags
(enc->
codec_id
));
//< mFormatFlags
154
avio_wb32
(pb, enc->
block_align
);
//< mBytesPerPacket
155
avio_wb32
(pb,
samples_per_packet
(enc->
codec_id
, enc->
channels
));
//< mFramesPerPacket
156
avio_wb32
(pb, enc->
channels
);
//< mChannelsPerFrame
157
avio_wb32
(pb,
av_get_bits_per_sample
(enc->
codec_id
));
//< mBitsPerChannel
158
159
if
(enc->
channel_layout
) {
160
ffio_wfourcc
(pb,
"chan"
);
161
avio_wb64
(pb, 12);
162
ff_mov_write_chan
(pb, enc->
channel_layout
);
163
}
164
165
if
(enc->
codec_id
==
AV_CODEC_ID_ALAC
) {
166
ffio_wfourcc
(pb,
"kuki"
);
167
avio_wb64
(pb, 12 + enc->
extradata_size
);
168
avio_write
(pb,
"\0\0\0\14frmaalac"
, 12);
169
avio_write
(pb, enc->
extradata
, enc->
extradata_size
);
170
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_NB
) {
171
ffio_wfourcc
(pb,
"kuki"
);
172
avio_wb64
(pb, 29);
173
avio_write
(pb,
"\0\0\0\14frmasamr"
, 12);
174
avio_wb32
(pb, 0x11);
/* size */
175
avio_write
(pb,
"samrFFMP"
, 8);
176
avio_w8
(pb, 0);
/* decoder version */
177
178
avio_wb16
(pb, 0x81FF);
/* Mode set (all modes for AMR_NB) */
179
avio_w8
(pb, 0x00);
/* Mode change period (no restriction) */
180
avio_w8
(pb, 0x01);
/* Frames per sample */
181
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_QDM2
) {
182
ffio_wfourcc
(pb,
"kuki"
);
183
avio_wb64
(pb, enc->
extradata_size
);
184
avio_write
(pb, enc->
extradata
, enc->
extradata_size
);
185
}
186
187
if
(
av_dict_count
(s->
metadata
)) {
188
ffio_wfourcc
(pb,
"info"
);
//< Information chunk
189
while
((t =
av_dict_get
(s->
metadata
,
""
, t,
AV_DICT_IGNORE_SUFFIX
))) {
190
chunk_size += strlen(t->
key
) + strlen(t->
value
) + 2;
191
}
192
avio_wb64
(pb, chunk_size + 4);
193
avio_wb32
(pb,
av_dict_count
(s->
metadata
));
194
t = NULL;
195
while
((t =
av_dict_get
(s->
metadata
,
""
, t,
AV_DICT_IGNORE_SUFFIX
))) {
196
avio_put_str
(pb, t->
key
);
197
avio_put_str
(pb, t->
value
);
198
}
199
}
200
201
ffio_wfourcc
(pb,
"data"
);
//< Audio Data chunk
202
caf->
data
=
avio_tell
(pb);
203
avio_wb64
(pb, -1);
//< mChunkSize
204
avio_wb32
(pb, 0);
//< mEditCount
205
206
avio_flush
(pb);
207
return
0;
208
}
209
210
static
int
caf_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
211
{
212
CAFContext
*caf = s->
priv_data
;
213
214
avio_write
(s->
pb
, pkt->
data
, pkt->
size
);
215
if
(!s->
streams
[0]->
codec
->
block_align
) {
216
void
*pkt_sizes = caf->
pkt_sizes
;
217
int
i, alloc_size = caf->
size_entries_used
+ 5;
218
if
(alloc_size < 0) {
219
caf->
pkt_sizes
= NULL;
220
}
else
{
221
caf->
pkt_sizes
=
av_fast_realloc
(caf->
pkt_sizes
,
222
&caf->
size_buffer_size
,
223
alloc_size);
224
}
225
if
(!caf->
pkt_sizes
) {
226
av_free
(pkt_sizes);
227
return
AVERROR
(ENOMEM);
228
}
229
for
(i = 4; i > 0; i--) {
230
unsigned
top = pkt->
size
>> i * 7;
231
if
(top)
232
caf->
pkt_sizes
[caf->
size_entries_used
++] = 128 | top;
233
}
234
caf->
pkt_sizes
[caf->
size_entries_used
++] = pkt->
size
& 127;
235
caf->
packets
++;
236
}
237
return
0;
238
}
239
240
static
int
caf_write_trailer
(
AVFormatContext
*
s
)
241
{
242
CAFContext
*caf = s->
priv_data
;
243
AVIOContext
*pb = s->
pb
;
244
AVCodecContext
*enc = s->
streams
[0]->
codec
;
245
246
if
(pb->
seekable
) {
247
int64_t file_size =
avio_tell
(pb);
248
249
avio_seek
(pb, caf->
data
, SEEK_SET);
250
avio_wb64
(pb, file_size - caf->
data
- 8);
251
avio_seek
(pb, file_size, SEEK_SET);
252
if
(!enc->
block_align
) {
253
ffio_wfourcc
(pb,
"pakt"
);
254
avio_wb64
(pb, caf->
size_entries_used
+ 24);
255
avio_wb64
(pb, caf->
packets
);
///< mNumberPackets
256
avio_wb64
(pb, caf->
packets
*
samples_per_packet
(enc->
codec_id
, enc->
channels
));
///< mNumberValidFrames
257
avio_wb32
(pb, 0);
///< mPrimingFrames
258
avio_wb32
(pb, 0);
///< mRemainderFrames
259
avio_write
(pb, caf->
pkt_sizes
, caf->
size_entries_used
);
260
caf->
size_buffer_size
= 0;
261
}
262
avio_flush
(pb);
263
}
264
av_freep
(&caf->
pkt_sizes
);
265
return
0;
266
}
267
268
AVOutputFormat
ff_caf_muxer
= {
269
.
name
=
"caf"
,
270
.long_name =
NULL_IF_CONFIG_SMALL
(
"Apple CAF (Core Audio Format)"
),
271
.mime_type =
"audio/x-caf"
,
272
.extensions =
"caf"
,
273
.priv_data_size =
sizeof
(
CAFContext
),
274
.audio_codec =
AV_CODEC_ID_PCM_S16BE
,
275
.video_codec =
AV_CODEC_ID_NONE
,
276
.
write_header
=
caf_write_header
,
277
.
write_packet
=
caf_write_packet
,
278
.
write_trailer
=
caf_write_trailer
,
279
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_codec_caf_tags
, 0},
280
};
Generated on Sat Jan 25 2014 19:52:02 for FFmpeg by
1.8.2