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);
63 static int ogg_restore(AVFormatContext *s, int discard);
65 //FIXME We could avoid some structure duplication
66 static int ogg_save(AVFormatContext *s)
68 struct ogg *ogg = s->priv_data;
69 struct ogg_state *ost =
70 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
75 return AVERROR(ENOMEM);
77 ost->pos = avio_tell(s->pb);
78 ost->curidx = ogg->curidx;
79 ost->next = ogg->state;
80 ost->nstreams = ogg->nstreams;
81 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
83 for (i = 0; i < ogg->nstreams; i++) {
84 struct ogg_stream *os = ogg->streams + i;
85 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
87 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
89 ret = AVERROR(ENOMEM);
90 os->new_metadata = NULL;
91 os->new_metadata_size = 0;
102 static int ogg_restore(AVFormatContext *s, int discard)
104 struct ogg *ogg = s->priv_data;
105 AVIOContext *bc = s->pb;
106 struct ogg_state *ost = ogg->state;
112 ogg->state = ost->next;
116 for (i = 0; i < ogg->nstreams; i++)
117 av_freep(&ogg->streams[i].buf);
119 avio_seek(bc, ost->pos, SEEK_SET);
121 ogg->curidx = ost->curidx;
122 ogg->nstreams = ost->nstreams;
123 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
124 sizeof(*ogg->streams))) < 0) {
128 memcpy(ogg->streams, ost->streams,
129 ost->nstreams * sizeof(*ogg->streams));
137 static int ogg_reset(AVFormatContext *s)
139 struct ogg *ogg = s->priv_data;
141 int64_t start_pos = avio_tell(s->pb);
143 for (i = 0; i < ogg->nstreams; i++) {
144 struct ogg_stream *os = ogg->streams + i;
149 os->lastpts = AV_NOPTS_VALUE;
150 os->lastdts = AV_NOPTS_VALUE;
157 if (start_pos <= s->internal->data_offset) {
160 os->end_trimming = 0;
161 av_freep(&os->new_metadata);
162 os->new_metadata_size = 0;
171 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
175 for (i = 0; ogg_codecs[i]; i++)
176 if (size >= ogg_codecs[i]->magicsize &&
177 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
178 return ogg_codecs[i];
184 * Replace the current stream with a new one. This is a typical webradio
185 * situation where a new audio stream spawn (identified with a new serial) and
186 * must replace the previous one (track switch).
188 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
190 struct ogg *ogg = s->priv_data;
191 struct ogg_stream *os;
192 const struct ogg_codec *codec;
195 if (s->pb->seekable) {
197 int64_t pos = avio_tell(s->pb);
198 avio_skip(s->pb, nsegs);
199 avio_read(s->pb, magic, sizeof(magic));
200 avio_seek(s->pb, pos, SEEK_SET);
201 codec = ogg_find_codec(magic, sizeof(magic));
203 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
204 return AVERROR_INVALIDDATA;
206 for (i = 0; i < ogg->nstreams; i++) {
207 if (ogg->streams[i].codec == codec)
210 if (i >= ogg->nstreams)
211 return ogg_new_stream(s, serial);
212 } else if (ogg->nstreams != 1) {
213 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
214 return AVERROR_PATCHWELCOME;
217 os = &ogg->streams[i];
224 bufsize = os->bufsize;
227 if (!ogg->state || ogg->state->streams[i].private != os->private)
228 av_freep(&ogg->streams[i].private);
230 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
231 * also re-use the ogg_stream allocated buffer */
232 memset(os, 0, sizeof(*os));
234 os->bufsize = bufsize;
243 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
245 struct ogg *ogg = s->priv_data;
246 int idx = ogg->nstreams;
248 struct ogg_stream *os;
252 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
253 "in between Ogg context save/restore operations.\n");
257 /* Allocate and init a new Ogg Stream */
258 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
259 !(os = av_realloc(ogg->streams, size)))
260 return AVERROR(ENOMEM);
262 os = ogg->streams + idx;
263 memset(os, 0, sizeof(*os));
265 os->bufsize = DECODER_BUFFER_SIZE;
266 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
268 os->start_granule = OGG_NOGRANULE_VALUE;
270 return AVERROR(ENOMEM);
272 /* Create the associated AVStream */
273 st = avformat_new_stream(s, NULL);
276 return AVERROR(ENOMEM);
279 avpriv_set_pts_info(st, 64, 1, 1000000);
285 static int ogg_new_buf(struct ogg *ogg, int idx)
287 struct ogg_stream *os = ogg->streams + idx;
288 uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
289 int size = os->bufpos - os->pstart;
292 return AVERROR(ENOMEM);
295 memcpy(nb, os->buf + os->pstart, size);
306 static int data_packets_seen(const struct ogg *ogg)
310 for (i = 0; i < ogg->nstreams; i++)
311 if (ogg->streams[i].got_data)
316 static int ogg_read_page(AVFormatContext *s, int *sid)
318 AVIOContext *bc = s->pb;
319 struct ogg *ogg = s->priv_data;
320 struct ogg_stream *os;
329 ret = avio_read(bc, sync, 4);
331 return ret < 0 ? ret : AVERROR_EOF;
336 if (sync[sp & 3] == 'O' &&
337 sync[(sp + 1) & 3] == 'g' &&
338 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
341 if(!i && bc->seekable && ogg->page_pos > 0) {
343 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
353 } while (i++ < MAX_PAGE_SIZE);
355 if (i >= MAX_PAGE_SIZE) {
356 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
357 return AVERROR_INVALIDDATA;
360 if (avio_r8(bc) != 0) { /* version */
361 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
362 return AVERROR_INVALIDDATA;
367 serial = avio_rl32(bc);
368 avio_skip(bc, 8); /* seq, crc */
371 idx = ogg_find_stream(ogg, serial);
373 if (data_packets_seen(ogg))
374 idx = ogg_replace_stream(s, serial, nsegs);
376 idx = ogg_new_stream(s, serial);
379 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
384 os = ogg->streams + idx;
386 os->page_pos = avio_tell(bc) - 27;
389 ret = ogg_new_buf(ogg, idx);
394 ret = avio_read(bc, os->segments, nsegs);
396 return ret < 0 ? ret : AVERROR_EOF;
402 for (i = 0; i < nsegs; i++)
403 size += os->segments[i];
405 if (!(flags & OGG_FLAG_BOS))
408 if (flags & OGG_FLAG_CONT || os->incomplete) {
410 // If this is the very first segment we started
411 // playback in the middle of a continuation packet.
412 // Discard it since we missed the start of it.
413 while (os->segp < os->nsegs) {
414 int seg = os->segments[os->segp++];
419 os->sync_pos = os->page_pos;
423 os->sync_pos = os->page_pos;
426 if (os->bufsize - os->bufpos < size) {
427 uint8_t *nb = av_malloc((os->bufsize *= 2) + AV_INPUT_BUFFER_PADDING_SIZE);
429 return AVERROR(ENOMEM);
430 memcpy(nb, os->buf, os->bufpos);
435 ret = avio_read(bc, os->buf + os->bufpos, size);
437 return ret < 0 ? ret : AVERROR_EOF;
443 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
451 * @brief find the next Ogg packet
452 * @param *sid is set to the stream for the packet or -1 if there is
453 * no matching stream, in that case assume all other return
454 * values to be uninitialized.
455 * @return negative value on error or EOF.
457 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
460 struct ogg *ogg = s->priv_data;
462 struct ogg_stream *os;
464 int segp = 0, psize = 0;
466 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
474 ret = ogg_read_page(s, &idx);
479 os = ogg->streams + idx;
481 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
482 idx, os->pstart, os->psize, os->segp, os->nsegs);
485 if (os->header < 0) {
486 os->codec = ogg_find_codec(os->buf, os->bufpos);
488 av_log(s, AV_LOG_WARNING, "Codec not found\n");
500 while (os->segp < os->nsegs) {
501 int ss = os->segments[os->segp++];
509 if (!complete && os->segp == os->nsegs) {
511 // Do not set incomplete for empty packets.
512 // Together with the code in ogg_read_page
513 // that discards all continuation of empty packets
514 // we would get an infinite loop.
515 os->incomplete = !!os->psize;
520 if (os->granule == -1)
521 av_log(s, AV_LOG_WARNING,
522 "Page at %"PRId64" is missing granule\n",
529 os->header = os->codec->header(s, idx);
534 // We have reached the first non-header packet in this stream.
535 // Unfortunately more header packets may still follow for others,
536 // but if we continue with header parsing we may lose data packets.
539 // Update the header state for all streams and
540 // compute the data_offset.
541 if (!s->internal->data_offset)
542 s->internal->data_offset = os->sync_pos;
544 for (i = 0; i < ogg->nstreams; i++) {
545 struct ogg_stream *cur_os = ogg->streams + i;
547 // if we have a partial non-header packet, its start is
548 // obviously at or after the data start
549 if (cur_os->incomplete)
550 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
554 os->pstart += os->psize;
560 if (os->codec && os->codec->packet)
561 os->codec->packet(s, idx);
565 *dstart = os->pstart;
569 *fpos = os->sync_pos;
570 os->pstart += os->psize;
572 if(os->pstart == os->bufpos)
573 os->bufpos = os->pstart = 0;
574 os->sync_pos = os->page_pos;
577 // determine whether there are more complete packets in this page
578 // if not, the page's granule will apply to this packet
580 for (i = os->segp; i < os->nsegs; i++)
581 if (os->segments[i] < 255) {
586 if (os->segp == os->nsegs)
592 static int ogg_get_length(AVFormatContext *s)
594 struct ogg *ogg = s->priv_data;
599 if (!s->pb->seekable)
603 if (s->duration != AV_NOPTS_VALUE)
606 size = avio_size(s->pb);
609 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
614 avio_seek(s->pb, end, SEEK_SET);
617 while (!ogg_read_page(s, &i)) {
618 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
619 ogg->streams[i].codec) {
620 s->streams[i]->duration =
621 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
622 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
623 s->streams[i]->duration -= s->streams[i]->start_time;
624 streams_left-= (ogg->streams[i].got_start==-1);
625 ogg->streams[i].got_start= 1;
626 } else if(!ogg->streams[i].got_start) {
627 ogg->streams[i].got_start= -1;
639 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
641 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
644 pts = ogg_calc_pts(s, i, NULL);
645 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
646 s->streams[i]->duration -= pts;
647 ogg->streams[i].got_start= 1;
649 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
650 ogg->streams[i].got_start= 1;
659 static int ogg_read_close(AVFormatContext *s)
661 struct ogg *ogg = s->priv_data;
664 for (i = 0; i < ogg->nstreams; i++) {
665 av_freep(&ogg->streams[i].buf);
666 if (ogg->streams[i].codec &&
667 ogg->streams[i].codec->cleanup) {
668 ogg->streams[i].codec->cleanup(s, i);
670 av_freep(&ogg->streams[i].private);
671 av_freep(&ogg->streams[i].new_metadata);
676 av_freep(&ogg->streams);
680 static int ogg_read_header(AVFormatContext *s)
682 struct ogg *ogg = s->priv_data;
687 //linear headers seek from start
689 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
694 } while (!ogg->headers);
695 av_log(s, AV_LOG_TRACE, "found headers\n");
697 for (i = 0; i < ogg->nstreams; i++) {
698 struct ogg_stream *os = ogg->streams + i;
700 if (ogg->streams[i].header < 0) {
701 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
702 ogg->streams[i].codec = NULL;
703 } else if (os->codec && os->nb_header < os->codec->nb_header) {
704 av_log(s, AV_LOG_WARNING,
705 "Headers mismatch for stream %d: "
706 "expected %d received %d.\n",
707 i, os->codec->nb_header, os->nb_header);
708 if (s->error_recognition & AV_EF_EXPLODE)
709 return AVERROR_INVALIDDATA;
711 if (os->start_granule != OGG_NOGRANULE_VALUE)
712 os->lastpts = s->streams[i]->start_time =
713 ogg_gptopts(s, i, os->start_granule, NULL);
716 //linear granulepos seek from end
717 ret = ogg_get_length(s);
726 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
728 struct ogg *ogg = s->priv_data;
729 struct ogg_stream *os = ogg->streams + idx;
730 int64_t pts = AV_NOPTS_VALUE;
733 *dts = AV_NOPTS_VALUE;
735 if (os->lastpts != AV_NOPTS_VALUE) {
737 os->lastpts = AV_NOPTS_VALUE;
739 if (os->lastdts != AV_NOPTS_VALUE) {
742 os->lastdts = AV_NOPTS_VALUE;
745 if (os->granule != -1LL) {
746 if (os->codec && os->codec->granule_is_start)
747 pts = ogg_gptopts(s, idx, os->granule, dts);
749 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
756 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
758 struct ogg *ogg = s->priv_data;
759 struct ogg_stream *os = ogg->streams + idx;
762 switch (s->streams[idx]->codec->codec_id) {
763 case AV_CODEC_ID_THEORA:
764 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
766 case AV_CODEC_ID_VP8:
767 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
770 os->pflags ^= AV_PKT_FLAG_KEY;
771 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
772 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
777 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
780 struct ogg_stream *os;
783 int64_t fpos, pts, dts;
785 if (s->io_repositioned) {
787 s->io_repositioned = 0;
793 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
796 } while (idx < 0 || !s->streams[idx]);
799 os = ogg->streams + idx;
801 // pflags might not be set until after this
802 pts = ogg_calc_pts(s, idx, &dts);
803 ogg_validate_keyframe(s, idx, pstart, psize);
805 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
807 os->keyframe_seek = 0;
810 ret = av_new_packet(pkt, psize);
813 pkt->stream_index = idx;
814 memcpy(pkt->data, os->buf + pstart, psize);
818 pkt->flags = os->pflags;
819 pkt->duration = os->pduration;
822 if (os->end_trimming) {
823 uint8_t *side_data = av_packet_new_side_data(pkt,
824 AV_PKT_DATA_SKIP_SAMPLES,
828 AV_WL32(side_data + 4, os->end_trimming);
829 os->end_trimming = 0;
832 if (os->new_metadata) {
833 uint8_t *side_data = av_packet_new_side_data(pkt,
834 AV_PKT_DATA_METADATA_UPDATE,
835 os->new_metadata_size);
839 memcpy(side_data, os->new_metadata, os->new_metadata_size);
840 av_freep(&os->new_metadata);
841 os->new_metadata_size = 0;
847 return AVERROR(ENOMEM);
850 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
851 int64_t *pos_arg, int64_t pos_limit)
853 struct ogg *ogg = s->priv_data;
854 AVIOContext *bc = s->pb;
855 int64_t pts = AV_NOPTS_VALUE;
859 avio_seek(bc, *pos_arg, SEEK_SET);
862 while ( avio_tell(bc) <= pos_limit
863 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
864 if (i == stream_index) {
865 struct ogg_stream *os = ogg->streams + stream_index;
866 // Do not trust the last timestamps of a ogm video
867 if ( (os->flags & OGG_FLAG_EOS)
868 && !(os->flags & OGG_FLAG_BOS)
869 && os->codec == &ff_ogm_video_codec)
871 pts = ogg_calc_pts(s, i, NULL);
872 ogg_validate_keyframe(s, i, pstart, psize);
873 if (os->pflags & AV_PKT_FLAG_KEY) {
875 } else if (os->keyframe_seek) {
876 // if we had a previous keyframe but no pts for it,
877 // return that keyframe with this pts value.
881 pts = AV_NOPTS_VALUE;
884 if (pts != AV_NOPTS_VALUE)
891 static int ogg_read_seek(AVFormatContext *s, int stream_index,
892 int64_t timestamp, int flags)
894 struct ogg *ogg = s->priv_data;
895 struct ogg_stream *os = ogg->streams + stream_index;
898 av_assert0(stream_index < ogg->nstreams);
899 // Ensure everything is reset even when seeking via
900 // the generated index.
903 // Try seeking to a keyframe first. If this fails (very possible),
904 // av_seek_frame will fall back to ignoring keyframes
905 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
906 && !(flags & AVSEEK_FLAG_ANY))
907 os->keyframe_seek = 1;
909 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
911 os = ogg->streams + stream_index;
913 os->keyframe_seek = 0;
917 static int ogg_probe(AVProbeData *p)
919 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
920 return AVPROBE_SCORE_MAX;
924 AVInputFormat ff_ogg_demuxer = {
926 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
927 .priv_data_size = sizeof(struct ogg),
928 .read_probe = ogg_probe,
929 .read_header = ogg_read_header,
930 .read_packet = ogg_read_packet,
931 .read_close = ogg_read_close,
932 .read_seek = ogg_read_seek,
933 .read_timestamp = ogg_read_timestamp,
935 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,