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 //FIXME We could avoid some structure duplication
67 static int ogg_save(AVFormatContext *s)
69 struct ogg *ogg = s->priv_data;
70 struct ogg_state *ost =
71 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
76 return AVERROR(ENOMEM);
78 ost->pos = avio_tell(s->pb);
79 ost->curidx = ogg->curidx;
80 ost->next = ogg->state;
81 ost->nstreams = ogg->nstreams;
82 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
84 for (i = 0; i < ogg->nstreams; i++) {
85 struct ogg_stream *os = ogg->streams + i;
86 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
88 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
90 ret = AVERROR(ENOMEM);
91 os->new_metadata = NULL;
92 os->new_metadata_size = 0;
103 static int ogg_restore(AVFormatContext *s)
105 struct ogg *ogg = s->priv_data;
106 AVIOContext *bc = s->pb;
107 struct ogg_state *ost = ogg->state;
113 ogg->state = ost->next;
115 for (i = 0; i < ogg->nstreams; i++)
116 av_freep(&ogg->streams[i].buf);
118 avio_seek(bc, ost->pos, SEEK_SET);
120 ogg->curidx = ost->curidx;
121 ogg->nstreams = ost->nstreams;
122 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
123 sizeof(*ogg->streams))) < 0) {
127 memcpy(ogg->streams, ost->streams,
128 ost->nstreams * sizeof(*ogg->streams));
135 static int ogg_reset(AVFormatContext *s)
137 struct ogg *ogg = s->priv_data;
139 int64_t start_pos = avio_tell(s->pb);
141 for (i = 0; i < ogg->nstreams; i++) {
142 struct ogg_stream *os = ogg->streams + i;
147 os->lastpts = AV_NOPTS_VALUE;
148 os->lastdts = AV_NOPTS_VALUE;
155 if (start_pos <= s->internal->data_offset) {
158 os->end_trimming = 0;
159 av_freep(&os->new_metadata);
160 os->new_metadata_size = 0;
169 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
173 for (i = 0; ogg_codecs[i]; i++)
174 if (size >= ogg_codecs[i]->magicsize &&
175 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
176 return ogg_codecs[i];
182 * Replace the current stream with a new one. This is a typical webradio
183 * situation where a new audio stream spawn (identified with a new serial) and
184 * must replace the previous one (track switch).
186 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
188 struct ogg *ogg = s->priv_data;
189 struct ogg_stream *os;
190 const struct ogg_codec *codec;
193 if (s->pb->seekable) {
195 int64_t pos = avio_tell(s->pb);
196 avio_skip(s->pb, nsegs);
197 avio_read(s->pb, magic, sizeof(magic));
198 avio_seek(s->pb, pos, SEEK_SET);
199 codec = ogg_find_codec(magic, sizeof(magic));
201 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
202 return AVERROR_INVALIDDATA;
204 for (i = 0; i < ogg->nstreams; i++) {
205 if (ogg->streams[i].codec == codec)
208 if (i >= ogg->nstreams)
209 return ogg_new_stream(s, serial);
210 } else if (ogg->nstreams != 1) {
211 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
212 return AVERROR_PATCHWELCOME;
215 os = &ogg->streams[i];
222 bufsize = os->bufsize;
225 if (!ogg->state || ogg->state->streams[i].private != os->private)
226 av_freep(&ogg->streams[i].private);
228 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
229 * also re-use the ogg_stream allocated buffer */
230 memset(os, 0, sizeof(*os));
232 os->bufsize = bufsize;
241 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
243 struct ogg *ogg = s->priv_data;
244 int idx = ogg->nstreams;
246 struct ogg_stream *os;
250 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
251 "in between Ogg context save/restore operations.\n");
255 /* Allocate and init a new Ogg Stream */
256 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
257 !(os = av_realloc(ogg->streams, size)))
258 return AVERROR(ENOMEM);
260 os = ogg->streams + idx;
261 memset(os, 0, sizeof(*os));
263 os->bufsize = DECODER_BUFFER_SIZE;
264 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
266 os->start_granule = OGG_NOGRANULE_VALUE;
268 return AVERROR(ENOMEM);
270 /* Create the associated AVStream */
271 st = avformat_new_stream(s, NULL);
274 return AVERROR(ENOMEM);
277 avpriv_set_pts_info(st, 64, 1, 1000000);
283 static int ogg_new_buf(struct ogg *ogg, int idx)
285 struct ogg_stream *os = ogg->streams + idx;
286 uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
287 int size = os->bufpos - os->pstart;
290 return AVERROR(ENOMEM);
293 memcpy(nb, os->buf + os->pstart, size);
304 static int data_packets_seen(const struct ogg *ogg)
308 for (i = 0; i < ogg->nstreams; i++)
309 if (ogg->streams[i].got_data)
314 static int ogg_read_page(AVFormatContext *s, int *sid)
316 AVIOContext *bc = s->pb;
317 struct ogg *ogg = s->priv_data;
318 struct ogg_stream *os;
327 ret = avio_read(bc, sync, 4);
329 return ret < 0 ? ret : AVERROR_EOF;
334 if (sync[sp & 3] == 'O' &&
335 sync[(sp + 1) & 3] == 'g' &&
336 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
339 if(!i && bc->seekable && ogg->page_pos > 0) {
341 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
351 } while (i++ < MAX_PAGE_SIZE);
353 if (i >= MAX_PAGE_SIZE) {
354 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
355 return AVERROR_INVALIDDATA;
358 if (avio_r8(bc) != 0) { /* version */
359 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
360 return AVERROR_INVALIDDATA;
365 serial = avio_rl32(bc);
366 avio_skip(bc, 8); /* seq, crc */
369 idx = ogg_find_stream(ogg, serial);
371 if (data_packets_seen(ogg))
372 idx = ogg_replace_stream(s, serial, nsegs);
374 idx = ogg_new_stream(s, serial);
377 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
382 os = ogg->streams + idx;
384 os->page_pos = avio_tell(bc) - 27;
387 ret = ogg_new_buf(ogg, idx);
392 ret = avio_read(bc, os->segments, nsegs);
394 return ret < 0 ? ret : AVERROR_EOF;
400 for (i = 0; i < nsegs; i++)
401 size += os->segments[i];
403 if (!(flags & OGG_FLAG_BOS))
406 if (flags & OGG_FLAG_CONT || os->incomplete) {
408 // If this is the very first segment we started
409 // playback in the middle of a continuation packet.
410 // Discard it since we missed the start of it.
411 while (os->segp < os->nsegs) {
412 int seg = os->segments[os->segp++];
417 os->sync_pos = os->page_pos;
421 os->sync_pos = os->page_pos;
424 if (os->bufsize - os->bufpos < size) {
425 uint8_t *nb = av_malloc((os->bufsize *= 2) + AV_INPUT_BUFFER_PADDING_SIZE);
427 return AVERROR(ENOMEM);
428 memcpy(nb, os->buf, os->bufpos);
433 ret = avio_read(bc, os->buf + os->bufpos, size);
435 return ret < 0 ? ret : AVERROR_EOF;
441 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
449 * @brief find the next Ogg packet
450 * @param *sid is set to the stream for the packet or -1 if there is
451 * no matching stream, in that case assume all other return
452 * values to be uninitialized.
453 * @return negative value on error or EOF.
455 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
458 struct ogg *ogg = s->priv_data;
460 struct ogg_stream *os;
462 int segp = 0, psize = 0;
464 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
472 ret = ogg_read_page(s, &idx);
477 os = ogg->streams + idx;
479 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
480 idx, os->pstart, os->psize, os->segp, os->nsegs);
483 if (os->header < 0) {
484 os->codec = ogg_find_codec(os->buf, os->bufpos);
486 av_log(s, AV_LOG_WARNING, "Codec not found\n");
498 while (os->segp < os->nsegs) {
499 int ss = os->segments[os->segp++];
507 if (!complete && os->segp == os->nsegs) {
509 // Do not set incomplete for empty packets.
510 // Together with the code in ogg_read_page
511 // that discards all continuation of empty packets
512 // we would get an infinite loop.
513 os->incomplete = !!os->psize;
518 if (os->granule == -1)
519 av_log(s, AV_LOG_WARNING,
520 "Page at %"PRId64" is missing granule\n",
527 os->header = os->codec->header(s, idx);
532 // We have reached the first non-header packet in this stream.
533 // Unfortunately more header packets may still follow for others,
534 // but if we continue with header parsing we may lose data packets.
537 // Update the header state for all streams and
538 // compute the data_offset.
539 if (!s->internal->data_offset)
540 s->internal->data_offset = os->sync_pos;
542 for (i = 0; i < ogg->nstreams; i++) {
543 struct ogg_stream *cur_os = ogg->streams + i;
545 // if we have a partial non-header packet, its start is
546 // obviously at or after the data start
547 if (cur_os->incomplete)
548 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
552 os->pstart += os->psize;
558 if (os->codec && os->codec->packet)
559 os->codec->packet(s, idx);
563 *dstart = os->pstart;
567 *fpos = os->sync_pos;
568 os->pstart += os->psize;
570 if(os->pstart == os->bufpos)
571 os->bufpos = os->pstart = 0;
572 os->sync_pos = os->page_pos;
575 // determine whether there are more complete packets in this page
576 // if not, the page's granule will apply to this packet
578 for (i = os->segp; i < os->nsegs; i++)
579 if (os->segments[i] < 255) {
584 if (os->segp == os->nsegs)
590 static int ogg_get_length(AVFormatContext *s)
592 struct ogg *ogg = s->priv_data;
597 if (!s->pb->seekable)
601 if (s->duration != AV_NOPTS_VALUE)
604 size = avio_size(s->pb);
607 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
612 avio_seek(s->pb, end, SEEK_SET);
615 while (!ogg_read_page(s, &i)) {
616 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
617 ogg->streams[i].codec) {
618 s->streams[i]->duration =
619 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
620 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
621 s->streams[i]->duration -= s->streams[i]->start_time;
622 streams_left-= (ogg->streams[i].got_start==-1);
623 ogg->streams[i].got_start= 1;
624 } else if(!ogg->streams[i].got_start) {
625 ogg->streams[i].got_start= -1;
637 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
639 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
642 pts = ogg_calc_pts(s, i, NULL);
643 if (s->streams[i]->duration == AV_NOPTS_VALUE)
645 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
646 s->streams[i]->duration -= pts;
647 ogg->streams[i].got_start= 1;
649 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
650 ogg->streams[i].got_start= 1;
659 static int ogg_read_close(AVFormatContext *s)
661 struct ogg *ogg = s->priv_data;
664 for (i = 0; i < ogg->nstreams; i++) {
665 av_freep(&ogg->streams[i].buf);
666 if (ogg->streams[i].codec &&
667 ogg->streams[i].codec->cleanup) {
668 ogg->streams[i].codec->cleanup(s, i);
670 av_freep(&ogg->streams[i].private);
671 av_freep(&ogg->streams[i].new_metadata);
676 av_freep(&ogg->streams);
680 static int ogg_read_header(AVFormatContext *s)
682 struct ogg *ogg = s->priv_data;
687 //linear headers seek from start
689 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
694 } while (!ogg->headers);
695 av_log(s, AV_LOG_TRACE, "found headers\n");
697 for (i = 0; i < ogg->nstreams; i++) {
698 struct ogg_stream *os = ogg->streams + i;
700 if (ogg->streams[i].header < 0) {
701 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
702 ogg->streams[i].codec = NULL;
703 av_freep(&ogg->streams[i].private);
704 } else if (os->codec && os->nb_header < os->codec->nb_header) {
705 av_log(s, AV_LOG_WARNING,
706 "Headers mismatch for stream %d: "
707 "expected %d received %d.\n",
708 i, os->codec->nb_header, os->nb_header);
709 if (s->error_recognition & AV_EF_EXPLODE)
710 return AVERROR_INVALIDDATA;
712 if (os->start_granule != OGG_NOGRANULE_VALUE)
713 os->lastpts = s->streams[i]->start_time =
714 ogg_gptopts(s, i, os->start_granule, NULL);
717 //linear granulepos seek from end
718 ret = ogg_get_length(s);
727 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
729 struct ogg *ogg = s->priv_data;
730 struct ogg_stream *os = ogg->streams + idx;
731 int64_t pts = AV_NOPTS_VALUE;
734 *dts = AV_NOPTS_VALUE;
736 if (os->lastpts != AV_NOPTS_VALUE) {
738 os->lastpts = AV_NOPTS_VALUE;
740 if (os->lastdts != AV_NOPTS_VALUE) {
743 os->lastdts = AV_NOPTS_VALUE;
746 if (os->granule != -1LL) {
747 if (os->codec && os->codec->granule_is_start)
748 pts = ogg_gptopts(s, idx, os->granule, dts);
750 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
757 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
759 struct ogg *ogg = s->priv_data;
760 struct ogg_stream *os = ogg->streams + idx;
763 switch (s->streams[idx]->codecpar->codec_id) {
764 case AV_CODEC_ID_THEORA:
765 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
767 case AV_CODEC_ID_VP8:
768 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
771 os->pflags ^= AV_PKT_FLAG_KEY;
772 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
773 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
778 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
781 struct ogg_stream *os;
784 int64_t fpos, pts, dts;
786 if (s->io_repositioned) {
788 s->io_repositioned = 0;
794 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
797 } while (idx < 0 || !s->streams[idx]);
800 os = ogg->streams + idx;
802 // pflags might not be set until after this
803 pts = ogg_calc_pts(s, idx, &dts);
804 ogg_validate_keyframe(s, idx, pstart, psize);
806 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
808 os->keyframe_seek = 0;
811 ret = av_new_packet(pkt, psize);
814 pkt->stream_index = idx;
815 memcpy(pkt->data, os->buf + pstart, psize);
819 pkt->flags = os->pflags;
820 pkt->duration = os->pduration;
823 if (os->end_trimming) {
824 uint8_t *side_data = av_packet_new_side_data(pkt,
825 AV_PKT_DATA_SKIP_SAMPLES,
829 AV_WL32(side_data + 4, os->end_trimming);
830 os->end_trimming = 0;
833 if (os->new_metadata) {
834 uint8_t *side_data = av_packet_new_side_data(pkt,
835 AV_PKT_DATA_METADATA_UPDATE,
836 os->new_metadata_size);
840 memcpy(side_data, os->new_metadata, os->new_metadata_size);
841 av_freep(&os->new_metadata);
842 os->new_metadata_size = 0;
847 av_packet_unref(pkt);
848 return AVERROR(ENOMEM);
851 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
852 int64_t *pos_arg, int64_t pos_limit)
854 struct ogg *ogg = s->priv_data;
855 AVIOContext *bc = s->pb;
856 int64_t pts = AV_NOPTS_VALUE;
860 avio_seek(bc, *pos_arg, SEEK_SET);
863 while ( avio_tell(bc) <= pos_limit
864 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
865 if (i == stream_index) {
866 struct ogg_stream *os = ogg->streams + stream_index;
867 // Do not trust the last timestamps of an ogm video
868 if ( (os->flags & OGG_FLAG_EOS)
869 && !(os->flags & OGG_FLAG_BOS)
870 && os->codec == &ff_ogm_video_codec)
872 pts = ogg_calc_pts(s, i, NULL);
873 ogg_validate_keyframe(s, i, pstart, psize);
874 if (os->pflags & AV_PKT_FLAG_KEY) {
876 } else if (os->keyframe_seek) {
877 // if we had a previous keyframe but no pts for it,
878 // return that keyframe with this pts value.
882 pts = AV_NOPTS_VALUE;
885 if (pts != AV_NOPTS_VALUE)
892 static int ogg_read_seek(AVFormatContext *s, int stream_index,
893 int64_t timestamp, int flags)
895 struct ogg *ogg = s->priv_data;
896 struct ogg_stream *os = ogg->streams + stream_index;
899 av_assert0(stream_index < ogg->nstreams);
900 // Ensure everything is reset even when seeking via
901 // the generated index.
904 // Try seeking to a keyframe first. If this fails (very possible),
905 // av_seek_frame will fall back to ignoring keyframes
906 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
907 && !(flags & AVSEEK_FLAG_ANY))
908 os->keyframe_seek = 1;
910 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
912 os = ogg->streams + stream_index;
914 os->keyframe_seek = 0;
918 static int ogg_probe(AVProbeData *p)
920 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
921 return AVPROBE_SCORE_MAX;
925 AVInputFormat ff_ogg_demuxer = {
927 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
928 .priv_data_size = sizeof(struct ogg),
929 .read_probe = ogg_probe,
930 .read_header = ogg_read_header,
931 .read_packet = ogg_read_packet,
932 .read_close = ogg_read_close,
933 .read_seek = ogg_read_seek,
934 .read_timestamp = ogg_read_timestamp,
936 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,