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"
33 #include "libavutil/intreadwrite.h"
37 #include "vorbiscomment.h"
39 #define MAX_PAGE_SIZE 65307
40 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
42 static const struct ogg_codec * const ogg_codecs[] = {
60 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
61 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
63 //FIXME We could avoid some structure duplication
64 static int ogg_save(AVFormatContext *s)
66 struct ogg *ogg = s->priv_data;
67 struct ogg_state *ost =
68 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
70 ost->pos = avio_tell(s->pb);
71 ost->curidx = ogg->curidx;
72 ost->next = ogg->state;
73 ost->nstreams = ogg->nstreams;
74 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
76 for (i = 0; i < ogg->nstreams; i++) {
77 struct ogg_stream *os = ogg->streams + i;
78 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
79 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
87 static int ogg_restore(AVFormatContext *s, int discard)
89 struct ogg *ogg = s->priv_data;
90 AVIOContext *bc = s->pb;
91 struct ogg_state *ost = ogg->state;
97 ogg->state = ost->next;
101 for (i = 0; i < ogg->nstreams; i++)
102 av_free(ogg->streams[i].buf);
104 avio_seek(bc, ost->pos, SEEK_SET);
106 ogg->curidx = ost->curidx;
107 ogg->nstreams = ost->nstreams;
108 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
109 sizeof(*ogg->streams))) < 0) {
113 memcpy(ogg->streams, ost->streams,
114 ost->nstreams * sizeof(*ogg->streams));
122 static int ogg_reset(AVFormatContext *s)
124 struct ogg *ogg = s->priv_data;
126 int64_t start_pos = avio_tell(s->pb);
128 for (i = 0; i < ogg->nstreams; i++) {
129 struct ogg_stream *os = ogg->streams + i;
134 os->lastpts = AV_NOPTS_VALUE;
135 os->lastdts = AV_NOPTS_VALUE;
142 if (start_pos <= s->data_offset) {
153 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
157 for (i = 0; ogg_codecs[i]; i++)
158 if (size >= ogg_codecs[i]->magicsize &&
159 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
160 return ogg_codecs[i];
166 * Replace the current stream with a new one. This is a typical webradio
167 * situation where a new audio stream spawn (identified with a new serial) and
168 * must replace the previous one (track switch).
170 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
172 struct ogg *ogg = s->priv_data;
173 struct ogg_stream *os;
174 const struct ogg_codec *codec;
177 if (s->pb->seekable) {
179 int64_t pos = avio_tell(s->pb);
180 avio_skip(s->pb, nsegs);
181 avio_read(s->pb, magic, sizeof(magic));
182 avio_seek(s->pb, pos, SEEK_SET);
183 codec = ogg_find_codec(magic, sizeof(magic));
185 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
186 return AVERROR_INVALIDDATA;
188 for (i = 0; i < ogg->nstreams; i++) {
189 if (ogg->streams[i].codec == codec)
192 if (i >= ogg->nstreams)
193 return ogg_new_stream(s, serial);
194 } else if (ogg->nstreams != 1) {
195 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
196 return AVERROR_PATCHWELCOME;
199 os = &ogg->streams[i];
206 bufsize = os->bufsize;
209 if (!ogg->state || ogg->state->streams[i].private != os->private)
210 av_freep(&ogg->streams[i].private);
212 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
213 * also re-use the ogg_stream allocated buffer */
214 memset(os, 0, sizeof(*os));
216 os->bufsize = bufsize;
225 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
227 struct ogg *ogg = s->priv_data;
228 int idx = ogg->nstreams;
230 struct ogg_stream *os;
234 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
235 "in between Ogg context save/restore operations.\n");
239 /* Allocate and init a new Ogg Stream */
240 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
241 !(os = av_realloc(ogg->streams, size)))
242 return AVERROR(ENOMEM);
244 os = ogg->streams + idx;
245 memset(os, 0, sizeof(*os));
247 os->bufsize = DECODER_BUFFER_SIZE;
248 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
250 os->start_granule = OGG_NOGRANULE_VALUE;
252 return AVERROR(ENOMEM);
254 /* Create the associated AVStream */
255 st = avformat_new_stream(s, NULL);
258 return AVERROR(ENOMEM);
261 avpriv_set_pts_info(st, 64, 1, 1000000);
267 static int ogg_new_buf(struct ogg *ogg, int idx)
269 struct ogg_stream *os = ogg->streams + idx;
270 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
271 int size = os->bufpos - os->pstart;
274 memcpy(nb, os->buf + os->pstart, size);
285 static int data_packets_seen(const struct ogg *ogg)
289 for (i = 0; i < ogg->nstreams; i++)
290 if (ogg->streams[i].got_data)
295 static int ogg_read_page(AVFormatContext *s, int *sid)
297 AVIOContext *bc = s->pb;
298 struct ogg *ogg = s->priv_data;
299 struct ogg_stream *os;
308 ret = avio_read(bc, sync, 4);
310 return ret < 0 ? ret : AVERROR_EOF;
315 if (sync[sp & 3] == 'O' &&
316 sync[(sp + 1) & 3] == 'g' &&
317 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
320 if(!i && bc->seekable && ogg->page_pos > 0) {
322 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
332 } while (i++ < MAX_PAGE_SIZE);
334 if (i >= MAX_PAGE_SIZE) {
335 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
336 return AVERROR_INVALIDDATA;
339 if (avio_r8(bc) != 0) { /* version */
340 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
341 return AVERROR_INVALIDDATA;
346 serial = avio_rl32(bc);
347 avio_skip(bc, 8); /* seq, crc */
350 idx = ogg_find_stream(ogg, serial);
352 if (data_packets_seen(ogg))
353 idx = ogg_replace_stream(s, serial, nsegs);
355 idx = ogg_new_stream(s, serial);
358 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
363 os = ogg->streams + idx;
365 os->page_pos = avio_tell(bc) - 27;
368 ogg_new_buf(ogg, idx);
370 ret = avio_read(bc, os->segments, nsegs);
372 return ret < 0 ? ret : AVERROR_EOF;
378 for (i = 0; i < nsegs; i++)
379 size += os->segments[i];
381 if (!(flags & OGG_FLAG_BOS))
384 if (flags & OGG_FLAG_CONT || os->incomplete) {
386 // If this is the very first segment we started
387 // playback in the middle of a continuation packet.
388 // Discard it since we missed the start of it.
389 while (os->segp < os->nsegs) {
390 int seg = os->segments[os->segp++];
395 os->sync_pos = os->page_pos;
399 os->sync_pos = os->page_pos;
402 if (os->bufsize - os->bufpos < size) {
403 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
405 return AVERROR(ENOMEM);
406 memcpy(nb, os->buf, os->bufpos);
411 ret = avio_read(bc, os->buf + os->bufpos, size);
413 return ret < 0 ? ret : AVERROR_EOF;
419 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
427 * @brief find the next Ogg packet
428 * @param *sid is set to the stream for the packet or -1 if there is
429 * no matching stream, in that case assume all other return
430 * values to be uninitialized.
431 * @return negative value on error or EOF.
433 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
436 struct ogg *ogg = s->priv_data;
438 struct ogg_stream *os;
440 int segp = 0, psize = 0;
442 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
450 ret = ogg_read_page(s, &idx);
455 os = ogg->streams + idx;
457 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
458 idx, os->pstart, os->psize, os->segp, os->nsegs);
461 if (os->header < 0) {
462 os->codec = ogg_find_codec(os->buf, os->bufpos);
464 av_log(s, AV_LOG_WARNING, "Codec not found\n");
476 while (os->segp < os->nsegs) {
477 int ss = os->segments[os->segp++];
485 if (!complete && os->segp == os->nsegs) {
487 // Do not set incomplete for empty packets.
488 // Together with the code in ogg_read_page
489 // that discards all continuation of empty packets
490 // we would get an infinite loop.
491 os->incomplete = !!os->psize;
496 if (os->granule == -1)
497 av_log(s, AV_LOG_WARNING,
498 "Page at %"PRId64" is missing granule\n",
505 os->header = os->codec->header(s, idx);
510 // We have reached the first non-header packet in this stream.
511 // Unfortunately more header packets may still follow for others,
512 // but if we continue with header parsing we may lose data packets.
515 // Update the header state for all streams and
516 // compute the data_offset.
518 s->data_offset = os->sync_pos;
520 for (i = 0; i < ogg->nstreams; i++) {
521 struct ogg_stream *cur_os = ogg->streams + i;
523 // if we have a partial non-header packet, its start is
524 // obviously at or after the data start
525 if (cur_os->incomplete)
526 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
530 os->pstart += os->psize;
536 if (os->codec && os->codec->packet)
537 os->codec->packet(s, idx);
541 *dstart = os->pstart;
545 *fpos = os->sync_pos;
546 os->pstart += os->psize;
548 if(os->pstart == os->bufpos)
549 os->bufpos = os->pstart = 0;
550 os->sync_pos = os->page_pos;
553 // determine whether there are more complete packets in this page
554 // if not, the page's granule will apply to this packet
556 for (i = os->segp; i < os->nsegs; i++)
557 if (os->segments[i] < 255) {
562 if (os->segp == os->nsegs)
568 static int ogg_get_length(AVFormatContext *s)
570 struct ogg *ogg = s->priv_data;
575 if (!s->pb->seekable)
579 if (s->duration != AV_NOPTS_VALUE)
582 size = avio_size(s->pb);
585 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
588 avio_seek(s->pb, end, SEEK_SET);
591 while (!ogg_read_page(s, &i)) {
592 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
593 ogg->streams[i].codec) {
594 s->streams[i]->duration =
595 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
596 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
597 s->streams[i]->duration -= s->streams[i]->start_time;
598 streams_left-= (ogg->streams[i].got_start==-1);
599 ogg->streams[i].got_start= 1;
600 } else if(!ogg->streams[i].got_start) {
601 ogg->streams[i].got_start= -1;
610 avio_seek (s->pb, s->data_offset, SEEK_SET);
612 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
615 pts = ogg_calc_pts(s, i, NULL);
616 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
617 s->streams[i]->duration -= pts;
618 ogg->streams[i].got_start= 1;
620 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
621 ogg->streams[i].got_start= 1;
630 static int ogg_read_close(AVFormatContext *s)
632 struct ogg *ogg = s->priv_data;
635 for (i = 0; i < ogg->nstreams; i++) {
636 av_free(ogg->streams[i].buf);
637 if (ogg->streams[i].codec &&
638 ogg->streams[i].codec->cleanup) {
639 ogg->streams[i].codec->cleanup(s, i);
641 av_free(ogg->streams[i].private);
643 av_free(ogg->streams);
647 static int ogg_read_header(AVFormatContext *s)
649 struct ogg *ogg = s->priv_data;
654 //linear headers seek from start
656 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
661 } while (!ogg->headers);
662 av_dlog(s, "found headers\n");
664 for (i = 0; i < ogg->nstreams; i++) {
665 struct ogg_stream *os = ogg->streams + i;
667 if (ogg->streams[i].header < 0) {
668 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
669 ogg->streams[i].codec = NULL;
670 } else if (os->codec && os->nb_header < os->codec->nb_header) {
671 av_log(s, AV_LOG_WARNING,
672 "Headers mismatch for stream %d: "
673 "expected %d received %d.\n",
674 i, os->codec->nb_header, os->nb_header);
675 if (s->error_recognition & AV_EF_EXPLODE)
676 return AVERROR_INVALIDDATA;
678 if (os->start_granule != OGG_NOGRANULE_VALUE)
679 os->lastpts = s->streams[i]->start_time =
680 ogg_gptopts(s, i, os->start_granule, NULL);
683 //linear granulepos seek from end
689 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
691 struct ogg *ogg = s->priv_data;
692 struct ogg_stream *os = ogg->streams + idx;
693 int64_t pts = AV_NOPTS_VALUE;
696 *dts = AV_NOPTS_VALUE;
698 if (os->lastpts != AV_NOPTS_VALUE) {
700 os->lastpts = AV_NOPTS_VALUE;
702 if (os->lastdts != AV_NOPTS_VALUE) {
705 os->lastdts = AV_NOPTS_VALUE;
708 if (os->granule != -1LL) {
709 if (os->codec && os->codec->granule_is_start)
710 pts = ogg_gptopts(s, idx, os->granule, dts);
712 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
719 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
721 struct ogg *ogg = s->priv_data;
722 struct ogg_stream *os = ogg->streams + idx;
723 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
724 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
725 os->pflags ^= AV_PKT_FLAG_KEY;
726 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
727 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
732 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
735 struct ogg_stream *os;
738 int64_t fpos, pts, dts;
740 if (s->io_repositioned) {
742 s->io_repositioned = 0;
748 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
751 } while (idx < 0 || !s->streams[idx]);
754 os = ogg->streams + idx;
756 // pflags might not be set until after this
757 pts = ogg_calc_pts(s, idx, &dts);
758 ogg_validate_keyframe(s, idx, pstart, psize);
760 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
762 os->keyframe_seek = 0;
765 ret = av_new_packet(pkt, psize);
768 pkt->stream_index = idx;
769 memcpy(pkt->data, os->buf + pstart, psize);
773 pkt->flags = os->pflags;
774 pkt->duration = os->pduration;
777 if (os->end_trimming) {
778 uint8_t *side_data = av_packet_new_side_data(pkt,
779 AV_PKT_DATA_SKIP_SAMPLES,
781 if(side_data == NULL) {
784 return AVERROR(ENOMEM);
786 AV_WL32(side_data + 4, os->end_trimming);
792 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
793 int64_t *pos_arg, int64_t pos_limit)
795 struct ogg *ogg = s->priv_data;
796 AVIOContext *bc = s->pb;
797 int64_t pts = AV_NOPTS_VALUE;
801 avio_seek(bc, *pos_arg, SEEK_SET);
804 while ( avio_tell(bc) <= pos_limit
805 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
806 if (i == stream_index) {
807 struct ogg_stream *os = ogg->streams + stream_index;
808 pts = ogg_calc_pts(s, i, NULL);
809 ogg_validate_keyframe(s, i, pstart, psize);
810 if (os->pflags & AV_PKT_FLAG_KEY) {
812 } else if (os->keyframe_seek) {
813 // if we had a previous keyframe but no pts for it,
814 // return that keyframe with this pts value.
818 pts = AV_NOPTS_VALUE;
821 if (pts != AV_NOPTS_VALUE)
828 static int ogg_read_seek(AVFormatContext *s, int stream_index,
829 int64_t timestamp, int flags)
831 struct ogg *ogg = s->priv_data;
832 struct ogg_stream *os = ogg->streams + stream_index;
835 av_assert0(stream_index < ogg->nstreams);
836 // Ensure everything is reset even when seeking via
837 // the generated index.
840 // Try seeking to a keyframe first. If this fails (very possible),
841 // av_seek_frame will fall back to ignoring keyframes
842 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
843 && !(flags & AVSEEK_FLAG_ANY))
844 os->keyframe_seek = 1;
846 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
847 os = ogg->streams + stream_index;
849 os->keyframe_seek = 0;
853 static int ogg_probe(AVProbeData *p)
855 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
856 return AVPROBE_SCORE_MAX;
860 AVInputFormat ff_ogg_demuxer = {
862 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
863 .priv_data_size = sizeof(struct ogg),
864 .read_probe = ogg_probe,
865 .read_header = ogg_read_header,
866 .read_packet = ogg_read_packet,
867 .read_close = ogg_read_close,
868 .read_seek = ogg_read_seek,
869 .read_timestamp = ogg_read_timestamp,
871 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,