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