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));
71 ost->pos = avio_tell(s->pb);
72 ost->curidx = ogg->curidx;
73 ost->next = ogg->state;
74 ost->nstreams = ogg->nstreams;
75 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
77 for (i = 0; i < ogg->nstreams; i++) {
78 struct ogg_stream *os = ogg->streams + i;
79 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
80 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
88 static int ogg_restore(AVFormatContext *s, int discard)
90 struct ogg *ogg = s->priv_data;
91 AVIOContext *bc = s->pb;
92 struct ogg_state *ost = ogg->state;
98 ogg->state = ost->next;
102 for (i = 0; i < ogg->nstreams; i++)
103 av_freep(&ogg->streams[i].buf);
105 avio_seek(bc, ost->pos, SEEK_SET);
107 ogg->curidx = ost->curidx;
108 ogg->nstreams = ost->nstreams;
109 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
110 sizeof(*ogg->streams))) < 0) {
114 memcpy(ogg->streams, ost->streams,
115 ost->nstreams * sizeof(*ogg->streams));
123 static int ogg_reset(AVFormatContext *s)
125 struct ogg *ogg = s->priv_data;
127 int64_t start_pos = avio_tell(s->pb);
129 for (i = 0; i < ogg->nstreams; i++) {
130 struct ogg_stream *os = ogg->streams + i;
135 os->lastpts = AV_NOPTS_VALUE;
136 os->lastdts = AV_NOPTS_VALUE;
143 if (start_pos <= s->data_offset) {
146 os->end_trimming = 0;
155 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
159 for (i = 0; ogg_codecs[i]; i++)
160 if (size >= ogg_codecs[i]->magicsize &&
161 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
162 return ogg_codecs[i];
168 * Replace the current stream with a new one. This is a typical webradio
169 * situation where a new audio stream spawn (identified with a new serial) and
170 * must replace the previous one (track switch).
172 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
174 struct ogg *ogg = s->priv_data;
175 struct ogg_stream *os;
176 const struct ogg_codec *codec;
179 if (s->pb->seekable) {
181 int64_t pos = avio_tell(s->pb);
182 avio_skip(s->pb, nsegs);
183 avio_read(s->pb, magic, sizeof(magic));
184 avio_seek(s->pb, pos, SEEK_SET);
185 codec = ogg_find_codec(magic, sizeof(magic));
187 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
188 return AVERROR_INVALIDDATA;
190 for (i = 0; i < ogg->nstreams; i++) {
191 if (ogg->streams[i].codec == codec)
194 if (i >= ogg->nstreams)
195 return ogg_new_stream(s, serial);
196 } else if (ogg->nstreams != 1) {
197 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
198 return AVERROR_PATCHWELCOME;
201 os = &ogg->streams[i];
208 bufsize = os->bufsize;
211 if (!ogg->state || ogg->state->streams[i].private != os->private)
212 av_freep(&ogg->streams[i].private);
214 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
215 * also re-use the ogg_stream allocated buffer */
216 memset(os, 0, sizeof(*os));
218 os->bufsize = bufsize;
227 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
229 struct ogg *ogg = s->priv_data;
230 int idx = ogg->nstreams;
232 struct ogg_stream *os;
236 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
237 "in between Ogg context save/restore operations.\n");
241 /* Allocate and init a new Ogg Stream */
242 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
243 !(os = av_realloc(ogg->streams, size)))
244 return AVERROR(ENOMEM);
246 os = ogg->streams + idx;
247 memset(os, 0, sizeof(*os));
249 os->bufsize = DECODER_BUFFER_SIZE;
250 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
252 os->start_granule = OGG_NOGRANULE_VALUE;
254 return AVERROR(ENOMEM);
256 /* Create the associated AVStream */
257 st = avformat_new_stream(s, NULL);
260 return AVERROR(ENOMEM);
263 avpriv_set_pts_info(st, 64, 1, 1000000);
269 static int ogg_new_buf(struct ogg *ogg, int idx)
271 struct ogg_stream *os = ogg->streams + idx;
272 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
273 int size = os->bufpos - os->pstart;
276 memcpy(nb, os->buf + os->pstart, size);
287 static int data_packets_seen(const struct ogg *ogg)
291 for (i = 0; i < ogg->nstreams; i++)
292 if (ogg->streams[i].got_data)
297 static int ogg_read_page(AVFormatContext *s, int *sid)
299 AVIOContext *bc = s->pb;
300 struct ogg *ogg = s->priv_data;
301 struct ogg_stream *os;
310 ret = avio_read(bc, sync, 4);
312 return ret < 0 ? ret : AVERROR_EOF;
317 if (sync[sp & 3] == 'O' &&
318 sync[(sp + 1) & 3] == 'g' &&
319 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
322 if(!i && bc->seekable && ogg->page_pos > 0) {
324 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
334 } while (i++ < MAX_PAGE_SIZE);
336 if (i >= MAX_PAGE_SIZE) {
337 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
338 return AVERROR_INVALIDDATA;
341 if (avio_r8(bc) != 0) { /* version */
342 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
343 return AVERROR_INVALIDDATA;
348 serial = avio_rl32(bc);
349 avio_skip(bc, 8); /* seq, crc */
352 idx = ogg_find_stream(ogg, serial);
354 if (data_packets_seen(ogg))
355 idx = ogg_replace_stream(s, serial, nsegs);
357 idx = ogg_new_stream(s, serial);
360 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
365 os = ogg->streams + idx;
367 os->page_pos = avio_tell(bc) - 27;
370 ogg_new_buf(ogg, idx);
372 ret = avio_read(bc, os->segments, nsegs);
374 return ret < 0 ? ret : AVERROR_EOF;
380 for (i = 0; i < nsegs; i++)
381 size += os->segments[i];
383 if (!(flags & OGG_FLAG_BOS))
386 if (flags & OGG_FLAG_CONT || os->incomplete) {
388 // If this is the very first segment we started
389 // playback in the middle of a continuation packet.
390 // Discard it since we missed the start of it.
391 while (os->segp < os->nsegs) {
392 int seg = os->segments[os->segp++];
397 os->sync_pos = os->page_pos;
401 os->sync_pos = os->page_pos;
404 if (os->bufsize - os->bufpos < size) {
405 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
407 return AVERROR(ENOMEM);
408 memcpy(nb, os->buf, os->bufpos);
413 ret = avio_read(bc, os->buf + os->bufpos, size);
415 return ret < 0 ? ret : AVERROR_EOF;
421 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
429 * @brief find the next Ogg packet
430 * @param *sid is set to the stream for the packet or -1 if there is
431 * no matching stream, in that case assume all other return
432 * values to be uninitialized.
433 * @return negative value on error or EOF.
435 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
438 struct ogg *ogg = s->priv_data;
440 struct ogg_stream *os;
442 int segp = 0, psize = 0;
444 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
452 ret = ogg_read_page(s, &idx);
457 os = ogg->streams + idx;
459 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
460 idx, os->pstart, os->psize, os->segp, os->nsegs);
463 if (os->header < 0) {
464 os->codec = ogg_find_codec(os->buf, os->bufpos);
466 av_log(s, AV_LOG_WARNING, "Codec not found\n");
478 while (os->segp < os->nsegs) {
479 int ss = os->segments[os->segp++];
487 if (!complete && os->segp == os->nsegs) {
489 // Do not set incomplete for empty packets.
490 // Together with the code in ogg_read_page
491 // that discards all continuation of empty packets
492 // we would get an infinite loop.
493 os->incomplete = !!os->psize;
498 if (os->granule == -1)
499 av_log(s, AV_LOG_WARNING,
500 "Page at %"PRId64" is missing granule\n",
507 os->header = os->codec->header(s, idx);
512 // We have reached the first non-header packet in this stream.
513 // Unfortunately more header packets may still follow for others,
514 // but if we continue with header parsing we may lose data packets.
517 // Update the header state for all streams and
518 // compute the data_offset.
520 s->data_offset = os->sync_pos;
522 for (i = 0; i < ogg->nstreams; i++) {
523 struct ogg_stream *cur_os = ogg->streams + i;
525 // if we have a partial non-header packet, its start is
526 // obviously at or after the data start
527 if (cur_os->incomplete)
528 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
532 os->pstart += os->psize;
538 if (os->codec && os->codec->packet)
539 os->codec->packet(s, idx);
543 *dstart = os->pstart;
547 *fpos = os->sync_pos;
548 os->pstart += os->psize;
550 if(os->pstart == os->bufpos)
551 os->bufpos = os->pstart = 0;
552 os->sync_pos = os->page_pos;
555 // determine whether there are more complete packets in this page
556 // if not, the page's granule will apply to this packet
558 for (i = os->segp; i < os->nsegs; i++)
559 if (os->segments[i] < 255) {
564 if (os->segp == os->nsegs)
570 static int ogg_get_length(AVFormatContext *s)
572 struct ogg *ogg = s->priv_data;
577 if (!s->pb->seekable)
581 if (s->duration != AV_NOPTS_VALUE)
584 size = avio_size(s->pb);
587 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
590 avio_seek(s->pb, end, SEEK_SET);
593 while (!ogg_read_page(s, &i)) {
594 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
595 ogg->streams[i].codec) {
596 s->streams[i]->duration =
597 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
598 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
599 s->streams[i]->duration -= s->streams[i]->start_time;
600 streams_left-= (ogg->streams[i].got_start==-1);
601 ogg->streams[i].got_start= 1;
602 } else if(!ogg->streams[i].got_start) {
603 ogg->streams[i].got_start= -1;
612 avio_seek (s->pb, s->data_offset, SEEK_SET);
614 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
617 pts = ogg_calc_pts(s, i, NULL);
618 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
619 s->streams[i]->duration -= pts;
620 ogg->streams[i].got_start= 1;
622 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
623 ogg->streams[i].got_start= 1;
632 static int ogg_read_close(AVFormatContext *s)
634 struct ogg *ogg = s->priv_data;
637 for (i = 0; i < ogg->nstreams; i++) {
638 av_freep(&ogg->streams[i].buf);
639 if (ogg->streams[i].codec &&
640 ogg->streams[i].codec->cleanup) {
641 ogg->streams[i].codec->cleanup(s, i);
643 av_freep(&ogg->streams[i].private);
645 av_freep(&ogg->streams);
649 static int ogg_read_header(AVFormatContext *s)
651 struct ogg *ogg = s->priv_data;
656 //linear headers seek from start
658 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
663 } while (!ogg->headers);
664 av_dlog(s, "found headers\n");
666 for (i = 0; i < ogg->nstreams; i++) {
667 struct ogg_stream *os = ogg->streams + i;
669 if (ogg->streams[i].header < 0) {
670 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
671 ogg->streams[i].codec = NULL;
672 } else if (os->codec && os->nb_header < os->codec->nb_header) {
673 av_log(s, AV_LOG_WARNING,
674 "Headers mismatch for stream %d: "
675 "expected %d received %d.\n",
676 i, os->codec->nb_header, os->nb_header);
677 if (s->error_recognition & AV_EF_EXPLODE)
678 return AVERROR_INVALIDDATA;
680 if (os->start_granule != OGG_NOGRANULE_VALUE)
681 os->lastpts = s->streams[i]->start_time =
682 ogg_gptopts(s, i, os->start_granule, NULL);
685 //linear granulepos seek from end
691 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
693 struct ogg *ogg = s->priv_data;
694 struct ogg_stream *os = ogg->streams + idx;
695 int64_t pts = AV_NOPTS_VALUE;
698 *dts = AV_NOPTS_VALUE;
700 if (os->lastpts != AV_NOPTS_VALUE) {
702 os->lastpts = AV_NOPTS_VALUE;
704 if (os->lastdts != AV_NOPTS_VALUE) {
707 os->lastdts = AV_NOPTS_VALUE;
710 if (os->granule != -1LL) {
711 if (os->codec && os->codec->granule_is_start)
712 pts = ogg_gptopts(s, idx, os->granule, dts);
714 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
721 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
723 struct ogg *ogg = s->priv_data;
724 struct ogg_stream *os = ogg->streams + idx;
725 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
726 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
727 os->pflags ^= AV_PKT_FLAG_KEY;
728 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
729 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
734 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
737 struct ogg_stream *os;
740 int64_t fpos, pts, dts;
742 if (s->io_repositioned) {
744 s->io_repositioned = 0;
750 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
753 } while (idx < 0 || !s->streams[idx]);
756 os = ogg->streams + idx;
758 // pflags might not be set until after this
759 pts = ogg_calc_pts(s, idx, &dts);
760 ogg_validate_keyframe(s, idx, pstart, psize);
762 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
764 os->keyframe_seek = 0;
767 ret = av_new_packet(pkt, psize);
770 pkt->stream_index = idx;
771 memcpy(pkt->data, os->buf + pstart, psize);
775 pkt->flags = os->pflags;
776 pkt->duration = os->pduration;
779 if (os->end_trimming) {
780 uint8_t *side_data = av_packet_new_side_data(pkt,
781 AV_PKT_DATA_SKIP_SAMPLES,
783 if(side_data == NULL) {
786 return AVERROR(ENOMEM);
788 AV_WL32(side_data + 4, os->end_trimming);
789 os->end_trimming = 0;
795 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
796 int64_t *pos_arg, int64_t pos_limit)
798 struct ogg *ogg = s->priv_data;
799 AVIOContext *bc = s->pb;
800 int64_t pts = AV_NOPTS_VALUE;
804 avio_seek(bc, *pos_arg, SEEK_SET);
807 while ( avio_tell(bc) <= pos_limit
808 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
809 if (i == stream_index) {
810 struct ogg_stream *os = ogg->streams + stream_index;
811 // Dont trust the last timestamps of a ogm video
812 if ( (os->flags & OGG_FLAG_EOS)
813 && !(os->flags & OGG_FLAG_BOS)
814 && os->codec == &ff_ogm_video_codec)
816 pts = ogg_calc_pts(s, i, NULL);
817 ogg_validate_keyframe(s, i, pstart, psize);
818 if (os->pflags & AV_PKT_FLAG_KEY) {
820 } else if (os->keyframe_seek) {
821 // if we had a previous keyframe but no pts for it,
822 // return that keyframe with this pts value.
826 pts = AV_NOPTS_VALUE;
829 if (pts != AV_NOPTS_VALUE)
836 static int ogg_read_seek(AVFormatContext *s, int stream_index,
837 int64_t timestamp, int flags)
839 struct ogg *ogg = s->priv_data;
840 struct ogg_stream *os = ogg->streams + stream_index;
843 av_assert0(stream_index < ogg->nstreams);
844 // Ensure everything is reset even when seeking via
845 // the generated index.
848 // Try seeking to a keyframe first. If this fails (very possible),
849 // av_seek_frame will fall back to ignoring keyframes
850 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
851 && !(flags & AVSEEK_FLAG_ANY))
852 os->keyframe_seek = 1;
854 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
855 os = ogg->streams + stream_index;
857 os->keyframe_seek = 0;
861 static int ogg_probe(AVProbeData *p)
863 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
864 return AVPROBE_SCORE_MAX;
868 AVInputFormat ff_ogg_demuxer = {
870 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
871 .priv_data_size = sizeof(struct ogg),
872 .read_probe = ogg_probe,
873 .read_header = ogg_read_header,
874 .read_packet = ogg_read_packet,
875 .read_close = ogg_read_close,
876 .read_seek = ogg_read_seek,
877 .read_timestamp = ogg_read_timestamp,
879 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,