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