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.
32 #include "libavutil/avassert.h"
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(AVFormatContext *s)
122 struct ogg *ogg = s->priv_data;
124 int64_t start_pos = avio_tell(s->pb);
126 for (i = 0; i < ogg->nstreams; i++){
127 struct ogg_stream *os = ogg->streams + i;
132 os->lastpts = AV_NOPTS_VALUE;
133 os->lastdts = AV_NOPTS_VALUE;
139 if (start_pos <= s->data_offset) {
149 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
153 for (i = 0; ogg_codecs[i]; i++)
154 if (size >= ogg_codecs[i]->magicsize &&
155 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
156 return ogg_codecs[i];
161 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
164 struct ogg *ogg = s->priv_data;
165 int idx = ogg->nstreams++;
167 struct ogg_stream *os;
169 ogg->streams = av_realloc (ogg->streams,
170 ogg->nstreams * sizeof (*ogg->streams));
171 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
172 os = ogg->streams + idx;
174 os->bufsize = DECODER_BUFFER_SIZE;
175 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
179 st = avformat_new_stream(s, NULL);
181 return AVERROR(ENOMEM);
184 avpriv_set_pts_info(st, 64, 1, 1000000);
190 static int ogg_new_buf(struct ogg *ogg, int idx)
192 struct ogg_stream *os = ogg->streams + idx;
193 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
194 int size = os->bufpos - os->pstart;
196 memcpy(nb, os->buf + os->pstart, size);
206 static int ogg_read_page(AVFormatContext *s, int *str)
208 AVIOContext *bc = s->pb;
209 struct ogg *ogg = s->priv_data;
210 struct ogg_stream *os;
219 ret = avio_read(bc, sync, 4);
221 return ret < 0 ? ret : AVERROR_EOF;
226 if (sync[sp & 3] == 'O' &&
227 sync[(sp + 1) & 3] == 'g' &&
228 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
235 }while (i++ < MAX_PAGE_SIZE);
237 if (i >= MAX_PAGE_SIZE){
238 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
239 return AVERROR_INVALIDDATA;
242 if (avio_r8(bc) != 0){ /* version */
243 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
244 return AVERROR_INVALIDDATA;
249 serial = avio_rl32 (bc);
250 avio_skip(bc, 8); /* seq, crc */
253 idx = ogg_find_stream (ogg, serial);
258 if (ogg->nstreams != 1) {
259 av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
263 for (n = 0; n < ogg->nstreams; n++) {
264 av_freep(&ogg->streams[n].buf);
265 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
266 av_freep(&ogg->streams[n].private);
270 idx = ogg_new_stream(s, serial, 0);
272 idx = ogg_new_stream(s, serial, 1);
275 av_log (s, AV_LOG_ERROR, "failed to create stream (OOM?)\n");
280 os = ogg->streams + idx;
281 os->page_pos = avio_tell(bc) - 27;
284 ogg_new_buf(ogg, idx);
286 ret = avio_read(bc, os->segments, nsegs);
288 return ret < 0 ? ret : AVERROR_EOF;
294 for (i = 0; i < nsegs; i++)
295 size += os->segments[i];
297 if (flags & OGG_FLAG_CONT || os->incomplete){
299 // If this is the very first segment we started
300 // playback in the middle of a continuation packet.
301 // Discard it since we missed the start of it.
302 while (os->segp < os->nsegs){
303 int seg = os->segments[os->segp++];
308 os->sync_pos = os->page_pos;
312 os->sync_pos = os->page_pos;
315 if (os->bufsize - os->bufpos < size){
316 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
317 memcpy (nb, os->buf, os->bufpos);
322 ret = avio_read(bc, os->buf + os->bufpos, size);
324 return ret < 0 ? ret : AVERROR_EOF;
330 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
337 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
340 struct ogg *ogg = s->priv_data;
342 struct ogg_stream *os;
344 int segp = 0, psize = 0;
346 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
352 ret = ogg_read_page(s, &idx);
357 os = ogg->streams + idx;
359 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
360 idx, os->pstart, os->psize, os->segp, os->nsegs);
364 os->codec = ogg_find_codec (os->buf, os->bufpos);
366 av_log(s, AV_LOG_WARNING, "Codec not found\n");
378 while (os->segp < os->nsegs){
379 int ss = os->segments[os->segp++];
387 if (!complete && os->segp == os->nsegs){
389 // Do not set incomplete for empty packets.
390 // Together with the code in ogg_read_page
391 // that discards all continuation of empty packets
392 // we would get an infinite loop.
393 os->incomplete = !!os->psize;
398 if (os->granule == -1)
399 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
405 os->header = os->codec->header (s, idx);
410 // We have reached the first non-header packet in this stream.
411 // Unfortunately more header packets may still follow for others,
412 // but if we continue with header parsing we may lose data packets.
415 // Update the header state for all streams and
416 // compute the data_offset.
418 s->data_offset = os->sync_pos;
419 for (i = 0; i < ogg->nstreams; i++) {
420 struct ogg_stream *cur_os = ogg->streams + i;
422 // if we have a partial non-header packet, its start is
423 // obviously at or after the data start
424 if (cur_os->incomplete)
425 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
428 os->pstart += os->psize;
434 if (os->codec && os->codec->packet)
435 os->codec->packet (s, idx);
439 *dstart = os->pstart;
443 *fpos = os->sync_pos;
444 os->pstart += os->psize;
446 if(os->pstart == os->bufpos)
447 os->bufpos = os->pstart = 0;
448 os->sync_pos = os->page_pos;
451 // determine whether there are more complete packets in this page
452 // if not, the page's granule will apply to this packet
454 for (i = os->segp; i < os->nsegs; i++)
455 if (os->segments[i] < 255) {
460 if (os->segp == os->nsegs)
466 static int ogg_get_headers(AVFormatContext *s)
468 struct ogg *ogg = s->priv_data;
472 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
475 }while (!ogg->headers);
477 av_dlog(s, "found headers\n");
482 static int ogg_get_length(AVFormatContext *s)
484 struct ogg *ogg = s->priv_data;
493 if (s->duration != AV_NOPTS_VALUE)
496 size = avio_size(s->pb);
499 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
502 avio_seek (s->pb, end, SEEK_SET);
504 while (!ogg_read_page (s, &i)){
505 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
506 ogg->streams[i].codec) {
507 s->streams[i]->duration =
508 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
509 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
510 s->streams[i]->duration -= s->streams[i]->start_time;
511 streams_left-= (ogg->streams[i].got_start==-1);
512 ogg->streams[i].got_start= 1;
513 }else if(!ogg->streams[i].got_start){
514 ogg->streams[i].got_start= -1;
523 avio_seek (s->pb, 0, SEEK_SET);
524 while (!ogg_read_page (s, &i)){
525 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
526 ogg->streams[i].codec) {
527 if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
528 int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
529 if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
530 s->streams[i]->duration -= start;
531 ogg->streams[i].got_start= 1;
543 static int ogg_read_header(AVFormatContext *s)
545 struct ogg *ogg = s->priv_data;
548 //linear headers seek from start
549 ret = ogg_get_headers(s);
553 for (i = 0; i < ogg->nstreams; i++)
554 if (ogg->streams[i].header < 0)
555 ogg->streams[i].codec = NULL;
557 //linear granulepos seek from end
560 //fill the extradata in the per codec callbacks
564 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
566 struct ogg *ogg = s->priv_data;
567 struct ogg_stream *os = ogg->streams + idx;
568 int64_t pts = AV_NOPTS_VALUE;
571 *dts = AV_NOPTS_VALUE;
573 if (os->lastpts != AV_NOPTS_VALUE) {
575 os->lastpts = AV_NOPTS_VALUE;
577 if (os->lastdts != AV_NOPTS_VALUE) {
580 os->lastdts = AV_NOPTS_VALUE;
583 if (os->granule != -1LL) {
584 if (os->codec && os->codec->granule_is_start)
585 pts = ogg_gptopts(s, idx, os->granule, dts);
587 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
594 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
596 struct ogg *ogg = s->priv_data;
597 struct ogg_stream *os = ogg->streams + idx;
598 if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
599 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
600 os->pflags ^= AV_PKT_FLAG_KEY;
601 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
602 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
607 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
610 struct ogg_stream *os;
613 int64_t fpos, pts, dts;
618 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
621 }while (idx < 0 || !s->streams[idx]);
624 os = ogg->streams + idx;
626 // pflags might not be set until after this
627 pts = ogg_calc_pts(s, idx, &dts);
628 ogg_validate_keyframe(s, idx, pstart, psize);
630 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
632 os->keyframe_seek = 0;
635 ret = av_new_packet(pkt, psize);
638 pkt->stream_index = idx;
639 memcpy (pkt->data, os->buf + pstart, psize);
643 pkt->flags = os->pflags;
644 pkt->duration = os->pduration;
650 static int ogg_read_close(AVFormatContext *s)
652 struct ogg *ogg = s->priv_data;
655 for (i = 0; i < ogg->nstreams; i++){
656 av_free (ogg->streams[i].buf);
657 av_free (ogg->streams[i].private);
659 av_free (ogg->streams);
663 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
664 int64_t *pos_arg, int64_t pos_limit)
666 struct ogg *ogg = s->priv_data;
667 AVIOContext *bc = s->pb;
668 int64_t pts = AV_NOPTS_VALUE;
672 avio_seek(bc, *pos_arg, SEEK_SET);
675 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
676 if (i == stream_index) {
677 struct ogg_stream *os = ogg->streams + stream_index;
678 pts = ogg_calc_pts(s, i, NULL);
679 ogg_validate_keyframe(s, i, pstart, psize);
680 if (os->pflags & AV_PKT_FLAG_KEY) {
682 } else if (os->keyframe_seek) {
683 // if we had a previous keyframe but no pts for it,
684 // return that keyframe with this pts value.
688 pts = AV_NOPTS_VALUE;
691 if (pts != AV_NOPTS_VALUE)
698 static int ogg_read_seek(AVFormatContext *s, int stream_index,
699 int64_t timestamp, int flags)
701 struct ogg *ogg = s->priv_data;
702 struct ogg_stream *os = ogg->streams + stream_index;
705 av_assert0(stream_index < ogg->nstreams);
706 // Ensure everything is reset even when seeking via
707 // the generated index.
710 // Try seeking to a keyframe first. If this fails (very possible),
711 // av_seek_frame will fall back to ignoring keyframes
712 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
713 && !(flags & AVSEEK_FLAG_ANY))
714 os->keyframe_seek = 1;
716 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
717 os = ogg->streams + stream_index;
719 os->keyframe_seek = 0;
723 static int ogg_probe(AVProbeData *p)
725 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
726 return AVPROBE_SCORE_MAX;
730 AVInputFormat ff_ogg_demuxer = {
732 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
733 .priv_data_size = sizeof(struct ogg),
734 .read_probe = ogg_probe,
735 .read_header = ogg_read_header,
736 .read_packet = ogg_read_packet,
737 .read_close = ogg_read_close,
738 .read_seek = ogg_read_seek,
739 .read_timestamp = ogg_read_timestamp,
741 .flags = AVFMT_GENERIC_INDEX,