2 * Ogg bitstream support
3 * Luca Barbato <lu_zero@gentoo.org>
4 * Based on tcvp implementation
9 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 DEALINGS IN THE SOFTWARE.
36 #include "vorbiscomment.h"
38 #define MAX_PAGE_SIZE 65307
39 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
41 static const struct ogg_codec * const ogg_codecs[] = {
57 //FIXME We could avoid some structure duplication
59 ogg_save (AVFormatContext * s)
61 struct ogg *ogg = s->priv_data;
62 struct ogg_state *ost =
63 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
65 ost->pos = avio_tell (s->pb);
66 ost->curidx = ogg->curidx;
67 ost->next = ogg->state;
68 ost->nstreams = ogg->nstreams;
69 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
71 for (i = 0; i < ogg->nstreams; i++){
72 struct ogg_stream *os = ogg->streams + i;
73 os->buf = av_malloc (os->bufsize);
74 memset (os->buf, 0, os->bufsize);
75 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
84 ogg_restore (AVFormatContext * s, int discard)
86 struct ogg *ogg = s->priv_data;
87 AVIOContext *bc = s->pb;
88 struct ogg_state *ost = ogg->state;
94 ogg->state = ost->next;
97 for (i = 0; i < ogg->nstreams; i++)
98 av_free (ogg->streams[i].buf);
100 avio_seek (bc, ost->pos, SEEK_SET);
101 ogg->curidx = ost->curidx;
102 ogg->nstreams = ost->nstreams;
103 memcpy(ogg->streams, ost->streams,
104 ost->nstreams * sizeof(*ogg->streams));
113 ogg_reset (struct ogg * ogg)
117 for (i = 0; i < ogg->nstreams; i++){
118 struct ogg_stream *os = ogg->streams + i;
123 os->lastpts = AV_NOPTS_VALUE;
124 os->lastdts = AV_NOPTS_VALUE;
137 static const struct ogg_codec *
138 ogg_find_codec (uint8_t * buf, int size)
142 for (i = 0; ogg_codecs[i]; i++)
143 if (size >= ogg_codecs[i]->magicsize &&
144 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
145 return ogg_codecs[i];
151 ogg_new_stream (AVFormatContext * s, uint32_t serial)
154 struct ogg *ogg = s->priv_data;
155 int idx = ogg->nstreams++;
157 struct ogg_stream *os;
159 ogg->streams = av_realloc (ogg->streams,
160 ogg->nstreams * sizeof (*ogg->streams));
161 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
162 os = ogg->streams + idx;
164 os->bufsize = DECODER_BUFFER_SIZE;
165 os->buf = av_malloc(os->bufsize);
169 st = av_new_stream (s, idx);
171 return AVERROR(ENOMEM);
173 av_set_pts_info(st, 64, 1, 1000000);
179 ogg_new_buf(struct ogg *ogg, int idx)
181 struct ogg_stream *os = ogg->streams + idx;
182 uint8_t *nb = av_malloc(os->bufsize);
183 int size = os->bufpos - os->pstart;
185 memcpy(nb, os->buf + os->pstart, size);
196 ogg_read_page (AVFormatContext * s, int *str)
198 AVIOContext *bc = s->pb;
199 struct ogg *ogg = s->priv_data;
200 struct ogg_stream *os;
211 if (avio_read (bc, sync, 4) < 4)
217 if (sync[sp & 3] == 'O' &&
218 sync[(sp + 1) & 3] == 'g' &&
219 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
226 }while (i++ < MAX_PAGE_SIZE);
228 if (i >= MAX_PAGE_SIZE){
229 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
233 if (avio_r8(bc) != 0) /* version */
238 serial = avio_rl32 (bc);
239 seq = avio_rl32 (bc);
240 crc = avio_rl32 (bc);
243 idx = ogg_find_stream (ogg, serial);
245 for (i = 0; i < ogg->nstreams; i++) {
246 if (!ogg->streams[i].page_begin) {
249 for (n = 0; n < ogg->nstreams; n++) {
250 av_free(ogg->streams[n].buf);
251 av_free(ogg->streams[n].private);
258 idx = ogg_new_stream (s, serial);
263 os = ogg->streams + idx;
264 if (!(flags & OGG_FLAG_BOS))
266 os->page_pos = avio_tell(bc) - 27;
269 ogg_new_buf(ogg, idx);
271 if (avio_read (bc, os->segments, nsegs) < nsegs)
278 for (i = 0; i < nsegs; i++)
279 size += os->segments[i];
281 if (flags & OGG_FLAG_CONT || os->incomplete){
283 while (os->segp < os->nsegs){
284 int seg = os->segments[os->segp++];
289 os->sync_pos = os->page_pos;
293 os->sync_pos = os->page_pos;
296 if (os->bufsize - os->bufpos < size){
297 uint8_t *nb = av_malloc (os->bufsize *= 2);
298 memcpy (nb, os->buf, os->bufpos);
303 if (avio_read (bc, os->buf + os->bufpos, size) < size)
317 ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t *fpos)
319 struct ogg *ogg = s->priv_data;
321 struct ogg_stream *os;
323 int segp = 0, psize = 0;
326 av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
333 if (ogg_read_page (s, &idx) < 0)
337 os = ogg->streams + idx;
340 av_log (s, AV_LOG_DEBUG,
341 "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
342 idx, os->pstart, os->psize, os->segp, os->nsegs);
347 os->codec = ogg_find_codec (os->buf, os->bufpos);
360 while (os->segp < os->nsegs){
361 int ss = os->segments[os->segp++];
369 if (!complete && os->segp == os->nsegs){
376 av_log (s, AV_LOG_DEBUG,
377 "ogg_packet: idx %i, frame size %i, start %i\n",
378 idx, os->psize, os->pstart);
381 if (os->granule == -1)
382 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
388 os->header = os->codec->header (s, idx);
393 // We have reached the first non-header packet in this stream.
394 // Unfortunately more header packets may still follow for others,
395 // so we reset this later unless we are done with the headers
399 // Update the header state for all streams and
400 // compute the data_offset.
402 s->data_offset = os->sync_pos;
403 for (i = 0; i < ogg->nstreams; i++) {
404 struct ogg_stream *cur_os = ogg->streams + i;
405 if (cur_os->header > 0)
408 // if we have a partial non-header packet, its start is
409 // obviously at or after the data start
410 if (cur_os->incomplete)
411 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
414 os->pstart += os->psize;
420 if (os->codec && os->codec->packet)
421 os->codec->packet (s, idx);
425 *dstart = os->pstart;
429 *fpos = os->sync_pos;
430 os->pstart += os->psize;
432 os->sync_pos = os->page_pos;
435 // determine whether there are more complete packets in this page
436 // if not, the page's granule will apply to this packet
438 for (i = os->segp; i < os->nsegs; i++)
439 if (os->segments[i] < 255) {
444 if (os->segp == os->nsegs)
451 ogg_get_headers (AVFormatContext * s)
453 struct ogg *ogg = s->priv_data;
456 if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
458 }while (!ogg->headers);
461 av_log (s, AV_LOG_DEBUG, "found headers\n");
468 ogg_get_length (AVFormatContext * s)
470 struct ogg *ogg = s->priv_data;
478 if (s->duration != AV_NOPTS_VALUE)
481 size = avio_size(s->pb);
484 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
487 avio_seek (s->pb, end, SEEK_SET);
489 while (!ogg_read_page (s, &i)){
490 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
491 ogg->streams[i].codec) {
492 s->streams[i]->duration =
493 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
494 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
495 s->streams[i]->duration -= s->streams[i]->start_time;
506 ogg_read_header (AVFormatContext * s, AVFormatParameters * ap)
508 struct ogg *ogg = s->priv_data;
511 //linear headers seek from start
512 if (ogg_get_headers (s) < 0){
516 for (i = 0; i < ogg->nstreams; i++)
517 if (ogg->streams[i].header < 0)
518 ogg->streams[i].codec = NULL;
520 //linear granulepos seek from end
523 //fill the extradata in the per codec callbacks
527 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
529 struct ogg *ogg = s->priv_data;
530 struct ogg_stream *os = ogg->streams + idx;
531 int64_t pts = AV_NOPTS_VALUE;
534 *dts = AV_NOPTS_VALUE;
536 if (os->lastpts != AV_NOPTS_VALUE) {
538 os->lastpts = AV_NOPTS_VALUE;
540 if (os->lastdts != AV_NOPTS_VALUE) {
543 os->lastdts = AV_NOPTS_VALUE;
546 if (os->granule != -1LL) {
547 if (os->codec && os->codec->granule_is_start)
548 pts = ogg_gptopts(s, idx, os->granule, dts);
550 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
558 ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
561 struct ogg_stream *os;
564 int64_t fpos, pts, dts;
569 if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
571 }while (idx < 0 || !s->streams[idx]);
574 os = ogg->streams + idx;
576 // pflags might not be set until after this
577 pts = ogg_calc_pts(s, idx, &dts);
579 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
581 os->keyframe_seek = 0;
584 if (av_new_packet (pkt, psize) < 0)
586 pkt->stream_index = idx;
587 memcpy (pkt->data, os->buf + pstart, psize);
591 pkt->flags = os->pflags;
592 pkt->duration = os->pduration;
600 ogg_read_close (AVFormatContext * s)
602 struct ogg *ogg = s->priv_data;
605 for (i = 0; i < ogg->nstreams; i++){
606 av_free (ogg->streams[i].buf);
607 av_free (ogg->streams[i].private);
609 av_free (ogg->streams);
615 ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg,
618 struct ogg *ogg = s->priv_data;
619 struct ogg_stream *os = ogg->streams + stream_index;
620 AVIOContext *bc = s->pb;
621 int64_t pts = AV_NOPTS_VALUE;
623 avio_seek(bc, *pos_arg, SEEK_SET);
626 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
627 if (i == stream_index) {
628 pts = ogg_calc_pts(s, i, NULL);
629 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
630 pts = AV_NOPTS_VALUE;
632 if (pts != AV_NOPTS_VALUE)
639 static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
641 struct ogg *ogg = s->priv_data;
642 struct ogg_stream *os = ogg->streams + stream_index;
645 // Try seeking to a keyframe first. If this fails (very possible),
646 // av_seek_frame will fall back to ignoring keyframes
647 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
648 && !(flags & AVSEEK_FLAG_ANY))
649 os->keyframe_seek = 1;
651 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
653 os->keyframe_seek = 0;
657 static int ogg_probe(AVProbeData *p)
659 if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
660 p->buf[2] == 'g' && p->buf[3] == 'S' &&
661 p->buf[4] == 0x0 && p->buf[5] <= 0x7 )
662 return AVPROBE_SCORE_MAX;
667 AVInputFormat ff_ogg_demuxer = {
669 NULL_IF_CONFIG_SMALL("Ogg"),
678 .flags = AVFMT_GENERIC_INDEX,