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, int discard);
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, int discard)
105 struct ogg *ogg = s->priv_data;
106 AVIOContext *bc = s->pb;
107 struct ogg_state *ost = ogg->state;
113 ogg->state = ost->next;
117 for (i = 0; i < ogg->nstreams; i++)
118 av_freep(&ogg->streams[i].buf);
120 avio_seek(bc, ost->pos, SEEK_SET);
122 ogg->curidx = ost->curidx;
123 ogg->nstreams = ost->nstreams;
124 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
125 sizeof(*ogg->streams))) < 0) {
129 memcpy(ogg->streams, ost->streams,
130 ost->nstreams * sizeof(*ogg->streams));
138 static int ogg_reset(AVFormatContext *s)
140 struct ogg *ogg = s->priv_data;
142 int64_t start_pos = avio_tell(s->pb);
144 for (i = 0; i < ogg->nstreams; i++) {
145 struct ogg_stream *os = ogg->streams + i;
150 os->lastpts = AV_NOPTS_VALUE;
151 os->lastdts = AV_NOPTS_VALUE;
158 if (start_pos <= s->internal->data_offset) {
161 os->end_trimming = 0;
162 av_freep(&os->new_metadata);
163 os->new_metadata_size = 0;
172 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
176 for (i = 0; ogg_codecs[i]; i++)
177 if (size >= ogg_codecs[i]->magicsize &&
178 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
179 return ogg_codecs[i];
185 * Replace the current stream with a new one. This is a typical webradio
186 * situation where a new audio stream spawn (identified with a new serial) and
187 * must replace the previous one (track switch).
189 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
191 struct ogg *ogg = s->priv_data;
192 struct ogg_stream *os;
193 const struct ogg_codec *codec;
196 if (s->pb->seekable) {
198 int64_t pos = avio_tell(s->pb);
199 avio_skip(s->pb, nsegs);
200 avio_read(s->pb, magic, sizeof(magic));
201 avio_seek(s->pb, pos, SEEK_SET);
202 codec = ogg_find_codec(magic, sizeof(magic));
204 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
205 return AVERROR_INVALIDDATA;
207 for (i = 0; i < ogg->nstreams; i++) {
208 if (ogg->streams[i].codec == codec)
211 if (i >= ogg->nstreams)
212 return ogg_new_stream(s, serial);
213 } else if (ogg->nstreams != 1) {
214 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
215 return AVERROR_PATCHWELCOME;
218 os = &ogg->streams[i];
225 bufsize = os->bufsize;
228 if (!ogg->state || ogg->state->streams[i].private != os->private)
229 av_freep(&ogg->streams[i].private);
231 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
232 * also re-use the ogg_stream allocated buffer */
233 memset(os, 0, sizeof(*os));
235 os->bufsize = bufsize;
244 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
246 struct ogg *ogg = s->priv_data;
247 int idx = ogg->nstreams;
249 struct ogg_stream *os;
253 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
254 "in between Ogg context save/restore operations.\n");
258 /* Allocate and init a new Ogg Stream */
259 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
260 !(os = av_realloc(ogg->streams, size)))
261 return AVERROR(ENOMEM);
263 os = ogg->streams + idx;
264 memset(os, 0, sizeof(*os));
266 os->bufsize = DECODER_BUFFER_SIZE;
267 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
269 os->start_granule = OGG_NOGRANULE_VALUE;
271 return AVERROR(ENOMEM);
273 /* Create the associated AVStream */
274 st = avformat_new_stream(s, NULL);
277 return AVERROR(ENOMEM);
280 avpriv_set_pts_info(st, 64, 1, 1000000);
286 static int ogg_new_buf(struct ogg *ogg, int idx)
288 struct ogg_stream *os = ogg->streams + idx;
289 uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
290 int size = os->bufpos - os->pstart;
293 return AVERROR(ENOMEM);
296 memcpy(nb, os->buf + os->pstart, size);
307 static int data_packets_seen(const struct ogg *ogg)
311 for (i = 0; i < ogg->nstreams; i++)
312 if (ogg->streams[i].got_data)
317 static int ogg_read_page(AVFormatContext *s, int *sid)
319 AVIOContext *bc = s->pb;
320 struct ogg *ogg = s->priv_data;
321 struct ogg_stream *os;
330 ret = avio_read(bc, sync, 4);
332 return ret < 0 ? ret : AVERROR_EOF;
337 if (sync[sp & 3] == 'O' &&
338 sync[(sp + 1) & 3] == 'g' &&
339 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
342 if(!i && bc->seekable && ogg->page_pos > 0) {
344 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
354 } while (i++ < MAX_PAGE_SIZE);
356 if (i >= MAX_PAGE_SIZE) {
357 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
358 return AVERROR_INVALIDDATA;
361 if (avio_r8(bc) != 0) { /* version */
362 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
363 return AVERROR_INVALIDDATA;
368 serial = avio_rl32(bc);
369 avio_skip(bc, 8); /* seq, crc */
372 idx = ogg_find_stream(ogg, serial);
374 if (data_packets_seen(ogg))
375 idx = ogg_replace_stream(s, serial, nsegs);
377 idx = ogg_new_stream(s, serial);
380 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
385 os = ogg->streams + idx;
387 os->page_pos = avio_tell(bc) - 27;
390 ret = ogg_new_buf(ogg, idx);
395 ret = avio_read(bc, os->segments, nsegs);
397 return ret < 0 ? ret : AVERROR_EOF;
403 for (i = 0; i < nsegs; i++)
404 size += os->segments[i];
406 if (!(flags & OGG_FLAG_BOS))
409 if (flags & OGG_FLAG_CONT || os->incomplete) {
411 // If this is the very first segment we started
412 // playback in the middle of a continuation packet.
413 // Discard it since we missed the start of it.
414 while (os->segp < os->nsegs) {
415 int seg = os->segments[os->segp++];
420 os->sync_pos = os->page_pos;
424 os->sync_pos = os->page_pos;
427 if (os->bufsize - os->bufpos < size) {
428 uint8_t *nb = av_malloc((os->bufsize *= 2) + AV_INPUT_BUFFER_PADDING_SIZE);
430 return AVERROR(ENOMEM);
431 memcpy(nb, os->buf, os->bufpos);
436 ret = avio_read(bc, os->buf + os->bufpos, size);
438 return ret < 0 ? ret : AVERROR_EOF;
444 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
452 * @brief find the next Ogg packet
453 * @param *sid is set to the stream for the packet or -1 if there is
454 * no matching stream, in that case assume all other return
455 * values to be uninitialized.
456 * @return negative value on error or EOF.
458 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
461 struct ogg *ogg = s->priv_data;
463 struct ogg_stream *os;
465 int segp = 0, psize = 0;
467 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
475 ret = ogg_read_page(s, &idx);
480 os = ogg->streams + idx;
482 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
483 idx, os->pstart, os->psize, os->segp, os->nsegs);
486 if (os->header < 0) {
487 os->codec = ogg_find_codec(os->buf, os->bufpos);
489 av_log(s, AV_LOG_WARNING, "Codec not found\n");
501 while (os->segp < os->nsegs) {
502 int ss = os->segments[os->segp++];
510 if (!complete && os->segp == os->nsegs) {
512 // Do not set incomplete for empty packets.
513 // Together with the code in ogg_read_page
514 // that discards all continuation of empty packets
515 // we would get an infinite loop.
516 os->incomplete = !!os->psize;
521 if (os->granule == -1)
522 av_log(s, AV_LOG_WARNING,
523 "Page at %"PRId64" is missing granule\n",
530 os->header = os->codec->header(s, idx);
535 // We have reached the first non-header packet in this stream.
536 // Unfortunately more header packets may still follow for others,
537 // but if we continue with header parsing we may lose data packets.
540 // Update the header state for all streams and
541 // compute the data_offset.
542 if (!s->internal->data_offset)
543 s->internal->data_offset = os->sync_pos;
545 for (i = 0; i < ogg->nstreams; i++) {
546 struct ogg_stream *cur_os = ogg->streams + i;
548 // if we have a partial non-header packet, its start is
549 // obviously at or after the data start
550 if (cur_os->incomplete)
551 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
555 os->pstart += os->psize;
561 if (os->codec && os->codec->packet)
562 os->codec->packet(s, idx);
566 *dstart = os->pstart;
570 *fpos = os->sync_pos;
571 os->pstart += os->psize;
573 if(os->pstart == os->bufpos)
574 os->bufpos = os->pstart = 0;
575 os->sync_pos = os->page_pos;
578 // determine whether there are more complete packets in this page
579 // if not, the page's granule will apply to this packet
581 for (i = os->segp; i < os->nsegs; i++)
582 if (os->segments[i] < 255) {
587 if (os->segp == os->nsegs)
593 static int ogg_get_length(AVFormatContext *s)
595 struct ogg *ogg = s->priv_data;
600 if (!s->pb->seekable)
604 if (s->duration != AV_NOPTS_VALUE)
607 size = avio_size(s->pb);
610 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
615 avio_seek(s->pb, end, SEEK_SET);
618 while (!ogg_read_page(s, &i)) {
619 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
620 ogg->streams[i].codec) {
621 s->streams[i]->duration =
622 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
623 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
624 s->streams[i]->duration -= s->streams[i]->start_time;
625 streams_left-= (ogg->streams[i].got_start==-1);
626 ogg->streams[i].got_start= 1;
627 } else if(!ogg->streams[i].got_start) {
628 ogg->streams[i].got_start= -1;
640 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
642 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
645 pts = ogg_calc_pts(s, i, NULL);
646 if (s->streams[i]->duration == AV_NOPTS_VALUE)
648 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
649 s->streams[i]->duration -= pts;
650 ogg->streams[i].got_start= 1;
652 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
653 ogg->streams[i].got_start= 1;
662 static int ogg_read_close(AVFormatContext *s)
664 struct ogg *ogg = s->priv_data;
667 for (i = 0; i < ogg->nstreams; i++) {
668 av_freep(&ogg->streams[i].buf);
669 if (ogg->streams[i].codec &&
670 ogg->streams[i].codec->cleanup) {
671 ogg->streams[i].codec->cleanup(s, i);
673 av_freep(&ogg->streams[i].private);
674 av_freep(&ogg->streams[i].new_metadata);
679 av_freep(&ogg->streams);
683 static int ogg_read_header(AVFormatContext *s)
685 struct ogg *ogg = s->priv_data;
690 //linear headers seek from start
692 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
697 } while (!ogg->headers);
698 av_log(s, AV_LOG_TRACE, "found headers\n");
700 for (i = 0; i < ogg->nstreams; i++) {
701 struct ogg_stream *os = ogg->streams + i;
703 if (ogg->streams[i].header < 0) {
704 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
705 ogg->streams[i].codec = NULL;
706 av_freep(&ogg->streams[i].private);
707 } else if (os->codec && os->nb_header < os->codec->nb_header) {
708 av_log(s, AV_LOG_WARNING,
709 "Headers mismatch for stream %d: "
710 "expected %d received %d.\n",
711 i, os->codec->nb_header, os->nb_header);
712 if (s->error_recognition & AV_EF_EXPLODE)
713 return AVERROR_INVALIDDATA;
715 if (os->start_granule != OGG_NOGRANULE_VALUE)
716 os->lastpts = s->streams[i]->start_time =
717 ogg_gptopts(s, i, os->start_granule, NULL);
720 //linear granulepos seek from end
721 ret = ogg_get_length(s);
730 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
732 struct ogg *ogg = s->priv_data;
733 struct ogg_stream *os = ogg->streams + idx;
734 int64_t pts = AV_NOPTS_VALUE;
737 *dts = AV_NOPTS_VALUE;
739 if (os->lastpts != AV_NOPTS_VALUE) {
741 os->lastpts = AV_NOPTS_VALUE;
743 if (os->lastdts != AV_NOPTS_VALUE) {
746 os->lastdts = AV_NOPTS_VALUE;
749 if (os->granule != -1LL) {
750 if (os->codec && os->codec->granule_is_start)
751 pts = ogg_gptopts(s, idx, os->granule, dts);
753 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
760 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
762 struct ogg *ogg = s->priv_data;
763 struct ogg_stream *os = ogg->streams + idx;
766 switch (s->streams[idx]->codecpar->codec_id) {
767 case AV_CODEC_ID_THEORA:
768 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
770 case AV_CODEC_ID_VP8:
771 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
774 os->pflags ^= AV_PKT_FLAG_KEY;
775 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
776 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
781 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
784 struct ogg_stream *os;
787 int64_t fpos, pts, dts;
789 if (s->io_repositioned) {
791 s->io_repositioned = 0;
797 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
800 } while (idx < 0 || !s->streams[idx]);
803 os = ogg->streams + idx;
805 // pflags might not be set until after this
806 pts = ogg_calc_pts(s, idx, &dts);
807 ogg_validate_keyframe(s, idx, pstart, psize);
809 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
811 os->keyframe_seek = 0;
814 ret = av_new_packet(pkt, psize);
817 pkt->stream_index = idx;
818 memcpy(pkt->data, os->buf + pstart, psize);
822 pkt->flags = os->pflags;
823 pkt->duration = os->pduration;
826 if (os->end_trimming) {
827 uint8_t *side_data = av_packet_new_side_data(pkt,
828 AV_PKT_DATA_SKIP_SAMPLES,
832 AV_WL32(side_data + 4, os->end_trimming);
833 os->end_trimming = 0;
836 if (os->new_metadata) {
837 uint8_t *side_data = av_packet_new_side_data(pkt,
838 AV_PKT_DATA_METADATA_UPDATE,
839 os->new_metadata_size);
843 memcpy(side_data, os->new_metadata, os->new_metadata_size);
844 av_freep(&os->new_metadata);
845 os->new_metadata_size = 0;
850 av_packet_unref(pkt);
851 return AVERROR(ENOMEM);
854 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
855 int64_t *pos_arg, int64_t pos_limit)
857 struct ogg *ogg = s->priv_data;
858 AVIOContext *bc = s->pb;
859 int64_t pts = AV_NOPTS_VALUE;
863 avio_seek(bc, *pos_arg, SEEK_SET);
866 while ( avio_tell(bc) <= pos_limit
867 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
868 if (i == stream_index) {
869 struct ogg_stream *os = ogg->streams + stream_index;
870 // Do not trust the last timestamps of an ogm video
871 if ( (os->flags & OGG_FLAG_EOS)
872 && !(os->flags & OGG_FLAG_BOS)
873 && os->codec == &ff_ogm_video_codec)
875 pts = ogg_calc_pts(s, i, NULL);
876 ogg_validate_keyframe(s, i, pstart, psize);
877 if (os->pflags & AV_PKT_FLAG_KEY) {
879 } else if (os->keyframe_seek) {
880 // if we had a previous keyframe but no pts for it,
881 // return that keyframe with this pts value.
885 pts = AV_NOPTS_VALUE;
888 if (pts != AV_NOPTS_VALUE)
895 static int ogg_read_seek(AVFormatContext *s, int stream_index,
896 int64_t timestamp, int flags)
898 struct ogg *ogg = s->priv_data;
899 struct ogg_stream *os = ogg->streams + stream_index;
902 av_assert0(stream_index < ogg->nstreams);
903 // Ensure everything is reset even when seeking via
904 // the generated index.
907 // Try seeking to a keyframe first. If this fails (very possible),
908 // av_seek_frame will fall back to ignoring keyframes
909 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
910 && !(flags & AVSEEK_FLAG_ANY))
911 os->keyframe_seek = 1;
913 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
915 os = ogg->streams + stream_index;
917 os->keyframe_seek = 0;
921 static int ogg_probe(AVProbeData *p)
923 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
924 return AVPROBE_SCORE_MAX;
928 AVInputFormat ff_ogg_demuxer = {
930 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
931 .priv_data_size = sizeof(struct ogg),
932 .read_probe = ogg_probe,
933 .read_header = ogg_read_header,
934 .read_packet = ogg_read_packet,
935 .read_close = ogg_read_close,
936 .read_seek = ogg_read_seek,
937 .read_timestamp = ogg_read_timestamp,
939 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,