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(AVIOContext *pb, AVCodecContext *enc)
52 int bps, blkalign, bytespersec, frame_size;
54 int waveformatextensible;
56 uint8_t *riff_extradata = temp;
57 uint8_t *riff_extradata_start = temp;
59 if (!enc->codec_tag || enc->codec_tag > 0xffff)
62 /* We use the known constant frame size for the codec if known, otherwise
63 * fall back on using AVCodecContext.frame_size, which is not as reliable
64 * for indicating packet duration. */
65 frame_size = av_get_audio_frame_duration(enc, enc->block_align);
67 waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
68 enc->sample_rate > 48000 ||
69 av_get_bits_per_sample(enc->codec_id) > 16;
71 if (waveformatextensible)
72 avio_wl16(pb, 0xfffe);
74 avio_wl16(pb, enc->codec_tag);
76 avio_wl16(pb, enc->channels);
77 avio_wl32(pb, enc->sample_rate);
78 if (enc->codec_id == AV_CODEC_ID_MP2 ||
79 enc->codec_id == AV_CODEC_ID_MP3 ||
80 enc->codec_id == AV_CODEC_ID_GSM_MS) {
83 if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
84 if (enc->bits_per_coded_sample)
85 bps = enc->bits_per_coded_sample;
87 bps = 16; // default to 16
90 if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
91 av_log(enc, AV_LOG_WARNING,
92 "requested bits_per_coded_sample (%d) "
93 "and actually stored (%d) differ\n",
94 enc->bits_per_coded_sample, bps);
97 if (enc->codec_id == AV_CODEC_ID_MP2) {
98 blkalign = frame_size;
99 } else if (enc->codec_id == AV_CODEC_ID_MP3) {
100 blkalign = 576 * (enc->sample_rate <= 24000 ? 1 : 2);
101 } else if (enc->codec_id == AV_CODEC_ID_AC3) {
102 blkalign = 3840; /* maximum bytes per frame */
103 } else if (enc->block_align != 0) { /* specified by the codec */
104 blkalign = enc->block_align;
106 blkalign = bps * enc->channels / av_gcd(8, bps);
107 if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
108 enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
109 enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
110 enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
111 enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
112 enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
113 bytespersec = enc->sample_rate * blkalign;
115 bytespersec = enc->bit_rate / 8;
117 avio_wl32(pb, bytespersec); /* bytes per second */
118 avio_wl16(pb, blkalign); /* block align */
119 avio_wl16(pb, bps); /* bits per sample */
120 if (enc->codec_id == AV_CODEC_ID_MP3) {
122 bytestream_put_le16(&riff_extradata, 1); /* wID */
123 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
124 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
125 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
126 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
127 } else if (enc->codec_id == AV_CODEC_ID_MP2) {
130 bytestream_put_le16(&riff_extradata, 2);
132 bytestream_put_le32(&riff_extradata, enc->bit_rate);
134 bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
136 bytestream_put_le16(&riff_extradata, 0);
138 bytestream_put_le16(&riff_extradata, 1);
140 bytestream_put_le16(&riff_extradata, 16);
142 bytestream_put_le32(&riff_extradata, 0);
144 bytestream_put_le32(&riff_extradata, 0);
145 } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
146 enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
148 /* wSamplesPerBlock */
149 bytestream_put_le16(&riff_extradata, frame_size);
150 } else if (enc->extradata_size) {
151 riff_extradata_start = enc->extradata;
152 riff_extradata = enc->extradata + enc->extradata_size;
153 hdrsize += enc->extradata_size;
155 /* write WAVEFORMATEXTENSIBLE extensions */
156 if (waveformatextensible) {
158 /* 22 is WAVEFORMATEXTENSIBLE size */
159 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
160 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
163 avio_wl32(pb, enc->channel_layout);
165 avio_wl32(pb, enc->codec_tag);
166 avio_wl32(pb, 0x00100000);
167 avio_wl32(pb, 0xAA000080);
168 avio_wl32(pb, 0x719B3800);
170 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
172 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
181 /* BITMAPINFOHEADER header */
182 void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
183 const AVCodecTag *tags, int for_asf)
186 avio_wl32(pb, 40 + enc->extradata_size);
187 avio_wl32(pb, enc->width);
188 //We always store RGB TopDown
189 avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
193 avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
194 /* compression type */
195 avio_wl32(pb, enc->codec_tag);
196 avio_wl32(pb, enc->width * enc->height * 3);
202 avio_write(pb, enc->extradata, enc->extradata_size);
204 if (!for_asf && enc->extradata_size & 1)
208 void ff_parse_specific_params(AVStream *st, int *au_rate,
209 int *au_ssize, int *au_scale)
211 AVCodecContext *codec = st->codec;
213 int audio_frame_size;
215 audio_frame_size = av_get_audio_frame_duration(codec, 0);
217 *au_ssize = codec->block_align;
218 if (audio_frame_size && codec->sample_rate) {
219 *au_scale = audio_frame_size;
220 *au_rate = codec->sample_rate;
221 } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
222 codec->codec_type == AVMEDIA_TYPE_DATA ||
223 codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
224 *au_scale = st->time_base.num;
225 *au_rate = st->time_base.den;
227 *au_scale = codec->block_align ? codec->block_align * 8 : 8;
228 *au_rate = codec->bit_rate ? codec->bit_rate :
229 8 * codec->sample_rate;
231 gcd = av_gcd(*au_scale, *au_rate);
236 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
238 int len = strlen(str);
241 ffio_wfourcc(pb, tag);
243 avio_put_str(pb, str);
249 static const char riff_tags[][5] = {
250 "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
251 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
252 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
256 static int riff_has_valid_tags(AVFormatContext *s)
260 for (i = 0; *riff_tags[i]; i++)
261 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
267 void ff_riff_write_info(AVFormatContext *s)
269 AVIOContext *pb = s->pb;
272 AVDictionaryEntry *t = NULL;
274 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
276 /* writing empty LIST is not nice and may cause problems */
277 if (!riff_has_valid_tags(s))
280 list_pos = ff_start_tag(pb, "LIST");
281 ffio_wfourcc(pb, "INFO");
282 for (i = 0; *riff_tags[i]; i++)
283 if ((t = av_dict_get(s->metadata, riff_tags[i],
284 NULL, AV_DICT_MATCH_CASE)))
285 ff_riff_write_info_tag(s->pb, t->key, t->value);
286 ff_end_tag(pb, list_pos);