2 * RIFF muxing functions
3 * Copyright (c) 2000 Fabrice Bellard
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
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)
42 av_assert0((start&1) == 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);
52 /* WAVEFORMATEX header */
53 /* returns the size or -1 on error */
54 int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
56 int bps, blkalign, bytespersec, frame_size;
58 int waveformatextensible;
60 uint8_t *riff_extradata = temp;
61 uint8_t *riff_extradata_start = temp;
63 if (!enc->codec_tag || enc->codec_tag > 0xffff)
66 /* We use the known constant frame size for the codec if known, otherwise
67 * fall back on using AVCodecContext.frame_size, which is not as reliable
68 * for indicating packet duration. */
69 frame_size = av_get_audio_frame_duration(enc, 0);
71 frame_size = enc->frame_size;
73 waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
74 enc->sample_rate > 48000 ||
75 av_get_bits_per_sample(enc->codec_id) > 16;
77 if (waveformatextensible)
78 avio_wl16(pb, 0xfffe);
80 avio_wl16(pb, enc->codec_tag);
82 avio_wl16(pb, enc->channels);
83 avio_wl32(pb, enc->sample_rate);
84 if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
85 enc->codec_id == AV_CODEC_ID_G723_1 ||
86 enc->codec_id == AV_CODEC_ID_MP2 ||
87 enc->codec_id == AV_CODEC_ID_MP3 ||
88 enc->codec_id == AV_CODEC_ID_GSM_MS) {
91 if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
92 if (enc->bits_per_coded_sample)
93 bps = enc->bits_per_coded_sample;
95 bps = 16; // default to 16
98 if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
99 av_log(enc, AV_LOG_WARNING,
100 "requested bits_per_coded_sample (%d) "
101 "and actually stored (%d) differ\n",
102 enc->bits_per_coded_sample, bps);
105 if (enc->codec_id == AV_CODEC_ID_MP2 ||
106 enc->codec_id == AV_CODEC_ID_MP3) {
107 /* This is wrong, but it seems many demuxers do not work if this
108 * is set correctly. */
109 blkalign = frame_size;
110 // blkalign = 144 * enc->bit_rate/enc->sample_rate;
111 } else if (enc->codec_id == AV_CODEC_ID_AC3) {
112 blkalign = 3840; /* maximum bytes per frame */
113 } else if (enc->codec_id == AV_CODEC_ID_AAC) {
114 blkalign = 768 * enc->channels; /* maximum bytes per frame */
115 } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
117 } else if (enc->block_align != 0) { /* specified by the codec */
118 blkalign = enc->block_align;
120 blkalign = bps * enc->channels / av_gcd(8, bps);
121 if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
122 enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
123 enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
124 enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
125 enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
126 enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
127 bytespersec = enc->sample_rate * blkalign;
128 } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
131 bytespersec = enc->bit_rate / 8;
133 avio_wl32(pb, bytespersec); /* bytes per second */
134 avio_wl16(pb, blkalign); /* block align */
135 avio_wl16(pb, bps); /* bits per sample */
136 if (enc->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 (enc->codec_id == AV_CODEC_ID_MP2) {
146 bytestream_put_le16(&riff_extradata, 2);
148 bytestream_put_le32(&riff_extradata, enc->bit_rate);
150 bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
152 bytestream_put_le16(&riff_extradata, 0);
154 bytestream_put_le16(&riff_extradata, 1);
156 bytestream_put_le16(&riff_extradata, 16);
158 bytestream_put_le32(&riff_extradata, 0);
160 bytestream_put_le32(&riff_extradata, 0);
161 } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
163 bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
164 bytestream_put_le32(&riff_extradata, 0xaea2f732);
165 bytestream_put_le16(&riff_extradata, 0xacde);
166 } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
167 enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
169 /* wSamplesPerBlock */
170 bytestream_put_le16(&riff_extradata, frame_size);
171 } else if (enc->extradata_size) {
172 riff_extradata_start = enc->extradata;
173 riff_extradata = enc->extradata + enc->extradata_size;
174 hdrsize += enc->extradata_size;
176 /* write WAVEFORMATEXTENSIBLE extensions */
177 if (waveformatextensible) {
179 /* 22 is WAVEFORMATEXTENSIBLE size */
180 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
181 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
184 avio_wl32(pb, enc->channel_layout);
186 avio_wl32(pb, enc->codec_tag);
187 avio_wl32(pb, 0x00100000);
188 avio_wl32(pb, 0xAA000080);
189 avio_wl32(pb, 0x719B3800);
191 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
193 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
202 /* BITMAPINFOHEADER header */
203 void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
204 const AVCodecTag *tags, int for_asf)
207 avio_wl32(pb, 40 + enc->extradata_size);
208 avio_wl32(pb, enc->width);
209 //We always store RGB TopDown
210 avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
214 avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
215 /* compression type */
216 avio_wl32(pb, enc->codec_tag);
217 avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
223 avio_write(pb, enc->extradata, enc->extradata_size);
225 if (!for_asf && enc->extradata_size & 1)
229 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
230 int *au_ssize, int *au_scale)
233 int audio_frame_size;
235 /* We use the known constant frame size for the codec if known, otherwise
236 * fall back on using AVCodecContext.frame_size, which is not as reliable
237 * for indicating packet duration. */
238 audio_frame_size = av_get_audio_frame_duration(stream, 0);
239 if (!audio_frame_size)
240 audio_frame_size = stream->frame_size;
242 *au_ssize = stream->block_align;
243 if (audio_frame_size && stream->sample_rate) {
244 *au_scale = audio_frame_size;
245 *au_rate = stream->sample_rate;
246 } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
247 stream->codec_type == AVMEDIA_TYPE_DATA ||
248 stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
249 *au_scale = stream->time_base.num;
250 *au_rate = stream->time_base.den;
252 *au_scale = stream->block_align ? stream->block_align * 8 : 8;
253 *au_rate = stream->bit_rate ? stream->bit_rate :
254 8 * stream->sample_rate;
256 gcd = av_gcd(*au_scale, *au_rate);
261 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
263 int len = strlen(str);
266 ffio_wfourcc(pb, tag);
268 avio_put_str(pb, str);
274 static const char riff_tags[][5] = {
275 "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
276 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
277 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
281 static int riff_has_valid_tags(AVFormatContext *s)
285 for (i = 0; *riff_tags[i]; i++)
286 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
292 void ff_riff_write_info(AVFormatContext *s)
294 AVIOContext *pb = s->pb;
297 AVDictionaryEntry *t = NULL;
299 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
301 /* writing empty LIST is not nice and may cause problems */
302 if (!riff_has_valid_tags(s))
305 list_pos = ff_start_tag(pb, "LIST");
306 ffio_wfourcc(pb, "INFO");
307 for (i = 0; *riff_tags[i]; i++)
308 if ((t = av_dict_get(s->metadata, riff_tags[i],
309 NULL, AV_DICT_MATCH_CASE)))
310 ff_riff_write_info_tag(s->pb, t->key, t->value);
311 ff_end_tag(pb, list_pos);