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/bswap.h"
29 #include "libavutil/dict.h"
30 #include "libavcodec/bytestream.h"
31 #include "libavcodec/get_bits.h"
32 #include "libavcodec/vorbis_parser.h"
36 #include "vorbiscomment.h"
38 static int ogm_chapter(AVFormatContext
*as
, uint8_t *key
, uint8_t *val
)
40 int i
, cnum
, h
, m
, s
, ms
, keylen
= strlen(key
);
41 AVChapter
*chapter
= NULL
;
43 if (keylen
< 9 || sscanf(key
, "CHAPTER%02d", &cnum
) != 1)
47 if (sscanf(val
, "%02d:%02d:%02d.%03d", &h
, &m
, &s
, &ms
) < 4)
50 avpriv_new_chapter(as
, cnum
, (AVRational
) { 1, 1000 },
51 ms
+ 1000 * (s
+ 60 * (m
+ 60 * h
)),
52 AV_NOPTS_VALUE
, NULL
);
54 } else if (!strcmp(key
+ 9, "NAME")) {
55 for (i
= 0; i
< as
->nb_chapters
; i
++)
56 if (as
->chapters
[i
]->id
== cnum
) {
57 chapter
= as
->chapters
[i
];
63 av_dict_set(&chapter
->metadata
, "title", val
, AV_DICT_DONT_STRDUP_VAL
);
71 int ff_vorbis_comment(AVFormatContext
*as
, AVDictionary
**m
,
72 const uint8_t *buf
, int size
)
74 const uint8_t *p
= buf
;
75 const uint8_t *end
= buf
+ size
;
79 /* must have vendor_length and user_comment_list_length */
81 return AVERROR_INVALIDDATA
;
83 s
= bytestream_get_le32(&p
);
85 if (end
- p
- 4 < s
|| s
< 0)
86 return AVERROR_INVALIDDATA
;
90 n
= bytestream_get_le32(&p
);
92 while (end
- p
>= 4 && n
> 0) {
96 s
= bytestream_get_le32(&p
);
98 if (end
- p
< s
|| s
< 0)
105 v
= memchr(t
, '=', s
);
116 tt
= av_malloc(tl
+ 1);
117 ct
= av_malloc(vl
+ 1);
121 av_log(as
, AV_LOG_WARNING
,
122 "out-of-memory error. skipping VorbisComment tag.\n");
126 for (j
= 0; j
< tl
; j
++)
127 tt
[j
] = av_toupper(t
[j
]);
133 if (!ogm_chapter(as
, tt
, ct
))
134 av_dict_set(m
, tt
, ct
,
135 AV_DICT_DONT_STRDUP_KEY
|
136 AV_DICT_DONT_STRDUP_VAL
);
141 av_log(as
, AV_LOG_INFO
,
142 "%ti bytes of comment header remain\n", end
- p
);
144 av_log(as
, AV_LOG_INFO
,
145 "truncated comment header, %i comments not found\n", n
);
147 ff_metadata_conv(m
, NULL
, ff_vorbiscomment_metadata_conv
);
153 * Parse the vorbis header
155 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
156 * [vorbis_version] = read 32 bits as unsigned integer | Not used
157 * [audio_channels] = read 8 bit integer as unsigned | Used
158 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
159 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
160 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
161 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
162 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
163 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
164 * [framing_flag] = read one bit | Not Used
167 struct oggvorbis_private
{
169 unsigned char *packet
[3];
170 VorbisParseContext vp
;
175 static unsigned int fixup_vorbis_headers(AVFormatContext
*as
,
176 struct oggvorbis_private
*priv
,
179 int i
, offset
, len
, err
;
182 len
= priv
->len
[0] + priv
->len
[1] + priv
->len
[2];
183 ptr
= *buf
= av_mallocz(len
+ len
/ 255 + 64);
187 offset
+= av_xiphlacing(&ptr
[offset
], priv
->len
[0]);
188 offset
+= av_xiphlacing(&ptr
[offset
], priv
->len
[1]);
189 for (i
= 0; i
< 3; i
++) {
190 memcpy(&ptr
[offset
], priv
->packet
[i
], priv
->len
[i
]);
191 offset
+= priv
->len
[i
];
192 av_freep(&priv
->packet
[i
]);
194 if ((err
= av_reallocp(buf
, offset
+ FF_INPUT_BUFFER_PADDING_SIZE
)) < 0)
199 static void vorbis_cleanup(AVFormatContext
*s
, int idx
)
201 struct ogg
*ogg
= s
->priv_data
;
202 struct ogg_stream
*os
= ogg
->streams
+ idx
;
203 struct oggvorbis_private
*priv
= os
->private;
206 for (i
= 0; i
< 3; i
++)
207 av_freep(&priv
->packet
[i
]);
210 static int vorbis_header(AVFormatContext
*s
, int idx
)
212 struct ogg
*ogg
= s
->priv_data
;
213 AVStream
*st
= s
->streams
[idx
];
214 struct ogg_stream
*os
= ogg
->streams
+ idx
;
215 struct oggvorbis_private
*priv
;
216 int pkt_type
= os
->buf
[os
->pstart
];
219 os
->private = av_mallocz(sizeof(struct oggvorbis_private
));
221 return AVERROR(ENOMEM
);
227 if (os
->psize
< 1 || pkt_type
> 5)
228 return AVERROR_INVALIDDATA
;
232 if (priv
->packet
[pkt_type
>> 1])
233 return AVERROR_INVALIDDATA
;
234 if (pkt_type
> 1 && !priv
->packet
[0] || pkt_type
> 3 && !priv
->packet
[1])
235 return AVERROR_INVALIDDATA
;
237 priv
->len
[pkt_type
>> 1] = os
->psize
;
238 priv
->packet
[pkt_type
>> 1] = av_mallocz(os
->psize
);
239 memcpy(priv
->packet
[pkt_type
>> 1], os
->buf
+ os
->pstart
, os
->psize
);
240 if (os
->buf
[os
->pstart
] == 1) {
241 const uint8_t *p
= os
->buf
+ os
->pstart
+ 7; /* skip "\001vorbis" tag */
242 unsigned blocksize
, bs0
, bs1
;
246 return AVERROR_INVALIDDATA
;
248 if (bytestream_get_le32(&p
) != 0) /* vorbis_version */
249 return AVERROR_INVALIDDATA
;
251 st
->codec
->channels
= bytestream_get_byte(&p
);
252 srate
= bytestream_get_le32(&p
);
253 p
+= 4; // skip maximum bitrate
254 st
->codec
->bit_rate
= bytestream_get_le32(&p
); // nominal bitrate
255 p
+= 4; // skip minimum bitrate
257 blocksize
= bytestream_get_byte(&p
);
258 bs0
= blocksize
& 15;
259 bs1
= blocksize
>> 4;
262 return AVERROR_INVALIDDATA
;
263 if (bs0
< 6 || bs1
> 13)
264 return AVERROR_INVALIDDATA
;
266 if (bytestream_get_byte(&p
) != 1) /* framing_flag */
267 return AVERROR_INVALIDDATA
;
269 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
270 st
->codec
->codec_id
= AV_CODEC_ID_VORBIS
;
273 st
->codec
->sample_rate
= srate
;
274 avpriv_set_pts_info(st
, 64, 1, srate
);
276 } else if (os
->buf
[os
->pstart
] == 3) {
278 ff_vorbis_comment(s
, &st
->metadata
, os
->buf
+ os
->pstart
+ 7,
279 os
->psize
- 8) >= 0) {
280 // drop all metadata we parsed and which is not required by libvorbis
281 unsigned new_len
= 7 + 4 + AV_RL32(priv
->packet
[1] + 7) + 4 + 1;
282 if (new_len
>= 16 && new_len
< os
->psize
) {
283 AV_WL32(priv
->packet
[1] + new_len
- 5, 0);
284 priv
->packet
[1][new_len
- 1] = 1;
285 priv
->len
[1] = new_len
;
289 int ret
= fixup_vorbis_headers(s
, priv
, &st
->codec
->extradata
);
291 st
->codec
->extradata_size
= 0;
294 st
->codec
->extradata_size
= ret
;
295 if ((ret
= avpriv_vorbis_parse_extradata(st
->codec
, &priv
->vp
))) {
296 av_freep(&st
->codec
->extradata
);
297 st
->codec
->extradata_size
= 0;
305 static int vorbis_packet(AVFormatContext
*s
, int idx
)
307 struct ogg
*ogg
= s
->priv_data
;
308 struct ogg_stream
*os
= ogg
->streams
+ idx
;
309 struct oggvorbis_private
*priv
= os
->private;
312 /* first packet handling
313 * here we parse the duration of each packet in the first page and compare
314 * the total duration to the page granule to find the encoder delay and
315 * set the first timestamp */
318 uint8_t *last_pkt
= os
->buf
+ os
->pstart
;
319 uint8_t *next_pkt
= last_pkt
;
320 int first_duration
= 0;
322 avpriv_vorbis_parse_reset(&priv
->vp
);
324 for (seg
= 0; seg
< os
->nsegs
; seg
++) {
325 if (os
->segments
[seg
] < 255) {
326 int d
= avpriv_vorbis_parse_frame(&priv
->vp
, last_pkt
, 1);
328 duration
= os
->granule
;
334 last_pkt
= next_pkt
+ os
->segments
[seg
];
336 next_pkt
+= os
->segments
[seg
];
339 os
->lastdts
= os
->granule
- duration
;
340 s
->streams
[idx
]->start_time
= os
->lastpts
+ first_duration
;
341 if (s
->streams
[idx
]->duration
)
342 s
->streams
[idx
]->duration
-= s
->streams
[idx
]->start_time
;
343 s
->streams
[idx
]->cur_dts
= AV_NOPTS_VALUE
;
344 priv
->final_pts
= AV_NOPTS_VALUE
;
345 avpriv_vorbis_parse_reset(&priv
->vp
);
348 /* parse packet duration */
350 duration
= avpriv_vorbis_parse_frame(&priv
->vp
, os
->buf
+ os
->pstart
, 1);
352 os
->pflags
|= AV_PKT_FLAG_CORRUPT
;
355 os
->pduration
= duration
;
358 /* final packet handling
359 * here we save the pts of the first packet in the final page, sum up all
360 * packet durations in the final page except for the last one, and compare
361 * to the page granule to find the duration of the final packet */
362 if (os
->flags
& OGG_FLAG_EOS
) {
363 if (os
->lastpts
!= AV_NOPTS_VALUE
) {
364 priv
->final_pts
= os
->lastpts
;
365 priv
->final_duration
= 0;
367 if (os
->segp
== os
->nsegs
)
368 os
->pduration
= os
->granule
- priv
->final_pts
- priv
->final_duration
;
369 priv
->final_duration
+= os
->pduration
;
375 const struct ogg_codec ff_vorbis_codec
= {
376 .magic
= "\001vorbis",
378 .header
= vorbis_header
,
379 .packet
= vorbis_packet
,
380 .cleanup
= vorbis_cleanup
,