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"
34 #include "avio_internal.h"
38 #include "vorbiscomment.h"
40 #define MAX_PAGE_SIZE 65307
41 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
43 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 static void free_stream(AVFormatContext *s, int i)
68 struct ogg *ogg = s->priv_data;
69 struct ogg_stream *stream = &ogg->streams[i];
71 av_freep(&stream->buf);
73 stream->codec->cleanup) {
74 stream->codec->cleanup(s, i);
77 av_freep(&stream->private);
78 av_freep(&stream->new_metadata);
81 //FIXME We could avoid some structure duplication
82 static int ogg_save(AVFormatContext *s)
84 struct ogg *ogg = s->priv_data;
85 struct ogg_state *ost =
86 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
91 return AVERROR(ENOMEM);
93 ost->pos = avio_tell(s->pb);
94 ost->curidx = ogg->curidx;
95 ost->next = ogg->state;
96 ost->nstreams = ogg->nstreams;
97 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
99 for (i = 0; i < ogg->nstreams; i++) {
100 struct ogg_stream *os = ogg->streams + i;
101 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
103 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
105 ret = AVERROR(ENOMEM);
106 os->new_metadata = NULL;
107 os->new_metadata_size = 0;
118 static int ogg_restore(AVFormatContext *s)
120 struct ogg *ogg = s->priv_data;
121 AVIOContext *bc = s->pb;
122 struct ogg_state *ost = ogg->state;
128 ogg->state = ost->next;
130 for (i = 0; i < ogg->nstreams; i++) {
131 struct ogg_stream *stream = &ogg->streams[i];
132 av_freep(&stream->buf);
133 av_freep(&stream->new_metadata);
135 if (i >= ost->nstreams || !ost->streams[i].private) {
140 avio_seek(bc, ost->pos, SEEK_SET);
142 ogg->curidx = ost->curidx;
143 ogg->nstreams = ost->nstreams;
144 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
145 sizeof(*ogg->streams))) < 0) {
149 memcpy(ogg->streams, ost->streams,
150 ost->nstreams * sizeof(*ogg->streams));
157 static int ogg_reset(AVFormatContext *s)
159 struct ogg *ogg = s->priv_data;
161 int64_t start_pos = avio_tell(s->pb);
163 for (i = 0; i < ogg->nstreams; i++) {
164 struct ogg_stream *os = ogg->streams + i;
169 os->lastpts = AV_NOPTS_VALUE;
170 os->lastdts = AV_NOPTS_VALUE;
177 if (start_pos <= s->internal->data_offset) {
180 os->start_trimming = 0;
181 os->end_trimming = 0;
182 av_freep(&os->new_metadata);
183 os->new_metadata_size = 0;
192 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
196 for (i = 0; ogg_codecs[i]; i++)
197 if (size >= ogg_codecs[i]->magicsize &&
198 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
199 return ogg_codecs[i];
205 * Replace the current stream with a new one. This is a typical webradio
206 * situation where a new audio stream spawn (identified with a new serial) and
207 * must replace the previous one (track switch).
209 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic,
212 struct ogg *ogg = s->priv_data;
213 struct ogg_stream *os;
214 const struct ogg_codec *codec;
217 if (ogg->nstreams != 1) {
218 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
219 return AVERROR_PATCHWELCOME;
222 /* Check for codecs */
223 codec = ogg_find_codec(magic, 8);
224 if (!codec && !probing) {
225 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
226 return AVERROR_INVALIDDATA;
229 /* We only have a single stream anyway, so if there's a new stream with
230 * a different codec just replace it */
231 os = &ogg->streams[0];
237 os->start_trimming = 0;
238 os->end_trimming = 0;
240 /* Chained files have extradata as a new packet */
241 if (codec == &ff_opus_codec)
247 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
249 struct ogg *ogg = s->priv_data;
250 int idx = ogg->nstreams;
252 struct ogg_stream *os;
256 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
257 "in between Ogg context save/restore operations.\n");
261 /* Allocate and init a new Ogg Stream */
262 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
263 !(os = av_realloc(ogg->streams, size)))
264 return AVERROR(ENOMEM);
266 os = ogg->streams + idx;
267 memset(os, 0, sizeof(*os));
269 os->bufsize = DECODER_BUFFER_SIZE;
270 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
272 os->start_granule = OGG_NOGRANULE_VALUE;
274 return AVERROR(ENOMEM);
276 /* Create the associated AVStream */
277 st = avformat_new_stream(s, NULL);
280 return AVERROR(ENOMEM);
283 avpriv_set_pts_info(st, 64, 1, 1000000);
289 static int data_packets_seen(const struct ogg *ogg)
293 for (i = 0; i < ogg->nstreams; i++)
294 if (ogg->streams[i].got_data)
299 static int buf_realloc(struct ogg_stream *os, int size)
301 /* Even if invalid guarantee there's enough memory to read the page */
302 if (os->bufsize - os->bufpos < size) {
303 uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
305 return AVERROR(ENOMEM);
313 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
315 AVIOContext *bc = s->pb;
316 struct ogg *ogg = s->priv_data;
317 struct ogg_stream *os;
322 uint32_t crc, crc_tmp;
324 int64_t version, page_pos;
327 uint8_t segments[255];
328 uint8_t *readout_buf;
331 ret = avio_read(bc, sync, 4);
333 return ret < 0 ? ret : AVERROR_EOF;
338 if (sync[sp & 3] == 'O' &&
339 sync[(sp + 1) & 3] == 'g' &&
340 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
343 if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
345 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
355 } while (i++ < MAX_PAGE_SIZE);
357 if (i >= MAX_PAGE_SIZE) {
358 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
359 return AVERROR_INVALIDDATA;
362 /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
363 ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
365 /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
366 ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
367 start_pos = avio_tell(bc);
369 version = avio_r8(bc);
372 serial = avio_rl32(bc);
373 avio_skip(bc, 4); /* seq */
375 crc_tmp = ffio_get_checksum(bc);
377 crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
378 ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
381 page_pos = avio_tell(bc) - 27;
383 ret = avio_read(bc, segments, nsegs);
385 return ret < 0 ? ret : AVERROR_EOF;
387 for (i = 0; i < nsegs; i++)
390 idx = ogg_find_stream(ogg, serial);
392 os = ogg->streams + idx;
394 ret = buf_realloc(os, size);
398 readout_buf = os->buf + os->bufpos;
400 readout_buf = av_malloc(size);
403 ret = avio_read(bc, readout_buf, size);
406 av_free(readout_buf);
407 return ret < 0 ? ret : AVERROR_EOF;
410 if (crc ^ ffio_get_checksum(bc)) {
411 av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
413 av_free(readout_buf);
414 avio_seek(bc, start_pos, SEEK_SET);
418 /* Since we're almost sure its a valid packet, checking the version after
419 * the checksum lets the demuxer be more tolerant */
421 av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
423 av_free(readout_buf);
424 avio_seek(bc, start_pos, SEEK_SET);
428 /* CRC is correct so we can be 99% sure there's an actual change here */
430 if (data_packets_seen(ogg))
431 idx = ogg_replace_stream(s, serial, readout_buf, probing);
433 idx = ogg_new_stream(s, serial);
436 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
437 av_free(readout_buf);
441 os = ogg->streams + idx;
443 ret = buf_realloc(os, size);
445 av_free(readout_buf);
449 memcpy(os->buf + os->bufpos, readout_buf, size);
450 av_free(readout_buf);
453 ogg->page_pos = page_pos;
454 os->page_pos = page_pos;
457 os->got_data = !(flags & OGG_FLAG_BOS);
461 memcpy(os->segments, segments, nsegs);
462 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
464 if (flags & OGG_FLAG_CONT || os->incomplete) {
466 // If this is the very first segment we started
467 // playback in the middle of a continuation packet.
468 // Discard it since we missed the start of it.
469 while (os->segp < os->nsegs) {
470 int seg = os->segments[os->segp++];
475 os->sync_pos = os->page_pos;
479 os->sync_pos = os->page_pos;
482 /* This function is always called with sid != NULL */
489 * @brief find the next Ogg packet
490 * @param *sid is set to the stream for the packet or -1 if there is
491 * no matching stream, in that case assume all other return
492 * values to be uninitialized.
493 * @return negative value on error or EOF.
495 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
498 struct ogg *ogg = s->priv_data;
500 struct ogg_stream *os;
502 int segp = 0, psize = 0;
504 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
512 ret = ogg_read_page(s, &idx, 0);
517 os = ogg->streams + idx;
519 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
520 idx, os->pstart, os->psize, os->segp, os->nsegs);
523 if (os->header < 0) {
524 os->codec = ogg_find_codec(os->buf, os->bufpos);
526 av_log(s, AV_LOG_WARNING, "Codec not found\n");
538 while (os->segp < os->nsegs) {
539 int ss = os->segments[os->segp++];
547 if (!complete && os->segp == os->nsegs) {
549 // Do not set incomplete for empty packets.
550 // Together with the code in ogg_read_page
551 // that discards all continuation of empty packets
552 // we would get an infinite loop.
553 os->incomplete = !!os->psize;
558 if (os->granule == -1)
559 av_log(s, AV_LOG_WARNING,
560 "Page at %"PRId64" is missing granule\n",
567 if ((ret = os->codec->header(s, idx)) < 0) {
568 av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
576 // We have reached the first non-header packet in this stream.
577 // Unfortunately more header packets may still follow for others,
578 // but if we continue with header parsing we may lose data packets.
581 // Update the header state for all streams and
582 // compute the data_offset.
583 if (!s->internal->data_offset)
584 s->internal->data_offset = os->sync_pos;
586 for (i = 0; i < ogg->nstreams; i++) {
587 struct ogg_stream *cur_os = ogg->streams + i;
589 // if we have a partial non-header packet, its start is
590 // obviously at or after the data start
591 if (cur_os->incomplete)
592 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
596 os->pstart += os->psize;
602 if (os->codec && os->codec->packet) {
603 if ((ret = os->codec->packet(s, idx)) < 0) {
604 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
611 *dstart = os->pstart;
615 *fpos = os->sync_pos;
616 os->pstart += os->psize;
618 if(os->pstart == os->bufpos)
619 os->bufpos = os->pstart = 0;
620 os->sync_pos = os->page_pos;
623 // determine whether there are more complete packets in this page
624 // if not, the page's granule will apply to this packet
626 for (i = os->segp; i < os->nsegs; i++)
627 if (os->segments[i] < 255) {
632 if (os->segp == os->nsegs)
638 static int ogg_get_length(AVFormatContext *s)
640 struct ogg *ogg = s->priv_data;
645 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
649 if (s->duration != AV_NOPTS_VALUE)
652 size = avio_size(s->pb);
655 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
660 avio_seek(s->pb, end, SEEK_SET);
663 while (!ogg_read_page(s, &i, 1)) {
664 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
665 ogg->streams[i].codec) {
666 s->streams[i]->duration =
667 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
668 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
669 s->streams[i]->duration -= s->streams[i]->start_time;
670 streams_left-= (ogg->streams[i].got_start==-1);
671 ogg->streams[i].got_start= 1;
672 } else if(!ogg->streams[i].got_start) {
673 ogg->streams[i].got_start= -1;
685 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
687 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
690 pts = ogg_calc_pts(s, i, NULL);
691 if (s->streams[i]->duration == AV_NOPTS_VALUE)
693 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
694 s->streams[i]->duration -= pts;
695 ogg->streams[i].got_start= 1;
697 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
698 ogg->streams[i].got_start= 1;
707 static int ogg_read_close(AVFormatContext *s)
709 struct ogg *ogg = s->priv_data;
712 for (i = 0; i < ogg->nstreams; i++) {
718 av_freep(&ogg->streams);
722 static int ogg_read_header(AVFormatContext *s)
724 struct ogg *ogg = s->priv_data;
729 //linear headers seek from start
731 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
736 } while (!ogg->headers);
737 av_log(s, AV_LOG_TRACE, "found headers\n");
739 for (i = 0; i < ogg->nstreams; i++) {
740 struct ogg_stream *os = ogg->streams + i;
742 if (ogg->streams[i].header < 0) {
743 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
744 ogg->streams[i].codec = NULL;
745 av_freep(&ogg->streams[i].private);
746 } else if (os->codec && os->nb_header < os->codec->nb_header) {
747 av_log(s, AV_LOG_WARNING,
748 "Headers mismatch for stream %d: "
749 "expected %d received %d.\n",
750 i, os->codec->nb_header, os->nb_header);
751 if (s->error_recognition & AV_EF_EXPLODE) {
753 return AVERROR_INVALIDDATA;
756 if (os->start_granule != OGG_NOGRANULE_VALUE)
757 os->lastpts = s->streams[i]->start_time =
758 ogg_gptopts(s, i, os->start_granule, NULL);
761 //linear granulepos seek from end
762 ret = ogg_get_length(s);
771 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
773 struct ogg *ogg = s->priv_data;
774 struct ogg_stream *os = ogg->streams + idx;
775 int64_t pts = AV_NOPTS_VALUE;
778 *dts = AV_NOPTS_VALUE;
780 if (os->lastpts != AV_NOPTS_VALUE) {
782 os->lastpts = AV_NOPTS_VALUE;
784 if (os->lastdts != AV_NOPTS_VALUE) {
787 os->lastdts = AV_NOPTS_VALUE;
790 if (os->granule != -1LL) {
791 if (os->codec && os->codec->granule_is_start)
792 pts = ogg_gptopts(s, idx, os->granule, dts);
794 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
801 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
803 struct ogg *ogg = s->priv_data;
804 struct ogg_stream *os = ogg->streams + idx;
807 switch (s->streams[idx]->codecpar->codec_id) {
808 case AV_CODEC_ID_THEORA:
809 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
811 case AV_CODEC_ID_VP8:
812 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
815 os->pflags ^= AV_PKT_FLAG_KEY;
816 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
817 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
822 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
825 struct ogg_stream *os;
828 int64_t fpos, pts, dts;
830 if (s->io_repositioned) {
832 s->io_repositioned = 0;
838 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
841 } while (idx < 0 || !s->streams[idx]);
844 os = ogg->streams + idx;
846 // pflags might not be set until after this
847 pts = ogg_calc_pts(s, idx, &dts);
848 ogg_validate_keyframe(s, idx, pstart, psize);
850 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
852 os->keyframe_seek = 0;
855 ret = av_new_packet(pkt, psize);
858 pkt->stream_index = idx;
859 memcpy(pkt->data, os->buf + pstart, psize);
863 pkt->flags = os->pflags;
864 pkt->duration = os->pduration;
867 if (os->start_trimming || os->end_trimming) {
868 uint8_t *side_data = av_packet_new_side_data(pkt,
869 AV_PKT_DATA_SKIP_SAMPLES,
872 return AVERROR(ENOMEM);
873 AV_WL32(side_data + 0, os->start_trimming);
874 AV_WL32(side_data + 4, os->end_trimming);
875 os->start_trimming = 0;
876 os->end_trimming = 0;
879 if (os->new_metadata) {
880 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_METADATA_UPDATE,
881 os->new_metadata, os->new_metadata_size);
885 os->new_metadata = NULL;
886 os->new_metadata_size = 0;
892 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
893 int64_t *pos_arg, int64_t pos_limit)
895 struct ogg *ogg = s->priv_data;
896 AVIOContext *bc = s->pb;
897 int64_t pts = AV_NOPTS_VALUE;
901 avio_seek(bc, *pos_arg, SEEK_SET);
904 while ( avio_tell(bc) <= pos_limit
905 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
906 if (i == stream_index) {
907 struct ogg_stream *os = ogg->streams + stream_index;
908 // Do not trust the last timestamps of an ogm video
909 if ( (os->flags & OGG_FLAG_EOS)
910 && !(os->flags & OGG_FLAG_BOS)
911 && os->codec == &ff_ogm_video_codec)
913 pts = ogg_calc_pts(s, i, NULL);
914 ogg_validate_keyframe(s, i, pstart, psize);
915 if (os->pflags & AV_PKT_FLAG_KEY) {
917 } else if (os->keyframe_seek) {
918 // if we had a previous keyframe but no pts for it,
919 // return that keyframe with this pts value.
923 pts = AV_NOPTS_VALUE;
926 if (pts != AV_NOPTS_VALUE)
933 static int ogg_read_seek(AVFormatContext *s, int stream_index,
934 int64_t timestamp, int flags)
936 struct ogg *ogg = s->priv_data;
937 struct ogg_stream *os = ogg->streams + stream_index;
940 av_assert0(stream_index < ogg->nstreams);
941 // Ensure everything is reset even when seeking via
942 // the generated index.
945 // Try seeking to a keyframe first. If this fails (very possible),
946 // av_seek_frame will fall back to ignoring keyframes
947 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
948 && !(flags & AVSEEK_FLAG_ANY))
949 os->keyframe_seek = 1;
951 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
953 os = ogg->streams + stream_index;
955 os->keyframe_seek = 0;
959 static int ogg_probe(const AVProbeData *p)
961 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
962 return AVPROBE_SCORE_MAX;
966 AVInputFormat ff_ogg_demuxer = {
968 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
969 .priv_data_size = sizeof(struct ogg),
970 .read_probe = ogg_probe,
971 .read_header = ogg_read_header,
972 .read_packet = ogg_read_packet,
973 .read_close = ogg_read_close,
974 .read_seek = ogg_read_seek,
975 .read_timestamp = ogg_read_timestamp,
977 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,