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,
int
block_align) {
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
(block_align - 4 * channels) * 8 / (4 * channels) + 1;
95
case
AV_CODEC_ID_ADPCM_MS
:
96
return
(block_align - 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
int
frame_size
= enc->
frame_size
;
111
112
if
(s->
nb_streams
!= 1) {
113
av_log
(s,
AV_LOG_ERROR
,
"CAF files have exactly one stream\n"
);
114
return
AVERROR
(EINVAL);
115
}
116
117
switch
(enc->
codec_id
) {
118
case
AV_CODEC_ID_AAC
:
119
av_log
(s,
AV_LOG_ERROR
,
"muxing codec currently unsupported\n"
);
120
return
AVERROR_PATCHWELCOME
;
121
}
122
123
switch
(enc->
codec_id
) {
124
case
AV_CODEC_ID_PCM_S8
:
125
case
AV_CODEC_ID_PCM_S16LE
:
126
case
AV_CODEC_ID_PCM_S16BE
:
127
case
AV_CODEC_ID_PCM_S24LE
:
128
case
AV_CODEC_ID_PCM_S24BE
:
129
case
AV_CODEC_ID_PCM_S32LE
:
130
case
AV_CODEC_ID_PCM_S32BE
:
131
case
AV_CODEC_ID_PCM_F32LE
:
132
case
AV_CODEC_ID_PCM_F32BE
:
133
case
AV_CODEC_ID_PCM_F64LE
:
134
case
AV_CODEC_ID_PCM_F64BE
:
135
codec_tag =
MKTAG
(
'l'
,
'p'
,
'c'
,
'm'
);
136
}
137
138
if
(!codec_tag) {
139
av_log
(s,
AV_LOG_ERROR
,
"unsupported codec\n"
);
140
return
AVERROR_INVALIDDATA
;
141
}
142
143
if
(!enc->
block_align
&& !pb->
seekable
) {
144
av_log
(s,
AV_LOG_ERROR
,
"Muxing variable packet size not supported on non seekable output\n"
);
145
return
AVERROR_INVALIDDATA
;
146
}
147
148
if
(enc->
codec_id
!=
AV_CODEC_ID_MP3
|| frame_size != 576)
149
frame_size =
samples_per_packet
(enc->
codec_id
, enc->
channels
, enc->
block_align
);
150
151
ffio_wfourcc
(pb,
"caff"
);
//< mFileType
152
avio_wb16
(pb, 1);
//< mFileVersion
153
avio_wb16
(pb, 0);
//< mFileFlags
154
155
ffio_wfourcc
(pb,
"desc"
);
//< Audio Description chunk
156
avio_wb64
(pb, 32);
//< mChunkSize
157
avio_wb64
(pb,
av_double2int
(enc->
sample_rate
));
//< mSampleRate
158
avio_wl32
(pb, codec_tag);
//< mFormatID
159
avio_wb32
(pb,
codec_flags
(enc->
codec_id
));
//< mFormatFlags
160
avio_wb32
(pb, enc->
block_align
);
//< mBytesPerPacket
161
avio_wb32
(pb, frame_size);
//< mFramesPerPacket
162
avio_wb32
(pb, enc->
channels
);
//< mChannelsPerFrame
163
avio_wb32
(pb,
av_get_bits_per_sample
(enc->
codec_id
));
//< mBitsPerChannel
164
165
if
(enc->
channel_layout
) {
166
ffio_wfourcc
(pb,
"chan"
);
167
avio_wb64
(pb, 12);
168
ff_mov_write_chan
(pb, enc->
channel_layout
);
169
}
170
171
if
(enc->
codec_id
==
AV_CODEC_ID_ALAC
) {
172
ffio_wfourcc
(pb,
"kuki"
);
173
avio_wb64
(pb, 12 + enc->
extradata_size
);
174
avio_write
(pb,
"\0\0\0\14frmaalac"
, 12);
175
avio_write
(pb, enc->
extradata
, enc->
extradata_size
);
176
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_NB
) {
177
ffio_wfourcc
(pb,
"kuki"
);
178
avio_wb64
(pb, 29);
179
avio_write
(pb,
"\0\0\0\14frmasamr"
, 12);
180
avio_wb32
(pb, 0x11);
/* size */
181
avio_write
(pb,
"samrFFMP"
, 8);
182
avio_w8
(pb, 0);
/* decoder version */
183
184
avio_wb16
(pb, 0x81FF);
/* Mode set (all modes for AMR_NB) */
185
avio_w8
(pb, 0x00);
/* Mode change period (no restriction) */
186
avio_w8
(pb, 0x01);
/* Frames per sample */
187
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_QDM2
) {
188
ffio_wfourcc
(pb,
"kuki"
);
189
avio_wb64
(pb, enc->
extradata_size
);
190
avio_write
(pb, enc->
extradata
, enc->
extradata_size
);
191
}
192
193
if
(
av_dict_count
(s->
metadata
)) {
194
ffio_wfourcc
(pb,
"info"
);
//< Information chunk
195
while
((t =
av_dict_get
(s->
metadata
,
""
, t,
AV_DICT_IGNORE_SUFFIX
))) {
196
chunk_size += strlen(t->
key
) + strlen(t->
value
) + 2;
197
}
198
avio_wb64
(pb, chunk_size + 4);
199
avio_wb32
(pb,
av_dict_count
(s->
metadata
));
200
t =
NULL
;
201
while
((t =
av_dict_get
(s->
metadata
,
""
, t,
AV_DICT_IGNORE_SUFFIX
))) {
202
avio_put_str
(pb, t->
key
);
203
avio_put_str
(pb, t->
value
);
204
}
205
}
206
207
ffio_wfourcc
(pb,
"data"
);
//< Audio Data chunk
208
caf->
data
=
avio_tell
(pb);
209
avio_wb64
(pb, -1);
//< mChunkSize
210
avio_wb32
(pb, 0);
//< mEditCount
211
212
avio_flush
(pb);
213
return
0;
214
}
215
216
static
int
caf_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
217
{
218
CAFContext
*caf = s->
priv_data
;
219
220
avio_write
(s->
pb
, pkt->
data
, pkt->
size
);
221
if
(!s->
streams
[0]->
codec
->
block_align
) {
222
void
*pkt_sizes = caf->
pkt_sizes
;
223
int
i, alloc_size = caf->
size_entries_used
+ 5;
224
if
(alloc_size < 0) {
225
caf->
pkt_sizes
=
NULL
;
226
}
else
{
227
caf->
pkt_sizes
=
av_fast_realloc
(caf->
pkt_sizes
,
228
&caf->
size_buffer_size
,
229
alloc_size);
230
}
231
if
(!caf->
pkt_sizes
) {
232
av_free
(pkt_sizes);
233
return
AVERROR
(ENOMEM);
234
}
235
for
(i = 4; i > 0; i--) {
236
unsigned
top = pkt->
size
>> i * 7;
237
if
(top)
238
caf->
pkt_sizes
[caf->
size_entries_used
++] = 128 | top;
239
}
240
caf->
pkt_sizes
[caf->
size_entries_used
++] = pkt->
size
& 127;
241
caf->
packets
++;
242
}
243
return
0;
244
}
245
246
static
int
caf_write_trailer
(
AVFormatContext
*
s
)
247
{
248
CAFContext
*caf = s->
priv_data
;
249
AVIOContext
*pb = s->
pb
;
250
AVCodecContext
*enc = s->
streams
[0]->
codec
;
251
252
if
(pb->
seekable
) {
253
int64_t file_size =
avio_tell
(pb);
254
255
avio_seek
(pb, caf->
data
, SEEK_SET);
256
avio_wb64
(pb, file_size - caf->
data
- 8);
257
avio_seek
(pb, file_size, SEEK_SET);
258
if
(!enc->
block_align
) {
259
ffio_wfourcc
(pb,
"pakt"
);
260
avio_wb64
(pb, caf->
size_entries_used
+ 24);
261
avio_wb64
(pb, caf->
packets
);
///< mNumberPackets
262
avio_wb64
(pb, caf->
packets
*
samples_per_packet
(enc->
codec_id
, enc->
channels
, enc->
block_align
));
///< mNumberValidFrames
263
avio_wb32
(pb, 0);
///< mPrimingFrames
264
avio_wb32
(pb, 0);
///< mRemainderFrames
265
avio_write
(pb, caf->
pkt_sizes
, caf->
size_entries_used
);
266
caf->
size_buffer_size
= 0;
267
}
268
avio_flush
(pb);
269
}
270
av_freep
(&caf->
pkt_sizes
);
271
return
0;
272
}
273
274
AVOutputFormat
ff_caf_muxer
= {
275
.
name
=
"caf"
,
276
.long_name =
NULL_IF_CONFIG_SMALL
(
"Apple CAF (Core Audio Format)"
),
277
.mime_type =
"audio/x-caf"
,
278
.extensions =
"caf"
,
279
.priv_data_size =
sizeof
(
CAFContext
),
280
.audio_codec =
AV_CODEC_ID_PCM_S16BE
,
281
.video_codec =
AV_CODEC_ID_NONE
,
282
.
write_header
=
caf_write_header
,
283
.
write_packet
=
caf_write_packet
,
284
.
write_trailer
=
caf_write_trailer
,
285
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_codec_caf_tags
, 0},
286
};
Generated on Sun Mar 8 2015 02:35:09 for FFmpeg by
1.8.2