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.
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"
35 #include "flac_picture.h"
38 #include "vorbiscomment.h"
39 #include "replaygain.h"
41 static int ogm_chapter(AVFormatContext
*as
, uint8_t *key
, uint8_t *val
)
43 int i
, cnum
, h
, m
, s
, ms
, keylen
= strlen(key
);
44 AVChapter
*chapter
= NULL
;
46 if (keylen
< 9 || sscanf(key
, "CHAPTER%03d", &cnum
) != 1)
50 if (sscanf(val
, "%02d:%02d:%02d.%03d", &h
, &m
, &s
, &ms
) < 4)
53 avpriv_new_chapter(as
, cnum
, (AVRational
) { 1, 1000 },
54 ms
+ 1000 * (s
+ 60 * (m
+ 60 * h
)),
55 AV_NOPTS_VALUE
, NULL
);
57 } else if (!strcmp(key
+ keylen
- 4, "NAME")) {
58 for (i
= 0; i
< as
->nb_chapters
; i
++)
59 if (as
->chapters
[i
]->id
== cnum
) {
60 chapter
= as
->chapters
[i
];
66 av_dict_set(&chapter
->metadata
, "title", val
, AV_DICT_DONT_STRDUP_VAL
);
74 int ff_vorbis_stream_comment(AVFormatContext
*as
, AVStream
*st
,
75 const uint8_t *buf
, int size
)
77 int updates
= ff_vorbis_comment(as
, &st
->metadata
, buf
, size
, 1);
80 st
->event_flags
|= AVSTREAM_EVENT_FLAG_METADATA_UPDATED
;
86 int ff_vorbis_comment(AVFormatContext
*as
, AVDictionary
**m
,
87 const uint8_t *buf
, int size
,
90 const uint8_t *p
= buf
;
91 const uint8_t *end
= buf
+ size
;
96 /* must have vendor_length and user_comment_list_length */
98 return AVERROR_INVALIDDATA
;
100 s
= bytestream_get_le32(&p
);
102 if (end
- p
- 4 < s
|| s
< 0)
103 return AVERROR_INVALIDDATA
;
107 n
= bytestream_get_le32(&p
);
109 while (end
- p
>= 4 && n
> 0) {
113 s
= bytestream_get_le32(&p
);
115 if (end
- p
< s
|| s
< 0)
122 v
= memchr(t
, '=', s
);
133 tt
= av_malloc(tl
+ 1);
134 ct
= av_malloc(vl
+ 1);
138 return AVERROR(ENOMEM
);
141 for (j
= 0; j
< tl
; j
++)
142 tt
[j
] = av_toupper(t
[j
]);
148 /* The format in which the pictures are stored is the FLAC format.
149 * Xiph says: "The binary FLAC picture structure is base64 encoded
150 * and placed within a VorbisComment with the tag name
151 * 'METADATA_BLOCK_PICTURE'. This is the preferred and
152 * recommended way of embedding cover art within VorbisComments."
154 if (!strcmp(tt
, "METADATA_BLOCK_PICTURE") && parse_picture
) {
156 char *pict
= av_malloc(vl
);
159 av_log(as
, AV_LOG_WARNING
, "out-of-memory error. Skipping cover art block.\n");
164 if ((ret
= av_base64_decode(pict
, ct
, vl
)) > 0)
165 ret
= ff_flac_parse_picture(as
, pict
, ret
);
170 av_log(as
, AV_LOG_WARNING
, "Failed to parse cover art block.\n");
173 } else if (!ogm_chapter(as
, tt
, ct
)) {
175 if (av_dict_get(*m
, tt
, NULL
, 0)) {
176 av_dict_set(m
, tt
, ";", AV_DICT_APPEND
);
178 av_dict_set(m
, tt
, ct
,
179 AV_DICT_DONT_STRDUP_KEY
|
187 av_log(as
, AV_LOG_INFO
,
188 "%"PTRDIFF_SPECIFIER
" bytes of comment header remain\n", end
- p
);
190 av_log(as
, AV_LOG_INFO
,
191 "truncated comment header, %i comments not found\n", n
);
193 ff_metadata_conv(m
, NULL
, ff_vorbiscomment_metadata_conv
);
199 * Parse the vorbis header
201 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
202 * [vorbis_version] = read 32 bits as unsigned integer | Not used
203 * [audio_channels] = read 8 bit integer as unsigned | Used
204 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
205 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
206 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
207 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
208 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
209 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
210 * [framing_flag] = read one bit | Not Used
213 struct oggvorbis_private
{
215 unsigned char *packet
[3];
216 AVVorbisParseContext
*vp
;
221 static int fixup_vorbis_headers(AVFormatContext
*as
,
222 struct oggvorbis_private
*priv
,
225 int i
, offset
, len
, err
;
229 len
= priv
->len
[0] + priv
->len
[1] + priv
->len
[2];
230 buf_len
= len
+ len
/ 255 + 64;
231 ptr
= *buf
= av_realloc(NULL
, buf_len
);
233 return AVERROR(ENOMEM
);
234 memset(*buf
, '\0', buf_len
);
238 offset
+= av_xiphlacing(&ptr
[offset
], priv
->len
[0]);
239 offset
+= av_xiphlacing(&ptr
[offset
], priv
->len
[1]);
240 for (i
= 0; i
< 3; i
++) {
241 memcpy(&ptr
[offset
], priv
->packet
[i
], priv
->len
[i
]);
242 offset
+= priv
->len
[i
];
243 av_freep(&priv
->packet
[i
]);
245 if ((err
= av_reallocp(buf
, offset
+ FF_INPUT_BUFFER_PADDING_SIZE
)) < 0)
250 static void vorbis_cleanup(AVFormatContext
*s
, int idx
)
252 struct ogg
*ogg
= s
->priv_data
;
253 struct ogg_stream
*os
= ogg
->streams
+ idx
;
254 struct oggvorbis_private
*priv
= os
->private;
257 av_vorbis_parse_free(&priv
->vp
);
258 for (i
= 0; i
< 3; i
++)
259 av_freep(&priv
->packet
[i
]);
263 static int vorbis_update_metadata(AVFormatContext
*s
, int idx
)
265 struct ogg
*ogg
= s
->priv_data
;
266 struct ogg_stream
*os
= ogg
->streams
+ idx
;
267 AVStream
*st
= s
->streams
[idx
];
273 /* New metadata packet; release old data. */
274 av_dict_free(&st
->metadata
);
275 ret
= ff_vorbis_stream_comment(s
, st
, os
->buf
+ os
->pstart
+ 7,
280 /* Update the metadata if possible. */
281 av_freep(&os
->new_metadata
);
283 os
->new_metadata
= av_packet_pack_dictionary(st
->metadata
, &os
->new_metadata_size
);
284 /* Send an empty dictionary to indicate that metadata has been cleared. */
286 os
->new_metadata
= av_malloc(1);
287 os
->new_metadata_size
= 0;
293 static int vorbis_header(AVFormatContext
*s
, int idx
)
295 struct ogg
*ogg
= s
->priv_data
;
296 AVStream
*st
= s
->streams
[idx
];
297 struct ogg_stream
*os
= ogg
->streams
+ idx
;
298 struct oggvorbis_private
*priv
;
299 int pkt_type
= os
->buf
[os
->pstart
];
302 os
->private = av_mallocz(sizeof(struct oggvorbis_private
));
304 return AVERROR(ENOMEM
);
310 return priv
->vp
? 0 : AVERROR_INVALIDDATA
;
312 if (os
->psize
< 1 || pkt_type
> 5)
313 return AVERROR_INVALIDDATA
;
315 if (priv
->packet
[pkt_type
>> 1])
316 return AVERROR_INVALIDDATA
;
317 if (pkt_type
> 1 && !priv
->packet
[0] || pkt_type
> 3 && !priv
->packet
[1])
318 return AVERROR_INVALIDDATA
;
320 priv
->len
[pkt_type
>> 1] = os
->psize
;
321 priv
->packet
[pkt_type
>> 1] = av_mallocz(os
->psize
);
322 if (!priv
->packet
[pkt_type
>> 1])
323 return AVERROR(ENOMEM
);
324 memcpy(priv
->packet
[pkt_type
>> 1], os
->buf
+ os
->pstart
, os
->psize
);
325 if (os
->buf
[os
->pstart
] == 1) {
326 const uint8_t *p
= os
->buf
+ os
->pstart
+ 7; /* skip "\001vorbis" tag */
327 unsigned blocksize
, bs0
, bs1
;
332 return AVERROR_INVALIDDATA
;
334 if (bytestream_get_le32(&p
) != 0) /* vorbis_version */
335 return AVERROR_INVALIDDATA
;
337 channels
= bytestream_get_byte(&p
);
338 if (st
->codec
->channels
&& channels
!= st
->codec
->channels
) {
339 av_log(s
, AV_LOG_ERROR
, "Channel change is not supported\n");
340 return AVERROR_PATCHWELCOME
;
342 st
->codec
->channels
= channels
;
343 srate
= bytestream_get_le32(&p
);
344 p
+= 4; // skip maximum bitrate
345 st
->codec
->bit_rate
= bytestream_get_le32(&p
); // nominal bitrate
346 p
+= 4; // skip minimum bitrate
348 blocksize
= bytestream_get_byte(&p
);
349 bs0
= blocksize
& 15;
350 bs1
= blocksize
>> 4;
353 return AVERROR_INVALIDDATA
;
354 if (bs0
< 6 || bs1
> 13)
355 return AVERROR_INVALIDDATA
;
357 if (bytestream_get_byte(&p
) != 1) /* framing_flag */
358 return AVERROR_INVALIDDATA
;
360 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
361 st
->codec
->codec_id
= AV_CODEC_ID_VORBIS
;
364 st
->codec
->sample_rate
= srate
;
365 avpriv_set_pts_info(st
, 64, 1, srate
);
367 } else if (os
->buf
[os
->pstart
] == 3) {
368 if (vorbis_update_metadata(s
, idx
) >= 0 && priv
->len
[1] > 10) {
371 int ret
= ff_replaygain_export(st
, st
->metadata
);
375 // drop all metadata we parsed and which is not required by libvorbis
376 new_len
= 7 + 4 + AV_RL32(priv
->packet
[1] + 7) + 4 + 1;
377 if (new_len
>= 16 && new_len
< os
->psize
) {
378 AV_WL32(priv
->packet
[1] + new_len
- 5, 0);
379 priv
->packet
[1][new_len
- 1] = 1;
380 priv
->len
[1] = new_len
;
384 int ret
= fixup_vorbis_headers(s
, priv
, &st
->codec
->extradata
);
386 st
->codec
->extradata_size
= 0;
389 st
->codec
->extradata_size
= ret
;
391 priv
->vp
= av_vorbis_parse_init(st
->codec
->extradata
, st
->codec
->extradata_size
);
393 av_freep(&st
->codec
->extradata
);
394 st
->codec
->extradata_size
= 0;
395 return AVERROR_UNKNOWN
;
402 static int vorbis_packet(AVFormatContext
*s
, int idx
)
404 struct ogg
*ogg
= s
->priv_data
;
405 struct ogg_stream
*os
= ogg
->streams
+ idx
;
406 struct oggvorbis_private
*priv
= os
->private;
407 int duration
, flags
= 0;
409 /* first packet handling
410 * here we parse the duration of each packet in the first page and compare
411 * the total duration to the page granule to find the encoder delay and
412 * set the first timestamp */
413 if ((!os
->lastpts
|| os
->lastpts
== AV_NOPTS_VALUE
) && !(os
->flags
& OGG_FLAG_EOS
) && (int64_t)os
->granule
>=0) {
415 uint8_t *last_pkt
= os
->buf
+ os
->pstart
;
416 uint8_t *next_pkt
= last_pkt
;
418 av_vorbis_parse_reset(priv
->vp
);
421 d
= av_vorbis_parse_frame_flags(priv
->vp
, last_pkt
, 1, &flags
);
423 os
->pflags
|= AV_PKT_FLAG_CORRUPT
;
425 } else if (flags
& VORBIS_FLAG_COMMENT
) {
426 vorbis_update_metadata(s
, idx
);
430 last_pkt
= next_pkt
= next_pkt
+ os
->psize
;
431 for (; seg
< os
->nsegs
; seg
++) {
432 if (os
->segments
[seg
] < 255) {
433 int d
= av_vorbis_parse_frame_flags(priv
->vp
, last_pkt
, 1, &flags
);
435 duration
= os
->granule
;
437 } else if (flags
& VORBIS_FLAG_COMMENT
) {
438 vorbis_update_metadata(s
, idx
);
442 last_pkt
= next_pkt
+ os
->segments
[seg
];
444 next_pkt
+= os
->segments
[seg
];
447 os
->lastdts
= os
->granule
- duration
;
449 if (!os
->granule
&& duration
) //hack to deal with broken files (Ticket3710)
450 os
->lastpts
= os
->lastdts
= AV_NOPTS_VALUE
;
452 if (s
->streams
[idx
]->start_time
== AV_NOPTS_VALUE
) {
453 s
->streams
[idx
]->start_time
= FFMAX(os
->lastpts
, 0);
454 if (s
->streams
[idx
]->duration
!= AV_NOPTS_VALUE
)
455 s
->streams
[idx
]->duration
-= s
->streams
[idx
]->start_time
;
457 priv
->final_pts
= AV_NOPTS_VALUE
;
458 av_vorbis_parse_reset(priv
->vp
);
461 /* parse packet duration */
463 duration
= av_vorbis_parse_frame_flags(priv
->vp
, os
->buf
+ os
->pstart
, 1, &flags
);
465 os
->pflags
|= AV_PKT_FLAG_CORRUPT
;
467 } else if (flags
& VORBIS_FLAG_COMMENT
) {
468 vorbis_update_metadata(s
, idx
);
471 os
->pduration
= duration
;
474 /* final packet handling
475 * here we save the pts of the first packet in the final page, sum up all
476 * packet durations in the final page except for the last one, and compare
477 * to the page granule to find the duration of the final packet */
478 if (os
->flags
& OGG_FLAG_EOS
) {
479 if (os
->lastpts
!= AV_NOPTS_VALUE
) {
480 priv
->final_pts
= os
->lastpts
;
481 priv
->final_duration
= 0;
483 if (os
->segp
== os
->nsegs
)
484 os
->pduration
= os
->granule
- priv
->final_pts
- priv
->final_duration
;
485 priv
->final_duration
+= os
->pduration
;
491 const struct ogg_codec ff_vorbis_codec
= {
492 .magic
= "\001vorbis",
494 .header
= vorbis_header
,
495 .packet
= vorbis_packet
,
496 .cleanup
= vorbis_cleanup
,