2 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
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:
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
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.
26 #include "libavutil/avstring.h"
27 #include "libavutil/base64.h"
28 #include "libavutil/bswap.h"
29 #include "libavutil/dict.h"
30 #include "libavcodec/get_bits.h"
31 #include "libavcodec/bytestream.h"
32 #include "libavcodec/vorbis_parser.h"
37 #include "vorbiscomment.h"
39 static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
41 int i, cnum, h, m, s, ms, keylen = strlen(key);
42 AVChapter *chapter = NULL;
44 if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
48 if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
51 avpriv_new_chapter(as, cnum, (AVRational){1,1000},
52 ms + 1000*(s + 60*(m + 60*h)),
53 AV_NOPTS_VALUE, NULL);
55 } else if (!strcmp(key+(keylen-4), "NAME")) {
56 for(i = 0; i < as->nb_chapters; i++)
57 if (as->chapters[i]->id == cnum) {
58 chapter = as->chapters[i];
64 av_dict_set(&chapter->metadata, "title", val,
65 AV_DICT_DONT_STRDUP_VAL);
74 ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
76 const uint8_t *p = buf;
77 const uint8_t *end = buf + size;
81 if (size < 8) /* must have vendor_length and user_comment_list_length */
84 s = bytestream_get_le32(&p);
86 if (end - p - 4 < s || s < 0)
91 n = bytestream_get_le32(&p);
93 while (end - p >= 4 && n > 0) {
97 s = bytestream_get_le32(&p);
99 if (end - p < s || s < 0)
106 v = memchr(t, '=', s);
117 tt = av_malloc(tl + 1);
118 ct = av_malloc(vl + 1);
122 av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
126 for (j = 0; j < tl; j++)
127 tt[j] = av_toupper(t[j]);
133 if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
135 char *pict = av_malloc(vl);
138 av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
143 if ((ret = av_base64_decode(pict, ct, vl)) > 0)
144 ret = ff_flac_parse_picture(as, pict, ret);
149 av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
152 } else if (!ogm_chapter(as, tt, ct))
153 av_dict_set(m, tt, ct,
154 AV_DICT_DONT_STRDUP_KEY |
155 AV_DICT_DONT_STRDUP_VAL);
160 av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
162 av_log(as, AV_LOG_INFO,
163 "truncated comment header, %i comments not found\n", n);
165 ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
171 /** Parse the vorbis header
172 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
173 * [vorbis_version] = read 32 bits as unsigned integer | Not used
174 * [audio_channels] = read 8 bit integer as unsigned | Used
175 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
176 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
177 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
178 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
179 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
180 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
181 * [framing_flag] = read one bit | Not Used
184 struct oggvorbis_private {
186 unsigned char *packet[3];
187 VorbisParseContext vp;
194 fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
197 int i,offset, len, buf_len;
200 len = priv->len[0] + priv->len[1] + priv->len[2];
201 buf_len = len + len/255 + 64;
202 ptr = *buf = av_realloc(NULL, buf_len);
205 memset(*buf, '\0', buf_len);
209 offset += av_xiphlacing(&ptr[offset], priv->len[0]);
210 offset += av_xiphlacing(&ptr[offset], priv->len[1]);
211 for (i = 0; i < 3; i++) {
212 memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
213 offset += priv->len[i];
214 av_freep(&priv->packet[i]);
216 *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
220 static void vorbis_cleanup(AVFormatContext *s, int idx)
222 struct ogg *ogg = s->priv_data;
223 struct ogg_stream *os = ogg->streams + idx;
224 struct oggvorbis_private *priv = os->private;
227 for (i = 0; i < 3; i++)
228 av_freep(&priv->packet[i]);
232 vorbis_header (AVFormatContext * s, int idx)
234 struct ogg *ogg = s->priv_data;
235 struct ogg_stream *os = ogg->streams + idx;
236 AVStream *st = s->streams[idx];
237 struct oggvorbis_private *priv;
238 int pkt_type = os->buf[os->pstart];
241 os->private = av_mallocz(sizeof(struct oggvorbis_private));
249 if (os->psize < 1 || pkt_type > 5)
254 if (priv->packet[pkt_type>>1])
256 if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
259 priv->len[pkt_type >> 1] = os->psize;
260 priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
261 if (!priv->packet[pkt_type >> 1])
262 return AVERROR(ENOMEM);
263 memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
264 if (os->buf[os->pstart] == 1) {
265 const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
266 unsigned blocksize, bs0, bs1;
273 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
276 channels= bytestream_get_byte(&p);
277 if (st->codec->channels && channels != st->codec->channels) {
278 av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
279 return AVERROR_PATCHWELCOME;
281 st->codec->channels = channels;
282 srate = bytestream_get_le32(&p);
283 p += 4; // skip maximum bitrate
284 st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
285 p += 4; // skip minimum bitrate
287 blocksize = bytestream_get_byte(&p);
288 bs0 = blocksize & 15;
289 bs1 = blocksize >> 4;
293 if (bs0 < 6 || bs1 > 13)
296 if (bytestream_get_byte(&p) != 1) /* framing_flag */
299 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
300 st->codec->codec_id = AV_CODEC_ID_VORBIS;
303 st->codec->sample_rate = srate;
304 avpriv_set_pts_info(st, 64, 1, srate);
306 } else if (os->buf[os->pstart] == 3) {
308 ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
309 // drop all metadata we parsed and which is not required by libvorbis
310 unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
311 if (new_len >= 16 && new_len < os->psize) {
312 AV_WL32(priv->packet[1] + new_len - 5, 0);
313 priv->packet[1][new_len - 1] = 1;
314 priv->len[1] = new_len;
319 st->codec->extradata_size =
320 fixup_vorbis_headers(s, priv, &st->codec->extradata);
321 if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
322 av_freep(&st->codec->extradata);
323 st->codec->extradata_size = 0;
331 static int vorbis_packet(AVFormatContext *s, int idx)
333 struct ogg *ogg = s->priv_data;
334 struct ogg_stream *os = ogg->streams + idx;
335 struct oggvorbis_private *priv = os->private;
338 /* first packet handling
339 here we parse the duration of each packet in the first page and compare
340 the total duration to the page granule to find the encoder delay and
341 set the first timestamp */
342 if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
344 uint8_t *last_pkt = os->buf + os->pstart;
345 uint8_t *next_pkt = last_pkt;
347 avpriv_vorbis_parse_reset(&priv->vp);
350 d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
352 os->pflags |= AV_PKT_FLAG_CORRUPT;
356 last_pkt = next_pkt = next_pkt + os->psize;
357 for (; seg < os->nsegs; seg++) {
358 if (os->segments[seg] < 255) {
359 int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
361 duration = os->granule;
365 last_pkt = next_pkt + os->segments[seg];
367 next_pkt += os->segments[seg];
369 os->lastpts = os->lastdts = os->granule - duration;
370 if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
371 s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
372 if (s->streams[idx]->duration)
373 s->streams[idx]->duration -= s->streams[idx]->start_time;
375 priv->final_pts = AV_NOPTS_VALUE;
376 avpriv_vorbis_parse_reset(&priv->vp);
379 /* parse packet duration */
381 duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
383 os->pflags |= AV_PKT_FLAG_CORRUPT;
386 os->pduration = duration;
389 /* final packet handling
390 here we save the pts of the first packet in the final page, sum up all
391 packet durations in the final page except for the last one, and compare
392 to the page granule to find the duration of the final packet */
393 if (os->flags & OGG_FLAG_EOS) {
394 if (os->lastpts != AV_NOPTS_VALUE) {
395 priv->final_pts = os->lastpts;
396 priv->final_duration = 0;
398 if (os->segp == os->nsegs)
399 os->pduration = os->granule - priv->final_pts - priv->final_duration;
400 priv->final_duration += os->pduration;
406 const struct ogg_codec ff_vorbis_codec = {
407 .magic = "\001vorbis",
409 .header = vorbis_header,
410 .packet = vorbis_packet,
411 .cleanup= vorbis_cleanup,