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 
72  waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
73  enc->sample_rate > 48000 ||
74  enc->codec_id == AV_CODEC_ID_EAC3 ||
76 
77  if (waveformatextensible)
78  avio_wl16(pb, 0xfffe);
79  else
80  avio_wl16(pb, enc->codec_tag);
81 
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) {
89  bps = 0;
90  } else {
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;
94  else
95  bps = 16; // default to 16
96  }
97  }
98  if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
100  "requested bits_per_coded_sample (%d) "
101  "and actually stored (%d) differ\n",
102  enc->bits_per_coded_sample, bps);
103  }
104 
105  if (enc->codec_id == AV_CODEC_ID_MP2) {
106  blkalign = frame_size;
107  } else if (enc->codec_id == AV_CODEC_ID_MP3) {
108  blkalign = 576 * (enc->sample_rate <= (24000 + 32000)/2 ? 1 : 2);
109  } else if (enc->codec_id == AV_CODEC_ID_AC3) {
110  blkalign = 3840; /* maximum bytes per frame */
111  } else if (enc->codec_id == AV_CODEC_ID_AAC) {
112  blkalign = 768 * enc->channels; /* maximum bytes per frame */
113  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
114  blkalign = 24;
115  } else if (enc->block_align != 0) { /* specified by the codec */
116  blkalign = enc->block_align;
117  } else
118  blkalign = bps * enc->channels / av_gcd(8, bps);
119  if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
125  bytespersec = enc->sample_rate * blkalign;
126  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
127  bytespersec = 800;
128  } else {
129  bytespersec = enc->bit_rate / 8;
130  }
131  avio_wl32(pb, bytespersec); /* bytes per second */
132  avio_wl16(pb, blkalign); /* block align */
133  avio_wl16(pb, bps); /* bits per sample */
134  if (enc->codec_id == AV_CODEC_ID_MP3) {
135  bytestream_put_le16(&riff_extradata, 1); /* wID */
136  bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
137  bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
138  bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
139  bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
140  } else if (enc->codec_id == AV_CODEC_ID_MP2) {
141  /* fwHeadLayer */
142  bytestream_put_le16(&riff_extradata, 2);
143  /* dwHeadBitrate */
144  bytestream_put_le32(&riff_extradata, enc->bit_rate);
145  /* fwHeadMode */
146  bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
147  /* fwHeadModeExt */
148  bytestream_put_le16(&riff_extradata, 0);
149  /* wHeadEmphasis */
150  bytestream_put_le16(&riff_extradata, 1);
151  /* fwHeadFlags */
152  bytestream_put_le16(&riff_extradata, 16);
153  /* dwPTSLow */
154  bytestream_put_le32(&riff_extradata, 0);
155  /* dwPTSHigh */
156  bytestream_put_le32(&riff_extradata, 0);
157  } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
158  bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
159  bytestream_put_le32(&riff_extradata, 0xaea2f732);
160  bytestream_put_le16(&riff_extradata, 0xacde);
161  } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
163  /* wSamplesPerBlock */
164  bytestream_put_le16(&riff_extradata, frame_size);
165  } else if (enc->extradata_size) {
166  riff_extradata_start = enc->extradata;
167  riff_extradata = enc->extradata + enc->extradata_size;
168  }
169  /* write WAVEFORMATEXTENSIBLE extensions */
170  if (waveformatextensible) {
171  int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
172  enc->channel_layout < 0x40000;
173  /* 22 is WAVEFORMATEXTENSIBLE size */
174  avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
175  /* ValidBitsPerSample || SamplesPerBlock || Reserved */
176  avio_wl16(pb, bps);
177  /* dwChannelMask */
178  avio_wl32(pb, write_channel_mask ? enc->channel_layout : 0);
179  /* GUID + next 3 */
180  if (enc->codec_id == AV_CODEC_ID_EAC3) {
182  } else {
183  avio_wl32(pb, enc->codec_tag);
184  avio_wl32(pb, 0x00100000);
185  avio_wl32(pb, 0xAA000080);
186  avio_wl32(pb, 0x719B3800);
187  }
188  } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
189  enc->codec_tag != 0x0001 /* PCM */ ||
190  riff_extradata - riff_extradata_start) {
191  /* WAVEFORMATEX */
192  avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
193  } /* else PCMWAVEFORMAT */
194  avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
195  hdrsize = avio_tell(pb) - hdrstart;
196  if (hdrsize & 1) {
197  hdrsize++;
198  avio_w8(pb, 0);
199  }
200 
201  return hdrsize;
202 }
203 
204 /* BITMAPINFOHEADER header */
206  const AVCodecTag *tags, int for_asf, int ignore_extradata)
207 {
208  int keep_height = enc->extradata_size >= 9 &&
209  !memcmp(enc->extradata + enc->extradata_size - 9, "BottomUp", 9);
210  int extradata_size = enc->extradata_size - 9*keep_height;
211 
212  /* size */
213  avio_wl32(pb, 40 + (ignore_extradata ? 0 :extradata_size));
214  avio_wl32(pb, enc->width);
215  //We always store RGB TopDown
216  avio_wl32(pb, enc->codec_tag || keep_height ? 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, extradata_size);
231 
232  if (!for_asf && 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 }