Libav
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 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 */
51  AVCodecParameters *par)
52 {
53  int bps, blkalign, bytespersec, frame_size;
54  int hdrsize = 18;
55  int waveformatextensible;
56  uint8_t temp[256];
57  uint8_t *riff_extradata = temp;
58  uint8_t *riff_extradata_start = temp;
59 
60  if (!par->codec_tag || par->codec_tag > 0xffff)
61  return -1;
62 
63  /* We use the known constant frame size for the codec if known, otherwise
64  * fall back on using AVCodecContext.frame_size, which is not as reliable
65  * for indicating packet duration. */
66  frame_size = av_get_audio_frame_duration2(par, par->block_align);
67 
68  waveformatextensible = (par->channels > 2 && par->channel_layout) ||
69  par->sample_rate > 48000 ||
71 
72  if (waveformatextensible)
73  avio_wl16(pb, 0xfffe);
74  else
75  avio_wl16(pb, par->codec_tag);
76 
77  avio_wl16(pb, par->channels);
78  avio_wl32(pb, par->sample_rate);
79  if (par->codec_id == AV_CODEC_ID_MP2 ||
80  par->codec_id == AV_CODEC_ID_MP3 ||
81  par->codec_id == AV_CODEC_ID_GSM_MS) {
82  bps = 0;
83  } else {
84  if (!(bps = av_get_bits_per_sample(par->codec_id))) {
85  if (par->bits_per_coded_sample)
86  bps = par->bits_per_coded_sample;
87  else
88  bps = 16; // default to 16
89  }
90  }
91  if (bps != par->bits_per_coded_sample && par->bits_per_coded_sample) {
93  "requested bits_per_coded_sample (%d) "
94  "and actually stored (%d) differ\n",
95  par->bits_per_coded_sample, bps);
96  }
97 
98  if (par->codec_id == AV_CODEC_ID_MP2) {
99  blkalign = frame_size;
100  } else if (par->codec_id == AV_CODEC_ID_MP3) {
101  blkalign = 576 * (par->sample_rate <= 24000 ? 1 : 2);
102  } else if (par->codec_id == AV_CODEC_ID_AC3) {
103  blkalign = 3840; /* maximum bytes per frame */
104  } else if (par->block_align != 0) { /* specified by the codec */
105  blkalign = par->block_align;
106  } else
107  blkalign = bps * par->channels / av_gcd(8, bps);
108  if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
114  bytespersec = par->sample_rate * blkalign;
115  } else {
116  bytespersec = par->bit_rate / 8;
117  }
118  avio_wl32(pb, bytespersec); /* bytes per second */
119  avio_wl16(pb, blkalign); /* block align */
120  avio_wl16(pb, bps); /* bits per sample */
121  if (par->codec_id == AV_CODEC_ID_MP3) {
122  hdrsize += 12;
123  bytestream_put_le16(&riff_extradata, 1); /* wID */
124  bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
125  bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
126  bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
127  bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
128  } else if (par->codec_id == AV_CODEC_ID_MP2) {
129  hdrsize += 22;
130  /* fwHeadLayer */
131  bytestream_put_le16(&riff_extradata, 2);
132  /* dwHeadBitrate */
133  bytestream_put_le32(&riff_extradata, par->bit_rate);
134  /* fwHeadMode */
135  bytestream_put_le16(&riff_extradata, par->channels == 2 ? 1 : 8);
136  /* fwHeadModeExt */
137  bytestream_put_le16(&riff_extradata, 0);
138  /* wHeadEmphasis */
139  bytestream_put_le16(&riff_extradata, 1);
140  /* fwHeadFlags */
141  bytestream_put_le16(&riff_extradata, 16);
142  /* dwPTSLow */
143  bytestream_put_le32(&riff_extradata, 0);
144  /* dwPTSHigh */
145  bytestream_put_le32(&riff_extradata, 0);
146  } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
148  hdrsize += 2;
149  /* wSamplesPerBlock */
150  bytestream_put_le16(&riff_extradata, frame_size);
151  } else if (par->extradata_size) {
152  riff_extradata_start = par->extradata;
153  riff_extradata = par->extradata + par->extradata_size;
154  hdrsize += par->extradata_size;
155  }
156  /* write WAVEFORMATEXTENSIBLE extensions */
157  if (waveformatextensible) {
158  hdrsize += 22;
159  /* 22 is WAVEFORMATEXTENSIBLE size */
160  avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
161  /* ValidBitsPerSample || SamplesPerBlock || Reserved */
162  avio_wl16(pb, bps);
163  /* dwChannelMask */
164  avio_wl32(pb, par->channel_layout);
165  /* GUID + next 3 */
166  avio_wl32(pb, par->codec_tag);
167  avio_wl32(pb, 0x00100000);
168  avio_wl32(pb, 0xAA000080);
169  avio_wl32(pb, 0x719B3800);
170  } else {
171  avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
172  }
173  avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
174  if (hdrsize & 1) {
175  hdrsize++;
176  avio_w8(pb, 0);
177  }
178 
179  return hdrsize;
180 }
181 
182 /* BITMAPINFOHEADER header */
184  const AVCodecTag *tags, int for_asf)
185 {
186  /* size */
187  avio_wl32(pb, 40 + par->extradata_size);
188  avio_wl32(pb, par->width);
189  //We always store RGB TopDown
190  avio_wl32(pb, par->codec_tag ? par->height : -par->height);
191  /* planes */
192  avio_wl16(pb, 1);
193  /* depth */
195  /* compression type */
196  avio_wl32(pb, par->codec_tag);
197  avio_wl32(pb, par->width * par->height * 3);
198  avio_wl32(pb, 0);
199  avio_wl32(pb, 0);
200  avio_wl32(pb, 0);
201  avio_wl32(pb, 0);
202 
203  avio_write(pb, par->extradata, par->extradata_size);
204 
205  if (!for_asf && par->extradata_size & 1)
206  avio_w8(pb, 0);
207 }
208 
209 void ff_parse_specific_params(AVStream *st, int *au_rate,
210  int *au_ssize, int *au_scale)
211 {
212  AVCodecParameters *par = st->codecpar;
213  int gcd;
214  int audio_frame_size;
215 
216  audio_frame_size = av_get_audio_frame_duration2(par, 0);
217 
218  *au_ssize = par->block_align;
219  if (audio_frame_size && par->sample_rate) {
220  *au_scale = audio_frame_size;
221  *au_rate = par->sample_rate;
222  } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
223  par->codec_type == AVMEDIA_TYPE_DATA ||
225  *au_scale = st->time_base.num;
226  *au_rate = st->time_base.den;
227  } else {
228  *au_scale = par->block_align ? par->block_align * 8 : 8;
229  *au_rate = par->bit_rate ? par->bit_rate :
230  8 * par->sample_rate;
231  }
232  gcd = av_gcd(*au_scale, *au_rate);
233  *au_scale /= gcd;
234  *au_rate /= gcd;
235 }
236 
237 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
238 {
239  int len = strlen(str);
240  if (len > 0) {
241  len++;
242  ffio_wfourcc(pb, tag);
243  avio_wl32(pb, len);
244  avio_put_str(pb, str);
245  if (len & 1)
246  avio_w8(pb, 0);
247  }
248 }
249 
250 static const char riff_tags[][5] = {
251  "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
252  "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
253  "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
254  { 0 }
255 };
256 
258 {
259  int i;
260 
261  for (i = 0; *riff_tags[i]; i++)
263  return 1;
264 
265  return 0;
266 }
267 
269 {
270  AVIOContext *pb = s->pb;
271  int i;
272  int64_t list_pos;
273  AVDictionaryEntry *t = NULL;
274 
276 
277  /* writing empty LIST is not nice and may cause problems */
278  if (!riff_has_valid_tags(s))
279  return;
280 
281  list_pos = ff_start_tag(pb, "LIST");
282  ffio_wfourcc(pb, "INFO");
283  for (i = 0; *riff_tags[i]; i++)
284  if ((t = av_dict_get(s->metadata, riff_tags[i],
286  ff_riff_write_info_tag(s->pb, t->key, t->value);
287  ff_end_tag(pb, list_pos);
288 }
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:398
Bytestream IO Context.
Definition: avio.h:104
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:130
static const uint8_t frame_size[4]
Definition: g723_1.h:219
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3483
int num
numerator
Definition: rational.h:44
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:242
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3475
void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, const AVCodecTag *tags, int for_asf)
Definition: riffenc.c:183
void ff_parse_specific_params(AVStream *st, int *au_rate, int *au_ssize, int *au_scale)
Definition: riffenc.c:209
Format I/O context.
Definition: avformat.h:940
Public dictionary API.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:316
uint8_t
Opaque data information usually continuous.
Definition: avutil.h:196
int width
Video only.
Definition: avcodec.h:3525
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:38
uint32_t tag
Definition: movenc.c:854
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:295
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:221
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:66
uint64_t channel_layout
Audio only.
Definition: avcodec.h:3556
void ff_riff_write_info(AVFormatContext *s)
Write all recognized RIFF tags from s->metadata.
Definition: riffenc.c:268
#define AV_DICT_MATCH_CASE
Definition: dict.h:59
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1148
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:2348
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: avcodec.h:479
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3479
int64_t av_gcd(int64_t a, int64_t b)
Return the greatest common divisor of a and b.
Definition: mathematics.c:32
int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes)
This function is the same as av_get_audio_frame_duration(), except it works with AVCodecParameters in...
Definition: utils.c:2515
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3501
int bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3512
int block_align
Audio only.
Definition: avcodec.h:3571
void ff_end_tag(AVIOContext *pb, int64_t start)
Definition: riffenc.c:38
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
Write a single RIFF info tag.
Definition: riffenc.c:237
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par)
Definition: riffenc.c:50
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:332
Stream structure.
Definition: avformat.h:705
NULL
Definition: eval.c:55
Libavcodec external API header.
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
Definition: riffenc.c:31
AVIOContext * pb
I/O context.
Definition: avformat.h:982
static const char riff_tags[][5]
Definition: riffenc.c:250
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:200
static int riff_has_valid_tags(AVFormatContext *s)
Definition: riffenc.c:257
const AVMetadataConv ff_riff_info_conv[]
Definition: riff.c:442
int sample_rate
Audio only.
Definition: avcodec.h:3564
Main libavformat public API header.
char * key
Definition: dict.h:73
int den
denominator
Definition: rational.h:45
unsigned bps
Definition: movenc.c:855
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
char * value
Definition: dict.h:74
int len
int bits_per_coded_sample
Definition: avcodec.h:3514
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3497
int channels
Audio only.
Definition: avcodec.h:3560
AVCodecParameters * codecpar
Definition: avformat.h:831
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3487
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:742