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[] = {
63 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
64 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
65 static int ogg_restore(AVFormatContext *s);
67 static void free_stream(AVFormatContext *s, int i)
69 struct ogg *ogg = s->priv_data;
70 struct ogg_stream *stream = &ogg->streams[i];
72 av_freep(&stream->buf);
74 stream->codec->cleanup) {
75 stream->codec->cleanup(s, i);
78 av_freep(&stream->private);
79 av_freep(&stream->new_metadata);
82 //FIXME We could avoid some structure duplication
83 static int ogg_save(AVFormatContext *s)
85 struct ogg *ogg = s->priv_data;
86 struct ogg_state *ost =
87 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
92 return AVERROR(ENOMEM);
94 ost->pos = avio_tell(s->pb);
95 ost->curidx = ogg->curidx;
96 ost->next = ogg->state;
97 ost->nstreams = ogg->nstreams;
98 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
100 for (i = 0; i < ogg->nstreams; i++) {
101 struct ogg_stream *os = ogg->streams + i;
102 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
104 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
106 ret = AVERROR(ENOMEM);
107 os->new_metadata = NULL;
108 os->new_metadata_size = 0;
119 static int ogg_restore(AVFormatContext *s)
121 struct ogg *ogg = s->priv_data;
122 AVIOContext *bc = s->pb;
123 struct ogg_state *ost = ogg->state;
129 ogg->state = ost->next;
131 for (i = 0; i < ogg->nstreams; i++) {
132 struct ogg_stream *stream = &ogg->streams[i];
133 av_freep(&stream->buf);
134 av_freep(&stream->new_metadata);
136 if (i >= ost->nstreams || !ost->streams[i].private) {
141 avio_seek(bc, ost->pos, SEEK_SET);
143 ogg->curidx = ost->curidx;
144 ogg->nstreams = ost->nstreams;
145 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
146 sizeof(*ogg->streams))) < 0) {
150 memcpy(ogg->streams, ost->streams,
151 ost->nstreams * sizeof(*ogg->streams));
158 static int ogg_reset(AVFormatContext *s)
160 struct ogg *ogg = s->priv_data;
162 int64_t start_pos = avio_tell(s->pb);
164 for (i = 0; i < ogg->nstreams; i++) {
165 struct ogg_stream *os = ogg->streams + i;
170 os->lastpts = AV_NOPTS_VALUE;
171 os->lastdts = AV_NOPTS_VALUE;
178 if (start_pos <= s->internal->data_offset) {
181 os->start_trimming = 0;
182 os->end_trimming = 0;
183 av_freep(&os->new_metadata);
184 os->new_metadata_size = 0;
193 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
197 for (i = 0; ogg_codecs[i]; i++)
198 if (size >= ogg_codecs[i]->magicsize &&
199 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
200 return ogg_codecs[i];
206 * Replace the current stream with a new one. This is a typical webradio
207 * situation where a new audio stream spawn (identified with a new serial) and
208 * must replace the previous one (track switch).
210 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic,
213 struct ogg *ogg = s->priv_data;
214 struct ogg_stream *os;
215 const struct ogg_codec *codec;
218 if (ogg->nstreams != 1) {
219 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
220 return AVERROR_PATCHWELCOME;
223 /* Check for codecs */
224 codec = ogg_find_codec(magic, 8);
225 if (!codec && !probing) {
226 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
227 return AVERROR_INVALIDDATA;
230 /* We only have a single stream anyway, so if there's a new stream with
231 * a different codec just replace it */
232 os = &ogg->streams[0];
238 os->start_trimming = 0;
239 os->end_trimming = 0;
241 /* Chained files have extradata as a new packet */
242 if (codec == &ff_opus_codec)
248 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
250 struct ogg *ogg = s->priv_data;
251 int idx = ogg->nstreams;
253 struct ogg_stream *os;
257 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
258 "in between Ogg context save/restore operations.\n");
262 /* Allocate and init a new Ogg Stream */
263 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
264 !(os = av_realloc(ogg->streams, size)))
265 return AVERROR(ENOMEM);
267 os = ogg->streams + idx;
268 memset(os, 0, sizeof(*os));
270 os->bufsize = DECODER_BUFFER_SIZE;
271 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
273 os->start_granule = OGG_NOGRANULE_VALUE;
275 return AVERROR(ENOMEM);
277 /* Create the associated AVStream */
278 st = avformat_new_stream(s, NULL);
281 return AVERROR(ENOMEM);
284 avpriv_set_pts_info(st, 64, 1, 1000000);
290 static int data_packets_seen(const struct ogg *ogg)
294 for (i = 0; i < ogg->nstreams; i++)
295 if (ogg->streams[i].got_data)
300 static int buf_realloc(struct ogg_stream *os, int size)
302 /* Even if invalid guarantee there's enough memory to read the page */
303 if (os->bufsize - os->bufpos < size) {
304 uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
306 return AVERROR(ENOMEM);
314 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
316 AVIOContext *bc = s->pb;
317 struct ogg *ogg = s->priv_data;
318 struct ogg_stream *os;
323 uint32_t crc, crc_tmp;
325 int64_t version, page_pos;
328 uint8_t segments[255];
329 uint8_t *readout_buf;
332 ret = avio_read(bc, sync, 4);
334 return ret < 0 ? ret : AVERROR_EOF;
339 if (sync[sp & 3] == 'O' &&
340 sync[(sp + 1) & 3] == 'g' &&
341 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
344 if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
346 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
356 } while (i++ < MAX_PAGE_SIZE);
358 if (i >= MAX_PAGE_SIZE) {
359 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
360 return AVERROR_INVALIDDATA;
363 /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
364 ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
366 /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
367 ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
368 start_pos = avio_tell(bc);
370 version = avio_r8(bc);
373 serial = avio_rl32(bc);
374 avio_skip(bc, 4); /* seq */
376 crc_tmp = ffio_get_checksum(bc);
378 crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
379 ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
382 page_pos = avio_tell(bc) - 27;
384 ret = avio_read(bc, segments, nsegs);
386 return ret < 0 ? ret : AVERROR_EOF;
388 for (i = 0; i < nsegs; i++)
391 idx = ogg_find_stream(ogg, serial);
393 os = ogg->streams + idx;
395 ret = buf_realloc(os, size);
399 readout_buf = os->buf + os->bufpos;
401 readout_buf = av_malloc(size);
404 ret = avio_read(bc, readout_buf, size);
407 av_free(readout_buf);
408 return ret < 0 ? ret : AVERROR_EOF;
411 if (crc ^ ffio_get_checksum(bc)) {
412 av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
414 av_free(readout_buf);
415 avio_seek(bc, start_pos, SEEK_SET);
419 /* Since we're almost sure its a valid packet, checking the version after
420 * the checksum lets the demuxer be more tolerant */
422 av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
424 av_free(readout_buf);
425 avio_seek(bc, start_pos, SEEK_SET);
429 /* CRC is correct so we can be 99% sure there's an actual change here */
431 if (data_packets_seen(ogg))
432 idx = ogg_replace_stream(s, serial, readout_buf, probing);
434 idx = ogg_new_stream(s, serial);
437 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
438 av_free(readout_buf);
442 os = ogg->streams + idx;
444 memcpy(os->buf + os->bufpos, readout_buf, size);
445 av_free(readout_buf);
448 ogg->page_pos = page_pos;
449 os->page_pos = page_pos;
452 os->got_data = !(flags & OGG_FLAG_BOS);
456 memcpy(os->segments, segments, nsegs);
457 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
459 if (flags & OGG_FLAG_CONT || os->incomplete) {
461 // If this is the very first segment we started
462 // playback in the middle of a continuation packet.
463 // Discard it since we missed the start of it.
464 while (os->segp < os->nsegs) {
465 int seg = os->segments[os->segp++];
470 os->sync_pos = os->page_pos;
474 os->sync_pos = os->page_pos;
477 /* This function is always called with sid != NULL */
484 * @brief find the next Ogg packet
485 * @param *sid is set to the stream for the packet or -1 if there is
486 * no matching stream, in that case assume all other return
487 * values to be uninitialized.
488 * @return negative value on error or EOF.
490 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
493 struct ogg *ogg = s->priv_data;
495 struct ogg_stream *os;
497 int segp = 0, psize = 0;
499 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
507 ret = ogg_read_page(s, &idx, 0);
512 os = ogg->streams + idx;
514 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
515 idx, os->pstart, os->psize, os->segp, os->nsegs);
518 if (os->header < 0) {
519 os->codec = ogg_find_codec(os->buf, os->bufpos);
521 av_log(s, AV_LOG_WARNING, "Codec not found\n");
533 while (os->segp < os->nsegs) {
534 int ss = os->segments[os->segp++];
542 if (!complete && os->segp == os->nsegs) {
544 // Do not set incomplete for empty packets.
545 // Together with the code in ogg_read_page
546 // that discards all continuation of empty packets
547 // we would get an infinite loop.
548 os->incomplete = !!os->psize;
553 if (os->granule == -1)
554 av_log(s, AV_LOG_WARNING,
555 "Page at %"PRId64" is missing granule\n",
562 if ((ret = os->codec->header(s, idx)) < 0) {
563 av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
571 // We have reached the first non-header packet in this stream.
572 // Unfortunately more header packets may still follow for others,
573 // but if we continue with header parsing we may lose data packets.
576 // Update the header state for all streams and
577 // compute the data_offset.
578 if (!s->internal->data_offset)
579 s->internal->data_offset = os->sync_pos;
581 for (i = 0; i < ogg->nstreams; i++) {
582 struct ogg_stream *cur_os = ogg->streams + i;
584 // if we have a partial non-header packet, its start is
585 // obviously at or after the data start
586 if (cur_os->incomplete)
587 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
591 os->pstart += os->psize;
597 if (os->codec && os->codec->packet) {
598 if ((ret = os->codec->packet(s, idx)) < 0) {
599 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
606 *dstart = os->pstart;
610 *fpos = os->sync_pos;
611 os->pstart += os->psize;
613 if(os->pstart == os->bufpos)
614 os->bufpos = os->pstart = 0;
615 os->sync_pos = os->page_pos;
618 // determine whether there are more complete packets in this page
619 // if not, the page's granule will apply to this packet
621 for (i = os->segp; i < os->nsegs; i++)
622 if (os->segments[i] < 255) {
627 if (os->segp == os->nsegs)
633 static int ogg_get_length(AVFormatContext *s)
635 struct ogg *ogg = s->priv_data;
640 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
644 if (s->duration != AV_NOPTS_VALUE)
647 size = avio_size(s->pb);
650 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
655 avio_seek(s->pb, end, SEEK_SET);
658 while (!ogg_read_page(s, &i, 1)) {
659 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
660 ogg->streams[i].codec) {
661 s->streams[i]->duration =
662 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
663 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
664 s->streams[i]->duration -= s->streams[i]->start_time;
665 streams_left-= (ogg->streams[i].got_start==-1);
666 ogg->streams[i].got_start= 1;
667 } else if(!ogg->streams[i].got_start) {
668 ogg->streams[i].got_start= -1;
680 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
682 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
685 pts = ogg_calc_pts(s, i, NULL);
686 if (s->streams[i]->duration == AV_NOPTS_VALUE)
688 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
689 s->streams[i]->duration -= pts;
690 ogg->streams[i].got_start= 1;
692 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
693 ogg->streams[i].got_start= 1;
702 static int ogg_read_close(AVFormatContext *s)
704 struct ogg *ogg = s->priv_data;
707 for (i = 0; i < ogg->nstreams; i++) {
713 av_freep(&ogg->streams);
717 static int ogg_read_header(AVFormatContext *s)
719 struct ogg *ogg = s->priv_data;
724 //linear headers seek from start
726 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
731 } while (!ogg->headers);
732 av_log(s, AV_LOG_TRACE, "found headers\n");
734 for (i = 0; i < ogg->nstreams; i++) {
735 struct ogg_stream *os = ogg->streams + i;
737 if (ogg->streams[i].header < 0) {
738 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
739 ogg->streams[i].codec = NULL;
740 av_freep(&ogg->streams[i].private);
741 } else if (os->codec && os->nb_header < os->codec->nb_header) {
742 av_log(s, AV_LOG_WARNING,
743 "Headers mismatch for stream %d: "
744 "expected %d received %d.\n",
745 i, os->codec->nb_header, os->nb_header);
746 if (s->error_recognition & AV_EF_EXPLODE) {
748 return AVERROR_INVALIDDATA;
751 if (os->start_granule != OGG_NOGRANULE_VALUE)
752 os->lastpts = s->streams[i]->start_time =
753 ogg_gptopts(s, i, os->start_granule, NULL);
756 //linear granulepos seek from end
757 ret = ogg_get_length(s);
766 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
768 struct ogg *ogg = s->priv_data;
769 struct ogg_stream *os = ogg->streams + idx;
770 int64_t pts = AV_NOPTS_VALUE;
773 *dts = AV_NOPTS_VALUE;
775 if (os->lastpts != AV_NOPTS_VALUE) {
777 os->lastpts = AV_NOPTS_VALUE;
779 if (os->lastdts != AV_NOPTS_VALUE) {
782 os->lastdts = AV_NOPTS_VALUE;
785 if (os->granule != -1LL) {
786 if (os->codec && os->codec->granule_is_start)
787 pts = ogg_gptopts(s, idx, os->granule, dts);
789 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
796 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
798 struct ogg *ogg = s->priv_data;
799 struct ogg_stream *os = ogg->streams + idx;
802 switch (s->streams[idx]->codecpar->codec_id) {
803 case AV_CODEC_ID_THEORA:
804 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
806 case AV_CODEC_ID_VP8:
807 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
810 os->pflags ^= AV_PKT_FLAG_KEY;
811 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
812 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
817 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
820 struct ogg_stream *os;
823 int64_t fpos, pts, dts;
825 if (s->io_repositioned) {
827 s->io_repositioned = 0;
833 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
836 } while (idx < 0 || !s->streams[idx]);
839 os = ogg->streams + idx;
841 // pflags might not be set until after this
842 pts = ogg_calc_pts(s, idx, &dts);
843 ogg_validate_keyframe(s, idx, pstart, psize);
845 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
847 os->keyframe_seek = 0;
850 ret = av_new_packet(pkt, psize);
853 pkt->stream_index = idx;
854 memcpy(pkt->data, os->buf + pstart, psize);
858 pkt->flags = os->pflags;
859 pkt->duration = os->pduration;
862 if (os->start_trimming || os->end_trimming) {
863 uint8_t *side_data = av_packet_new_side_data(pkt,
864 AV_PKT_DATA_SKIP_SAMPLES,
867 return AVERROR(ENOMEM);
868 AV_WL32(side_data + 0, os->start_trimming);
869 AV_WL32(side_data + 4, os->end_trimming);
870 os->start_trimming = 0;
871 os->end_trimming = 0;
874 if (os->new_metadata) {
875 uint8_t *side_data = av_packet_new_side_data(pkt,
876 AV_PKT_DATA_METADATA_UPDATE,
877 os->new_metadata_size);
879 return AVERROR(ENOMEM);
881 memcpy(side_data, os->new_metadata, os->new_metadata_size);
882 av_freep(&os->new_metadata);
883 os->new_metadata_size = 0;
889 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
890 int64_t *pos_arg, int64_t pos_limit)
892 struct ogg *ogg = s->priv_data;
893 AVIOContext *bc = s->pb;
894 int64_t pts = AV_NOPTS_VALUE;
898 avio_seek(bc, *pos_arg, SEEK_SET);
901 while ( avio_tell(bc) <= pos_limit
902 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
903 if (i == stream_index) {
904 struct ogg_stream *os = ogg->streams + stream_index;
905 // Do not trust the last timestamps of an ogm video
906 if ( (os->flags & OGG_FLAG_EOS)
907 && !(os->flags & OGG_FLAG_BOS)
908 && os->codec == &ff_ogm_video_codec)
910 pts = ogg_calc_pts(s, i, NULL);
911 ogg_validate_keyframe(s, i, pstart, psize);
912 if (os->pflags & AV_PKT_FLAG_KEY) {
914 } else if (os->keyframe_seek) {
915 // if we had a previous keyframe but no pts for it,
916 // return that keyframe with this pts value.
920 pts = AV_NOPTS_VALUE;
923 if (pts != AV_NOPTS_VALUE)
930 static int ogg_read_seek(AVFormatContext *s, int stream_index,
931 int64_t timestamp, int flags)
933 struct ogg *ogg = s->priv_data;
934 struct ogg_stream *os = ogg->streams + stream_index;
937 av_assert0(stream_index < ogg->nstreams);
938 // Ensure everything is reset even when seeking via
939 // the generated index.
942 // Try seeking to a keyframe first. If this fails (very possible),
943 // av_seek_frame will fall back to ignoring keyframes
944 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
945 && !(flags & AVSEEK_FLAG_ANY))
946 os->keyframe_seek = 1;
948 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
950 os = ogg->streams + stream_index;
952 os->keyframe_seek = 0;
956 static int ogg_probe(const AVProbeData *p)
958 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
959 return AVPROBE_SCORE_MAX;
963 AVInputFormat ff_ogg_demuxer = {
965 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
966 .priv_data_size = sizeof(struct ogg),
967 .read_probe = ogg_probe,
968 .read_header = ogg_read_header,
969 .read_packet = ogg_read_packet,
970 .read_close = ogg_read_close,
971 .read_seek = ogg_read_seek,
972 .read_timestamp = ogg_read_timestamp,
974 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,