OSDN Git Service

rtpdec: Don't pass non-const pointers to fmtp attribute parsing functions
[android-x86/external-ffmpeg.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     /* We use the known constant frame size for the codec if known, otherwise
216      * fall back on using AVCodecContext.frame_size, which is not as reliable
217      * for indicating packet duration. */
218     audio_frame_size = av_get_audio_frame_duration(codec, 0);
219     if (!audio_frame_size)
220         audio_frame_size = codec->frame_size;
221
222     *au_ssize = codec->block_align;
223     if (audio_frame_size && codec->sample_rate) {
224         *au_scale = audio_frame_size;
225         *au_rate  = codec->sample_rate;
226     } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
227                codec->codec_type == AVMEDIA_TYPE_DATA ||
228                codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
229         *au_scale = st->time_base.num;
230         *au_rate  = st->time_base.den;
231     } else {
232         *au_scale = codec->block_align ? codec->block_align * 8 : 8;
233         *au_rate  = codec->bit_rate ? codec->bit_rate :
234                     8 * codec->sample_rate;
235     }
236     gcd        = av_gcd(*au_scale, *au_rate);
237     *au_scale /= gcd;
238     *au_rate  /= gcd;
239 }
240
241 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
242 {
243     int len = strlen(str);
244     if (len > 0) {
245         len++;
246         ffio_wfourcc(pb, tag);
247         avio_wl32(pb, len);
248         avio_put_str(pb, str);
249         if (len & 1)
250             avio_w8(pb, 0);
251     }
252 }
253
254 static const char riff_tags[][5] = {
255     "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
256     "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
257     "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
258     { 0 }
259 };
260
261 static int riff_has_valid_tags(AVFormatContext *s)
262 {
263     int i;
264
265     for (i = 0; *riff_tags[i]; i++)
266         if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
267             return 1;
268
269     return 0;
270 }
271
272 void ff_riff_write_info(AVFormatContext *s)
273 {
274     AVIOContext *pb = s->pb;
275     int i;
276     int64_t list_pos;
277     AVDictionaryEntry *t = NULL;
278
279     ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
280
281     /* writing empty LIST is not nice and may cause problems */
282     if (!riff_has_valid_tags(s))
283         return;
284
285     list_pos = ff_start_tag(pb, "LIST");
286     ffio_wfourcc(pb, "INFO");
287     for (i = 0; *riff_tags[i]; i++)
288         if ((t = av_dict_get(s->metadata, riff_tags[i],
289                              NULL, AV_DICT_MATCH_CASE)))
290             ff_riff_write_info_tag(s->pb, t->key, t->value);
291     ff_end_tag(pb, list_pos);
292 }