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, int ignore_extradata)
207 avio_wl32(pb, 40 + (ignore_extradata ? 0 : 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 if (!ignore_extradata) {
224 avio_write(pb, enc->extradata, enc->extradata_size);
226 if (!for_asf && enc->extradata_size & 1)
231 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
232 int *au_ssize, int *au_scale)
235 int audio_frame_size;
237 /* We use the known constant frame size for the codec if known, otherwise
238 * fall back on using AVCodecContext.frame_size, which is not as reliable
239 * for indicating packet duration. */
240 audio_frame_size = av_get_audio_frame_duration(stream, 0);
241 if (!audio_frame_size)
242 audio_frame_size = stream->frame_size;
244 *au_ssize = stream->block_align;
245 if (audio_frame_size && stream->sample_rate) {
246 *au_scale = audio_frame_size;
247 *au_rate = stream->sample_rate;
248 } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
249 stream->codec_type == AVMEDIA_TYPE_DATA ||
250 stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
251 *au_scale = stream->time_base.num;
252 *au_rate = stream->time_base.den;
254 *au_scale = stream->block_align ? stream->block_align * 8 : 8;
255 *au_rate = stream->bit_rate ? stream->bit_rate :
256 8 * stream->sample_rate;
258 gcd = av_gcd(*au_scale, *au_rate);
263 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
265 int len = strlen(str);
268 ffio_wfourcc(pb, tag);
270 avio_put_str(pb, str);
276 static const char riff_tags[][5] = {
277 "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
278 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
279 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
283 static int riff_has_valid_tags(AVFormatContext *s)
287 for (i = 0; *riff_tags[i]; i++)
288 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
294 void ff_riff_write_info(AVFormatContext *s)
296 AVIOContext *pb = s->pb;
299 AVDictionaryEntry *t = NULL;
301 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
303 /* writing empty LIST is not nice and may cause problems */
304 if (!riff_has_valid_tags(s))
307 list_pos = ff_start_tag(pb, "LIST");
308 ffio_wfourcc(pb, "INFO");
309 for (i = 0; *riff_tags[i]; i++)
310 if ((t = av_dict_get(s->metadata, riff_tags[i],
311 NULL, AV_DICT_MATCH_CASE)))
312 ff_riff_write_info_tag(s->pb, t->key, t->value);
313 ff_end_tag(pb, list_pos);