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[] = {
59 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
61 //FIXME We could avoid some structure duplication
62 static int ogg_save(AVFormatContext *s)
64 struct ogg *ogg = s->priv_data;
65 struct ogg_state *ost =
66 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
68 ost->pos = avio_tell(s->pb);
69 ost->curidx = ogg->curidx;
70 ost->next = ogg->state;
71 ost->nstreams = ogg->nstreams;
72 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
74 for (i = 0; i < ogg->nstreams; i++) {
75 struct ogg_stream *os = ogg->streams + i;
76 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
77 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
85 static int ogg_restore(AVFormatContext *s, int discard)
87 struct ogg *ogg = s->priv_data;
88 AVIOContext *bc = s->pb;
89 struct ogg_state *ost = ogg->state;
95 ogg->state = ost->next;
98 struct ogg_stream *old_streams = ogg->streams;
100 for (i = 0; i < ogg->nstreams; i++)
101 av_free(ogg->streams[i].buf);
103 avio_seek(bc, ost->pos, SEEK_SET);
105 ogg->curidx = ost->curidx;
106 ogg->nstreams = ost->nstreams;
107 ogg->streams = av_realloc(ogg->streams,
108 ogg->nstreams * sizeof(*ogg->streams));
111 memcpy(ogg->streams, ost->streams,
112 ost->nstreams * sizeof(*ogg->streams));
114 av_free(old_streams);
124 static int ogg_reset(AVFormatContext *s)
126 struct ogg *ogg = s->priv_data;
128 int64_t start_pos = avio_tell(s->pb);
130 for (i = 0; i < ogg->nstreams; i++) {
131 struct ogg_stream *os = ogg->streams + i;
136 os->lastpts = AV_NOPTS_VALUE;
137 os->lastdts = AV_NOPTS_VALUE;
144 if (start_pos <= s->data_offset) {
155 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
159 for (i = 0; ogg_codecs[i]; i++)
160 if (size >= ogg_codecs[i]->magicsize &&
161 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
162 return ogg_codecs[i];
168 * Replace the current stream with a new one. This is a typical webradio
169 * situation where a new audio stream spawn (identified with a new serial) and
170 * must replace the previous one (track switch).
172 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
174 struct ogg *ogg = s->priv_data;
175 struct ogg_stream *os;
178 const struct ogg_codec *codec;
180 if (ogg->nstreams != 1) {
181 av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
182 return AVERROR_PATCHWELCOME;
185 os = &ogg->streams[0];
191 bufsize = os->bufsize;
194 if (!ogg->state || ogg->state->streams[0].private != os->private)
195 av_freep(&ogg->streams[0].private);
197 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
198 * also re-use the ogg_stream allocated buffer */
199 memset(os, 0, sizeof(*os));
201 os->bufsize = bufsize;
209 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
211 struct ogg *ogg = s->priv_data;
212 int idx = ogg->nstreams;
214 struct ogg_stream *os;
218 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
219 "in between Ogg context save/restore operations.\n");
223 /* Allocate and init a new Ogg Stream */
224 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
225 !(os = av_realloc(ogg->streams, size)))
226 return AVERROR(ENOMEM);
228 os = ogg->streams + idx;
229 memset(os, 0, sizeof(*os));
231 os->bufsize = DECODER_BUFFER_SIZE;
232 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
234 os->start_granule = OGG_NOGRANULE_VALUE;
236 return AVERROR(ENOMEM);
238 /* Create the associated AVStream */
239 st = avformat_new_stream(s, NULL);
242 return AVERROR(ENOMEM);
245 avpriv_set_pts_info(st, 64, 1, 1000000);
251 static int ogg_new_buf(struct ogg *ogg, int idx)
253 struct ogg_stream *os = ogg->streams + idx;
254 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
255 int size = os->bufpos - os->pstart;
258 memcpy(nb, os->buf + os->pstart, size);
269 static int data_packets_seen(const struct ogg *ogg)
273 for (i = 0; i < ogg->nstreams; i++)
274 if (ogg->streams[i].got_data)
279 static int ogg_read_page(AVFormatContext *s, int *sid)
281 AVIOContext *bc = s->pb;
282 struct ogg *ogg = s->priv_data;
283 struct ogg_stream *os;
292 ret = avio_read(bc, sync, 4);
294 return ret < 0 ? ret : AVERROR_EOF;
299 if (sync[sp & 3] == 'O' &&
300 sync[(sp + 1) & 3] == 'g' &&
301 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
304 if(!i && bc->seekable && ogg->page_pos > 0) {
306 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
316 } while (i++ < MAX_PAGE_SIZE);
318 if (i >= MAX_PAGE_SIZE) {
319 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
320 return AVERROR_INVALIDDATA;
323 if (avio_r8(bc) != 0) { /* version */
324 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
325 return AVERROR_INVALIDDATA;
330 serial = avio_rl32(bc);
331 avio_skip(bc, 8); /* seq, crc */
334 idx = ogg_find_stream(ogg, serial);
336 if (data_packets_seen(ogg))
337 idx = ogg_replace_stream(s, serial);
339 idx = ogg_new_stream(s, serial);
342 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
347 os = ogg->streams + idx;
349 os->page_pos = avio_tell(bc) - 27;
352 ogg_new_buf(ogg, idx);
354 ret = avio_read(bc, os->segments, nsegs);
356 return ret < 0 ? ret : AVERROR_EOF;
362 for (i = 0; i < nsegs; i++)
363 size += os->segments[i];
365 if (!(flags & OGG_FLAG_BOS))
368 if (flags & OGG_FLAG_CONT || os->incomplete) {
370 // If this is the very first segment we started
371 // playback in the middle of a continuation packet.
372 // Discard it since we missed the start of it.
373 while (os->segp < os->nsegs) {
374 int seg = os->segments[os->segp++];
379 os->sync_pos = os->page_pos;
383 os->sync_pos = os->page_pos;
386 if (os->bufsize - os->bufpos < size) {
387 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
389 return AVERROR(ENOMEM);
390 memcpy(nb, os->buf, os->bufpos);
395 ret = avio_read(bc, os->buf + os->bufpos, size);
397 return ret < 0 ? ret : AVERROR_EOF;
403 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
411 * @brief find the next Ogg packet
412 * @param *sid is set to the stream for the packet or -1 if there is
413 * no matching stream, in that case assume all other return
414 * values to be uninitialized.
415 * @return negative value on error or EOF.
417 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
420 struct ogg *ogg = s->priv_data;
422 struct ogg_stream *os;
424 int segp = 0, psize = 0;
426 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
434 ret = ogg_read_page(s, &idx);
439 os = ogg->streams + idx;
441 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
442 idx, os->pstart, os->psize, os->segp, os->nsegs);
445 if (os->header < 0) {
446 os->codec = ogg_find_codec(os->buf, os->bufpos);
448 av_log(s, AV_LOG_WARNING, "Codec not found\n");
460 while (os->segp < os->nsegs) {
461 int ss = os->segments[os->segp++];
469 if (!complete && os->segp == os->nsegs) {
471 // Do not set incomplete for empty packets.
472 // Together with the code in ogg_read_page
473 // that discards all continuation of empty packets
474 // we would get an infinite loop.
475 os->incomplete = !!os->psize;
480 if (os->granule == -1)
481 av_log(s, AV_LOG_WARNING,
482 "Page at %"PRId64" is missing granule\n",
489 os->header = os->codec->header(s, idx);
494 // We have reached the first non-header packet in this stream.
495 // Unfortunately more header packets may still follow for others,
496 // but if we continue with header parsing we may lose data packets.
499 // Update the header state for all streams and
500 // compute the data_offset.
502 s->data_offset = os->sync_pos;
504 for (i = 0; i < ogg->nstreams; i++) {
505 struct ogg_stream *cur_os = ogg->streams + i;
507 // if we have a partial non-header packet, its start is
508 // obviously at or after the data start
509 if (cur_os->incomplete)
510 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
514 os->pstart += os->psize;
520 if (os->codec && os->codec->packet)
521 os->codec->packet(s, idx);
525 *dstart = os->pstart;
529 *fpos = os->sync_pos;
530 os->pstart += os->psize;
532 if(os->pstart == os->bufpos)
533 os->bufpos = os->pstart = 0;
534 os->sync_pos = os->page_pos;
537 // determine whether there are more complete packets in this page
538 // if not, the page's granule will apply to this packet
540 for (i = os->segp; i < os->nsegs; i++)
541 if (os->segments[i] < 255) {
546 if (os->segp == os->nsegs)
552 static int ogg_get_length(AVFormatContext *s)
554 struct ogg *ogg = s->priv_data;
559 if (!s->pb->seekable)
563 if (s->duration != AV_NOPTS_VALUE)
566 size = avio_size(s->pb);
569 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
572 avio_seek(s->pb, end, SEEK_SET);
575 while (!ogg_read_page(s, &i)) {
576 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
577 ogg->streams[i].codec) {
578 s->streams[i]->duration =
579 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
580 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
581 s->streams[i]->duration -= s->streams[i]->start_time;
582 streams_left-= (ogg->streams[i].got_start==-1);
583 ogg->streams[i].got_start= 1;
584 } else if(!ogg->streams[i].got_start) {
585 ogg->streams[i].got_start= -1;
594 avio_seek (s->pb, s->data_offset, SEEK_SET);
596 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
599 pts = ogg_calc_pts(s, i, NULL);
600 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
601 s->streams[i]->duration -= pts;
602 ogg->streams[i].got_start= 1;
604 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
605 ogg->streams[i].got_start= 1;
614 static int ogg_read_close(AVFormatContext *s)
616 struct ogg *ogg = s->priv_data;
619 for (i = 0; i < ogg->nstreams; i++) {
620 av_free(ogg->streams[i].buf);
621 if (ogg->streams[i].codec &&
622 ogg->streams[i].codec->cleanup) {
623 ogg->streams[i].codec->cleanup(s, i);
625 av_free(ogg->streams[i].private);
627 av_free(ogg->streams);
631 static int ogg_read_header(AVFormatContext *s)
633 struct ogg *ogg = s->priv_data;
638 //linear headers seek from start
640 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
645 } while (!ogg->headers);
646 av_dlog(s, "found headers\n");
648 for (i = 0; i < ogg->nstreams; i++) {
649 struct ogg_stream *os = ogg->streams + i;
651 if (ogg->streams[i].header < 0) {
652 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
653 ogg->streams[i].codec = NULL;
654 } else if (os->codec && os->nb_header < os->codec->nb_header) {
655 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
657 if (os->start_granule != OGG_NOGRANULE_VALUE)
658 os->lastpts = s->streams[i]->start_time =
659 ogg_gptopts(s, i, os->start_granule, NULL);
662 //linear granulepos seek from end
668 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
670 struct ogg *ogg = s->priv_data;
671 struct ogg_stream *os = ogg->streams + idx;
672 int64_t pts = AV_NOPTS_VALUE;
675 *dts = AV_NOPTS_VALUE;
677 if (os->lastpts != AV_NOPTS_VALUE) {
679 os->lastpts = AV_NOPTS_VALUE;
681 if (os->lastdts != AV_NOPTS_VALUE) {
684 os->lastdts = AV_NOPTS_VALUE;
687 if (os->granule != -1LL) {
688 if (os->codec && os->codec->granule_is_start)
689 pts = ogg_gptopts(s, idx, os->granule, dts);
691 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
698 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
700 struct ogg *ogg = s->priv_data;
701 struct ogg_stream *os = ogg->streams + idx;
702 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
703 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
704 os->pflags ^= AV_PKT_FLAG_KEY;
705 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
706 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
711 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
714 struct ogg_stream *os;
717 int64_t fpos, pts, dts;
722 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
725 } while (idx < 0 || !s->streams[idx]);
728 os = ogg->streams + idx;
730 // pflags might not be set until after this
731 pts = ogg_calc_pts(s, idx, &dts);
732 ogg_validate_keyframe(s, idx, pstart, psize);
734 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
736 os->keyframe_seek = 0;
739 ret = av_new_packet(pkt, psize);
742 pkt->stream_index = idx;
743 memcpy(pkt->data, os->buf + pstart, psize);
747 pkt->flags = os->pflags;
748 pkt->duration = os->pduration;
754 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
755 int64_t *pos_arg, int64_t pos_limit)
757 struct ogg *ogg = s->priv_data;
758 AVIOContext *bc = s->pb;
759 int64_t pts = AV_NOPTS_VALUE;
763 avio_seek(bc, *pos_arg, SEEK_SET);
766 while ( avio_tell(bc) <= pos_limit
767 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
768 if (i == stream_index) {
769 struct ogg_stream *os = ogg->streams + stream_index;
770 pts = ogg_calc_pts(s, i, NULL);
771 ogg_validate_keyframe(s, i, pstart, psize);
772 if (os->pflags & AV_PKT_FLAG_KEY) {
774 } else if (os->keyframe_seek) {
775 // if we had a previous keyframe but no pts for it,
776 // return that keyframe with this pts value.
780 pts = AV_NOPTS_VALUE;
783 if (pts != AV_NOPTS_VALUE)
790 static int ogg_read_seek(AVFormatContext *s, int stream_index,
791 int64_t timestamp, int flags)
793 struct ogg *ogg = s->priv_data;
794 struct ogg_stream *os = ogg->streams + stream_index;
797 av_assert0(stream_index < ogg->nstreams);
798 // Ensure everything is reset even when seeking via
799 // the generated index.
802 // Try seeking to a keyframe first. If this fails (very possible),
803 // av_seek_frame will fall back to ignoring keyframes
804 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
805 && !(flags & AVSEEK_FLAG_ANY))
806 os->keyframe_seek = 1;
808 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
809 os = ogg->streams + stream_index;
811 os->keyframe_seek = 0;
815 static int ogg_probe(AVProbeData *p)
817 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
818 return AVPROBE_SCORE_MAX;
822 AVInputFormat ff_ogg_demuxer = {
824 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
825 .priv_data_size = sizeof(struct ogg),
826 .read_probe = ogg_probe,
827 .read_header = ogg_read_header,
828 .read_packet = ogg_read_packet,
829 .read_close = ogg_read_close,
830 .read_seek = ogg_read_seek,
831 .read_timestamp = ogg_read_timestamp,
833 .flags = AVFMT_GENERIC_INDEX,