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));
73 return AVERROR(ENOMEM);
75 ost->pos = avio_tell(s->pb);
76 ost->curidx = ogg->curidx;
77 ost->next = ogg->state;
78 ost->nstreams = ogg->nstreams;
79 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
81 for (i = 0; i < ogg->nstreams; i++) {
82 struct ogg_stream *os = ogg->streams + i;
83 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
84 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
85 os->new_metadata = NULL;
86 os->new_metadata_size = 0;
94 static int ogg_restore(AVFormatContext *s, int discard)
96 struct ogg *ogg = s->priv_data;
97 AVIOContext *bc = s->pb;
98 struct ogg_state *ost = ogg->state;
104 ogg->state = ost->next;
108 for (i = 0; i < ogg->nstreams; i++)
109 av_freep(&ogg->streams[i].buf);
111 avio_seek(bc, ost->pos, SEEK_SET);
113 ogg->curidx = ost->curidx;
114 ogg->nstreams = ost->nstreams;
115 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
116 sizeof(*ogg->streams))) < 0) {
120 memcpy(ogg->streams, ost->streams,
121 ost->nstreams * sizeof(*ogg->streams));
129 static int ogg_reset(AVFormatContext *s)
131 struct ogg *ogg = s->priv_data;
133 int64_t start_pos = avio_tell(s->pb);
135 for (i = 0; i < ogg->nstreams; i++) {
136 struct ogg_stream *os = ogg->streams + i;
141 os->lastpts = AV_NOPTS_VALUE;
142 os->lastdts = AV_NOPTS_VALUE;
149 if (start_pos <= s->internal->data_offset) {
152 os->end_trimming = 0;
153 av_freep(&os->new_metadata);
154 os->new_metadata_size = 0;
163 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
167 for (i = 0; ogg_codecs[i]; i++)
168 if (size >= ogg_codecs[i]->magicsize &&
169 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
170 return ogg_codecs[i];
176 * Replace the current stream with a new one. This is a typical webradio
177 * situation where a new audio stream spawn (identified with a new serial) and
178 * must replace the previous one (track switch).
180 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
182 struct ogg *ogg = s->priv_data;
183 struct ogg_stream *os;
184 const struct ogg_codec *codec;
187 if (s->pb->seekable) {
189 int64_t pos = avio_tell(s->pb);
190 avio_skip(s->pb, nsegs);
191 avio_read(s->pb, magic, sizeof(magic));
192 avio_seek(s->pb, pos, SEEK_SET);
193 codec = ogg_find_codec(magic, sizeof(magic));
195 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
196 return AVERROR_INVALIDDATA;
198 for (i = 0; i < ogg->nstreams; i++) {
199 if (ogg->streams[i].codec == codec)
202 if (i >= ogg->nstreams)
203 return ogg_new_stream(s, serial);
204 } else if (ogg->nstreams != 1) {
205 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
206 return AVERROR_PATCHWELCOME;
209 os = &ogg->streams[i];
216 bufsize = os->bufsize;
219 if (!ogg->state || ogg->state->streams[i].private != os->private)
220 av_freep(&ogg->streams[i].private);
222 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
223 * also re-use the ogg_stream allocated buffer */
224 memset(os, 0, sizeof(*os));
226 os->bufsize = bufsize;
235 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
237 struct ogg *ogg = s->priv_data;
238 int idx = ogg->nstreams;
240 struct ogg_stream *os;
244 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
245 "in between Ogg context save/restore operations.\n");
249 /* Allocate and init a new Ogg Stream */
250 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
251 !(os = av_realloc(ogg->streams, size)))
252 return AVERROR(ENOMEM);
254 os = ogg->streams + idx;
255 memset(os, 0, sizeof(*os));
257 os->bufsize = DECODER_BUFFER_SIZE;
258 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
260 os->start_granule = OGG_NOGRANULE_VALUE;
262 return AVERROR(ENOMEM);
264 /* Create the associated AVStream */
265 st = avformat_new_stream(s, NULL);
268 return AVERROR(ENOMEM);
271 avpriv_set_pts_info(st, 64, 1, 1000000);
277 static int ogg_new_buf(struct ogg *ogg, int idx)
279 struct ogg_stream *os = ogg->streams + idx;
280 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
281 int size = os->bufpos - os->pstart;
284 return AVERROR(ENOMEM);
287 memcpy(nb, os->buf + os->pstart, size);
298 static int data_packets_seen(const struct ogg *ogg)
302 for (i = 0; i < ogg->nstreams; i++)
303 if (ogg->streams[i].got_data)
308 static int ogg_read_page(AVFormatContext *s, int *sid)
310 AVIOContext *bc = s->pb;
311 struct ogg *ogg = s->priv_data;
312 struct ogg_stream *os;
321 ret = avio_read(bc, sync, 4);
323 return ret < 0 ? ret : AVERROR_EOF;
328 if (sync[sp & 3] == 'O' &&
329 sync[(sp + 1) & 3] == 'g' &&
330 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
333 if(!i && bc->seekable && ogg->page_pos > 0) {
335 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
345 } while (i++ < MAX_PAGE_SIZE);
347 if (i >= MAX_PAGE_SIZE) {
348 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
349 return AVERROR_INVALIDDATA;
352 if (avio_r8(bc) != 0) { /* version */
353 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
354 return AVERROR_INVALIDDATA;
359 serial = avio_rl32(bc);
360 avio_skip(bc, 8); /* seq, crc */
363 idx = ogg_find_stream(ogg, serial);
365 if (data_packets_seen(ogg))
366 idx = ogg_replace_stream(s, serial, nsegs);
368 idx = ogg_new_stream(s, serial);
371 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
376 os = ogg->streams + idx;
378 os->page_pos = avio_tell(bc) - 27;
381 ret = ogg_new_buf(ogg, idx);
386 ret = avio_read(bc, os->segments, nsegs);
388 return ret < 0 ? ret : AVERROR_EOF;
394 for (i = 0; i < nsegs; i++)
395 size += os->segments[i];
397 if (!(flags & OGG_FLAG_BOS))
400 if (flags & OGG_FLAG_CONT || os->incomplete) {
402 // If this is the very first segment we started
403 // playback in the middle of a continuation packet.
404 // Discard it since we missed the start of it.
405 while (os->segp < os->nsegs) {
406 int seg = os->segments[os->segp++];
411 os->sync_pos = os->page_pos;
415 os->sync_pos = os->page_pos;
418 if (os->bufsize - os->bufpos < size) {
419 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
421 return AVERROR(ENOMEM);
422 memcpy(nb, os->buf, os->bufpos);
427 ret = avio_read(bc, os->buf + os->bufpos, size);
429 return ret < 0 ? ret : AVERROR_EOF;
435 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
443 * @brief find the next Ogg packet
444 * @param *sid is set to the stream for the packet or -1 if there is
445 * no matching stream, in that case assume all other return
446 * values to be uninitialized.
447 * @return negative value on error or EOF.
449 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
452 struct ogg *ogg = s->priv_data;
454 struct ogg_stream *os;
456 int segp = 0, psize = 0;
458 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
466 ret = ogg_read_page(s, &idx);
471 os = ogg->streams + idx;
473 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
474 idx, os->pstart, os->psize, os->segp, os->nsegs);
477 if (os->header < 0) {
478 os->codec = ogg_find_codec(os->buf, os->bufpos);
480 av_log(s, AV_LOG_WARNING, "Codec not found\n");
492 while (os->segp < os->nsegs) {
493 int ss = os->segments[os->segp++];
501 if (!complete && os->segp == os->nsegs) {
503 // Do not set incomplete for empty packets.
504 // Together with the code in ogg_read_page
505 // that discards all continuation of empty packets
506 // we would get an infinite loop.
507 os->incomplete = !!os->psize;
512 if (os->granule == -1)
513 av_log(s, AV_LOG_WARNING,
514 "Page at %"PRId64" is missing granule\n",
521 os->header = os->codec->header(s, idx);
526 // We have reached the first non-header packet in this stream.
527 // Unfortunately more header packets may still follow for others,
528 // but if we continue with header parsing we may lose data packets.
531 // Update the header state for all streams and
532 // compute the data_offset.
533 if (!s->internal->data_offset)
534 s->internal->data_offset = os->sync_pos;
536 for (i = 0; i < ogg->nstreams; i++) {
537 struct ogg_stream *cur_os = ogg->streams + i;
539 // if we have a partial non-header packet, its start is
540 // obviously at or after the data start
541 if (cur_os->incomplete)
542 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
546 os->pstart += os->psize;
552 if (os->codec && os->codec->packet)
553 os->codec->packet(s, idx);
557 *dstart = os->pstart;
561 *fpos = os->sync_pos;
562 os->pstart += os->psize;
564 if(os->pstart == os->bufpos)
565 os->bufpos = os->pstart = 0;
566 os->sync_pos = os->page_pos;
569 // determine whether there are more complete packets in this page
570 // if not, the page's granule will apply to this packet
572 for (i = os->segp; i < os->nsegs; i++)
573 if (os->segments[i] < 255) {
578 if (os->segp == os->nsegs)
584 static int ogg_get_length(AVFormatContext *s)
586 struct ogg *ogg = s->priv_data;
591 if (!s->pb->seekable)
595 if (s->duration != AV_NOPTS_VALUE)
598 size = avio_size(s->pb);
601 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
606 avio_seek(s->pb, end, SEEK_SET);
609 while (!ogg_read_page(s, &i)) {
610 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
611 ogg->streams[i].codec) {
612 s->streams[i]->duration =
613 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
614 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
615 s->streams[i]->duration -= s->streams[i]->start_time;
616 streams_left-= (ogg->streams[i].got_start==-1);
617 ogg->streams[i].got_start= 1;
618 } else if(!ogg->streams[i].got_start) {
619 ogg->streams[i].got_start= -1;
631 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
633 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
636 pts = ogg_calc_pts(s, i, NULL);
637 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
638 s->streams[i]->duration -= pts;
639 ogg->streams[i].got_start= 1;
641 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
642 ogg->streams[i].got_start= 1;
651 static int ogg_read_close(AVFormatContext *s)
653 struct ogg *ogg = s->priv_data;
656 for (i = 0; i < ogg->nstreams; i++) {
657 av_freep(&ogg->streams[i].buf);
658 if (ogg->streams[i].codec &&
659 ogg->streams[i].codec->cleanup) {
660 ogg->streams[i].codec->cleanup(s, i);
662 av_freep(&ogg->streams[i].private);
663 av_freep(&ogg->streams[i].new_metadata);
668 av_freep(&ogg->streams);
672 static int ogg_read_header(AVFormatContext *s)
674 struct ogg *ogg = s->priv_data;
679 //linear headers seek from start
681 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
686 } while (!ogg->headers);
687 av_log(s, AV_LOG_TRACE, "found headers\n");
689 for (i = 0; i < ogg->nstreams; i++) {
690 struct ogg_stream *os = ogg->streams + i;
692 if (ogg->streams[i].header < 0) {
693 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
694 ogg->streams[i].codec = NULL;
695 } else if (os->codec && os->nb_header < os->codec->nb_header) {
696 av_log(s, AV_LOG_WARNING,
697 "Headers mismatch for stream %d: "
698 "expected %d received %d.\n",
699 i, os->codec->nb_header, os->nb_header);
700 if (s->error_recognition & AV_EF_EXPLODE)
701 return AVERROR_INVALIDDATA;
703 if (os->start_granule != OGG_NOGRANULE_VALUE)
704 os->lastpts = s->streams[i]->start_time =
705 ogg_gptopts(s, i, os->start_granule, NULL);
708 //linear granulepos seek from end
709 ret = ogg_get_length(s);
718 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
720 struct ogg *ogg = s->priv_data;
721 struct ogg_stream *os = ogg->streams + idx;
722 int64_t pts = AV_NOPTS_VALUE;
725 *dts = AV_NOPTS_VALUE;
727 if (os->lastpts != AV_NOPTS_VALUE) {
729 os->lastpts = AV_NOPTS_VALUE;
731 if (os->lastdts != AV_NOPTS_VALUE) {
734 os->lastdts = AV_NOPTS_VALUE;
737 if (os->granule != -1LL) {
738 if (os->codec && os->codec->granule_is_start)
739 pts = ogg_gptopts(s, idx, os->granule, dts);
741 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
748 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
750 struct ogg *ogg = s->priv_data;
751 struct ogg_stream *os = ogg->streams + idx;
754 switch (s->streams[idx]->codec->codec_id) {
755 case AV_CODEC_ID_THEORA:
756 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
758 case AV_CODEC_ID_VP8:
759 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
762 os->pflags ^= AV_PKT_FLAG_KEY;
763 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
764 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
769 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
772 struct ogg_stream *os;
775 int64_t fpos, pts, dts;
777 if (s->io_repositioned) {
779 s->io_repositioned = 0;
785 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
788 } while (idx < 0 || !s->streams[idx]);
791 os = ogg->streams + idx;
793 // pflags might not be set until after this
794 pts = ogg_calc_pts(s, idx, &dts);
795 ogg_validate_keyframe(s, idx, pstart, psize);
797 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
799 os->keyframe_seek = 0;
802 ret = av_new_packet(pkt, psize);
805 pkt->stream_index = idx;
806 memcpy(pkt->data, os->buf + pstart, psize);
810 pkt->flags = os->pflags;
811 pkt->duration = os->pduration;
814 if (os->end_trimming) {
815 uint8_t *side_data = av_packet_new_side_data(pkt,
816 AV_PKT_DATA_SKIP_SAMPLES,
820 AV_WL32(side_data + 4, os->end_trimming);
821 os->end_trimming = 0;
824 if (os->new_metadata) {
825 uint8_t *side_data = av_packet_new_side_data(pkt,
826 AV_PKT_DATA_METADATA_UPDATE,
827 os->new_metadata_size);
831 memcpy(side_data, os->new_metadata, os->new_metadata_size);
832 av_freep(&os->new_metadata);
833 os->new_metadata_size = 0;
839 return AVERROR(ENOMEM);
842 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
843 int64_t *pos_arg, int64_t pos_limit)
845 struct ogg *ogg = s->priv_data;
846 AVIOContext *bc = s->pb;
847 int64_t pts = AV_NOPTS_VALUE;
851 avio_seek(bc, *pos_arg, SEEK_SET);
854 while ( avio_tell(bc) <= pos_limit
855 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
856 if (i == stream_index) {
857 struct ogg_stream *os = ogg->streams + stream_index;
858 // Do not trust the last timestamps of a ogm video
859 if ( (os->flags & OGG_FLAG_EOS)
860 && !(os->flags & OGG_FLAG_BOS)
861 && os->codec == &ff_ogm_video_codec)
863 pts = ogg_calc_pts(s, i, NULL);
864 ogg_validate_keyframe(s, i, pstart, psize);
865 if (os->pflags & AV_PKT_FLAG_KEY) {
867 } else if (os->keyframe_seek) {
868 // if we had a previous keyframe but no pts for it,
869 // return that keyframe with this pts value.
873 pts = AV_NOPTS_VALUE;
876 if (pts != AV_NOPTS_VALUE)
883 static int ogg_read_seek(AVFormatContext *s, int stream_index,
884 int64_t timestamp, int flags)
886 struct ogg *ogg = s->priv_data;
887 struct ogg_stream *os = ogg->streams + stream_index;
890 av_assert0(stream_index < ogg->nstreams);
891 // Ensure everything is reset even when seeking via
892 // the generated index.
895 // Try seeking to a keyframe first. If this fails (very possible),
896 // av_seek_frame will fall back to ignoring keyframes
897 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
898 && !(flags & AVSEEK_FLAG_ANY))
899 os->keyframe_seek = 1;
901 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
902 os = ogg->streams + stream_index;
904 os->keyframe_seek = 0;
908 static int ogg_probe(AVProbeData *p)
910 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
911 return AVPROBE_SCORE_MAX;
915 AVInputFormat ff_ogg_demuxer = {
917 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
918 .priv_data_size = sizeof(struct ogg),
919 .read_probe = ogg_probe,
920 .read_header = ogg_read_header,
921 .read_packet = ogg_read_packet,
922 .read_close = ogg_read_close,
923 .read_seek = ogg_read_seek,
924 .read_timestamp = ogg_read_timestamp,
926 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,