2 * Ogg bitstream support
3 * Luca Barbato <lu_zero@gentoo.org>
4 * Based on tcvp implementation
8 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
10 Permission is hereby granted, free of charge, to any person
11 obtaining a copy of this software and associated documentation
12 files (the "Software"), to deal in the Software without
13 restriction, including without limitation the rights to use, copy,
14 modify, merge, publish, distribute, sublicense, and/or sell copies
15 of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be
19 included in all copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 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[] = {
58 //FIXME We could avoid some structure duplication
59 static int 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_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
74 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
82 static int ogg_restore(AVFormatContext *s, int discard)
84 struct ogg *ogg = s->priv_data;
85 AVIOContext *bc = s->pb;
86 struct ogg_state *ost = ogg->state;
92 ogg->state = ost->next;
95 struct ogg_stream *old_streams = ogg->streams;
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 ogg->streams = av_realloc (ogg->streams,
104 ogg->nstreams * sizeof (*ogg->streams));
107 memcpy(ogg->streams, ost->streams,
108 ost->nstreams * sizeof(*ogg->streams));
110 av_free(old_streams);
120 static int ogg_reset(struct ogg *ogg)
124 for (i = 0; i < ogg->nstreams; i++){
125 struct ogg_stream *os = ogg->streams + i;
130 os->lastpts = AV_NOPTS_VALUE;
131 os->lastdts = AV_NOPTS_VALUE;
144 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
148 for (i = 0; ogg_codecs[i]; i++)
149 if (size >= ogg_codecs[i]->magicsize &&
150 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
151 return ogg_codecs[i];
156 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
159 struct ogg *ogg = s->priv_data;
160 int idx = ogg->nstreams++;
162 struct ogg_stream *os;
164 ogg->streams = av_realloc (ogg->streams,
165 ogg->nstreams * sizeof (*ogg->streams));
166 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
167 os = ogg->streams + idx;
169 os->bufsize = DECODER_BUFFER_SIZE;
170 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
172 os->start_granule = OGG_NOGRANULE_VALUE;
175 st = avformat_new_stream(s, NULL);
177 return AVERROR(ENOMEM);
180 avpriv_set_pts_info(st, 64, 1, 1000000);
186 static int ogg_new_buf(struct ogg *ogg, int idx)
188 struct ogg_stream *os = ogg->streams + idx;
189 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
190 int size = os->bufpos - os->pstart;
192 memcpy(nb, os->buf + os->pstart, size);
202 static int ogg_read_page(AVFormatContext *s, int *str)
204 AVIOContext *bc = s->pb;
205 struct ogg *ogg = s->priv_data;
206 struct ogg_stream *os;
215 ret = avio_read(bc, sync, 4);
217 return ret < 0 ? ret : AVERROR_EOF;
222 if (sync[sp & 3] == 'O' &&
223 sync[(sp + 1) & 3] == 'g' &&
224 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
231 }while (i++ < MAX_PAGE_SIZE);
233 if (i >= MAX_PAGE_SIZE){
234 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
235 return AVERROR_INVALIDDATA;
238 if (avio_r8(bc) != 0) /* version */
239 return AVERROR_INVALIDDATA;
243 serial = avio_rl32 (bc);
244 avio_skip(bc, 8); /* seq, crc */
247 idx = ogg_find_stream (ogg, serial);
252 for (n = 0; n < ogg->nstreams; n++) {
253 av_freep(&ogg->streams[n].buf);
254 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
255 av_freep(&ogg->streams[n].private);
259 idx = ogg_new_stream(s, serial, 0);
261 idx = ogg_new_stream(s, serial, 1);
267 os = ogg->streams + idx;
268 os->page_pos = avio_tell(bc) - 27;
271 ogg_new_buf(ogg, idx);
273 ret = avio_read(bc, os->segments, nsegs);
275 return ret < 0 ? ret : AVERROR_EOF;
281 for (i = 0; i < nsegs; i++)
282 size += os->segments[i];
284 if (flags & OGG_FLAG_CONT || os->incomplete){
286 while (os->segp < os->nsegs){
287 int seg = os->segments[os->segp++];
292 os->sync_pos = os->page_pos;
296 os->sync_pos = os->page_pos;
299 if (os->bufsize - os->bufpos < size){
300 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
301 memcpy (nb, os->buf, os->bufpos);
306 ret = avio_read(bc, os->buf + os->bufpos, size);
308 return ret < 0 ? ret : AVERROR_EOF;
314 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
321 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
324 struct ogg *ogg = s->priv_data;
326 struct ogg_stream *os;
328 int segp = 0, psize = 0;
330 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
336 ret = ogg_read_page(s, &idx);
341 os = ogg->streams + idx;
343 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
344 idx, os->pstart, os->psize, os->segp, os->nsegs);
348 os->codec = ogg_find_codec (os->buf, os->bufpos);
350 av_log(s, AV_LOG_WARNING, "Codec not found\n");
362 while (os->segp < os->nsegs){
363 int ss = os->segments[os->segp++];
371 if (!complete && os->segp == os->nsegs){
377 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
378 idx, os->psize, os->pstart);
380 if (os->granule == -1)
381 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
387 os->header = os->codec->header (s, idx);
392 // We have reached the first non-header packet in this stream.
393 // Unfortunately more header packets may still follow for others,
394 // but if we continue with header parsing we may lose data packets.
397 // Update the header state for all streams and
398 // compute the data_offset.
400 s->data_offset = os->sync_pos;
401 for (i = 0; i < ogg->nstreams; i++) {
402 struct ogg_stream *cur_os = ogg->streams + i;
404 // if we have a partial non-header packet, its start is
405 // obviously at or after the data start
406 if (cur_os->incomplete)
407 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
411 os->pstart += os->psize;
417 if (os->codec && os->codec->packet)
418 os->codec->packet (s, idx);
422 *dstart = os->pstart;
426 *fpos = os->sync_pos;
427 os->pstart += os->psize;
429 os->sync_pos = os->page_pos;
432 // determine whether there are more complete packets in this page
433 // if not, the page's granule will apply to this packet
435 for (i = os->segp; i < os->nsegs; i++)
436 if (os->segments[i] < 255) {
441 if (os->segp == os->nsegs)
447 static int ogg_get_headers(AVFormatContext *s)
449 struct ogg *ogg = s->priv_data;
453 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
456 }while (!ogg->headers);
458 for (i = 0; i < ogg->nstreams; i++) {
459 struct ogg_stream *os = ogg->streams + i;
461 if (os->codec && os->codec->nb_header &&
462 os->nb_header < os->codec->nb_header) {
463 av_log(s, AV_LOG_ERROR,
464 "Headers mismatch for stream %d\n", i);
465 return AVERROR_INVALIDDATA;
467 if (os->start_granule != OGG_NOGRANULE_VALUE)
468 os->lastpts = s->streams[i]->start_time =
469 ogg_gptopts(s, i, os->start_granule, NULL);
471 av_dlog(s, "found headers\n");
476 static int ogg_get_length(AVFormatContext *s)
478 struct ogg *ogg = s->priv_data;
486 if (s->duration != AV_NOPTS_VALUE)
489 size = avio_size(s->pb);
492 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
495 avio_seek (s->pb, end, SEEK_SET);
497 while (!ogg_read_page (s, &i)){
498 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
499 ogg->streams[i].codec) {
500 s->streams[i]->duration =
501 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
502 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
503 s->streams[i]->duration -= s->streams[i]->start_time;
512 static int ogg_read_header(AVFormatContext *s)
514 struct ogg *ogg = s->priv_data;
517 //linear headers seek from start
518 ret = ogg_get_headers(s);
522 for (i = 0; i < ogg->nstreams; i++)
523 if (ogg->streams[i].header < 0)
524 ogg->streams[i].codec = NULL;
526 //linear granulepos seek from end
529 //fill the extradata in the per codec callbacks
533 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
535 struct ogg *ogg = s->priv_data;
536 struct ogg_stream *os = ogg->streams + idx;
537 int64_t pts = AV_NOPTS_VALUE;
540 *dts = AV_NOPTS_VALUE;
542 if (os->lastpts != AV_NOPTS_VALUE) {
544 os->lastpts = AV_NOPTS_VALUE;
546 if (os->lastdts != AV_NOPTS_VALUE) {
549 os->lastdts = AV_NOPTS_VALUE;
552 if (os->granule != -1LL) {
553 if (os->codec && os->codec->granule_is_start)
554 pts = ogg_gptopts(s, idx, os->granule, dts);
556 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
563 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
566 struct ogg_stream *os;
569 int64_t fpos, pts, dts;
574 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
577 }while (idx < 0 || !s->streams[idx]);
580 os = ogg->streams + idx;
582 // pflags might not be set until after this
583 pts = ogg_calc_pts(s, idx, &dts);
585 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
587 os->keyframe_seek = 0;
590 ret = av_new_packet(pkt, psize);
593 pkt->stream_index = idx;
594 memcpy (pkt->data, os->buf + pstart, psize);
598 pkt->flags = os->pflags;
599 pkt->duration = os->pduration;
605 static int ogg_read_close(AVFormatContext *s)
607 struct ogg *ogg = s->priv_data;
610 for (i = 0; i < ogg->nstreams; i++){
611 av_free (ogg->streams[i].buf);
612 av_free (ogg->streams[i].private);
614 av_free (ogg->streams);
618 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
619 int64_t *pos_arg, int64_t pos_limit)
621 struct ogg *ogg = s->priv_data;
622 AVIOContext *bc = s->pb;
623 int64_t pts = AV_NOPTS_VALUE;
625 avio_seek(bc, *pos_arg, SEEK_SET);
628 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
629 if (i == stream_index) {
630 struct ogg_stream *os = ogg->streams + stream_index;
631 pts = ogg_calc_pts(s, i, NULL);
632 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
633 pts = AV_NOPTS_VALUE;
635 if (pts != AV_NOPTS_VALUE)
642 static int ogg_read_seek(AVFormatContext *s, int stream_index,
643 int64_t timestamp, int flags)
645 struct ogg *ogg = s->priv_data;
646 struct ogg_stream *os = ogg->streams + stream_index;
649 // Try seeking to a keyframe first. If this fails (very possible),
650 // av_seek_frame will fall back to ignoring keyframes
651 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
652 && !(flags & AVSEEK_FLAG_ANY))
653 os->keyframe_seek = 1;
655 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
656 os = ogg->streams + stream_index;
658 os->keyframe_seek = 0;
662 static int ogg_probe(AVProbeData *p)
664 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
665 return AVPROBE_SCORE_MAX;
669 AVInputFormat ff_ogg_demuxer = {
671 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
672 .priv_data_size = sizeof(struct ogg),
673 .read_probe = ogg_probe,
674 .read_header = ogg_read_header,
675 .read_packet = ogg_read_packet,
676 .read_close = ogg_read_close,
677 .read_seek = ogg_read_seek,
678 .read_timestamp = ogg_read_timestamp,
680 .flags = AVFMT_GENERIC_INDEX,