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[] = {
61 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
62 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
64 //FIXME We could avoid some structure duplication
65 static int ogg_save(AVFormatContext *s)
67 struct ogg *ogg = s->priv_data;
68 struct ogg_state *ost =
69 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
71 ost->pos = avio_tell(s->pb);
72 ost->curidx = ogg->curidx;
73 ost->next = ogg->state;
74 ost->nstreams = ogg->nstreams;
75 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
77 for (i = 0; i < ogg->nstreams; i++) {
78 struct ogg_stream *os = ogg->streams + i;
79 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
80 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
81 os->new_metadata = NULL;
82 os->new_metadata_size = 0;
90 static int ogg_restore(AVFormatContext *s, int discard)
92 struct ogg *ogg = s->priv_data;
93 AVIOContext *bc = s->pb;
94 struct ogg_state *ost = ogg->state;
100 ogg->state = ost->next;
104 for (i = 0; i < ogg->nstreams; i++)
105 av_freep(&ogg->streams[i].buf);
107 avio_seek(bc, ost->pos, SEEK_SET);
109 ogg->curidx = ost->curidx;
110 ogg->nstreams = ost->nstreams;
111 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
112 sizeof(*ogg->streams))) < 0) {
116 memcpy(ogg->streams, ost->streams,
117 ost->nstreams * sizeof(*ogg->streams));
125 static int ogg_reset(AVFormatContext *s)
127 struct ogg *ogg = s->priv_data;
129 int64_t start_pos = avio_tell(s->pb);
131 for (i = 0; i < ogg->nstreams; i++) {
132 struct ogg_stream *os = ogg->streams + i;
137 os->lastpts = AV_NOPTS_VALUE;
138 os->lastdts = AV_NOPTS_VALUE;
145 if (start_pos <= s->data_offset) {
148 os->end_trimming = 0;
149 av_freep(&os->new_metadata);
150 os->new_metadata_size = 0;
159 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
163 for (i = 0; ogg_codecs[i]; i++)
164 if (size >= ogg_codecs[i]->magicsize &&
165 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
166 return ogg_codecs[i];
172 * Replace the current stream with a new one. This is a typical webradio
173 * situation where a new audio stream spawn (identified with a new serial) and
174 * must replace the previous one (track switch).
176 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
178 struct ogg *ogg = s->priv_data;
179 struct ogg_stream *os;
180 const struct ogg_codec *codec;
183 if (s->pb->seekable) {
185 int64_t pos = avio_tell(s->pb);
186 avio_skip(s->pb, nsegs);
187 avio_read(s->pb, magic, sizeof(magic));
188 avio_seek(s->pb, pos, SEEK_SET);
189 codec = ogg_find_codec(magic, sizeof(magic));
191 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
192 return AVERROR_INVALIDDATA;
194 for (i = 0; i < ogg->nstreams; i++) {
195 if (ogg->streams[i].codec == codec)
198 if (i >= ogg->nstreams)
199 return ogg_new_stream(s, serial);
200 } else if (ogg->nstreams != 1) {
201 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
202 return AVERROR_PATCHWELCOME;
205 os = &ogg->streams[i];
212 bufsize = os->bufsize;
215 if (!ogg->state || ogg->state->streams[i].private != os->private)
216 av_freep(&ogg->streams[i].private);
218 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
219 * also re-use the ogg_stream allocated buffer */
220 memset(os, 0, sizeof(*os));
222 os->bufsize = bufsize;
231 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
233 struct ogg *ogg = s->priv_data;
234 int idx = ogg->nstreams;
236 struct ogg_stream *os;
240 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
241 "in between Ogg context save/restore operations.\n");
245 /* Allocate and init a new Ogg Stream */
246 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
247 !(os = av_realloc(ogg->streams, size)))
248 return AVERROR(ENOMEM);
250 os = ogg->streams + idx;
251 memset(os, 0, sizeof(*os));
253 os->bufsize = DECODER_BUFFER_SIZE;
254 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
256 os->start_granule = OGG_NOGRANULE_VALUE;
258 return AVERROR(ENOMEM);
260 /* Create the associated AVStream */
261 st = avformat_new_stream(s, NULL);
264 return AVERROR(ENOMEM);
267 avpriv_set_pts_info(st, 64, 1, 1000000);
273 static int ogg_new_buf(struct ogg *ogg, int idx)
275 struct ogg_stream *os = ogg->streams + idx;
276 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
277 int size = os->bufpos - os->pstart;
280 memcpy(nb, os->buf + os->pstart, size);
291 static int data_packets_seen(const struct ogg *ogg)
295 for (i = 0; i < ogg->nstreams; i++)
296 if (ogg->streams[i].got_data)
301 static int ogg_read_page(AVFormatContext *s, int *sid)
303 AVIOContext *bc = s->pb;
304 struct ogg *ogg = s->priv_data;
305 struct ogg_stream *os;
314 ret = avio_read(bc, sync, 4);
316 return ret < 0 ? ret : AVERROR_EOF;
321 if (sync[sp & 3] == 'O' &&
322 sync[(sp + 1) & 3] == 'g' &&
323 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
326 if(!i && bc->seekable && ogg->page_pos > 0) {
328 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
338 } while (i++ < MAX_PAGE_SIZE);
340 if (i >= MAX_PAGE_SIZE) {
341 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
342 return AVERROR_INVALIDDATA;
345 if (avio_r8(bc) != 0) { /* version */
346 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
347 return AVERROR_INVALIDDATA;
352 serial = avio_rl32(bc);
353 avio_skip(bc, 8); /* seq, crc */
356 idx = ogg_find_stream(ogg, serial);
358 if (data_packets_seen(ogg))
359 idx = ogg_replace_stream(s, serial, nsegs);
361 idx = ogg_new_stream(s, serial);
364 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
369 os = ogg->streams + idx;
371 os->page_pos = avio_tell(bc) - 27;
374 ogg_new_buf(ogg, idx);
376 ret = avio_read(bc, os->segments, nsegs);
378 return ret < 0 ? ret : AVERROR_EOF;
384 for (i = 0; i < nsegs; i++)
385 size += os->segments[i];
387 if (!(flags & OGG_FLAG_BOS))
390 if (flags & OGG_FLAG_CONT || os->incomplete) {
392 // If this is the very first segment we started
393 // playback in the middle of a continuation packet.
394 // Discard it since we missed the start of it.
395 while (os->segp < os->nsegs) {
396 int seg = os->segments[os->segp++];
401 os->sync_pos = os->page_pos;
405 os->sync_pos = os->page_pos;
408 if (os->bufsize - os->bufpos < size) {
409 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
411 return AVERROR(ENOMEM);
412 memcpy(nb, os->buf, os->bufpos);
417 ret = avio_read(bc, os->buf + os->bufpos, size);
419 return ret < 0 ? ret : AVERROR_EOF;
425 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
433 * @brief find the next Ogg packet
434 * @param *sid is set to the stream for the packet or -1 if there is
435 * no matching stream, in that case assume all other return
436 * values to be uninitialized.
437 * @return negative value on error or EOF.
439 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
442 struct ogg *ogg = s->priv_data;
444 struct ogg_stream *os;
446 int segp = 0, psize = 0;
448 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
456 ret = ogg_read_page(s, &idx);
461 os = ogg->streams + idx;
463 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
464 idx, os->pstart, os->psize, os->segp, os->nsegs);
467 if (os->header < 0) {
468 os->codec = ogg_find_codec(os->buf, os->bufpos);
470 av_log(s, AV_LOG_WARNING, "Codec not found\n");
482 while (os->segp < os->nsegs) {
483 int ss = os->segments[os->segp++];
491 if (!complete && os->segp == os->nsegs) {
493 // Do not set incomplete for empty packets.
494 // Together with the code in ogg_read_page
495 // that discards all continuation of empty packets
496 // we would get an infinite loop.
497 os->incomplete = !!os->psize;
502 if (os->granule == -1)
503 av_log(s, AV_LOG_WARNING,
504 "Page at %"PRId64" is missing granule\n",
511 os->header = os->codec->header(s, idx);
516 // We have reached the first non-header packet in this stream.
517 // Unfortunately more header packets may still follow for others,
518 // but if we continue with header parsing we may lose data packets.
521 // Update the header state for all streams and
522 // compute the data_offset.
524 s->data_offset = os->sync_pos;
526 for (i = 0; i < ogg->nstreams; i++) {
527 struct ogg_stream *cur_os = ogg->streams + i;
529 // if we have a partial non-header packet, its start is
530 // obviously at or after the data start
531 if (cur_os->incomplete)
532 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
536 os->pstart += os->psize;
542 if (os->codec && os->codec->packet)
543 os->codec->packet(s, idx);
547 *dstart = os->pstart;
551 *fpos = os->sync_pos;
552 os->pstart += os->psize;
554 if(os->pstart == os->bufpos)
555 os->bufpos = os->pstart = 0;
556 os->sync_pos = os->page_pos;
559 // determine whether there are more complete packets in this page
560 // if not, the page's granule will apply to this packet
562 for (i = os->segp; i < os->nsegs; i++)
563 if (os->segments[i] < 255) {
568 if (os->segp == os->nsegs)
574 static int ogg_get_length(AVFormatContext *s)
576 struct ogg *ogg = s->priv_data;
581 if (!s->pb->seekable)
585 if (s->duration != AV_NOPTS_VALUE)
588 size = avio_size(s->pb);
591 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
594 avio_seek(s->pb, end, SEEK_SET);
597 while (!ogg_read_page(s, &i)) {
598 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
599 ogg->streams[i].codec) {
600 s->streams[i]->duration =
601 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
602 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
603 s->streams[i]->duration -= s->streams[i]->start_time;
604 streams_left-= (ogg->streams[i].got_start==-1);
605 ogg->streams[i].got_start= 1;
606 } else if(!ogg->streams[i].got_start) {
607 ogg->streams[i].got_start= -1;
616 avio_seek (s->pb, s->data_offset, SEEK_SET);
618 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
621 pts = ogg_calc_pts(s, i, NULL);
622 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
623 s->streams[i]->duration -= pts;
624 ogg->streams[i].got_start= 1;
626 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
627 ogg->streams[i].got_start= 1;
636 static int ogg_read_close(AVFormatContext *s)
638 struct ogg *ogg = s->priv_data;
641 for (i = 0; i < ogg->nstreams; i++) {
642 av_freep(&ogg->streams[i].buf);
643 if (ogg->streams[i].codec &&
644 ogg->streams[i].codec->cleanup) {
645 ogg->streams[i].codec->cleanup(s, i);
647 av_freep(&ogg->streams[i].private);
648 av_freep(&ogg->streams[i].new_metadata);
650 av_freep(&ogg->streams);
654 static int ogg_read_header(AVFormatContext *s)
656 struct ogg *ogg = s->priv_data;
661 //linear headers seek from start
663 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
668 } while (!ogg->headers);
669 av_dlog(s, "found headers\n");
671 for (i = 0; i < ogg->nstreams; i++) {
672 struct ogg_stream *os = ogg->streams + i;
674 if (ogg->streams[i].header < 0) {
675 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
676 ogg->streams[i].codec = NULL;
677 } else if (os->codec && os->nb_header < os->codec->nb_header) {
678 av_log(s, AV_LOG_WARNING,
679 "Headers mismatch for stream %d: "
680 "expected %d received %d.\n",
681 i, os->codec->nb_header, os->nb_header);
682 if (s->error_recognition & AV_EF_EXPLODE)
683 return AVERROR_INVALIDDATA;
685 if (os->start_granule != OGG_NOGRANULE_VALUE)
686 os->lastpts = s->streams[i]->start_time =
687 ogg_gptopts(s, i, os->start_granule, NULL);
690 //linear granulepos seek from end
696 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
698 struct ogg *ogg = s->priv_data;
699 struct ogg_stream *os = ogg->streams + idx;
700 int64_t pts = AV_NOPTS_VALUE;
703 *dts = AV_NOPTS_VALUE;
705 if (os->lastpts != AV_NOPTS_VALUE) {
707 os->lastpts = AV_NOPTS_VALUE;
709 if (os->lastdts != AV_NOPTS_VALUE) {
712 os->lastdts = AV_NOPTS_VALUE;
715 if (os->granule != -1LL) {
716 if (os->codec && os->codec->granule_is_start)
717 pts = ogg_gptopts(s, idx, os->granule, dts);
719 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
726 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
728 struct ogg *ogg = s->priv_data;
729 struct ogg_stream *os = ogg->streams + idx;
732 switch (s->streams[idx]->codec->codec_id) {
733 case AV_CODEC_ID_THEORA:
734 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
736 case AV_CODEC_ID_VP8:
737 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
740 os->pflags ^= AV_PKT_FLAG_KEY;
741 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
742 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
747 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
750 struct ogg_stream *os;
753 int64_t fpos, pts, dts;
755 if (s->io_repositioned) {
757 s->io_repositioned = 0;
763 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
766 } while (idx < 0 || !s->streams[idx]);
769 os = ogg->streams + idx;
771 // pflags might not be set until after this
772 pts = ogg_calc_pts(s, idx, &dts);
773 ogg_validate_keyframe(s, idx, pstart, psize);
775 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
777 os->keyframe_seek = 0;
780 ret = av_new_packet(pkt, psize);
783 pkt->stream_index = idx;
784 memcpy(pkt->data, os->buf + pstart, psize);
788 pkt->flags = os->pflags;
789 pkt->duration = os->pduration;
792 if (os->end_trimming) {
793 uint8_t *side_data = av_packet_new_side_data(pkt,
794 AV_PKT_DATA_SKIP_SAMPLES,
796 if(side_data == NULL) {
799 return AVERROR(ENOMEM);
801 AV_WL32(side_data + 4, os->end_trimming);
802 os->end_trimming = 0;
805 if (os->new_metadata) {
806 uint8_t *side_data = av_packet_new_side_data(pkt,
807 AV_PKT_DATA_METADATA_UPDATE,
808 os->new_metadata_size);
809 memcpy(side_data, os->new_metadata, os->new_metadata_size);
810 av_freep(&os->new_metadata);
811 os->new_metadata_size = 0;
817 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
818 int64_t *pos_arg, int64_t pos_limit)
820 struct ogg *ogg = s->priv_data;
821 AVIOContext *bc = s->pb;
822 int64_t pts = AV_NOPTS_VALUE;
826 avio_seek(bc, *pos_arg, SEEK_SET);
829 while ( avio_tell(bc) <= pos_limit
830 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
831 if (i == stream_index) {
832 struct ogg_stream *os = ogg->streams + stream_index;
833 // Dont trust the last timestamps of a ogm video
834 if ( (os->flags & OGG_FLAG_EOS)
835 && !(os->flags & OGG_FLAG_BOS)
836 && os->codec == &ff_ogm_video_codec)
838 pts = ogg_calc_pts(s, i, NULL);
839 ogg_validate_keyframe(s, i, pstart, psize);
840 if (os->pflags & AV_PKT_FLAG_KEY) {
842 } else if (os->keyframe_seek) {
843 // if we had a previous keyframe but no pts for it,
844 // return that keyframe with this pts value.
848 pts = AV_NOPTS_VALUE;
851 if (pts != AV_NOPTS_VALUE)
858 static int ogg_read_seek(AVFormatContext *s, int stream_index,
859 int64_t timestamp, int flags)
861 struct ogg *ogg = s->priv_data;
862 struct ogg_stream *os = ogg->streams + stream_index;
865 av_assert0(stream_index < ogg->nstreams);
866 // Ensure everything is reset even when seeking via
867 // the generated index.
870 // Try seeking to a keyframe first. If this fails (very possible),
871 // av_seek_frame will fall back to ignoring keyframes
872 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
873 && !(flags & AVSEEK_FLAG_ANY))
874 os->keyframe_seek = 1;
876 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
877 os = ogg->streams + stream_index;
879 os->keyframe_seek = 0;
883 static int ogg_probe(AVProbeData *p)
885 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
886 return AVPROBE_SCORE_MAX;
890 AVInputFormat ff_ogg_demuxer = {
892 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
893 .priv_data_size = sizeof(struct ogg),
894 .read_probe = ogg_probe,
895 .read_header = ogg_read_header,
896 .read_packet = ogg_read_packet,
897 .read_close = ogg_read_close,
898 .read_seek = ogg_read_seek,
899 .read_timestamp = ogg_read_timestamp,
901 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,