summaryrefslogtreecommitdiff
path: root/libavformat/riffenc.c (plain)
blob: c96329da48786767688492ec6226241b0d2ac4ef
1/*
2 * RIFF muxing functions
3 * Copyright (c) 2000 Fabrice Bellard
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 "libavutil/dict.h"
23#include "libavutil/log.h"
24#include "libavutil/mathematics.h"
25#include "libavcodec/avcodec.h"
26#include "libavcodec/bytestream.h"
27#include "avformat.h"
28#include "avio_internal.h"
29#include "riff.h"
30
31int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32{
33 ffio_wfourcc(pb, tag);
34 avio_wl32(pb, -1);
35 return avio_tell(pb);
36}
37
38void ff_end_tag(AVIOContext *pb, int64_t start)
39{
40 int64_t pos;
41
42 av_assert0((start&1) == 0);
43
44 pos = avio_tell(pb);
45 if (pos & 1)
46 avio_w8(pb, 0);
47 avio_seek(pb, start - 4, SEEK_SET);
48 avio_wl32(pb, (uint32_t)(pos - start));
49 avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
50}
51
52/* WAVEFORMATEX header */
53/* returns the size or -1 on error */
54int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb,
55 AVCodecParameters *par, int flags)
56{
57 int bps, blkalign, bytespersec, frame_size;
58 int hdrsize;
59 int64_t hdrstart = avio_tell(pb);
60 int waveformatextensible;
61 uint8_t temp[256];
62 uint8_t *riff_extradata = temp;
63 uint8_t *riff_extradata_start = temp;
64
65 if (!par->codec_tag || par->codec_tag > 0xffff)
66 return -1;
67
68 /* We use the known constant frame size for the codec if known, otherwise
69 * fall back on using AVCodecContext.frame_size, which is not as reliable
70 * for indicating packet duration. */
71 frame_size = av_get_audio_frame_duration2(par, par->block_align);
72
73 waveformatextensible = (par->channels > 2 && par->channel_layout) ||
74 par->channels == 1 && par->channel_layout && par->channel_layout != AV_CH_LAYOUT_MONO ||
75 par->channels == 2 && par->channel_layout && par->channel_layout != AV_CH_LAYOUT_STEREO ||
76 par->sample_rate > 48000 ||
77 par->codec_id == AV_CODEC_ID_EAC3 ||
78 av_get_bits_per_sample(par->codec_id) > 16;
79
80 if (waveformatextensible)
81 avio_wl16(pb, 0xfffe);
82 else
83 avio_wl16(pb, par->codec_tag);
84
85 avio_wl16(pb, par->channels);
86 avio_wl32(pb, par->sample_rate);
87 if (par->codec_id == AV_CODEC_ID_ATRAC3 ||
88 par->codec_id == AV_CODEC_ID_G723_1 ||
89 par->codec_id == AV_CODEC_ID_MP2 ||
90 par->codec_id == AV_CODEC_ID_MP3 ||
91 par->codec_id == AV_CODEC_ID_GSM_MS) {
92 bps = 0;
93 } else {
94 if (!(bps = av_get_bits_per_sample(par->codec_id))) {
95 if (par->bits_per_coded_sample)
96 bps = par->bits_per_coded_sample;
97 else
98 bps = 16; // default to 16
99 }
100 }
101 if (bps != par->bits_per_coded_sample && par->bits_per_coded_sample) {
102 av_log(s, AV_LOG_WARNING,
103 "requested bits_per_coded_sample (%d) "
104 "and actually stored (%d) differ\n",
105 par->bits_per_coded_sample, bps);
106 }
107
108 if (par->codec_id == AV_CODEC_ID_MP2) {
109 blkalign = (144 * par->bit_rate - 1)/par->sample_rate + 1;
110 } else if (par->codec_id == AV_CODEC_ID_MP3) {
111 blkalign = 576 * (par->sample_rate <= (24000 + 32000)/2 ? 1 : 2);
112 } else if (par->codec_id == AV_CODEC_ID_AC3) {
113 blkalign = 3840; /* maximum bytes per frame */
114 } else if (par->codec_id == AV_CODEC_ID_AAC) {
115 blkalign = 768 * par->channels; /* maximum bytes per frame */
116 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
117 blkalign = 24;
118 } else if (par->block_align != 0) { /* specified by the codec */
119 blkalign = par->block_align;
120 } else
121 blkalign = bps * par->channels / av_gcd(8, bps);
122 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
123 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
124 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
125 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
126 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
127 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
128 bytespersec = par->sample_rate * blkalign;
129 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
130 bytespersec = 800;
131 } else {
132 bytespersec = par->bit_rate / 8;
133 }
134 avio_wl32(pb, bytespersec); /* bytes per second */
135 avio_wl16(pb, blkalign); /* block align */
136 avio_wl16(pb, bps); /* bits per sample */
137 if (par->codec_id == AV_CODEC_ID_MP3) {
138 bytestream_put_le16(&riff_extradata, 1); /* wID */
139 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
140 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
141 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
142 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
143 } else if (par->codec_id == AV_CODEC_ID_MP2) {
144 /* fwHeadLayer */
145 bytestream_put_le16(&riff_extradata, 2);
146 /* dwHeadBitrate */
147 bytestream_put_le32(&riff_extradata, par->bit_rate);
148 /* fwHeadMode */
149 bytestream_put_le16(&riff_extradata, par->channels == 2 ? 1 : 8);
150 /* fwHeadModeExt */
151 bytestream_put_le16(&riff_extradata, 0);
152 /* wHeadEmphasis */
153 bytestream_put_le16(&riff_extradata, 1);
154 /* fwHeadFlags */
155 bytestream_put_le16(&riff_extradata, 16);
156 /* dwPTSLow */
157 bytestream_put_le32(&riff_extradata, 0);
158 /* dwPTSHigh */
159 bytestream_put_le32(&riff_extradata, 0);
160 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
161 bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
162 bytestream_put_le32(&riff_extradata, 0xaea2f732);
163 bytestream_put_le16(&riff_extradata, 0xacde);
164 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
165 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
166 /* wSamplesPerBlock */
167 bytestream_put_le16(&riff_extradata, frame_size);
168 } else if (par->extradata_size) {
169 riff_extradata_start = par->extradata;
170 riff_extradata = par->extradata + par->extradata_size;
171 }
172 /* write WAVEFORMATEXTENSIBLE extensions */
173 if (waveformatextensible) {
174 int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
175 (s->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
176 par->channel_layout < 0x40000);
177 /* 22 is WAVEFORMATEXTENSIBLE size */
178 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
179 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
180 avio_wl16(pb, bps);
181 /* dwChannelMask */
182 avio_wl32(pb, write_channel_mask ? par->channel_layout : 0);
183 /* GUID + next 3 */
184 if (par->codec_id == AV_CODEC_ID_EAC3) {
185 ff_put_guid(pb, ff_get_codec_guid(par->codec_id, ff_codec_wav_guids));
186 } else {
187 avio_wl32(pb, par->codec_tag);
188 avio_wl32(pb, 0x00100000);
189 avio_wl32(pb, 0xAA000080);
190 avio_wl32(pb, 0x719B3800);
191 }
192 } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
193 par->codec_tag != 0x0001 /* PCM */ ||
194 riff_extradata - riff_extradata_start) {
195 /* WAVEFORMATEX */
196 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
197 } /* else PCMWAVEFORMAT */
198 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
199 hdrsize = avio_tell(pb) - hdrstart;
200 if (hdrsize & 1) {
201 hdrsize++;
202 avio_w8(pb, 0);
203 }
204
205 return hdrsize;
206}
207
208/* BITMAPINFOHEADER header */
209void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
210 const AVCodecTag *tags, int for_asf, int ignore_extradata)
211{
212 int keep_height = par->extradata_size >= 9 &&
213 !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9);
214 int extradata_size = par->extradata_size - 9*keep_height;
215 enum AVPixelFormat pix_fmt = par->format;
216 int pal_avi;
217
218 if (pix_fmt == AV_PIX_FMT_NONE && par->bits_per_coded_sample == 1)
219 pix_fmt = AV_PIX_FMT_MONOWHITE;
220 pal_avi = !for_asf &&
221 (pix_fmt == AV_PIX_FMT_PAL8 ||
222 pix_fmt == AV_PIX_FMT_MONOWHITE ||
223 pix_fmt == AV_PIX_FMT_MONOBLACK);
224
225 /* Size (not including the size of the color table or color masks) */
226 avio_wl32(pb, 40 + (ignore_extradata || pal_avi ? 0 : extradata_size));
227 avio_wl32(pb, par->width);
228 //We always store RGB TopDown
229 avio_wl32(pb, par->codec_tag || keep_height ? par->height : -par->height);
230 /* planes */
231 avio_wl16(pb, 1);
232 /* depth */
233 avio_wl16(pb, par->bits_per_coded_sample ? par->bits_per_coded_sample : 24);
234 /* compression type */
235 avio_wl32(pb, par->codec_tag);
236 avio_wl32(pb, (par->width * par->height * (par->bits_per_coded_sample ? par->bits_per_coded_sample : 24)+7) / 8);
237 avio_wl32(pb, 0);
238 avio_wl32(pb, 0);
239 /* Number of color indices in the color table that are used.
240 * A value of 0 means 2^biBitCount indices, but this doesn't work
241 * with Windows Media Player and files containing xxpc chunks. */
242 avio_wl32(pb, pal_avi ? 1 << par->bits_per_coded_sample : 0);
243 avio_wl32(pb, 0);
244
245 if (!ignore_extradata) {
246 if (par->extradata_size) {
247 avio_write(pb, par->extradata, extradata_size);
248 if (!for_asf && extradata_size & 1)
249 avio_w8(pb, 0);
250 } else if (pal_avi) {
251 int i;
252 for (i = 0; i < 1 << par->bits_per_coded_sample; i++) {
253 /* Initialize 1 bpp palette to black & white */
254 if (i == 0 && pix_fmt == AV_PIX_FMT_MONOWHITE)
255 avio_wl32(pb, 0xffffff);
256 else if (i == 1 && pix_fmt == AV_PIX_FMT_MONOBLACK)
257 avio_wl32(pb, 0xffffff);
258 else
259 avio_wl32(pb, 0);
260 }
261 }
262 }
263}
264
265void ff_parse_specific_params(AVStream *st, int *au_rate,
266 int *au_ssize, int *au_scale)
267{
268 AVCodecParameters *par = st->codecpar;
269 int gcd;
270 int audio_frame_size;
271
272 audio_frame_size = av_get_audio_frame_duration2(par, 0);
273 if (!audio_frame_size)
274 audio_frame_size = par->frame_size;
275
276 *au_ssize = par->block_align;
277 if (audio_frame_size && par->sample_rate) {
278 *au_scale = audio_frame_size;
279 *au_rate = par->sample_rate;
280 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
281 par->codec_type == AVMEDIA_TYPE_DATA ||
282 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
283 *au_scale = st->time_base.num;
284 *au_rate = st->time_base.den;
285 } else {
286 *au_scale = par->block_align ? par->block_align * 8 : 8;
287 *au_rate = par->bit_rate ? par->bit_rate :
288 8 * par->sample_rate;
289 }
290 gcd = av_gcd(*au_scale, *au_rate);
291 *au_scale /= gcd;
292 *au_rate /= gcd;
293}
294
295void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
296{
297 size_t len = strlen(str);
298 if (len > 0 && len < UINT32_MAX) {
299 len++;
300 ffio_wfourcc(pb, tag);
301 avio_wl32(pb, len);
302 avio_put_str(pb, str);
303 if (len & 1)
304 avio_w8(pb, 0);
305 }
306}
307
308static const char riff_tags[][5] = {
309 "IARL", "IART", "IAS1", "IAS2", "IAS3", "IAS4", "IAS5", "IAS6", "IAS7",
310 "IAS8", "IAS9", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
311 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
312 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
313 { 0 }
314};
315
316static int riff_has_valid_tags(AVFormatContext *s)
317{
318 int i;
319
320 for (i = 0; *riff_tags[i]; i++)
321 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
322 return 1;
323
324 return 0;
325}
326
327void ff_riff_write_info(AVFormatContext *s)
328{
329 AVIOContext *pb = s->pb;
330 int i;
331 int64_t list_pos;
332 AVDictionaryEntry *t = NULL;
333
334 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
335
336 /* writing empty LIST is not nice and may cause problems */
337 if (!riff_has_valid_tags(s))
338 return;
339
340 list_pos = ff_start_tag(pb, "LIST");
341 ffio_wfourcc(pb, "INFO");
342 for (i = 0; *riff_tags[i]; i++)
343 if ((t = av_dict_get(s->metadata, riff_tags[i],
344 NULL, AV_DICT_MATCH_CASE)))
345 ff_riff_write_info_tag(s->pb, t->key, t->value);
346 ff_end_tag(pb, list_pos);
347}
348
349void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
350{
351 av_assert0(sizeof(*g) == 16);
352 avio_write(s, *g, sizeof(*g));
353}
354
355const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
356{
357 int i;
358 for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
359 if (id == av_guid[i].id)
360 return &(av_guid[i].guid);
361 }
362 return NULL;
363}
364