avconv: pass input stream timestamps to audio encoders
[libav.git] / libavformat / oggparsevorbis.c
CommitLineData
9146ca37
MR
1/**
2 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
3
4 Permission is hereby granted, free of charge, to any person
5 obtaining a copy of this software and associated documentation
6 files (the "Software"), to deal in the Software without
7 restriction, including without limitation the rights to use, copy,
8 modify, merge, publish, distribute, sublicense, and/or sell copies
9 of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23**/
24
25#include <stdlib.h>
245976da
DB
26#include "libavutil/avstring.h"
27#include "libavutil/bswap.h"
d2d67e42 28#include "libavutil/dict.h"
9106a698 29#include "libavcodec/get_bits.h"
245976da 30#include "libavcodec/bytestream.h"
9146ca37 31#include "avformat.h"
19711af5 32#include "internal.h"
a0ddef24 33#include "oggdec.h"
fb66c31d 34#include "vorbiscomment.h"
9146ca37 35
8730fad5
DC
36static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
37{
38 int i, cnum, h, m, s, ms, keylen = strlen(key);
39 AVChapter *chapter = NULL;
40
41 if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
42 return 0;
43
44 if (keylen == 9) {
45 if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
46 return 0;
47
1fa395e4 48 avpriv_new_chapter(as, cnum, (AVRational){1,1000},
8730fad5
DC
49 ms + 1000*(s + 60*(m + 60*h)),
50 AV_NOPTS_VALUE, NULL);
51 av_free(val);
52 } else if (!strcmp(key+9, "NAME")) {
53 for(i = 0; i < as->nb_chapters; i++)
54 if (as->chapters[i]->id == cnum) {
55 chapter = as->chapters[i];
56 break;
57 }
58 if (!chapter)
59 return 0;
60
d2d67e42
AK
61 av_dict_set(&chapter->metadata, "title", val,
62 AV_DICT_DONT_STRDUP_VAL);
8730fad5
DC
63 } else
64 return 0;
65
66 av_free(key);
67 return 1;
68}
69
9686df2b 70int
d2d67e42 71ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
9146ca37 72{
47a0513b
BC
73 const uint8_t *p = buf;
74 const uint8_t *end = buf + size;
98422c44
RD
75 unsigned n, j;
76 int s;
9146ca37 77
f5475e1b 78 if (size < 8) /* must have vendor_length and user_comment_list_length */
9146ca37
MR
79 return -1;
80
0a770ae7 81 s = bytestream_get_le32(&p);
9146ca37 82
98422c44 83 if (end - p - 4 < s || s < 0)
9146ca37
MR
84 return -1;
85
86 p += s;
9146ca37 87
0a770ae7 88 n = bytestream_get_le32(&p);
9146ca37 89
98422c44 90 while (end - p >= 4 && n > 0) {
47a0513b 91 const char *t, *v;
9146ca37
MR
92 int tl, vl;
93
0a770ae7 94 s = bytestream_get_le32(&p);
9146ca37 95
98422c44 96 if (end - p < s || s < 0)
9146ca37
MR
97 break;
98
99 t = p;
100 p += s;
9146ca37
MR
101 n--;
102
4bd684bc 103 v = memchr(t, '=', s);
9146ca37
MR
104 if (!v)
105 continue;
106
107 tl = v - t;
108 vl = s - tl - 1;
109 v++;
110
4bd684bc 111 if (tl && vl) {
e3b44649
JR
112 char *tt, *ct;
113
114 tt = av_malloc(tl + 1);
115 ct = av_malloc(vl + 1);
116 if (!tt || !ct) {
117 av_freep(&tt);
118 av_freep(&ct);
119 av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
120 continue;
121 }
9146ca37
MR
122
123 for (j = 0; j < tl; j++)
4bd684bc 124 tt[j] = toupper(t[j]);
9146ca37
MR
125 tt[tl] = 0;
126
4bd684bc 127 memcpy(ct, v, vl);
9146ca37
MR
128 ct[vl] = 0;
129
8730fad5 130 if (!ogm_chapter(as, tt, ct))
d2d67e42
AK
131 av_dict_set(m, tt, ct,
132 AV_DICT_DONT_STRDUP_KEY |
133 AV_DICT_DONT_STRDUP_VAL);
9146ca37
MR
134 }
135 }
136
972c5f9e 137 if (p != end)
7d507ceb 138 av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
9146ca37 139 if (n > 0)
4bd684bc
MR
140 av_log(as, AV_LOG_INFO,
141 "truncated comment header, %i comments not found\n", n);
9146ca37 142
ad7768f4 143 ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
03700d39 144
9146ca37
MR
145 return 0;
146}
147
148
149/** Parse the vorbis header
150 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
151 * [vorbis_version] = read 32 bits as unsigned integer | Not used
152 * [audio_channels] = read 8 bit integer as unsigned | Used
115329f1 153 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
9146ca37
MR
154 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
155 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
156 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
157 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
158 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
159 * [framing_flag] = read one bit | Not Used
160 * */
161
77be08ee 162struct oggvorbis_private {
ad2b531d
MR
163 unsigned int len[3];
164 unsigned char *packet[3];
77be08ee 165};
ad2b531d
MR
166
167
168static unsigned int
77be08ee 169fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
19f4ceca 170 uint8_t **buf)
ad2b531d
MR
171{
172 int i,offset, len;
173 unsigned char *ptr;
174
175 len = priv->len[0] + priv->len[1] + priv->len[2];
176 ptr = *buf = av_mallocz(len + len/255 + 64);
177
178 ptr[0] = 2;
179 offset = 1;
180 offset += av_xiphlacing(&ptr[offset], priv->len[0]);
181 offset += av_xiphlacing(&ptr[offset], priv->len[1]);
4bd684bc 182 for (i = 0; i < 3; i++) {
ad2b531d
MR
183 memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
184 offset += priv->len[i];
2ac41150 185 av_freep(&priv->packet[i]);
ad2b531d 186 }
589790c2 187 *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
ad2b531d
MR
188 return offset;
189}
190
191
9146ca37
MR
192static int
193vorbis_header (AVFormatContext * s, int idx)
194{
77be08ee
MR
195 struct ogg *ogg = s->priv_data;
196 struct ogg_stream *os = ogg->streams + idx;
9146ca37 197 AVStream *st = s->streams[idx];
77be08ee 198 struct oggvorbis_private *priv;
8f8320d7 199 int pkt_type = os->buf[os->pstart];
9146ca37 200
8f8320d7 201 if (!(pkt_type & 1))
9146ca37
MR
202 return 0;
203
8f8320d7 204 if (!os->private) {
77be08ee 205 os->private = av_mallocz(sizeof(struct oggvorbis_private));
4bd684bc 206 if (!os->private)
ad2b531d
MR
207 return 0;
208 }
9146ca37 209
8f8320d7 210 if (os->psize < 1 || pkt_type > 5)
f5475e1b
MR
211 return -1;
212
ad2b531d 213 priv = os->private;
73c44cb2
AC
214
215 if (priv->packet[pkt_type>>1])
216 return -1;
217 if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
218 return -1;
219
8f8320d7
DC
220 priv->len[pkt_type >> 1] = os->psize;
221 priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
222 memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
9146ca37 223 if (os->buf[os->pstart] == 1) {
47a0513b 224 const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
736e63ed 225 unsigned blocksize, bs0, bs1;
ce20edb7 226 int srate;
f5475e1b
MR
227
228 if (os->psize != 30)
229 return -1;
230
736e63ed
MR
231 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
232 return -1;
233
739587bf 234 st->codec->channels = bytestream_get_byte(&p);
ce20edb7 235 srate = bytestream_get_le32(&p);
739587bf
MR
236 p += 4; // skip maximum bitrate
237 st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
736e63ed
MR
238 p += 4; // skip minimum bitrate
239
240 blocksize = bytestream_get_byte(&p);
241 bs0 = blocksize & 15;
242 bs1 = blocksize >> 4;
243
244 if (bs0 > bs1)
245 return -1;
246 if (bs0 < 6 || bs1 > 13)
247 return -1;
248
249 if (bytestream_get_byte(&p) != 1) /* framing_flag */
250 return -1;
9146ca37 251
72415b2a 252 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
01f4895c 253 st->codec->codec_id = CODEC_ID_VORBIS;
5602a464 254 st->need_parsing = AVSTREAM_PARSE_HEADERS;
9146ca37 255
ce20edb7
RD
256 if (srate > 0) {
257 st->codec->sample_rate = srate;
c3f9ebf7 258 avpriv_set_pts_info(st, 64, 1, srate);
ce20edb7 259 }
9146ca37 260 } else if (os->buf[os->pstart] == 3) {
8cb3c557
RD
261 if (os->psize > 8 &&
262 ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
263 // drop all metadata we parsed and which is not required by libvorbis
264 unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
265 if (new_len >= 16 && new_len < os->psize) {
266 AV_WL32(priv->packet[1] + new_len - 5, 0);
267 priv->packet[1][new_len - 1] = 1;
268 priv->len[1] = new_len;
269 }
270 }
ad2b531d 271 } else {
01f4895c
MN
272 st->codec->extradata_size =
273 fixup_vorbis_headers(s, priv, &st->codec->extradata);
9146ca37
MR
274 }
275
8f8320d7 276 return 1;
9146ca37
MR
277}
278
77be08ee 279const struct ogg_codec ff_vorbis_codec = {
9146ca37
MR
280 .magic = "\001vorbis",
281 .magicsize = 7,
282 .header = vorbis_header
283};