ff_parse_specific_params: do not use AVCodecContext.frame_size
[libav.git] / libavformat / riffenc.c
1 /*
2 * RIFF muxing functions
3 * Copyright (c) 2000 Fabrice Bellard
4 *
5 * This file is part of Libav.
6 *
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.
11 *
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.
16 *
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
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
31 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32 {
33 ffio_wfourcc(pb, tag);
34 avio_wl32(pb, 0);
35 return avio_tell(pb);
36 }
37
38 void ff_end_tag(AVIOContext *pb, int64_t start)
39 {
40 int64_t pos;
41
42 pos = avio_tell(pb);
43 avio_seek(pb, start - 4, SEEK_SET);
44 avio_wl32(pb, (uint32_t)(pos - start));
45 avio_seek(pb, pos, SEEK_SET);
46 }
47
48 /* WAVEFORMATEX header */
49 /* returns the size or -1 on error */
50 int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
51 {
52 int bps, blkalign, bytespersec, frame_size;
53 int hdrsize = 18;
54 int waveformatextensible;
55 uint8_t temp[256];
56 uint8_t *riff_extradata = temp;
57 uint8_t *riff_extradata_start = temp;
58
59 if (!enc->codec_tag || enc->codec_tag > 0xffff)
60 return -1;
61
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);
66
67 waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
68 enc->sample_rate > 48000 ||
69 av_get_bits_per_sample(enc->codec_id) > 16;
70
71 if (waveformatextensible)
72 avio_wl16(pb, 0xfffe);
73 else
74 avio_wl16(pb, enc->codec_tag);
75
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) {
81 bps = 0;
82 } else {
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;
86 else
87 bps = 16; // default to 16
88 }
89 }
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);
95 }
96
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;
105 } else
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;
114 } else {
115 bytespersec = enc->bit_rate / 8;
116 }
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) {
121 hdrsize += 12;
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) {
128 hdrsize += 22;
129 /* fwHeadLayer */
130 bytestream_put_le16(&riff_extradata, 2);
131 /* dwHeadBitrate */
132 bytestream_put_le32(&riff_extradata, enc->bit_rate);
133 /* fwHeadMode */
134 bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
135 /* fwHeadModeExt */
136 bytestream_put_le16(&riff_extradata, 0);
137 /* wHeadEmphasis */
138 bytestream_put_le16(&riff_extradata, 1);
139 /* fwHeadFlags */
140 bytestream_put_le16(&riff_extradata, 16);
141 /* dwPTSLow */
142 bytestream_put_le32(&riff_extradata, 0);
143 /* dwPTSHigh */
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) {
147 hdrsize += 2;
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;
154 }
155 /* write WAVEFORMATEXTENSIBLE extensions */
156 if (waveformatextensible) {
157 hdrsize += 22;
158 /* 22 is WAVEFORMATEXTENSIBLE size */
159 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
160 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
161 avio_wl16(pb, bps);
162 /* dwChannelMask */
163 avio_wl32(pb, enc->channel_layout);
164 /* GUID + next 3 */
165 avio_wl32(pb, enc->codec_tag);
166 avio_wl32(pb, 0x00100000);
167 avio_wl32(pb, 0xAA000080);
168 avio_wl32(pb, 0x719B3800);
169 } else {
170 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
171 }
172 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
173 if (hdrsize & 1) {
174 hdrsize++;
175 avio_w8(pb, 0);
176 }
177
178 return hdrsize;
179 }
180
181 /* BITMAPINFOHEADER header */
182 void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
183 const AVCodecTag *tags, int for_asf)
184 {
185 /* size */
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);
190 /* planes */
191 avio_wl16(pb, 1);
192 /* depth */
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);
197 avio_wl32(pb, 0);
198 avio_wl32(pb, 0);
199 avio_wl32(pb, 0);
200 avio_wl32(pb, 0);
201
202 avio_write(pb, enc->extradata, enc->extradata_size);
203
204 if (!for_asf && enc->extradata_size & 1)
205 avio_w8(pb, 0);
206 }
207
208 void ff_parse_specific_params(AVStream *st, int *au_rate,
209 int *au_ssize, int *au_scale)
210 {
211 AVCodecContext *codec = st->codec;
212 int gcd;
213 int audio_frame_size;
214
215 audio_frame_size = av_get_audio_frame_duration(codec, 0);
216
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;
226 } else {
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;
230 }
231 gcd = av_gcd(*au_scale, *au_rate);
232 *au_scale /= gcd;
233 *au_rate /= gcd;
234 }
235
236 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
237 {
238 int len = strlen(str);
239 if (len > 0) {
240 len++;
241 ffio_wfourcc(pb, tag);
242 avio_wl32(pb, len);
243 avio_put_str(pb, str);
244 if (len & 1)
245 avio_w8(pb, 0);
246 }
247 }
248
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",
253 { 0 }
254 };
255
256 static int riff_has_valid_tags(AVFormatContext *s)
257 {
258 int i;
259
260 for (i = 0; *riff_tags[i]; i++)
261 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
262 return 1;
263
264 return 0;
265 }
266
267 void ff_riff_write_info(AVFormatContext *s)
268 {
269 AVIOContext *pb = s->pb;
270 int i;
271 int64_t list_pos;
272 AVDictionaryEntry *t = NULL;
273
274 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
275
276 /* writing empty LIST is not nice and may cause problems */
277 if (!riff_has_valid_tags(s))
278 return;
279
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);
287 }