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[] = {
62 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
63 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
64 static int ogg_restore(AVFormatContext *s);
66 static void free_stream(AVFormatContext *s, int i)
68 struct ogg *ogg = s->priv_data;
69 struct ogg_stream *stream = &ogg->streams[i];
71 av_freep(&stream->buf);
73 stream->codec->cleanup) {
74 stream->codec->cleanup(s, i);
77 av_freep(&stream->private);
78 av_freep(&stream->new_metadata);
81 //FIXME We could avoid some structure duplication
82 static int ogg_save(AVFormatContext *s)
84 struct ogg *ogg = s->priv_data;
85 struct ogg_state *ost =
86 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
91 return AVERROR(ENOMEM);
93 ost->pos = avio_tell(s->pb);
94 ost->curidx = ogg->curidx;
95 ost->next = ogg->state;
96 ost->nstreams = ogg->nstreams;
97 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
99 for (i = 0; i < ogg->nstreams; i++) {
100 struct ogg_stream *os = ogg->streams + i;
101 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
103 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
105 ret = AVERROR(ENOMEM);
106 os->new_metadata = NULL;
107 os->new_metadata_size = 0;
118 static int ogg_restore(AVFormatContext *s)
120 struct ogg *ogg = s->priv_data;
121 AVIOContext *bc = s->pb;
122 struct ogg_state *ost = ogg->state;
128 ogg->state = ost->next;
130 for (i = 0; i < ogg->nstreams; i++) {
131 struct ogg_stream *stream = &ogg->streams[i];
132 av_freep(&stream->buf);
133 av_freep(&stream->new_metadata);
135 if (i >= ost->nstreams || !ost->streams[i].private) {
140 avio_seek(bc, ost->pos, SEEK_SET);
142 ogg->curidx = ost->curidx;
143 ogg->nstreams = ost->nstreams;
144 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
145 sizeof(*ogg->streams))) < 0) {
149 memcpy(ogg->streams, ost->streams,
150 ost->nstreams * sizeof(*ogg->streams));
157 static int ogg_reset(AVFormatContext *s)
159 struct ogg *ogg = s->priv_data;
161 int64_t start_pos = avio_tell(s->pb);
163 for (i = 0; i < ogg->nstreams; i++) {
164 struct ogg_stream *os = ogg->streams + i;
169 os->lastpts = AV_NOPTS_VALUE;
170 os->lastdts = AV_NOPTS_VALUE;
177 if (start_pos <= s->internal->data_offset) {
180 os->end_trimming = 0;
181 av_freep(&os->new_metadata);
182 os->new_metadata_size = 0;
191 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
195 for (i = 0; ogg_codecs[i]; i++)
196 if (size >= ogg_codecs[i]->magicsize &&
197 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
198 return ogg_codecs[i];
204 * Replace the current stream with a new one. This is a typical webradio
205 * situation where a new audio stream spawn (identified with a new serial) and
206 * must replace the previous one (track switch).
208 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int size)
210 struct ogg *ogg = s->priv_data;
211 struct ogg_stream *os;
212 const struct ogg_codec *codec;
215 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
217 avio_seek(s->pb, -size, SEEK_CUR);
218 if (avio_read(s->pb, magic, sizeof(magic)) != sizeof(magic))
219 return AVERROR_INVALIDDATA;
220 avio_seek(s->pb, size - sizeof(magic), SEEK_CUR);
221 codec = ogg_find_codec(magic, sizeof(magic));
223 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
224 return AVERROR_INVALIDDATA;
226 for (i = 0; i < ogg->nstreams; i++) {
227 if (ogg->streams[i].codec == codec)
230 if (i >= ogg->nstreams)
231 return ogg_new_stream(s, serial);
232 } else if (ogg->nstreams != 1) {
233 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
234 return AVERROR_PATCHWELCOME;
237 os = &ogg->streams[i];
244 bufsize = os->bufsize;
247 if (!ogg->state || ogg->state->streams[i].private != os->private)
248 av_freep(&ogg->streams[i].private);
250 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
251 * also re-use the ogg_stream allocated buffer */
252 memset(os, 0, sizeof(*os));
254 os->bufsize = bufsize;
263 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
265 struct ogg *ogg = s->priv_data;
266 int idx = ogg->nstreams;
268 struct ogg_stream *os;
272 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
273 "in between Ogg context save/restore operations.\n");
277 /* Allocate and init a new Ogg Stream */
278 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
279 !(os = av_realloc(ogg->streams, size)))
280 return AVERROR(ENOMEM);
282 os = ogg->streams + idx;
283 memset(os, 0, sizeof(*os));
285 os->bufsize = DECODER_BUFFER_SIZE;
286 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
288 os->start_granule = OGG_NOGRANULE_VALUE;
290 return AVERROR(ENOMEM);
292 /* Create the associated AVStream */
293 st = avformat_new_stream(s, NULL);
296 return AVERROR(ENOMEM);
299 avpriv_set_pts_info(st, 64, 1, 1000000);
305 static int data_packets_seen(const struct ogg *ogg)
309 for (i = 0; i < ogg->nstreams; i++)
310 if (ogg->streams[i].got_data)
315 static int ogg_read_page(AVFormatContext *s, int *sid)
317 AVIOContext *bc = s->pb;
318 struct ogg *ogg = s->priv_data;
319 struct ogg_stream *os;
327 uint8_t segments[255];
328 uint8_t *readout_buf;
331 ret = avio_read(bc, sync, 4);
333 return ret < 0 ? ret : AVERROR_EOF;
338 if (sync[sp & 3] == 'O' &&
339 sync[(sp + 1) & 3] == 'g' &&
340 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
343 if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
345 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
355 } while (i++ < MAX_PAGE_SIZE);
357 if (i >= MAX_PAGE_SIZE) {
358 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
359 return AVERROR_INVALIDDATA;
362 if (avio_r8(bc) != 0) { /* version */
363 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
364 return AVERROR_INVALIDDATA;
369 serial = avio_rl32(bc);
370 avio_skip(bc, 8); /* seq, crc */
373 page_pos = avio_tell(bc) - 27;
375 ret = avio_read(bc, segments, nsegs);
377 return ret < 0 ? ret : AVERROR_EOF;
382 for (i = 0; i < nsegs; i++)
385 idx = ogg_find_stream(ogg, serial);
387 os = ogg->streams + idx;
389 /* Even if invalid guarantee there's enough memory to read the page */
390 if (os->bufsize - os->bufpos < size) {
391 uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
393 return AVERROR(ENOMEM);
398 readout_buf = os->buf + os->bufpos;
400 readout_buf = av_malloc(size);
403 ret = avio_read(bc, readout_buf, size);
406 av_free(readout_buf);
407 return ret < 0 ? ret : AVERROR_EOF;
411 if (data_packets_seen(ogg))
412 idx = ogg_replace_stream(s, serial, size);
414 idx = ogg_new_stream(s, serial);
417 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
418 av_free(readout_buf);
422 os = ogg->streams + idx;
424 memcpy(os->buf + os->bufpos, readout_buf, size);
425 av_free(readout_buf);
428 ogg->page_pos = page_pos;
429 os->page_pos = page_pos;
432 os->got_data = !(flags & OGG_FLAG_BOS);
436 memcpy(os->segments, segments, nsegs);
437 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
439 if (flags & OGG_FLAG_CONT || os->incomplete) {
441 // If this is the very first segment we started
442 // playback in the middle of a continuation packet.
443 // Discard it since we missed the start of it.
444 while (os->segp < os->nsegs) {
445 int seg = os->segments[os->segp++];
450 os->sync_pos = os->page_pos;
454 os->sync_pos = os->page_pos;
457 /* This function is always called with sid != NULL */
464 * @brief find the next Ogg packet
465 * @param *sid is set to the stream for the packet or -1 if there is
466 * no matching stream, in that case assume all other return
467 * values to be uninitialized.
468 * @return negative value on error or EOF.
470 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
473 struct ogg *ogg = s->priv_data;
475 struct ogg_stream *os;
477 int segp = 0, psize = 0;
479 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
487 ret = ogg_read_page(s, &idx);
492 os = ogg->streams + idx;
494 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
495 idx, os->pstart, os->psize, os->segp, os->nsegs);
498 if (os->header < 0) {
499 os->codec = ogg_find_codec(os->buf, os->bufpos);
501 av_log(s, AV_LOG_WARNING, "Codec not found\n");
513 while (os->segp < os->nsegs) {
514 int ss = os->segments[os->segp++];
522 if (!complete && os->segp == os->nsegs) {
524 // Do not set incomplete for empty packets.
525 // Together with the code in ogg_read_page
526 // that discards all continuation of empty packets
527 // we would get an infinite loop.
528 os->incomplete = !!os->psize;
533 if (os->granule == -1)
534 av_log(s, AV_LOG_WARNING,
535 "Page at %"PRId64" is missing granule\n",
542 if ((ret = os->codec->header(s, idx)) < 0) {
543 av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
551 // We have reached the first non-header packet in this stream.
552 // Unfortunately more header packets may still follow for others,
553 // but if we continue with header parsing we may lose data packets.
556 // Update the header state for all streams and
557 // compute the data_offset.
558 if (!s->internal->data_offset)
559 s->internal->data_offset = os->sync_pos;
561 for (i = 0; i < ogg->nstreams; i++) {
562 struct ogg_stream *cur_os = ogg->streams + i;
564 // if we have a partial non-header packet, its start is
565 // obviously at or after the data start
566 if (cur_os->incomplete)
567 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
571 os->pstart += os->psize;
577 if (os->codec && os->codec->packet) {
578 if ((ret = os->codec->packet(s, idx)) < 0) {
579 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
586 *dstart = os->pstart;
590 *fpos = os->sync_pos;
591 os->pstart += os->psize;
593 if(os->pstart == os->bufpos)
594 os->bufpos = os->pstart = 0;
595 os->sync_pos = os->page_pos;
598 // determine whether there are more complete packets in this page
599 // if not, the page's granule will apply to this packet
601 for (i = os->segp; i < os->nsegs; i++)
602 if (os->segments[i] < 255) {
607 if (os->segp == os->nsegs)
613 static int ogg_get_length(AVFormatContext *s)
615 struct ogg *ogg = s->priv_data;
620 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
624 if (s->duration != AV_NOPTS_VALUE)
627 size = avio_size(s->pb);
630 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
635 avio_seek(s->pb, end, SEEK_SET);
638 while (!ogg_read_page(s, &i)) {
639 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
640 ogg->streams[i].codec) {
641 s->streams[i]->duration =
642 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
643 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
644 s->streams[i]->duration -= s->streams[i]->start_time;
645 streams_left-= (ogg->streams[i].got_start==-1);
646 ogg->streams[i].got_start= 1;
647 } else if(!ogg->streams[i].got_start) {
648 ogg->streams[i].got_start= -1;
660 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
662 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
665 pts = ogg_calc_pts(s, i, NULL);
666 if (s->streams[i]->duration == AV_NOPTS_VALUE)
668 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
669 s->streams[i]->duration -= pts;
670 ogg->streams[i].got_start= 1;
672 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
673 ogg->streams[i].got_start= 1;
682 static int ogg_read_close(AVFormatContext *s)
684 struct ogg *ogg = s->priv_data;
687 for (i = 0; i < ogg->nstreams; i++) {
693 av_freep(&ogg->streams);
697 static int ogg_read_header(AVFormatContext *s)
699 struct ogg *ogg = s->priv_data;
704 //linear headers seek from start
706 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
711 } while (!ogg->headers);
712 av_log(s, AV_LOG_TRACE, "found headers\n");
714 for (i = 0; i < ogg->nstreams; i++) {
715 struct ogg_stream *os = ogg->streams + i;
717 if (ogg->streams[i].header < 0) {
718 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
719 ogg->streams[i].codec = NULL;
720 av_freep(&ogg->streams[i].private);
721 } else if (os->codec && os->nb_header < os->codec->nb_header) {
722 av_log(s, AV_LOG_WARNING,
723 "Headers mismatch for stream %d: "
724 "expected %d received %d.\n",
725 i, os->codec->nb_header, os->nb_header);
726 if (s->error_recognition & AV_EF_EXPLODE) {
728 return AVERROR_INVALIDDATA;
731 if (os->start_granule != OGG_NOGRANULE_VALUE)
732 os->lastpts = s->streams[i]->start_time =
733 ogg_gptopts(s, i, os->start_granule, NULL);
736 //linear granulepos seek from end
737 ret = ogg_get_length(s);
746 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
748 struct ogg *ogg = s->priv_data;
749 struct ogg_stream *os = ogg->streams + idx;
750 int64_t pts = AV_NOPTS_VALUE;
753 *dts = AV_NOPTS_VALUE;
755 if (os->lastpts != AV_NOPTS_VALUE) {
757 os->lastpts = AV_NOPTS_VALUE;
759 if (os->lastdts != AV_NOPTS_VALUE) {
762 os->lastdts = AV_NOPTS_VALUE;
765 if (os->granule != -1LL) {
766 if (os->codec && os->codec->granule_is_start)
767 pts = ogg_gptopts(s, idx, os->granule, dts);
769 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
776 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
778 struct ogg *ogg = s->priv_data;
779 struct ogg_stream *os = ogg->streams + idx;
782 switch (s->streams[idx]->codecpar->codec_id) {
783 case AV_CODEC_ID_THEORA:
784 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
786 case AV_CODEC_ID_VP8:
787 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
790 os->pflags ^= AV_PKT_FLAG_KEY;
791 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
792 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
797 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
800 struct ogg_stream *os;
803 int64_t fpos, pts, dts;
805 if (s->io_repositioned) {
807 s->io_repositioned = 0;
813 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
816 } while (idx < 0 || !s->streams[idx]);
819 os = ogg->streams + idx;
821 // pflags might not be set until after this
822 pts = ogg_calc_pts(s, idx, &dts);
823 ogg_validate_keyframe(s, idx, pstart, psize);
825 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
827 os->keyframe_seek = 0;
830 ret = av_new_packet(pkt, psize);
833 pkt->stream_index = idx;
834 memcpy(pkt->data, os->buf + pstart, psize);
838 pkt->flags = os->pflags;
839 pkt->duration = os->pduration;
842 if (os->end_trimming) {
843 uint8_t *side_data = av_packet_new_side_data(pkt,
844 AV_PKT_DATA_SKIP_SAMPLES,
847 return AVERROR(ENOMEM);
848 AV_WL32(side_data + 4, os->end_trimming);
849 os->end_trimming = 0;
852 if (os->new_metadata) {
853 uint8_t *side_data = av_packet_new_side_data(pkt,
854 AV_PKT_DATA_METADATA_UPDATE,
855 os->new_metadata_size);
857 return AVERROR(ENOMEM);
859 memcpy(side_data, os->new_metadata, os->new_metadata_size);
860 av_freep(&os->new_metadata);
861 os->new_metadata_size = 0;
867 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
868 int64_t *pos_arg, int64_t pos_limit)
870 struct ogg *ogg = s->priv_data;
871 AVIOContext *bc = s->pb;
872 int64_t pts = AV_NOPTS_VALUE;
876 avio_seek(bc, *pos_arg, SEEK_SET);
879 while ( avio_tell(bc) <= pos_limit
880 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
881 if (i == stream_index) {
882 struct ogg_stream *os = ogg->streams + stream_index;
883 // Do not trust the last timestamps of an ogm video
884 if ( (os->flags & OGG_FLAG_EOS)
885 && !(os->flags & OGG_FLAG_BOS)
886 && os->codec == &ff_ogm_video_codec)
888 pts = ogg_calc_pts(s, i, NULL);
889 ogg_validate_keyframe(s, i, pstart, psize);
890 if (os->pflags & AV_PKT_FLAG_KEY) {
892 } else if (os->keyframe_seek) {
893 // if we had a previous keyframe but no pts for it,
894 // return that keyframe with this pts value.
898 pts = AV_NOPTS_VALUE;
901 if (pts != AV_NOPTS_VALUE)
908 static int ogg_read_seek(AVFormatContext *s, int stream_index,
909 int64_t timestamp, int flags)
911 struct ogg *ogg = s->priv_data;
912 struct ogg_stream *os = ogg->streams + stream_index;
915 av_assert0(stream_index < ogg->nstreams);
916 // Ensure everything is reset even when seeking via
917 // the generated index.
920 // Try seeking to a keyframe first. If this fails (very possible),
921 // av_seek_frame will fall back to ignoring keyframes
922 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
923 && !(flags & AVSEEK_FLAG_ANY))
924 os->keyframe_seek = 1;
926 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
928 os = ogg->streams + stream_index;
930 os->keyframe_seek = 0;
934 static int ogg_probe(const AVProbeData *p)
936 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
937 return AVPROBE_SCORE_MAX;
941 AVInputFormat ff_ogg_demuxer = {
943 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
944 .priv_data_size = sizeof(struct ogg),
945 .read_probe = ogg_probe,
946 .read_header = ogg_read_header,
947 .read_packet = ogg_read_packet,
948 .read_close = ogg_read_close,
949 .read_seek = ogg_read_seek,
950 .read_timestamp = ogg_read_timestamp,
952 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,