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_freep(&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) {
145 os->end_trimming = 0;
154 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
158 for (i = 0; ogg_codecs[i]; i++)
159 if (size >= ogg_codecs[i]->magicsize &&
160 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
161 return ogg_codecs[i];
167 * Replace the current stream with a new one. This is a typical webradio
168 * situation where a new audio stream spawn (identified with a new serial) and
169 * must replace the previous one (track switch).
171 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
173 struct ogg *ogg = s->priv_data;
174 struct ogg_stream *os;
175 const struct ogg_codec *codec;
178 if (s->pb->seekable) {
180 int64_t pos = avio_tell(s->pb);
181 avio_skip(s->pb, nsegs);
182 avio_read(s->pb, magic, sizeof(magic));
183 avio_seek(s->pb, pos, SEEK_SET);
184 codec = ogg_find_codec(magic, sizeof(magic));
186 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
187 return AVERROR_INVALIDDATA;
189 for (i = 0; i < ogg->nstreams; i++) {
190 if (ogg->streams[i].codec == codec)
193 if (i >= ogg->nstreams)
194 return ogg_new_stream(s, serial);
195 } else if (ogg->nstreams != 1) {
196 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
197 return AVERROR_PATCHWELCOME;
200 os = &ogg->streams[i];
207 bufsize = os->bufsize;
210 if (!ogg->state || ogg->state->streams[i].private != os->private)
211 av_freep(&ogg->streams[i].private);
213 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
214 * also re-use the ogg_stream allocated buffer */
215 memset(os, 0, sizeof(*os));
217 os->bufsize = bufsize;
226 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
228 struct ogg *ogg = s->priv_data;
229 int idx = ogg->nstreams;
231 struct ogg_stream *os;
235 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
236 "in between Ogg context save/restore operations.\n");
240 /* Allocate and init a new Ogg Stream */
241 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
242 !(os = av_realloc(ogg->streams, size)))
243 return AVERROR(ENOMEM);
245 os = ogg->streams + idx;
246 memset(os, 0, sizeof(*os));
248 os->bufsize = DECODER_BUFFER_SIZE;
249 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
251 os->start_granule = OGG_NOGRANULE_VALUE;
253 return AVERROR(ENOMEM);
255 /* Create the associated AVStream */
256 st = avformat_new_stream(s, NULL);
259 return AVERROR(ENOMEM);
262 avpriv_set_pts_info(st, 64, 1, 1000000);
268 static int ogg_new_buf(struct ogg *ogg, int idx)
270 struct ogg_stream *os = ogg->streams + idx;
271 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
272 int size = os->bufpos - os->pstart;
275 memcpy(nb, os->buf + os->pstart, size);
286 static int data_packets_seen(const struct ogg *ogg)
290 for (i = 0; i < ogg->nstreams; i++)
291 if (ogg->streams[i].got_data)
296 static int ogg_read_page(AVFormatContext *s, int *sid)
298 AVIOContext *bc = s->pb;
299 struct ogg *ogg = s->priv_data;
300 struct ogg_stream *os;
309 ret = avio_read(bc, sync, 4);
311 return ret < 0 ? ret : AVERROR_EOF;
316 if (sync[sp & 3] == 'O' &&
317 sync[(sp + 1) & 3] == 'g' &&
318 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
321 if(!i && bc->seekable && ogg->page_pos > 0) {
323 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
333 } while (i++ < MAX_PAGE_SIZE);
335 if (i >= MAX_PAGE_SIZE) {
336 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
337 return AVERROR_INVALIDDATA;
340 if (avio_r8(bc) != 0) { /* version */
341 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
342 return AVERROR_INVALIDDATA;
347 serial = avio_rl32(bc);
348 avio_skip(bc, 8); /* seq, crc */
351 idx = ogg_find_stream(ogg, serial);
353 if (data_packets_seen(ogg))
354 idx = ogg_replace_stream(s, serial, nsegs);
356 idx = ogg_new_stream(s, serial);
359 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
364 os = ogg->streams + idx;
366 os->page_pos = avio_tell(bc) - 27;
369 ogg_new_buf(ogg, idx);
371 ret = avio_read(bc, os->segments, nsegs);
373 return ret < 0 ? ret : AVERROR_EOF;
379 for (i = 0; i < nsegs; i++)
380 size += os->segments[i];
382 if (!(flags & OGG_FLAG_BOS))
385 if (flags & OGG_FLAG_CONT || os->incomplete) {
387 // If this is the very first segment we started
388 // playback in the middle of a continuation packet.
389 // Discard it since we missed the start of it.
390 while (os->segp < os->nsegs) {
391 int seg = os->segments[os->segp++];
396 os->sync_pos = os->page_pos;
400 os->sync_pos = os->page_pos;
403 if (os->bufsize - os->bufpos < size) {
404 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
406 return AVERROR(ENOMEM);
407 memcpy(nb, os->buf, os->bufpos);
412 ret = avio_read(bc, os->buf + os->bufpos, size);
414 return ret < 0 ? ret : AVERROR_EOF;
420 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
428 * @brief find the next Ogg packet
429 * @param *sid is set to the stream for the packet or -1 if there is
430 * no matching stream, in that case assume all other return
431 * values to be uninitialized.
432 * @return negative value on error or EOF.
434 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
437 struct ogg *ogg = s->priv_data;
439 struct ogg_stream *os;
441 int segp = 0, psize = 0;
443 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
451 ret = ogg_read_page(s, &idx);
456 os = ogg->streams + idx;
458 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
459 idx, os->pstart, os->psize, os->segp, os->nsegs);
462 if (os->header < 0) {
463 os->codec = ogg_find_codec(os->buf, os->bufpos);
465 av_log(s, AV_LOG_WARNING, "Codec not found\n");
477 while (os->segp < os->nsegs) {
478 int ss = os->segments[os->segp++];
486 if (!complete && os->segp == os->nsegs) {
488 // Do not set incomplete for empty packets.
489 // Together with the code in ogg_read_page
490 // that discards all continuation of empty packets
491 // we would get an infinite loop.
492 os->incomplete = !!os->psize;
497 if (os->granule == -1)
498 av_log(s, AV_LOG_WARNING,
499 "Page at %"PRId64" is missing granule\n",
506 os->header = os->codec->header(s, idx);
511 // We have reached the first non-header packet in this stream.
512 // Unfortunately more header packets may still follow for others,
513 // but if we continue with header parsing we may lose data packets.
516 // Update the header state for all streams and
517 // compute the data_offset.
519 s->data_offset = os->sync_pos;
521 for (i = 0; i < ogg->nstreams; i++) {
522 struct ogg_stream *cur_os = ogg->streams + i;
524 // if we have a partial non-header packet, its start is
525 // obviously at or after the data start
526 if (cur_os->incomplete)
527 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
531 os->pstart += os->psize;
537 if (os->codec && os->codec->packet)
538 os->codec->packet(s, idx);
542 *dstart = os->pstart;
546 *fpos = os->sync_pos;
547 os->pstart += os->psize;
549 if(os->pstart == os->bufpos)
550 os->bufpos = os->pstart = 0;
551 os->sync_pos = os->page_pos;
554 // determine whether there are more complete packets in this page
555 // if not, the page's granule will apply to this packet
557 for (i = os->segp; i < os->nsegs; i++)
558 if (os->segments[i] < 255) {
563 if (os->segp == os->nsegs)
569 static int ogg_get_length(AVFormatContext *s)
571 struct ogg *ogg = s->priv_data;
576 if (!s->pb->seekable)
580 if (s->duration != AV_NOPTS_VALUE)
583 size = avio_size(s->pb);
586 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
589 avio_seek(s->pb, end, SEEK_SET);
592 while (!ogg_read_page(s, &i)) {
593 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
594 ogg->streams[i].codec) {
595 s->streams[i]->duration =
596 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
597 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
598 s->streams[i]->duration -= s->streams[i]->start_time;
599 streams_left-= (ogg->streams[i].got_start==-1);
600 ogg->streams[i].got_start= 1;
601 } else if(!ogg->streams[i].got_start) {
602 ogg->streams[i].got_start= -1;
611 avio_seek (s->pb, s->data_offset, SEEK_SET);
613 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
616 pts = ogg_calc_pts(s, i, NULL);
617 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
618 s->streams[i]->duration -= pts;
619 ogg->streams[i].got_start= 1;
621 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
622 ogg->streams[i].got_start= 1;
631 static int ogg_read_close(AVFormatContext *s)
633 struct ogg *ogg = s->priv_data;
636 for (i = 0; i < ogg->nstreams; i++) {
637 av_freep(&ogg->streams[i].buf);
638 if (ogg->streams[i].codec &&
639 ogg->streams[i].codec->cleanup) {
640 ogg->streams[i].codec->cleanup(s, i);
642 av_freep(&ogg->streams[i].private);
644 av_freep(&ogg->streams);
648 static int ogg_read_header(AVFormatContext *s)
650 struct ogg *ogg = s->priv_data;
655 //linear headers seek from start
657 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
662 } while (!ogg->headers);
663 av_dlog(s, "found headers\n");
665 for (i = 0; i < ogg->nstreams; i++) {
666 struct ogg_stream *os = ogg->streams + i;
668 if (ogg->streams[i].header < 0) {
669 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
670 ogg->streams[i].codec = NULL;
671 } else if (os->codec && os->nb_header < os->codec->nb_header) {
672 av_log(s, AV_LOG_WARNING,
673 "Headers mismatch for stream %d: "
674 "expected %d received %d.\n",
675 i, os->codec->nb_header, os->nb_header);
676 if (s->error_recognition & AV_EF_EXPLODE)
677 return AVERROR_INVALIDDATA;
679 if (os->start_granule != OGG_NOGRANULE_VALUE)
680 os->lastpts = s->streams[i]->start_time =
681 ogg_gptopts(s, i, os->start_granule, NULL);
684 //linear granulepos seek from end
690 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
692 struct ogg *ogg = s->priv_data;
693 struct ogg_stream *os = ogg->streams + idx;
694 int64_t pts = AV_NOPTS_VALUE;
697 *dts = AV_NOPTS_VALUE;
699 if (os->lastpts != AV_NOPTS_VALUE) {
701 os->lastpts = AV_NOPTS_VALUE;
703 if (os->lastdts != AV_NOPTS_VALUE) {
706 os->lastdts = AV_NOPTS_VALUE;
709 if (os->granule != -1LL) {
710 if (os->codec && os->codec->granule_is_start)
711 pts = ogg_gptopts(s, idx, os->granule, dts);
713 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
720 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
722 struct ogg *ogg = s->priv_data;
723 struct ogg_stream *os = ogg->streams + idx;
724 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
725 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
726 os->pflags ^= AV_PKT_FLAG_KEY;
727 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
728 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
733 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
736 struct ogg_stream *os;
739 int64_t fpos, pts, dts;
741 if (s->io_repositioned) {
743 s->io_repositioned = 0;
749 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
752 } while (idx < 0 || !s->streams[idx]);
755 os = ogg->streams + idx;
757 // pflags might not be set until after this
758 pts = ogg_calc_pts(s, idx, &dts);
759 ogg_validate_keyframe(s, idx, pstart, psize);
761 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
763 os->keyframe_seek = 0;
766 ret = av_new_packet(pkt, psize);
769 pkt->stream_index = idx;
770 memcpy(pkt->data, os->buf + pstart, psize);
774 pkt->flags = os->pflags;
775 pkt->duration = os->pduration;
778 if (os->end_trimming) {
779 uint8_t *side_data = av_packet_new_side_data(pkt,
780 AV_PKT_DATA_SKIP_SAMPLES,
782 if(side_data == NULL) {
785 return AVERROR(ENOMEM);
787 AV_WL32(side_data + 4, os->end_trimming);
788 os->end_trimming = 0;
794 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
795 int64_t *pos_arg, int64_t pos_limit)
797 struct ogg *ogg = s->priv_data;
798 AVIOContext *bc = s->pb;
799 int64_t pts = AV_NOPTS_VALUE;
803 avio_seek(bc, *pos_arg, SEEK_SET);
806 while ( avio_tell(bc) <= pos_limit
807 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
808 if (i == stream_index) {
809 struct ogg_stream *os = ogg->streams + stream_index;
810 pts = ogg_calc_pts(s, i, NULL);
811 ogg_validate_keyframe(s, i, pstart, psize);
812 if (os->pflags & AV_PKT_FLAG_KEY) {
814 } else if (os->keyframe_seek) {
815 // if we had a previous keyframe but no pts for it,
816 // return that keyframe with this pts value.
820 pts = AV_NOPTS_VALUE;
823 if (pts != AV_NOPTS_VALUE)
830 static int ogg_read_seek(AVFormatContext *s, int stream_index,
831 int64_t timestamp, int flags)
833 struct ogg *ogg = s->priv_data;
834 struct ogg_stream *os = ogg->streams + stream_index;
837 av_assert0(stream_index < ogg->nstreams);
838 // Ensure everything is reset even when seeking via
839 // the generated index.
842 // Try seeking to a keyframe first. If this fails (very possible),
843 // av_seek_frame will fall back to ignoring keyframes
844 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
845 && !(flags & AVSEEK_FLAG_ANY))
846 os->keyframe_seek = 1;
848 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
849 os = ogg->streams + stream_index;
851 os->keyframe_seek = 0;
855 static int ogg_probe(AVProbeData *p)
857 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
858 return AVPROBE_SCORE_MAX;
862 AVInputFormat ff_ogg_demuxer = {
864 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
865 .priv_data_size = sizeof(struct ogg),
866 .read_probe = ogg_probe,
867 .read_header = ogg_read_header,
868 .read_packet = ogg_read_packet,
869 .read_close = ogg_read_close,
870 .read_seek = ogg_read_seek,
871 .read_timestamp = ogg_read_timestamp,
873 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,