FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
riffenc.c
Go to the documentation of this file.
1 /*
2  * RIFF muxing functions
3  * Copyright (c) 2000 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
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, -1);
35  return avio_tell(pb);
36 }
37 
38 void ff_end_tag(AVIOContext *pb, int64_t start)
39 {
40  int64_t pos;
41 
42  av_assert0((start&1) == 0);
43 
44  pos = avio_tell(pb);
45  if (pos & 1)
46  avio_w8(pb, 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);
50 }
51 
52 /* WAVEFORMATEX header */
53 /* returns the size or -1 on error */
55 {
56  int bps, blkalign, bytespersec, frame_size;
57  int hdrsize;
58  int64_t hdrstart = avio_tell(pb);
59  int waveformatextensible;
60  uint8_t temp[256];
61  uint8_t *riff_extradata = temp;
62  uint8_t *riff_extradata_start = temp;
63 
64  if (!enc->codec_tag || enc->codec_tag > 0xffff)
65  return -1;
66 
67  /* We use the known constant frame size for the codec if known, otherwise
68  * fall back on using AVCodecContext.frame_size, which is not as reliable
69  * for indicating packet duration. */
70  frame_size = av_get_audio_frame_duration(enc, enc->block_align);
71  if (!frame_size)
72  frame_size = enc->frame_size;
73 
74  waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
75  enc->sample_rate > 48000 ||
76  enc->codec_id == AV_CODEC_ID_EAC3 ||
78 
79  if (waveformatextensible)
80  avio_wl16(pb, 0xfffe);
81  else
82  avio_wl16(pb, enc->codec_tag);
83 
84  avio_wl16(pb, enc->channels);
85  avio_wl32(pb, enc->sample_rate);
86  if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
87  enc->codec_id == AV_CODEC_ID_G723_1 ||
88  enc->codec_id == AV_CODEC_ID_MP2 ||
89  enc->codec_id == AV_CODEC_ID_MP3 ||
90  enc->codec_id == AV_CODEC_ID_GSM_MS) {
91  bps = 0;
92  } else {
93  if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
94  if (enc->bits_per_coded_sample)
95  bps = enc->bits_per_coded_sample;
96  else
97  bps = 16; // default to 16
98  }
99  }
100  if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
101  av_log(enc, AV_LOG_WARNING,
102  "requested bits_per_coded_sample (%d) "
103  "and actually stored (%d) differ\n",
104  enc->bits_per_coded_sample, bps);
105  }
106 
107  if (enc->codec_id == AV_CODEC_ID_MP2 ||
108  enc->codec_id == AV_CODEC_ID_MP3) {
109  /* This is wrong, but it seems many demuxers do not work if this
110  * is set correctly. */
111  blkalign = frame_size;
112  // blkalign = 144 * enc->bit_rate/enc->sample_rate;
113  } else if (enc->codec_id == AV_CODEC_ID_AC3) {
114  blkalign = 3840; /* maximum bytes per frame */
115  } else if (enc->codec_id == AV_CODEC_ID_AAC) {
116  blkalign = 768 * enc->channels; /* maximum bytes per frame */
117  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
118  blkalign = 24;
119  } else if (enc->block_align != 0) { /* specified by the codec */
120  blkalign = enc->block_align;
121  } else
122  blkalign = bps * enc->channels / av_gcd(8, bps);
123  if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
129  bytespersec = enc->sample_rate * blkalign;
130  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
131  bytespersec = 800;
132  } else {
133  bytespersec = enc->bit_rate / 8;
134  }
135  avio_wl32(pb, bytespersec); /* bytes per second */
136  avio_wl16(pb, blkalign); /* block align */
137  avio_wl16(pb, bps); /* bits per sample */
138  if (enc->codec_id == AV_CODEC_ID_MP3) {
139  bytestream_put_le16(&riff_extradata, 1); /* wID */
140  bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
141  bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
142  bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
143  bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
144  } else if (enc->codec_id == AV_CODEC_ID_MP2) {
145  /* fwHeadLayer */
146  bytestream_put_le16(&riff_extradata, 2);
147  /* dwHeadBitrate */
148  bytestream_put_le32(&riff_extradata, enc->bit_rate);
149  /* fwHeadMode */
150  bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
151  /* fwHeadModeExt */
152  bytestream_put_le16(&riff_extradata, 0);
153  /* wHeadEmphasis */
154  bytestream_put_le16(&riff_extradata, 1);
155  /* fwHeadFlags */
156  bytestream_put_le16(&riff_extradata, 16);
157  /* dwPTSLow */
158  bytestream_put_le32(&riff_extradata, 0);
159  /* dwPTSHigh */
160  bytestream_put_le32(&riff_extradata, 0);
161  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
162  bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
163  bytestream_put_le32(&riff_extradata, 0xaea2f732);
164  bytestream_put_le16(&riff_extradata, 0xacde);
165  } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
167  /* wSamplesPerBlock */
168  bytestream_put_le16(&riff_extradata, frame_size);
169  } else if (enc->extradata_size) {
170  riff_extradata_start = enc->extradata;
171  riff_extradata = enc->extradata + enc->extradata_size;
172  }
173  /* write WAVEFORMATEXTENSIBLE extensions */
174  if (waveformatextensible) {
175  int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
176  enc->channel_layout < 0x40000;
177  /* 22 is WAVEFORMATEXTENSIBLE size */
178  avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
179  /* ValidBitsPerSample || SamplesPerBlock || Reserved */
180  avio_wl16(pb, bps);
181  /* dwChannelMask */
182  avio_wl32(pb, write_channel_mask ? enc->channel_layout : 0);
183  /* GUID + next 3 */
184  if (enc->codec_id == AV_CODEC_ID_EAC3) {
186  } else {
187  avio_wl32(pb, enc->codec_tag);
188  avio_wl32(pb, 0x00100000);
189  avio_wl32(pb, 0xAA000080);
190  avio_wl32(pb, 0x719B3800);
191  }
192  } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
193  enc->codec_tag != 0x0001 /* PCM */ ||
194  riff_extradata - riff_extradata_start) {
195  /* WAVEFORMATEX */
196  avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
197  } /* else PCMWAVEFORMAT */
198  avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
199  hdrsize = avio_tell(pb) - hdrstart;
200  if (hdrsize & 1) {
201  hdrsize++;
202  avio_w8(pb, 0);
203  }
204 
205  return hdrsize;
206 }
207 
208 /* BITMAPINFOHEADER header */
210  const AVCodecTag *tags, int for_asf, int ignore_extradata)
211 {
212  /* size */
213  avio_wl32(pb, 40 + (ignore_extradata ? 0 : enc->extradata_size));
214  avio_wl32(pb, enc->width);
215  //We always store RGB TopDown
216  avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
217  /* planes */
218  avio_wl16(pb, 1);
219  /* depth */
221  /* compression type */
222  avio_wl32(pb, enc->codec_tag);
223  avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
224  avio_wl32(pb, 0);
225  avio_wl32(pb, 0);
226  avio_wl32(pb, 0);
227  avio_wl32(pb, 0);
228 
229  if (!ignore_extradata) {
230  avio_write(pb, enc->extradata, enc->extradata_size);
231 
232  if (!for_asf && enc->extradata_size & 1)
233  avio_w8(pb, 0);
234  }
235 }
236 
237 void ff_parse_specific_params(AVStream *st, int *au_rate,
238  int *au_ssize, int *au_scale)
239 {
240  AVCodecContext *codec = st->codec;
241  int gcd;
242  int audio_frame_size;
243 
244  /* We use the known constant frame size for the codec if known, otherwise
245  * fall back on using AVCodecContext.frame_size, which is not as reliable
246  * for indicating packet duration. */
247  audio_frame_size = av_get_audio_frame_duration(codec, 0);
248  if (!audio_frame_size)
249  audio_frame_size = codec->frame_size;
250 
251  *au_ssize = codec->block_align;
252  if (audio_frame_size && codec->sample_rate) {
253  *au_scale = audio_frame_size;
254  *au_rate = codec->sample_rate;
255  } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
256  codec->codec_type == AVMEDIA_TYPE_DATA ||
257  codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
258  *au_scale = st->time_base.num;
259  *au_rate = st->time_base.den;
260  } else {
261  *au_scale = codec->block_align ? codec->block_align * 8 : 8;
262  *au_rate = codec->bit_rate ? codec->bit_rate :
263  8 * codec->sample_rate;
264  }
265  gcd = av_gcd(*au_scale, *au_rate);
266  *au_scale /= gcd;
267  *au_rate /= gcd;
268 }
269 
270 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
271 {
272  int len = strlen(str);
273  if (len > 0) {
274  len++;
275  ffio_wfourcc(pb, tag);
276  avio_wl32(pb, len);
277  avio_put_str(pb, str);
278  if (len & 1)
279  avio_w8(pb, 0);
280  }
281 }
282 
283 static const char riff_tags[][5] = {
284  "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
285  "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
286  "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
287  { 0 }
288 };
289 
291 {
292  int i;
293 
294  for (i = 0; *riff_tags[i]; i++)
296  return 1;
297 
298  return 0;
299 }
300 
302 {
303  AVIOContext *pb = s->pb;
304  int i;
305  int64_t list_pos;
306  AVDictionaryEntry *t = NULL;
307 
309 
310  /* writing empty LIST is not nice and may cause problems */
311  if (!riff_has_valid_tags(s))
312  return;
313 
314  list_pos = ff_start_tag(pb, "LIST");
315  ffio_wfourcc(pb, "INFO");
316  for (i = 0; *riff_tags[i]; i++)
317  if ((t = av_dict_get(s->metadata, riff_tags[i],
318  NULL, AV_DICT_MATCH_CASE)))
319  ff_riff_write_info_tag(s->pb, t->key, t->value);
320  ff_end_tag(pb, list_pos);
321 }
322 
324 {
325  av_assert0(sizeof(*g) == 16);
326  avio_write(s, *g, sizeof(*g));
327 }
328 
329 const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
330 {
331  int i;
332  for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
333  if (id == av_guid[i].id)
334  return &(av_guid[i].guid);
335  }
336  return NULL;
337 }