avcodec/x86/h264_idct: Fix ff_h264_luma_dc_dequant_idct_sse2 checkasm failures
[ffmpeg.git] / libavformat / aiffenc.c
1 /*
2 * AIFF/AIFF-C muxer
3 * Copyright (c) 2006 Patrick Guimond
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 <stdint.h>
23
24 #include "libavutil/intfloat.h"
25 #include "libavutil/opt.h"
26 #include "libavcodec/packet_internal.h"
27 #include "avformat.h"
28 #include "internal.h"
29 #include "aiff.h"
30 #include "avio_internal.h"
31 #include "isom.h"
32 #include "id3v2.h"
33 #include "mux.h"
34
35 typedef struct AIFFOutputContext {
36 const AVClass *class;
37 int64_t form;
38 int64_t frames;
39 int64_t ssnd;
40 int audio_stream_idx;
41 PacketList pict_list;
42 int write_id3v2;
43 int id3v2_version;
44 } AIFFOutputContext;
45
46 static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff)
47 {
48 int ret;
49 uint64_t pos, end, size;
50 ID3v2EncContext id3v2 = { 0 };
51 AVIOContext *pb = s->pb;
52 PacketListEntry *list_entry = aiff->pict_list.head;
53
54 if (!s->metadata && !s->nb_chapters && !list_entry)
55 return 0;
56
57 avio_wb32(pb, MKBETAG('I', 'D', '3', ' '));
58 avio_wb32(pb, 0);
59 pos = avio_tell(pb);
60
61 ff_id3v2_start(&id3v2, pb, aiff->id3v2_version, ID3v2_DEFAULT_MAGIC);
62 ff_id3v2_write_metadata(s, &id3v2);
63 while (list_entry) {
64 if ((ret = ff_id3v2_write_apic(s, &id3v2, &list_entry->pkt)) < 0)
65 return ret;
66 list_entry = list_entry->next;
67 }
68 ff_id3v2_finish(&id3v2, pb, s->metadata_header_padding);
69
70 end = avio_tell(pb);
71 size = end - pos;
72
73 /* Update chunk size */
74 avio_seek(pb, pos - 4, SEEK_SET);
75 avio_wb32(pb, size);
76 avio_seek(pb, end, SEEK_SET);
77
78 if (size & 1)
79 avio_w8(pb, 0);
80
81 return 0;
82 }
83
84 static void put_meta(AVFormatContext *s, const char *key, uint32_t id)
85 {
86 AVDictionaryEntry *tag;
87 AVIOContext *pb = s->pb;
88
89 if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
90 size_t size = strlen(tag->value);
91
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);
95
96 avio_wb32(pb, id);
97 avio_wb32(pb, size);
98 avio_write(pb, tag->value, size);
99 }
100 }
101
102 static int aiff_write_header(AVFormatContext *s)
103 {
104 AIFFOutputContext *aiff = s->priv_data;
105 AVIOContext *pb = s->pb;
106 AVCodecParameters *par;
107 uint64_t sample_rate;
108 int i, aifc = 0;
109
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);
118 }
119 }
120 if (aiff->audio_stream_idx < 0) {
121 av_log(s, AV_LOG_ERROR, "No audio stream present.\n");
122 return AVERROR(EINVAL);
123 }
124
125 par = s->streams[aiff->audio_stream_idx]->codecpar;
126
127 /* First verify if format is ok */
128 if (!par->codec_tag)
129 return AVERROR(EINVAL);
130 if (par->codec_tag != MKTAG('N','O','N','E'))
131 aifc = 1;
132
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");
138
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);
143 }
144 /* Version chunk */
145 ffio_wfourcc(pb, "FVER");
146 avio_wb32(pb, 4);
147 avio_wb32(pb, 0xA2805140);
148 }
149
150 if (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && par->ch_layout.nb_channels > 2) {
151 ffio_wfourcc(pb, "CHAN");
152 avio_wb32(pb, 12);
153 ff_mov_write_chan(pb, par->ch_layout.u.mask);
154 }
155
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'));
160
161 /* Common chunk */
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 */
165
166 aiff->frames = avio_tell(pb);
167 avio_wb32(pb, 0); /* Number of frames */
168
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);
174 }
175 if (!par->block_align)
176 par->block_align = (par->bits_per_coded_sample * par->ch_layout.nb_channels) >> 3;
177
178 avio_wb16(pb, par->bits_per_coded_sample); /* Sample size */
179
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);
183
184 if (aifc) {
185 avio_wl32(pb, par->codec_tag);
186 avio_wb16(pb, 0);
187 }
188
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);
194 }
195
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) */
202
203 avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
204 s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
205
206 return 0;
207 }
208
209 static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
210 {
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);
215 else {
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);
220 }
221 if (s->streams[pkt->stream_index]->nb_frames >= 1)
222 return 0;
223
224 return avpriv_packet_list_put(&aiff->pict_list, pkt, NULL, 0);
225 }
226
227 return 0;
228 }
229
230 static int aiff_write_trailer(AVFormatContext *s)
231 {
232 int ret = 0;
233 AVIOContext *pb = s->pb;
234 AIFFOutputContext *aiff = s->priv_data;
235 AVCodecParameters *par = s->streams[aiff->audio_stream_idx]->codecpar;
236
237 /* Chunks sizes must be even */
238 int64_t file_size, data_size;
239 data_size = avio_tell(pb);
240 if (data_size & 1)
241 avio_w8(pb, 0);
242
243 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
244 /* Write ID3 tags */
245 if (aiff->write_id3v2)
246 if ((ret = put_id3v2_tags(s, aiff)) < 0)
247 return ret;
248
249 /* File length */
250 file_size = avio_tell(pb);
251 avio_seek(pb, aiff->form, SEEK_SET);
252 avio_wb32(pb, file_size - aiff->form - 4);
253
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);
257
258 /* Sound Data chunk size */
259 avio_seek(pb, aiff->ssnd, SEEK_SET);
260 avio_wb32(pb, data_size - aiff->ssnd - 4);
261 }
262
263 return ret;
264 }
265
266 static void aiff_deinit(AVFormatContext *s)
267 {
268 AIFFOutputContext *aiff = s->priv_data;
269
270 avpriv_packet_list_free(&aiff->pict_list);
271 }
272
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 },
280 { NULL },
281 };
282
283 static const AVClass aiff_muxer_class = {
284 .class_name = "AIFF muxer",
285 .item_name = av_default_item_name,
286 .option = options,
287 .version = LIBAVUTIL_VERSION_INT,
288 };
289
290 const FFOutputFormat ff_aiff_muxer = {
291 .p.name = "aiff",
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,
304 };