3 * Copyright (c) 2006 Patrick Guimond
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/intfloat.h"
25 #include "libavutil/opt.h"
26 #include "libavcodec/packet_internal.h"
30 #include "avio_internal.h"
35 typedef struct AIFFOutputContext
{
46 static int put_id3v2_tags(AVFormatContext
*s
, AIFFOutputContext
*aiff
)
49 uint64_t pos
, end
, size
;
50 ID3v2EncContext id3v2
= { 0 };
51 AVIOContext
*pb
= s
->pb
;
52 PacketListEntry
*list_entry
= aiff
->pict_list
.head
;
54 if (!s
->metadata
&& !s
->nb_chapters
&& !list_entry
)
57 avio_wb32(pb
, MKBETAG('I', 'D', '3', ' '));
61 ff_id3v2_start(&id3v2
, pb
, aiff
->id3v2_version
, ID3v2_DEFAULT_MAGIC
);
62 ff_id3v2_write_metadata(s
, &id3v2
);
64 if ((ret
= ff_id3v2_write_apic(s
, &id3v2
, &list_entry
->pkt
)) < 0)
66 list_entry
= list_entry
->next
;
68 ff_id3v2_finish(&id3v2
, pb
, s
->metadata_header_padding
);
73 /* Update chunk size */
74 avio_seek(pb
, pos
- 4, SEEK_SET
);
76 avio_seek(pb
, end
, SEEK_SET
);
84 static void put_meta(AVFormatContext
*s
, const char *key
, uint32_t id
)
86 AVDictionaryEntry
*tag
;
87 AVIOContext
*pb
= s
->pb
;
89 if (tag
= av_dict_get(s
->metadata
, key
, NULL
, 0)) {
90 size_t size
= strlen(tag
->value
);
92 // AIFF tags are zero-padded to an even length.
93 // So simply copy the terminating \0 if the length is odd.
94 size
= FFALIGN(size
, 2);
98 avio_write(pb
, tag
->value
, size
);
102 static int aiff_write_header(AVFormatContext
*s
)
104 AIFFOutputContext
*aiff
= s
->priv_data
;
105 AVIOContext
*pb
= s
->pb
;
106 AVCodecParameters
*par
;
107 uint64_t sample_rate
;
110 aiff
->audio_stream_idx
= -1;
111 for (i
= 0; i
< s
->nb_streams
; i
++) {
112 AVStream
*st
= s
->streams
[i
];
113 if (aiff
->audio_stream_idx
< 0 && st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
114 aiff
->audio_stream_idx
= i
;
115 } else if (st
->codecpar
->codec_type
!= AVMEDIA_TYPE_VIDEO
) {
116 av_log(s
, AV_LOG_ERROR
, "AIFF allows only one audio stream and a picture.\n");
117 return AVERROR(EINVAL
);
120 if (aiff
->audio_stream_idx
< 0) {
121 av_log(s
, AV_LOG_ERROR
, "No audio stream present.\n");
122 return AVERROR(EINVAL
);
125 par
= s
->streams
[aiff
->audio_stream_idx
]->codecpar
;
127 /* First verify if format is ok */
129 return AVERROR(EINVAL
);
130 if (par
->codec_tag
!= MKTAG('N','O','N','E'))
133 /* FORM AIFF header */
134 ffio_wfourcc(pb
, "FORM");
135 aiff
->form
= avio_tell(pb
);
136 avio_wb32(pb
, 0); /* file length */
137 ffio_wfourcc(pb
, aifc
? "AIFC" : "AIFF");
139 if (aifc
) { // compressed audio
140 if (!par
->block_align
) {
141 av_log(s
, AV_LOG_ERROR
, "block align not set\n");
142 return AVERROR(EINVAL
);
145 ffio_wfourcc(pb
, "FVER");
147 avio_wb32(pb
, 0xA2805140);
150 if (par
->ch_layout
.order
== AV_CHANNEL_ORDER_NATIVE
&& par
->ch_layout
.nb_channels
> 2) {
151 ffio_wfourcc(pb
, "CHAN");
153 ff_mov_write_chan(pb
, par
->ch_layout
.u
.mask
);
156 put_meta(s
, "title", MKBETAG('N', 'A', 'M', 'E'));
157 put_meta(s
, "author", MKBETAG('A', 'U', 'T', 'H'));
158 put_meta(s
, "copyright", MKBETAG('(', 'c', ')', ' '));
159 put_meta(s
, "comment", MKBETAG('A', 'N', 'N', 'O'));
162 ffio_wfourcc(pb
, "COMM");
163 avio_wb32(pb
, aifc
? 24 : 18); /* size */
164 avio_wb16(pb
, par
->ch_layout
.nb_channels
); /* Number of channels */
166 aiff
->frames
= avio_tell(pb
);
167 avio_wb32(pb
, 0); /* Number of frames */
169 if (!par
->bits_per_coded_sample
)
170 par
->bits_per_coded_sample
= av_get_bits_per_sample(par
->codec_id
);
171 if (!par
->bits_per_coded_sample
) {
172 av_log(s
, AV_LOG_ERROR
, "could not compute bits per sample\n");
173 return AVERROR(EINVAL
);
175 if (!par
->block_align
)
176 par
->block_align
= (par
->bits_per_coded_sample
* par
->ch_layout
.nb_channels
) >> 3;
178 avio_wb16(pb
, par
->bits_per_coded_sample
); /* Sample size */
180 sample_rate
= av_double2int(par
->sample_rate
);
181 avio_wb16(pb
, (sample_rate
>> 52) + (16383 - 1023));
182 avio_wb64(pb
, UINT64_C(1) << 63 | sample_rate
<< 11);
185 avio_wl32(pb
, par
->codec_tag
);
189 if ( (par
->codec_tag
== MKTAG('Q','D','M','2')
190 || par
->codec_tag
== MKTAG('Q','c','l','p')) && par
->extradata_size
) {
191 ffio_wfourcc(pb
, "wave");
192 avio_wb32(pb
, par
->extradata_size
);
193 avio_write(pb
, par
->extradata
, par
->extradata_size
);
196 /* Sound data chunk */
197 ffio_wfourcc(pb
, "SSND");
198 aiff
->ssnd
= avio_tell(pb
); /* Sound chunk size */
199 avio_wb32(pb
, 0); /* Sound samples data size */
200 avio_wb32(pb
, 0); /* Data offset */
201 avio_wb32(pb
, 0); /* Block-size (block align) */
203 avpriv_set_pts_info(s
->streams
[aiff
->audio_stream_idx
], 64, 1,
204 s
->streams
[aiff
->audio_stream_idx
]->codecpar
->sample_rate
);
209 static int aiff_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
211 AIFFOutputContext
*aiff
= s
->priv_data
;
212 AVIOContext
*pb
= s
->pb
;
213 if (pkt
->stream_index
== aiff
->audio_stream_idx
)
214 avio_write(pb
, pkt
->data
, pkt
->size
);
216 /* warn only once for each stream */
217 if (s
->streams
[pkt
->stream_index
]->nb_frames
== 1) {
218 av_log(s
, AV_LOG_WARNING
, "Got more than one picture in stream %d,"
219 " ignoring.\n", pkt
->stream_index
);
221 if (s
->streams
[pkt
->stream_index
]->nb_frames
>= 1)
224 return avpriv_packet_list_put(&aiff
->pict_list
, pkt
, NULL
, 0);
230 static int aiff_write_trailer(AVFormatContext
*s
)
233 AVIOContext
*pb
= s
->pb
;
234 AIFFOutputContext
*aiff
= s
->priv_data
;
235 AVCodecParameters
*par
= s
->streams
[aiff
->audio_stream_idx
]->codecpar
;
237 /* Chunks sizes must be even */
238 int64_t file_size
, data_size
;
239 data_size
= avio_tell(pb
);
243 if (s
->pb
->seekable
& AVIO_SEEKABLE_NORMAL
) {
245 if (aiff
->write_id3v2
)
246 if ((ret
= put_id3v2_tags(s
, aiff
)) < 0)
250 file_size
= avio_tell(pb
);
251 avio_seek(pb
, aiff
->form
, SEEK_SET
);
252 avio_wb32(pb
, file_size
- aiff
->form
- 4);
254 /* Number of sample frames */
255 avio_seek(pb
, aiff
->frames
, SEEK_SET
);
256 avio_wb32(pb
, (data_size
- aiff
->ssnd
- 12) / par
->block_align
);
258 /* Sound Data chunk size */
259 avio_seek(pb
, aiff
->ssnd
, SEEK_SET
);
260 avio_wb32(pb
, data_size
- aiff
->ssnd
- 4);
266 static void aiff_deinit(AVFormatContext
*s
)
268 AIFFOutputContext
*aiff
= s
->priv_data
;
270 avpriv_packet_list_free(&aiff
->pict_list
);
273 #define OFFSET(x) offsetof(AIFFOutputContext, x)
274 #define ENC AV_OPT_FLAG_ENCODING_PARAM
275 static const AVOption options
[] = {
276 { "write_id3v2", "Enable ID3 tags writing.",
277 OFFSET(write_id3v2
), AV_OPT_TYPE_BOOL
, {.i64
= 0}, 0, 1, ENC
},
278 { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
279 OFFSET(id3v2_version
), AV_OPT_TYPE_INT
, {.i64
= 4}, 3, 4, ENC
},
283 static const AVClass aiff_muxer_class
= {
284 .class_name
= "AIFF muxer",
285 .item_name
= av_default_item_name
,
287 .version
= LIBAVUTIL_VERSION_INT
,
290 const FFOutputFormat ff_aiff_muxer
= {
292 .p
.long_name
= NULL_IF_CONFIG_SMALL("Audio IFF"),
293 .p
.mime_type
= "audio/aiff",
294 .p
.extensions
= "aif,aiff,afc,aifc",
295 .priv_data_size
= sizeof(AIFFOutputContext
),
296 .p
.audio_codec
= AV_CODEC_ID_PCM_S16BE
,
297 .p
.video_codec
= AV_CODEC_ID_PNG
,
298 .write_header
= aiff_write_header
,
299 .write_packet
= aiff_write_packet
,
300 .write_trailer
= aiff_write_trailer
,
301 .deinit
= aiff_deinit
,
302 .p
.codec_tag
= ff_aiff_codec_tags_list
,
303 .p
.priv_class
= &aiff_muxer_class
,