2 * RIFF muxing functions
3 * Copyright (c) 2000 Fabrice Bellard
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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"
28 #include "avio_internal.h"
31 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
33 ffio_wfourcc(pb, tag);
38 void ff_end_tag(AVIOContext *pb, int64_t start)
43 avio_seek(pb, start - 4, SEEK_SET);
44 avio_wl32(pb, (uint32_t)(pos - start));
45 avio_seek(pb, pos, SEEK_SET);
48 /* WAVEFORMATEX header */
49 /* returns the size or -1 on error */
50 int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb,
51 AVCodecParameters *par)
53 int bps, blkalign, bytespersec, frame_size;
55 int waveformatextensible;
57 uint8_t *riff_extradata = temp;
58 uint8_t *riff_extradata_start = temp;
60 if (!par->codec_tag || par->codec_tag > 0xffff)
63 /* We use the known constant frame size for the codec if known, otherwise
64 * fall back on using AVCodecContext.frame_size, which is not as reliable
65 * for indicating packet duration. */
66 frame_size = av_get_audio_frame_duration2(par, par->block_align);
68 waveformatextensible = (par->channels > 2 && par->channel_layout) ||
69 par->sample_rate > 48000 ||
70 av_get_bits_per_sample(par->codec_id) > 16;
72 if (waveformatextensible)
73 avio_wl16(pb, 0xfffe);
75 avio_wl16(pb, par->codec_tag);
77 avio_wl16(pb, par->channels);
78 avio_wl32(pb, par->sample_rate);
79 if (par->codec_id == AV_CODEC_ID_MP2 ||
80 par->codec_id == AV_CODEC_ID_MP3 ||
81 par->codec_id == AV_CODEC_ID_GSM_MS) {
84 if (!(bps = av_get_bits_per_sample(par->codec_id))) {
85 if (par->bits_per_coded_sample)
86 bps = par->bits_per_coded_sample;
88 bps = 16; // default to 16
91 if (bps != par->bits_per_coded_sample && par->bits_per_coded_sample) {
92 av_log(s, AV_LOG_WARNING,
93 "requested bits_per_coded_sample (%d) "
94 "and actually stored (%d) differ\n",
95 par->bits_per_coded_sample, bps);
98 if (par->codec_id == AV_CODEC_ID_MP2) {
99 blkalign = frame_size;
100 } else if (par->codec_id == AV_CODEC_ID_MP3) {
101 blkalign = 576 * (par->sample_rate <= 24000 ? 1 : 2);
102 } else if (par->codec_id == AV_CODEC_ID_AC3) {
103 blkalign = 3840; /* maximum bytes per frame */
104 } else if (par->block_align != 0) { /* specified by the codec */
105 blkalign = par->block_align;
107 blkalign = bps * par->channels / av_gcd(8, bps);
108 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
109 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
110 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
111 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
112 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
113 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
114 bytespersec = par->sample_rate * blkalign;
116 bytespersec = par->bit_rate / 8;
118 avio_wl32(pb, bytespersec); /* bytes per second */
119 avio_wl16(pb, blkalign); /* block align */
120 avio_wl16(pb, bps); /* bits per sample */
121 if (par->codec_id == AV_CODEC_ID_MP3) {
123 bytestream_put_le16(&riff_extradata, 1); /* wID */
124 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
125 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
126 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
127 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
128 } else if (par->codec_id == AV_CODEC_ID_MP2) {
131 bytestream_put_le16(&riff_extradata, 2);
133 bytestream_put_le32(&riff_extradata, par->bit_rate);
135 bytestream_put_le16(&riff_extradata, par->channels == 2 ? 1 : 8);
137 bytestream_put_le16(&riff_extradata, 0);
139 bytestream_put_le16(&riff_extradata, 1);
141 bytestream_put_le16(&riff_extradata, 16);
143 bytestream_put_le32(&riff_extradata, 0);
145 bytestream_put_le32(&riff_extradata, 0);
146 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
147 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
149 /* wSamplesPerBlock */
150 bytestream_put_le16(&riff_extradata, frame_size);
151 } else if (par->extradata_size) {
152 riff_extradata_start = par->extradata;
153 riff_extradata = par->extradata + par->extradata_size;
154 hdrsize += par->extradata_size;
156 /* write WAVEFORMATEXTENSIBLE extensions */
157 if (waveformatextensible) {
159 /* 22 is WAVEFORMATEXTENSIBLE size */
160 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
161 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
164 avio_wl32(pb, par->channel_layout);
166 avio_wl32(pb, par->codec_tag);
167 avio_wl32(pb, 0x00100000);
168 avio_wl32(pb, 0xAA000080);
169 avio_wl32(pb, 0x719B3800);
171 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
173 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
182 /* BITMAPINFOHEADER header */
183 void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
184 const AVCodecTag *tags, int for_asf)
187 avio_wl32(pb, 40 + par->extradata_size);
188 avio_wl32(pb, par->width);
189 //We always store RGB TopDown
190 avio_wl32(pb, par->codec_tag ? par->height : -par->height);
194 avio_wl16(pb, par->bits_per_coded_sample ? par->bits_per_coded_sample : 24);
195 /* compression type */
196 avio_wl32(pb, par->codec_tag);
197 avio_wl32(pb, par->width * par->height * 3);
203 avio_write(pb, par->extradata, par->extradata_size);
205 if (!for_asf && par->extradata_size & 1)
209 void ff_parse_specific_params(AVStream *st, int *au_rate,
210 int *au_ssize, int *au_scale)
212 AVCodecParameters *par = st->codecpar;
214 int audio_frame_size;
216 audio_frame_size = av_get_audio_frame_duration2(par, 0);
218 *au_ssize = par->block_align;
219 if (audio_frame_size && par->sample_rate) {
220 *au_scale = audio_frame_size;
221 *au_rate = par->sample_rate;
222 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
223 par->codec_type == AVMEDIA_TYPE_DATA ||
224 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
225 *au_scale = st->time_base.num;
226 *au_rate = st->time_base.den;
228 *au_scale = par->block_align ? par->block_align * 8 : 8;
229 *au_rate = par->bit_rate ? par->bit_rate :
230 8 * par->sample_rate;
232 gcd = av_gcd(*au_scale, *au_rate);
237 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
239 int len = strlen(str);
242 ffio_wfourcc(pb, tag);
244 avio_put_str(pb, str);
250 static const char riff_tags[][5] = {
251 "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
252 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
253 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
257 static int riff_has_valid_tags(AVFormatContext *s)
261 for (i = 0; *riff_tags[i]; i++)
262 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
268 void ff_riff_write_info(AVFormatContext *s)
270 AVIOContext *pb = s->pb;
273 AVDictionaryEntry *t = NULL;
275 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
277 /* writing empty LIST is not nice and may cause problems */
278 if (!riff_has_valid_tags(s))
281 list_pos = ff_start_tag(pb, "LIST");
282 ffio_wfourcc(pb, "INFO");
283 for (i = 0; *riff_tags[i]; i++)
284 if ((t = av_dict_get(s->metadata, riff_tags[i],
285 NULL, AV_DICT_MATCH_CASE)))
286 ff_riff_write_info_tag(s->pb, t->key, t->value);
287 ff_end_tag(pb, list_pos);