Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6148 | serge | 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 |
||
26 | |||
27 | #include "libavutil/avstring.h" |
||
28 | #include "libavutil/base64.h" |
||
29 | #include "libavutil/bswap.h" |
||
30 | #include "libavutil/dict.h" |
||
31 | #include "libavcodec/bytestream.h" |
||
32 | #include "libavcodec/get_bits.h" |
||
33 | #include "libavcodec/vorbis_parser.h" |
||
34 | #include "avformat.h" |
||
35 | #include "flac_picture.h" |
||
36 | #include "internal.h" |
||
37 | #include "oggdec.h" |
||
38 | #include "vorbiscomment.h" |
||
39 | |||
40 | static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val) |
||
41 | { |
||
42 | int i, cnum, h, m, s, ms, keylen = strlen(key); |
||
43 | AVChapter *chapter = NULL; |
||
44 | |||
45 | if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1) |
||
46 | return 0; |
||
47 | |||
48 | if (keylen <= 10) { |
||
49 | if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4) |
||
50 | return 0; |
||
51 | |||
52 | avpriv_new_chapter(as, cnum, (AVRational) { 1, 1000 }, |
||
53 | ms + 1000 * (s + 60 * (m + 60 * h)), |
||
54 | AV_NOPTS_VALUE, NULL); |
||
55 | av_free(val); |
||
56 | } else if (!strcmp(key + keylen - 4, "NAME")) { |
||
57 | for (i = 0; i < as->nb_chapters; i++) |
||
58 | if (as->chapters[i]->id == cnum) { |
||
59 | chapter = as->chapters[i]; |
||
60 | break; |
||
61 | } |
||
62 | if (!chapter) |
||
63 | return 0; |
||
64 | |||
65 | av_dict_set(&chapter->metadata, "title", val, AV_DICT_DONT_STRDUP_VAL); |
||
66 | } else |
||
67 | return 0; |
||
68 | |||
69 | av_free(key); |
||
70 | return 1; |
||
71 | } |
||
72 | |||
73 | int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, |
||
74 | const uint8_t *buf, int size) |
||
75 | { |
||
76 | const uint8_t *p = buf; |
||
77 | const uint8_t *end = buf + size; |
||
78 | unsigned n, j; |
||
79 | int s; |
||
80 | |||
81 | /* must have vendor_length and user_comment_list_length */ |
||
82 | if (size < 8) |
||
83 | return AVERROR_INVALIDDATA; |
||
84 | |||
85 | s = bytestream_get_le32(&p); |
||
86 | |||
87 | if (end - p - 4 < s || s < 0) |
||
88 | return AVERROR_INVALIDDATA; |
||
89 | |||
90 | p += s; |
||
91 | |||
92 | n = bytestream_get_le32(&p); |
||
93 | |||
94 | while (end - p >= 4 && n > 0) { |
||
95 | const char *t, *v; |
||
96 | int tl, vl; |
||
97 | |||
98 | s = bytestream_get_le32(&p); |
||
99 | |||
100 | if (end - p < s || s < 0) |
||
101 | break; |
||
102 | |||
103 | t = p; |
||
104 | p += s; |
||
105 | n--; |
||
106 | |||
107 | v = memchr(t, '=', s); |
||
108 | if (!v) |
||
109 | continue; |
||
110 | |||
111 | tl = v - t; |
||
112 | vl = s - tl - 1; |
||
113 | v++; |
||
114 | |||
115 | if (tl && vl) { |
||
116 | char *tt, *ct; |
||
117 | |||
118 | tt = av_malloc(tl + 1); |
||
119 | ct = av_malloc(vl + 1); |
||
120 | if (!tt || !ct) { |
||
121 | av_freep(&tt); |
||
122 | av_freep(&ct); |
||
123 | return AVERROR(ENOMEM); |
||
124 | } |
||
125 | |||
126 | for (j = 0; j < tl; j++) |
||
127 | tt[j] = av_toupper(t[j]); |
||
128 | tt[tl] = 0; |
||
129 | |||
130 | memcpy(ct, v, vl); |
||
131 | ct[vl] = 0; |
||
132 | |||
133 | /* The format in which the pictures are stored is the FLAC format. |
||
134 | * Xiph says: "The binary FLAC picture structure is base64 encoded |
||
135 | * and placed within a VorbisComment with the tag name |
||
136 | * 'METADATA_BLOCK_PICTURE'. This is the preferred and |
||
137 | * recommended way of embedding cover art within VorbisComments." |
||
138 | */ |
||
139 | if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) { |
||
140 | int ret; |
||
141 | char *pict = av_malloc(vl); |
||
142 | |||
143 | if (!pict) { |
||
144 | av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n"); |
||
145 | av_freep(&tt); |
||
146 | av_freep(&ct); |
||
147 | continue; |
||
148 | } |
||
149 | if ((ret = av_base64_decode(pict, ct, vl)) > 0) |
||
150 | ret = ff_flac_parse_picture(as, pict, ret); |
||
151 | av_freep(&tt); |
||
152 | av_freep(&ct); |
||
153 | av_freep(&pict); |
||
154 | if (ret < 0) { |
||
155 | av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n"); |
||
156 | continue; |
||
157 | } |
||
158 | } else if (!ogm_chapter(as, tt, ct)) |
||
159 | av_dict_set(m, tt, ct, |
||
160 | AV_DICT_DONT_STRDUP_KEY | |
||
161 | AV_DICT_DONT_STRDUP_VAL); |
||
162 | } |
||
163 | } |
||
164 | |||
165 | if (p != end) |
||
166 | av_log(as, AV_LOG_INFO, |
||
167 | "%ti bytes of comment header remain\n", end - p); |
||
168 | if (n > 0) |
||
169 | av_log(as, AV_LOG_INFO, |
||
170 | "truncated comment header, %i comments not found\n", n); |
||
171 | |||
172 | ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv); |
||
173 | |||
174 | return 0; |
||
175 | } |
||
176 | |||
177 | /* |
||
178 | * Parse the vorbis header |
||
179 | * |
||
180 | * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec |
||
181 | * [vorbis_version] = read 32 bits as unsigned integer | Not used |
||
182 | * [audio_channels] = read 8 bit integer as unsigned | Used |
||
183 | * [audio_sample_rate] = read 32 bits as unsigned integer | Used |
||
184 | * [bitrate_maximum] = read 32 bits as signed integer | Not used yet |
||
185 | * [bitrate_nominal] = read 32 bits as signed integer | Not used yet |
||
186 | * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate |
||
187 | * [blocksize_0] = read 4 bits as unsigned integer | Not Used |
||
188 | * [blocksize_1] = read 4 bits as unsigned integer | Not Used |
||
189 | * [framing_flag] = read one bit | Not Used |
||
190 | */ |
||
191 | |||
192 | struct oggvorbis_private { |
||
193 | unsigned int len[3]; |
||
194 | unsigned char *packet[3]; |
||
195 | VorbisParseContext vp; |
||
196 | int64_t final_pts; |
||
197 | int final_duration; |
||
198 | }; |
||
199 | |||
200 | static int fixup_vorbis_headers(AVFormatContext *as, |
||
201 | struct oggvorbis_private *priv, |
||
202 | uint8_t **buf) |
||
203 | { |
||
204 | int i, offset, len, err; |
||
205 | int buf_len; |
||
206 | unsigned char *ptr; |
||
207 | |||
208 | len = priv->len[0] + priv->len[1] + priv->len[2]; |
||
209 | buf_len = len + len / 255 + 64; |
||
210 | ptr = *buf = av_realloc(NULL, buf_len); |
||
211 | if (!ptr) |
||
212 | return AVERROR(ENOMEM); |
||
213 | memset(*buf, '\0', buf_len); |
||
214 | |||
215 | ptr[0] = 2; |
||
216 | offset = 1; |
||
217 | offset += av_xiphlacing(&ptr[offset], priv->len[0]); |
||
218 | offset += av_xiphlacing(&ptr[offset], priv->len[1]); |
||
219 | for (i = 0; i < 3; i++) { |
||
220 | memcpy(&ptr[offset], priv->packet[i], priv->len[i]); |
||
221 | offset += priv->len[i]; |
||
222 | av_freep(&priv->packet[i]); |
||
223 | } |
||
224 | if ((err = av_reallocp(buf, offset + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) |
||
225 | return err; |
||
226 | return offset; |
||
227 | } |
||
228 | |||
229 | static void vorbis_cleanup(AVFormatContext *s, int idx) |
||
230 | { |
||
231 | struct ogg *ogg = s->priv_data; |
||
232 | struct ogg_stream *os = ogg->streams + idx; |
||
233 | struct oggvorbis_private *priv = os->private; |
||
234 | int i; |
||
235 | if (os->private) |
||
236 | for (i = 0; i < 3; i++) |
||
237 | av_freep(&priv->packet[i]); |
||
238 | } |
||
239 | |||
240 | static int vorbis_header(AVFormatContext *s, int idx) |
||
241 | { |
||
242 | struct ogg *ogg = s->priv_data; |
||
243 | AVStream *st = s->streams[idx]; |
||
244 | struct ogg_stream *os = ogg->streams + idx; |
||
245 | struct oggvorbis_private *priv; |
||
246 | int pkt_type = os->buf[os->pstart]; |
||
247 | |||
248 | if (!os->private) { |
||
249 | os->private = av_mallocz(sizeof(struct oggvorbis_private)); |
||
250 | if (!os->private) |
||
251 | return AVERROR(ENOMEM); |
||
252 | } |
||
253 | |||
254 | if (!(pkt_type & 1)) |
||
255 | return 0; |
||
256 | |||
257 | if (os->psize < 1 || pkt_type > 5) |
||
258 | return AVERROR_INVALIDDATA; |
||
259 | |||
260 | priv = os->private; |
||
261 | |||
262 | if (priv->packet[pkt_type >> 1]) |
||
263 | return AVERROR_INVALIDDATA; |
||
264 | if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1]) |
||
265 | return AVERROR_INVALIDDATA; |
||
266 | |||
267 | priv->len[pkt_type >> 1] = os->psize; |
||
268 | priv->packet[pkt_type >> 1] = av_mallocz(os->psize); |
||
269 | if (!priv->packet[pkt_type >> 1]) |
||
270 | return AVERROR(ENOMEM); |
||
271 | memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize); |
||
272 | if (os->buf[os->pstart] == 1) { |
||
273 | const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */ |
||
274 | unsigned blocksize, bs0, bs1; |
||
275 | int srate; |
||
276 | int channels; |
||
277 | |||
278 | if (os->psize != 30) |
||
279 | return AVERROR_INVALIDDATA; |
||
280 | |||
281 | if (bytestream_get_le32(&p) != 0) /* vorbis_version */ |
||
282 | return AVERROR_INVALIDDATA; |
||
283 | |||
284 | channels = bytestream_get_byte(&p); |
||
285 | if (st->codec->channels && channels != st->codec->channels) { |
||
286 | av_log(s, AV_LOG_ERROR, "Channel change is not supported\n"); |
||
287 | return AVERROR_PATCHWELCOME; |
||
288 | } |
||
289 | st->codec->channels = channels; |
||
290 | srate = bytestream_get_le32(&p); |
||
291 | p += 4; // skip maximum bitrate |
||
292 | st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate |
||
293 | p += 4; // skip minimum bitrate |
||
294 | |||
295 | blocksize = bytestream_get_byte(&p); |
||
296 | bs0 = blocksize & 15; |
||
297 | bs1 = blocksize >> 4; |
||
298 | |||
299 | if (bs0 > bs1) |
||
300 | return AVERROR_INVALIDDATA; |
||
301 | if (bs0 < 6 || bs1 > 13) |
||
302 | return AVERROR_INVALIDDATA; |
||
303 | |||
304 | if (bytestream_get_byte(&p) != 1) /* framing_flag */ |
||
305 | return AVERROR_INVALIDDATA; |
||
306 | |||
307 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
||
308 | st->codec->codec_id = AV_CODEC_ID_VORBIS; |
||
309 | |||
310 | if (srate > 0) { |
||
311 | st->codec->sample_rate = srate; |
||
312 | avpriv_set_pts_info(st, 64, 1, srate); |
||
313 | } |
||
314 | } else if (os->buf[os->pstart] == 3) { |
||
315 | if (os->psize > 8 && |
||
316 | ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, |
||
317 | os->psize - 8) >= 0) { |
||
318 | // drop all metadata we parsed and which is not required by libvorbis |
||
319 | unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1; |
||
320 | if (new_len >= 16 && new_len < os->psize) { |
||
321 | AV_WL32(priv->packet[1] + new_len - 5, 0); |
||
322 | priv->packet[1][new_len - 1] = 1; |
||
323 | priv->len[1] = new_len; |
||
324 | } |
||
325 | } |
||
326 | } else { |
||
327 | int ret = fixup_vorbis_headers(s, priv, &st->codec->extradata); |
||
328 | if (ret < 0) { |
||
329 | st->codec->extradata_size = 0; |
||
330 | return ret; |
||
331 | } |
||
332 | st->codec->extradata_size = ret; |
||
333 | if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) { |
||
334 | av_freep(&st->codec->extradata); |
||
335 | st->codec->extradata_size = 0; |
||
336 | return ret; |
||
337 | } |
||
338 | } |
||
339 | |||
340 | return 1; |
||
341 | } |
||
342 | |||
343 | static int vorbis_packet(AVFormatContext *s, int idx) |
||
344 | { |
||
345 | struct ogg *ogg = s->priv_data; |
||
346 | struct ogg_stream *os = ogg->streams + idx; |
||
347 | struct oggvorbis_private *priv = os->private; |
||
348 | int duration; |
||
349 | |||
350 | /* first packet handling |
||
351 | * here we parse the duration of each packet in the first page and compare |
||
352 | * the total duration to the page granule to find the encoder delay and |
||
353 | * set the first timestamp */ |
||
354 | if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { |
||
355 | int seg, d; |
||
356 | uint8_t *last_pkt = os->buf + os->pstart; |
||
357 | uint8_t *next_pkt = last_pkt; |
||
358 | |||
359 | avpriv_vorbis_parse_reset(&priv->vp); |
||
360 | duration = 0; |
||
361 | seg = os->segp; |
||
362 | d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); |
||
363 | if (d < 0) { |
||
364 | os->pflags |= AV_PKT_FLAG_CORRUPT; |
||
365 | return 0; |
||
366 | } |
||
367 | duration += d; |
||
368 | last_pkt = next_pkt = next_pkt + os->psize; |
||
369 | for (; seg < os->nsegs; seg++) { |
||
370 | if (os->segments[seg] < 255) { |
||
371 | int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); |
||
372 | if (d < 0) { |
||
373 | duration = os->granule; |
||
374 | break; |
||
375 | } |
||
376 | duration += d; |
||
377 | last_pkt = next_pkt + os->segments[seg]; |
||
378 | } |
||
379 | next_pkt += os->segments[seg]; |
||
380 | } |
||
381 | os->lastpts = |
||
382 | os->lastdts = os->granule - duration; |
||
383 | if (s->streams[idx]->start_time == AV_NOPTS_VALUE) { |
||
384 | s->streams[idx]->start_time = FFMAX(os->lastpts, 0); |
||
385 | if (s->streams[idx]->duration) |
||
386 | s->streams[idx]->duration -= s->streams[idx]->start_time; |
||
387 | } |
||
388 | priv->final_pts = AV_NOPTS_VALUE; |
||
389 | avpriv_vorbis_parse_reset(&priv->vp); |
||
390 | } |
||
391 | |||
392 | /* parse packet duration */ |
||
393 | if (os->psize > 0) { |
||
394 | duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1); |
||
395 | if (duration < 0) { |
||
396 | os->pflags |= AV_PKT_FLAG_CORRUPT; |
||
397 | return 0; |
||
398 | } |
||
399 | os->pduration = duration; |
||
400 | } |
||
401 | |||
402 | /* final packet handling |
||
403 | * here we save the pts of the first packet in the final page, sum up all |
||
404 | * packet durations in the final page except for the last one, and compare |
||
405 | * to the page granule to find the duration of the final packet */ |
||
406 | if (os->flags & OGG_FLAG_EOS) { |
||
407 | if (os->lastpts != AV_NOPTS_VALUE) { |
||
408 | priv->final_pts = os->lastpts; |
||
409 | priv->final_duration = 0; |
||
410 | } |
||
411 | if (os->segp == os->nsegs) |
||
412 | os->pduration = os->granule - priv->final_pts - priv->final_duration; |
||
413 | priv->final_duration += os->pduration; |
||
414 | } |
||
415 | |||
416 | return 0; |
||
417 | } |
||
418 | |||
419 | const struct ogg_codec ff_vorbis_codec = { |
||
420 | .magic = "\001vorbis", |
||
421 | .magicsize = 7, |
||
422 | .header = vorbis_header, |
||
423 | .packet = vorbis_packet, |
||
424 | .cleanup = vorbis_cleanup, |
||
425 | .nb_header = 3, |
||
426 | };>>>>>>>>>>>>>>>>>>>>>=>> |