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 av_freep(&ogg->streams[i].buf);
133 avio_seek(bc, ost->pos, SEEK_SET);
135 ogg->curidx = ost->curidx;
136 ogg->nstreams = ost->nstreams;
137 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
138 sizeof(*ogg->streams))) < 0) {
142 memcpy(ogg->streams, ost->streams,
143 ost->nstreams * sizeof(*ogg->streams));
150 static int ogg_reset(AVFormatContext *s)
152 struct ogg *ogg = s->priv_data;
154 int64_t start_pos = avio_tell(s->pb);
156 for (i = 0; i < ogg->nstreams; i++) {
157 struct ogg_stream *os = ogg->streams + i;
162 os->lastpts = AV_NOPTS_VALUE;
163 os->lastdts = AV_NOPTS_VALUE;
170 if (start_pos <= s->internal->data_offset) {
173 os->end_trimming = 0;
174 av_freep(&os->new_metadata);
175 os->new_metadata_size = 0;
184 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
188 for (i = 0; ogg_codecs[i]; i++)
189 if (size >= ogg_codecs[i]->magicsize &&
190 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
191 return ogg_codecs[i];
197 * Replace the current stream with a new one. This is a typical webradio
198 * situation where a new audio stream spawn (identified with a new serial) and
199 * must replace the previous one (track switch).
201 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
203 struct ogg *ogg = s->priv_data;
204 struct ogg_stream *os;
205 const struct ogg_codec *codec;
208 if (s->pb->seekable) {
210 int64_t pos = avio_tell(s->pb);
211 avio_skip(s->pb, nsegs);
212 avio_read(s->pb, magic, sizeof(magic));
213 avio_seek(s->pb, pos, SEEK_SET);
214 codec = ogg_find_codec(magic, sizeof(magic));
216 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
217 return AVERROR_INVALIDDATA;
219 for (i = 0; i < ogg->nstreams; i++) {
220 if (ogg->streams[i].codec == codec)
223 if (i >= ogg->nstreams)
224 return ogg_new_stream(s, serial);
225 } else if (ogg->nstreams != 1) {
226 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
227 return AVERROR_PATCHWELCOME;
230 os = &ogg->streams[i];
237 bufsize = os->bufsize;
240 if (!ogg->state || ogg->state->streams[i].private != os->private)
241 av_freep(&ogg->streams[i].private);
243 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
244 * also re-use the ogg_stream allocated buffer */
245 memset(os, 0, sizeof(*os));
247 os->bufsize = bufsize;
256 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
258 struct ogg *ogg = s->priv_data;
259 int idx = ogg->nstreams;
261 struct ogg_stream *os;
265 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
266 "in between Ogg context save/restore operations.\n");
270 /* Allocate and init a new Ogg Stream */
271 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
272 !(os = av_realloc(ogg->streams, size)))
273 return AVERROR(ENOMEM);
275 os = ogg->streams + idx;
276 memset(os, 0, sizeof(*os));
278 os->bufsize = DECODER_BUFFER_SIZE;
279 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
281 os->start_granule = OGG_NOGRANULE_VALUE;
283 return AVERROR(ENOMEM);
285 /* Create the associated AVStream */
286 st = avformat_new_stream(s, NULL);
289 return AVERROR(ENOMEM);
292 avpriv_set_pts_info(st, 64, 1, 1000000);
298 static int ogg_new_buf(struct ogg *ogg, int idx)
300 struct ogg_stream *os = ogg->streams + idx;
301 uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
302 int size = os->bufpos - os->pstart;
305 return AVERROR(ENOMEM);
308 memcpy(nb, os->buf + os->pstart, size);
319 static int data_packets_seen(const struct ogg *ogg)
323 for (i = 0; i < ogg->nstreams; i++)
324 if (ogg->streams[i].got_data)
329 static int ogg_read_page(AVFormatContext *s, int *sid)
331 AVIOContext *bc = s->pb;
332 struct ogg *ogg = s->priv_data;
333 struct ogg_stream *os;
342 ret = avio_read(bc, sync, 4);
344 return ret < 0 ? ret : AVERROR_EOF;
349 if (sync[sp & 3] == 'O' &&
350 sync[(sp + 1) & 3] == 'g' &&
351 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
354 if(!i && bc->seekable && ogg->page_pos > 0) {
356 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
366 } while (i++ < MAX_PAGE_SIZE);
368 if (i >= MAX_PAGE_SIZE) {
369 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
370 return AVERROR_INVALIDDATA;
373 if (avio_r8(bc) != 0) { /* version */
374 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
375 return AVERROR_INVALIDDATA;
380 serial = avio_rl32(bc);
381 avio_skip(bc, 8); /* seq, crc */
384 idx = ogg_find_stream(ogg, serial);
386 if (data_packets_seen(ogg))
387 idx = ogg_replace_stream(s, serial, nsegs);
389 idx = ogg_new_stream(s, serial);
392 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
397 os = ogg->streams + idx;
399 os->page_pos = avio_tell(bc) - 27;
402 ret = ogg_new_buf(ogg, idx);
407 ret = avio_read(bc, os->segments, nsegs);
409 return ret < 0 ? ret : AVERROR_EOF;
415 for (i = 0; i < nsegs; i++)
416 size += os->segments[i];
418 if (!(flags & OGG_FLAG_BOS))
421 if (flags & OGG_FLAG_CONT || os->incomplete) {
423 // If this is the very first segment we started
424 // playback in the middle of a continuation packet.
425 // Discard it since we missed the start of it.
426 while (os->segp < os->nsegs) {
427 int seg = os->segments[os->segp++];
432 os->sync_pos = os->page_pos;
436 os->sync_pos = os->page_pos;
439 if (os->bufsize - os->bufpos < size) {
440 uint8_t *nb = av_malloc((os->bufsize *= 2) + AV_INPUT_BUFFER_PADDING_SIZE);
442 return AVERROR(ENOMEM);
443 memcpy(nb, os->buf, os->bufpos);
448 ret = avio_read(bc, os->buf + os->bufpos, size);
450 return ret < 0 ? ret : AVERROR_EOF;
456 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
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 os->header = os->codec->header(s, idx);
547 // We have reached the first non-header packet in this stream.
548 // Unfortunately more header packets may still follow for others,
549 // but if we continue with header parsing we may lose data packets.
552 // Update the header state for all streams and
553 // compute the data_offset.
554 if (!s->internal->data_offset)
555 s->internal->data_offset = os->sync_pos;
557 for (i = 0; i < ogg->nstreams; i++) {
558 struct ogg_stream *cur_os = ogg->streams + i;
560 // if we have a partial non-header packet, its start is
561 // obviously at or after the data start
562 if (cur_os->incomplete)
563 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
567 os->pstart += os->psize;
573 if (os->codec && os->codec->packet)
574 os->codec->packet(s, idx);
578 *dstart = os->pstart;
582 *fpos = os->sync_pos;
583 os->pstart += os->psize;
585 if(os->pstart == os->bufpos)
586 os->bufpos = os->pstart = 0;
587 os->sync_pos = os->page_pos;
590 // determine whether there are more complete packets in this page
591 // if not, the page's granule will apply to this packet
593 for (i = os->segp; i < os->nsegs; i++)
594 if (os->segments[i] < 255) {
599 if (os->segp == os->nsegs)
605 static int ogg_get_length(AVFormatContext *s)
607 struct ogg *ogg = s->priv_data;
612 if (!s->pb->seekable)
616 if (s->duration != AV_NOPTS_VALUE)
619 size = avio_size(s->pb);
622 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
627 avio_seek(s->pb, end, SEEK_SET);
630 while (!ogg_read_page(s, &i)) {
631 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
632 ogg->streams[i].codec) {
633 s->streams[i]->duration =
634 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
635 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
636 s->streams[i]->duration -= s->streams[i]->start_time;
637 streams_left-= (ogg->streams[i].got_start==-1);
638 ogg->streams[i].got_start= 1;
639 } else if(!ogg->streams[i].got_start) {
640 ogg->streams[i].got_start= -1;
652 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
654 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
657 pts = ogg_calc_pts(s, i, NULL);
658 if (s->streams[i]->duration == AV_NOPTS_VALUE)
660 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
661 s->streams[i]->duration -= pts;
662 ogg->streams[i].got_start= 1;
664 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
665 ogg->streams[i].got_start= 1;
674 static int ogg_read_close(AVFormatContext *s)
676 struct ogg *ogg = s->priv_data;
679 for (i = 0; i < ogg->nstreams; i++) {
685 av_freep(&ogg->streams);
689 static int ogg_read_header(AVFormatContext *s)
691 struct ogg *ogg = s->priv_data;
696 //linear headers seek from start
698 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
703 } while (!ogg->headers);
704 av_log(s, AV_LOG_TRACE, "found headers\n");
706 for (i = 0; i < ogg->nstreams; i++) {
707 struct ogg_stream *os = ogg->streams + i;
709 if (ogg->streams[i].header < 0) {
710 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
711 ogg->streams[i].codec = NULL;
712 av_freep(&ogg->streams[i].private);
713 } else if (os->codec && os->nb_header < os->codec->nb_header) {
714 av_log(s, AV_LOG_WARNING,
715 "Headers mismatch for stream %d: "
716 "expected %d received %d.\n",
717 i, os->codec->nb_header, os->nb_header);
718 if (s->error_recognition & AV_EF_EXPLODE)
719 return AVERROR_INVALIDDATA;
721 if (os->start_granule != OGG_NOGRANULE_VALUE)
722 os->lastpts = s->streams[i]->start_time =
723 ogg_gptopts(s, i, os->start_granule, NULL);
726 //linear granulepos seek from end
727 ret = ogg_get_length(s);
736 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
738 struct ogg *ogg = s->priv_data;
739 struct ogg_stream *os = ogg->streams + idx;
740 int64_t pts = AV_NOPTS_VALUE;
743 *dts = AV_NOPTS_VALUE;
745 if (os->lastpts != AV_NOPTS_VALUE) {
747 os->lastpts = AV_NOPTS_VALUE;
749 if (os->lastdts != AV_NOPTS_VALUE) {
752 os->lastdts = AV_NOPTS_VALUE;
755 if (os->granule != -1LL) {
756 if (os->codec && os->codec->granule_is_start)
757 pts = ogg_gptopts(s, idx, os->granule, dts);
759 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
766 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
768 struct ogg *ogg = s->priv_data;
769 struct ogg_stream *os = ogg->streams + idx;
772 switch (s->streams[idx]->codecpar->codec_id) {
773 case AV_CODEC_ID_THEORA:
774 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
776 case AV_CODEC_ID_VP8:
777 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
780 os->pflags ^= AV_PKT_FLAG_KEY;
781 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
782 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
787 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
790 struct ogg_stream *os;
793 int64_t fpos, pts, dts;
795 if (s->io_repositioned) {
797 s->io_repositioned = 0;
803 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
806 } while (idx < 0 || !s->streams[idx]);
809 os = ogg->streams + idx;
811 // pflags might not be set until after this
812 pts = ogg_calc_pts(s, idx, &dts);
813 ogg_validate_keyframe(s, idx, pstart, psize);
815 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
817 os->keyframe_seek = 0;
820 ret = av_new_packet(pkt, psize);
823 pkt->stream_index = idx;
824 memcpy(pkt->data, os->buf + pstart, psize);
828 pkt->flags = os->pflags;
829 pkt->duration = os->pduration;
832 if (os->end_trimming) {
833 uint8_t *side_data = av_packet_new_side_data(pkt,
834 AV_PKT_DATA_SKIP_SAMPLES,
838 AV_WL32(side_data + 4, os->end_trimming);
839 os->end_trimming = 0;
842 if (os->new_metadata) {
843 uint8_t *side_data = av_packet_new_side_data(pkt,
844 AV_PKT_DATA_METADATA_UPDATE,
845 os->new_metadata_size);
849 memcpy(side_data, os->new_metadata, os->new_metadata_size);
850 av_freep(&os->new_metadata);
851 os->new_metadata_size = 0;
856 av_packet_unref(pkt);
857 return AVERROR(ENOMEM);
860 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
861 int64_t *pos_arg, int64_t pos_limit)
863 struct ogg *ogg = s->priv_data;
864 AVIOContext *bc = s->pb;
865 int64_t pts = AV_NOPTS_VALUE;
869 avio_seek(bc, *pos_arg, SEEK_SET);
872 while ( avio_tell(bc) <= pos_limit
873 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
874 if (i == stream_index) {
875 struct ogg_stream *os = ogg->streams + stream_index;
876 // Do not trust the last timestamps of an ogm video
877 if ( (os->flags & OGG_FLAG_EOS)
878 && !(os->flags & OGG_FLAG_BOS)
879 && os->codec == &ff_ogm_video_codec)
881 pts = ogg_calc_pts(s, i, NULL);
882 ogg_validate_keyframe(s, i, pstart, psize);
883 if (os->pflags & AV_PKT_FLAG_KEY) {
885 } else if (os->keyframe_seek) {
886 // if we had a previous keyframe but no pts for it,
887 // return that keyframe with this pts value.
891 pts = AV_NOPTS_VALUE;
894 if (pts != AV_NOPTS_VALUE)
901 static int ogg_read_seek(AVFormatContext *s, int stream_index,
902 int64_t timestamp, int flags)
904 struct ogg *ogg = s->priv_data;
905 struct ogg_stream *os = ogg->streams + stream_index;
908 av_assert0(stream_index < ogg->nstreams);
909 // Ensure everything is reset even when seeking via
910 // the generated index.
913 // Try seeking to a keyframe first. If this fails (very possible),
914 // av_seek_frame will fall back to ignoring keyframes
915 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
916 && !(flags & AVSEEK_FLAG_ANY))
917 os->keyframe_seek = 1;
919 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
921 os = ogg->streams + stream_index;
923 os->keyframe_seek = 0;
927 static int ogg_probe(AVProbeData *p)
929 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
930 return AVPROBE_SCORE_MAX;
934 AVInputFormat ff_ogg_demuxer = {
936 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
937 .priv_data_size = sizeof(struct ogg),
938 .read_probe = ogg_probe,
939 .read_header = ogg_read_header,
940 .read_packet = ogg_read_packet,
941 .read_close = ogg_read_close,
942 .read_seek = ogg_read_seek,
943 .read_timestamp = ogg_read_timestamp,
945 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,