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