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"
36 #include "vorbiscomment.h"
38 #define MAX_PAGE_SIZE 65307
39 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
41 static const struct ogg_codec * const ogg_codecs[] = {
59 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
60 static int ogg_read_close(AVFormatContext *s);
62 //FIXME We could avoid some structure duplication
63 static int ogg_save(AVFormatContext *s)
65 struct ogg *ogg = s->priv_data;
66 struct ogg_state *ost =
67 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
69 ost->pos = avio_tell(s->pb);
70 ost->curidx = ogg->curidx;
71 ost->next = ogg->state;
72 ost->nstreams = ogg->nstreams;
73 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
75 for (i = 0; i < ogg->nstreams; i++) {
76 struct ogg_stream *os = ogg->streams + i;
77 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
78 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
86 static int ogg_restore(AVFormatContext *s, int discard)
88 struct ogg *ogg = s->priv_data;
89 AVIOContext *bc = s->pb;
90 struct ogg_state *ost = ogg->state;
96 ogg->state = ost->next;
99 struct ogg_stream *old_streams = ogg->streams;
101 for (i = 0; i < ogg->nstreams; i++)
102 av_free(ogg->streams[i].buf);
104 avio_seek(bc, ost->pos, SEEK_SET);
105 ogg->curidx = ost->curidx;
106 ogg->nstreams = ost->nstreams;
107 ogg->streams = av_realloc(ogg->streams,
108 ogg->nstreams * sizeof(*ogg->streams));
111 memcpy(ogg->streams, ost->streams,
112 ost->nstreams * sizeof(*ogg->streams));
114 av_free(old_streams);
124 static int ogg_reset(AVFormatContext *s)
126 struct ogg *ogg = s->priv_data;
128 int64_t start_pos = avio_tell(s->pb);
130 for (i = 0; i < ogg->nstreams; i++) {
131 struct ogg_stream *os = ogg->streams + i;
136 os->lastpts = AV_NOPTS_VALUE;
137 os->lastdts = AV_NOPTS_VALUE;
144 if (start_pos <= s->data_offset) {
154 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
158 for (i = 0; ogg_codecs[i]; i++)
159 if (size >= ogg_codecs[i]->magicsize &&
160 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
161 return ogg_codecs[i];
167 * Replace the current stream with a new one. This is a typical webradio
168 * situation where a new audio stream spawn (identified with a new serial) and
169 * must replace the previous one (track switch).
171 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
173 struct ogg *ogg = s->priv_data;
174 struct ogg_stream *os;
177 struct ogg_codec *codec;
179 if (ogg->nstreams != 1) {
180 av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
181 return AVERROR_PATCHWELCOME;
184 os = &ogg->streams[0];
187 bufsize = os->bufsize;
190 if (!ogg->state || ogg->state->streams[0].private != os->private)
191 av_freep(&ogg->streams[0].private);
193 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
194 * also re-use the ogg_stream allocated buffer */
195 memset(os, 0, sizeof(*os));
197 os->bufsize = bufsize;
205 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
207 struct ogg *ogg = s->priv_data;
208 int idx = ogg->nstreams;
210 struct ogg_stream *os;
214 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
215 "in between Ogg context save/restore operations.\n");
219 /* Allocate and init a new Ogg Stream */
220 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
221 !(os = av_realloc(ogg->streams, size)))
222 return AVERROR(ENOMEM);
224 os = ogg->streams + idx;
225 memset(os, 0, sizeof(*os));
227 os->bufsize = DECODER_BUFFER_SIZE;
228 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
230 os->start_granule = OGG_NOGRANULE_VALUE;
232 return AVERROR(ENOMEM);
234 /* Create the associated AVStream */
235 st = avformat_new_stream(s, NULL);
238 return AVERROR(ENOMEM);
241 avpriv_set_pts_info(st, 64, 1, 1000000);
247 static int ogg_new_buf(struct ogg *ogg, int idx)
249 struct ogg_stream *os = ogg->streams + idx;
250 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
251 int size = os->bufpos - os->pstart;
254 memcpy(nb, os->buf + os->pstart, size);
265 static int data_packets_seen(const struct ogg *ogg)
269 for (i = 0; i < ogg->nstreams; i++)
270 if (ogg->streams[i].got_data)
275 static int ogg_read_page(AVFormatContext *s, int *sid)
277 AVIOContext *bc = s->pb;
278 struct ogg *ogg = s->priv_data;
279 struct ogg_stream *os;
288 ret = avio_read(bc, sync, 4);
290 return ret < 0 ? ret : AVERROR_EOF;
295 if (sync[sp & 3] == 'O' &&
296 sync[(sp + 1) & 3] == 'g' &&
297 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
306 } while (i++ < MAX_PAGE_SIZE);
308 if (i >= MAX_PAGE_SIZE) {
309 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
310 return AVERROR_INVALIDDATA;
313 if (avio_r8(bc) != 0) { /* version */
314 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
315 return AVERROR_INVALIDDATA;
320 serial = avio_rl32(bc);
321 avio_skip(bc, 8); /* seq, crc */
324 idx = ogg_find_stream(ogg, serial);
326 if (data_packets_seen(ogg))
327 idx = ogg_replace_stream(s, serial);
329 idx = ogg_new_stream(s, serial);
332 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
337 os = ogg->streams + idx;
338 os->page_pos = avio_tell(bc) - 27;
341 ogg_new_buf(ogg, idx);
343 ret = avio_read(bc, os->segments, nsegs);
345 return ret < 0 ? ret : AVERROR_EOF;
351 for (i = 0; i < nsegs; i++)
352 size += os->segments[i];
354 if (!(flags & OGG_FLAG_BOS))
357 if (flags & OGG_FLAG_CONT || os->incomplete) {
359 // If this is the very first segment we started
360 // playback in the middle of a continuation packet.
361 // Discard it since we missed the start of it.
362 while (os->segp < os->nsegs) {
363 int seg = os->segments[os->segp++];
368 os->sync_pos = os->page_pos;
372 os->sync_pos = os->page_pos;
375 if (os->bufsize - os->bufpos < size) {
376 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
378 return AVERROR(ENOMEM);
379 memcpy(nb, os->buf, os->bufpos);
384 ret = avio_read(bc, os->buf + os->bufpos, size);
386 return ret < 0 ? ret : AVERROR_EOF;
392 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
400 * @brief find the next Ogg packet
401 * @param *sid is set to the stream for the packet or -1 if there is
402 * no matching stream, in that case assume all other return
403 * values to be uninitialized.
404 * @return negative value on error or EOF.
406 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
409 struct ogg *ogg = s->priv_data;
411 struct ogg_stream *os;
413 int segp = 0, psize = 0;
415 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
423 ret = ogg_read_page(s, &idx);
428 os = ogg->streams + idx;
430 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
431 idx, os->pstart, os->psize, os->segp, os->nsegs);
434 if (os->header < 0) {
435 os->codec = ogg_find_codec(os->buf, os->bufpos);
437 av_log(s, AV_LOG_WARNING, "Codec not found\n");
449 while (os->segp < os->nsegs) {
450 int ss = os->segments[os->segp++];
458 if (!complete && os->segp == os->nsegs) {
460 // Do not set incomplete for empty packets.
461 // Together with the code in ogg_read_page
462 // that discards all continuation of empty packets
463 // we would get an infinite loop.
464 os->incomplete = !!os->psize;
469 if (os->granule == -1)
470 av_log(s, AV_LOG_WARNING,
471 "Page at %"PRId64" is missing granule\n",
478 os->header = os->codec->header(s, idx);
483 // We have reached the first non-header packet in this stream.
484 // Unfortunately more header packets may still follow for others,
485 // but if we continue with header parsing we may lose data packets.
488 // Update the header state for all streams and
489 // compute the data_offset.
491 s->data_offset = os->sync_pos;
493 for (i = 0; i < ogg->nstreams; i++) {
494 struct ogg_stream *cur_os = ogg->streams + i;
496 // if we have a partial non-header packet, its start is
497 // obviously at or after the data start
498 if (cur_os->incomplete)
499 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
503 os->pstart += os->psize;
509 if (os->codec && os->codec->packet)
510 os->codec->packet(s, idx);
514 *dstart = os->pstart;
518 *fpos = os->sync_pos;
519 os->pstart += os->psize;
521 if(os->pstart == os->bufpos)
522 os->bufpos = os->pstart = 0;
523 os->sync_pos = os->page_pos;
526 // determine whether there are more complete packets in this page
527 // if not, the page's granule will apply to this packet
529 for (i = os->segp; i < os->nsegs; i++)
530 if (os->segments[i] < 255) {
535 if (os->segp == os->nsegs)
541 static int ogg_get_length(AVFormatContext *s)
543 struct ogg *ogg = s->priv_data;
548 if (!s->pb->seekable)
552 if (s->duration != AV_NOPTS_VALUE)
555 size = avio_size(s->pb);
558 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
561 avio_seek(s->pb, end, SEEK_SET);
563 while (!ogg_read_page(s, &i)) {
564 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
565 ogg->streams[i].codec) {
566 s->streams[i]->duration =
567 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
568 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
569 s->streams[i]->duration -= s->streams[i]->start_time;
570 streams_left-= (ogg->streams[i].got_start==-1);
571 ogg->streams[i].got_start= 1;
572 } else if(!ogg->streams[i].got_start) {
573 ogg->streams[i].got_start= -1;
582 avio_seek (s->pb, s->data_offset, SEEK_SET);
584 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
587 pts = ogg_calc_pts(s, i, NULL);
588 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
589 s->streams[i]->duration -= pts;
590 ogg->streams[i].got_start= 1;
592 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
593 ogg->streams[i].got_start= 1;
602 static int ogg_read_header(AVFormatContext *s)
604 struct ogg *ogg = s->priv_data;
609 //linear headers seek from start
611 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
616 } while (!ogg->headers);
617 av_dlog(s, "found headers\n");
619 for (i = 0; i < ogg->nstreams; i++) {
620 struct ogg_stream *os = ogg->streams + i;
622 if (ogg->streams[i].header < 0) {
623 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
624 ogg->streams[i].codec = NULL;
625 } else if (os->codec && os->nb_header < os->codec->nb_header) {
626 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
628 if (os->start_granule != OGG_NOGRANULE_VALUE)
629 os->lastpts = s->streams[i]->start_time =
630 ogg_gptopts(s, i, os->start_granule, NULL);
633 //linear granulepos seek from end
639 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
641 struct ogg *ogg = s->priv_data;
642 struct ogg_stream *os = ogg->streams + idx;
643 int64_t pts = AV_NOPTS_VALUE;
646 *dts = AV_NOPTS_VALUE;
648 if (os->lastpts != AV_NOPTS_VALUE) {
650 os->lastpts = AV_NOPTS_VALUE;
652 if (os->lastdts != AV_NOPTS_VALUE) {
655 os->lastdts = AV_NOPTS_VALUE;
658 if (os->granule != -1LL) {
659 if (os->codec && os->codec->granule_is_start)
660 pts = ogg_gptopts(s, idx, os->granule, dts);
662 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
669 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
671 struct ogg *ogg = s->priv_data;
672 struct ogg_stream *os = ogg->streams + idx;
673 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
674 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
675 os->pflags ^= AV_PKT_FLAG_KEY;
676 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
677 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
682 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
685 struct ogg_stream *os;
688 int64_t fpos, pts, dts;
693 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
696 } while (idx < 0 || !s->streams[idx]);
699 os = ogg->streams + idx;
701 // pflags might not be set until after this
702 pts = ogg_calc_pts(s, idx, &dts);
703 ogg_validate_keyframe(s, idx, pstart, psize);
705 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
707 os->keyframe_seek = 0;
710 ret = av_new_packet(pkt, psize);
713 pkt->stream_index = idx;
714 memcpy(pkt->data, os->buf + pstart, psize);
718 pkt->flags = os->pflags;
719 pkt->duration = os->pduration;
725 static int ogg_read_close(AVFormatContext *s)
727 struct ogg *ogg = s->priv_data;
730 for (i = 0; i < ogg->nstreams; i++) {
731 av_free(ogg->streams[i].buf);
732 av_free(ogg->streams[i].private);
734 av_free(ogg->streams);
738 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
739 int64_t *pos_arg, int64_t pos_limit)
741 struct ogg *ogg = s->priv_data;
742 AVIOContext *bc = s->pb;
743 int64_t pts = AV_NOPTS_VALUE;
747 avio_seek(bc, *pos_arg, SEEK_SET);
750 while ( avio_tell(bc) <= pos_limit
751 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
752 if (i == stream_index) {
753 struct ogg_stream *os = ogg->streams + stream_index;
754 pts = ogg_calc_pts(s, i, NULL);
755 ogg_validate_keyframe(s, i, pstart, psize);
756 if (os->pflags & AV_PKT_FLAG_KEY) {
758 } else if (os->keyframe_seek) {
759 // if we had a previous keyframe but no pts for it,
760 // return that keyframe with this pts value.
764 pts = AV_NOPTS_VALUE;
767 if (pts != AV_NOPTS_VALUE)
774 static int ogg_read_seek(AVFormatContext *s, int stream_index,
775 int64_t timestamp, int flags)
777 struct ogg *ogg = s->priv_data;
778 struct ogg_stream *os = ogg->streams + stream_index;
781 av_assert0(stream_index < ogg->nstreams);
782 // Ensure everything is reset even when seeking via
783 // the generated index.
786 // Try seeking to a keyframe first. If this fails (very possible),
787 // av_seek_frame will fall back to ignoring keyframes
788 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
789 && !(flags & AVSEEK_FLAG_ANY))
790 os->keyframe_seek = 1;
792 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
793 os = ogg->streams + stream_index;
795 os->keyframe_seek = 0;
799 static int ogg_probe(AVProbeData *p)
801 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
802 return AVPROBE_SCORE_MAX;
806 AVInputFormat ff_ogg_demuxer = {
808 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
809 .priv_data_size = sizeof(struct ogg),
810 .read_probe = ogg_probe,
811 .read_header = ogg_read_header,
812 .read_packet = ogg_read_packet,
813 .read_close = ogg_read_close,
814 .read_seek = ogg_read_seek,
815 .read_timestamp = ogg_read_timestamp,
817 .flags = AVFMT_GENERIC_INDEX,