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 {
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  if (!frame_size)
67  frame_size = enc->frame_size;
68 
69  waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
70  enc->sample_rate > 48000 ||
72 
73  if (waveformatextensible)
74  avio_wl16(pb, 0xfffe);
75  else
76  avio_wl16(pb, enc->codec_tag);
77 
78  avio_wl16(pb, enc->channels);
79  avio_wl32(pb, enc->sample_rate);
80  if (enc->codec_id == AV_CODEC_ID_MP2 ||
81  enc->codec_id == AV_CODEC_ID_MP3 ||
82  enc->codec_id == AV_CODEC_ID_GSM_MS) {
83  bps = 0;
84  } else {
85  if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
86  if (enc->bits_per_coded_sample)
87  bps = enc->bits_per_coded_sample;
88  else
89  bps = 16; // default to 16
90  }
91  }
92  if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
94  "requested bits_per_coded_sample (%d) "
95  "and actually stored (%d) differ\n",
96  enc->bits_per_coded_sample, bps);
97  }
98 
99  if (enc->codec_id == AV_CODEC_ID_MP2 ||
100  enc->codec_id == AV_CODEC_ID_MP3) {
101  /* This is wrong, but it seems many demuxers do not work if this
102  * is set correctly. */
103  blkalign = frame_size;
104  // blkalign = 144 * enc->bit_rate/enc->sample_rate;
105  } else if (enc->codec_id == AV_CODEC_ID_AC3) {
106  blkalign = 3840; /* maximum bytes per frame */
107  } else if (enc->block_align != 0) { /* specified by the codec */
108  blkalign = enc->block_align;
109  } else
110  blkalign = bps * enc->channels / av_gcd(8, bps);
111  if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
117  bytespersec = enc->sample_rate * blkalign;
118  } else {
119  bytespersec = enc->bit_rate / 8;
120  }
121  avio_wl32(pb, bytespersec); /* bytes per second */
122  avio_wl16(pb, blkalign); /* block align */
123  avio_wl16(pb, bps); /* bits per sample */
124  if (enc->codec_id == AV_CODEC_ID_MP3) {
125  hdrsize += 12;
126  bytestream_put_le16(&riff_extradata, 1); /* wID */
127  bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
128  bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
129  bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
130  bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
131  } else if (enc->codec_id == AV_CODEC_ID_MP2) {
132  hdrsize += 22;
133  /* fwHeadLayer */
134  bytestream_put_le16(&riff_extradata, 2);
135  /* dwHeadBitrate */
136  bytestream_put_le32(&riff_extradata, enc->bit_rate);
137  /* fwHeadMode */
138  bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
139  /* fwHeadModeExt */
140  bytestream_put_le16(&riff_extradata, 0);
141  /* wHeadEmphasis */
142  bytestream_put_le16(&riff_extradata, 1);
143  /* fwHeadFlags */
144  bytestream_put_le16(&riff_extradata, 16);
145  /* dwPTSLow */
146  bytestream_put_le32(&riff_extradata, 0);
147  /* dwPTSHigh */
148  bytestream_put_le32(&riff_extradata, 0);
149  } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
151  hdrsize += 2;
152  /* wSamplesPerBlock */
153  bytestream_put_le16(&riff_extradata, frame_size);
154  } else if (enc->extradata_size) {
155  riff_extradata_start = enc->extradata;
156  riff_extradata = enc->extradata + enc->extradata_size;
157  hdrsize += enc->extradata_size;
158  }
159  /* write WAVEFORMATEXTENSIBLE extensions */
160  if (waveformatextensible) {
161  hdrsize += 22;
162  /* 22 is WAVEFORMATEXTENSIBLE size */
163  avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
164  /* ValidBitsPerSample || SamplesPerBlock || Reserved */
165  avio_wl16(pb, bps);
166  /* dwChannelMask */
167  avio_wl32(pb, enc->channel_layout);
168  /* GUID + next 3 */
169  avio_wl32(pb, enc->codec_tag);
170  avio_wl32(pb, 0x00100000);
171  avio_wl32(pb, 0xAA000080);
172  avio_wl32(pb, 0x719B3800);
173  } else {
174  avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
175  }
176  avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
177  if (hdrsize & 1) {
178  hdrsize++;
179  avio_w8(pb, 0);
180  }
181 
182  return hdrsize;
183 }
184 
185 /* BITMAPINFOHEADER header */
187  const AVCodecTag *tags, int for_asf)
188 {
189  /* size */
190  avio_wl32(pb, 40 + enc->extradata_size);
191  avio_wl32(pb, enc->width);
192  //We always store RGB TopDown
193  avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
194  /* planes */
195  avio_wl16(pb, 1);
196  /* depth */
198  /* compression type */
199  avio_wl32(pb, enc->codec_tag);
200  avio_wl32(pb, enc->width * enc->height * 3);
201  avio_wl32(pb, 0);
202  avio_wl32(pb, 0);
203  avio_wl32(pb, 0);
204  avio_wl32(pb, 0);
205 
206  avio_write(pb, enc->extradata, enc->extradata_size);
207 
208  if (!for_asf && enc->extradata_size & 1)
209  avio_w8(pb, 0);
210 }
211 
212 void ff_parse_specific_params(AVStream *st, int *au_rate,
213  int *au_ssize, int *au_scale)
214 {
215  AVCodecContext *codec = st->codec;
216  int gcd;
217  int audio_frame_size;
218 
219  /* We use the known constant frame size for the codec if known, otherwise
220  * fall back on using AVCodecContext.frame_size, which is not as reliable
221  * for indicating packet duration. */
222  audio_frame_size = av_get_audio_frame_duration(codec, 0);
223  if (!audio_frame_size)
224  audio_frame_size = codec->frame_size;
225 
226  *au_ssize = codec->block_align;
227  if (audio_frame_size && codec->sample_rate) {
228  *au_scale = audio_frame_size;
229  *au_rate = codec->sample_rate;
230  } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
231  codec->codec_type == AVMEDIA_TYPE_DATA ||
232  codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
233  *au_scale = st->time_base.num;
234  *au_rate = st->time_base.den;
235  } else {
236  *au_scale = codec->block_align ? codec->block_align * 8 : 8;
237  *au_rate = codec->bit_rate ? codec->bit_rate :
238  8 * codec->sample_rate;
239  }
240  gcd = av_gcd(*au_scale, *au_rate);
241  *au_scale /= gcd;
242  *au_rate /= gcd;
243 }
244 
245 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
246 {
247  int len = strlen(str);
248  if (len > 0) {
249  len++;
250  ffio_wfourcc(pb, tag);
251  avio_wl32(pb, len);
252  avio_put_str(pb, str);
253  if (len & 1)
254  avio_w8(pb, 0);
255  }
256 }
257 
258 static const char riff_tags[][5] = {
259  "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
260  "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
261  "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
262  { 0 }
263 };
264 
266 {
267  int i;
268 
269  for (i = 0; *riff_tags[i]; i++)
271  return 1;
272 
273  return 0;
274 }
275 
277 {
278  AVIOContext *pb = s->pb;
279  int i;
280  int64_t list_pos;
281  AVDictionaryEntry *t = NULL;
282 
284 
285  /* writing empty LIST is not nice and may cause problems */
286  if (!riff_has_valid_tags(s))
287  return;
288 
289  list_pos = ff_start_tag(pb, "LIST");
290  ffio_wfourcc(pb, "INFO");
291  for (i = 0; *riff_tags[i]; i++)
292  if ((t = av_dict_get(s->metadata, riff_tags[i],
294  ff_riff_write_info_tag(s->pb, t->key, t->value);
295  ff_end_tag(pb, list_pos);
296 }
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:347
Bytestream IO Context.
Definition: avio.h:68
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:129
int num
numerator
Definition: rational.h:44
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:186
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
Definition: avcodec.h:1844
void ff_parse_specific_params(AVStream *st, int *au_rate, int *au_ssize, int *au_scale)
Definition: riffenc.c:212
Format I/O context.
Definition: avformat.h:922
Public dictionary API.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:271
uint8_t
Opaque data information usually continuous.
Definition: avutil.h:189
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1164
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:844
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:219
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2523
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:165
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:67
int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
Definition: riffenc.c:50
void ff_riff_write_info(AVFormatContext *s)
Write all recognized RIFF tags from s->metadata.
Definition: riffenc.c:276
static const uint8_t frame_size[4]
Definition: g723_1_data.h:47
#define AV_DICT_MATCH_CASE
Definition: dict.h:61
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1130
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:2055
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: avcodec.h:379
int64_t av_gcd(int64_t a, int64_t b)
Return the greatest common divisor of a and b.
Definition: mathematics.c:53
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:1868
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:718
int bit_rate
the average bitrate
Definition: avcodec.h:1114
int width
picture width / height.
Definition: avcodec.h:1229
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:245
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:287
Stream structure.
Definition: avformat.h:699
int frame_size
Number of samples per channel in an audio frame.
Definition: avcodec.h:1827
NULL
Definition: eval.c:55
Libavcodec external API header.
enum AVMediaType codec_type
Definition: avcodec.h:1058
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
Definition: riffenc.c:31
enum AVCodecID codec_id
Definition: avcodec.h:1067
int sample_rate
samples per second
Definition: avcodec.h:1807
AVIOContext * pb
I/O context.
Definition: avformat.h:964
static const char riff_tags[][5]
Definition: riffenc.c:258
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:144
main external API structure.
Definition: avcodec.h:1050
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1082
static int riff_has_valid_tags(AVFormatContext *s)
Definition: riffenc.c:265
int extradata_size
Definition: avcodec.h:1165
int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
Return audio frame duration.
Definition: utils.c:2073
const AVMetadataConv ff_riff_info_conv[]
Definition: riff.c:421
Main libavformat public API header.
char * key
Definition: dict.h:75
int den
denominator
Definition: rational.h:45
unsigned bps
Definition: movenc.c:845
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf)
Definition: riffenc.c:186
char * value
Definition: dict.h:76
int len
int channels
number of audio channels
Definition: avcodec.h:1808
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:741