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);
61 //FIXME We could avoid some structure duplication
62 static int ogg_save(AVFormatContext *s)
64 struct ogg *ogg = s->priv_data;
65 struct ogg_state *ost =
66 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
68 ost->pos = avio_tell(s->pb);
69 ost->curidx = ogg->curidx;
70 ost->next = ogg->state;
71 ost->nstreams = ogg->nstreams;
72 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
74 for (i = 0; i < ogg->nstreams; i++) {
75 struct ogg_stream *os = ogg->streams + i;
76 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
77 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
85 static int ogg_restore(AVFormatContext *s, int discard)
87 struct ogg *ogg = s->priv_data;
88 AVIOContext *bc = s->pb;
89 struct ogg_state *ost = ogg->state;
95 ogg->state = ost->next;
98 struct ogg_stream *old_streams = ogg->streams;
100 for (i = 0; i < ogg->nstreams; i++)
101 av_free(ogg->streams[i].buf);
103 avio_seek(bc, ost->pos, SEEK_SET);
104 ogg->curidx = ost->curidx;
105 ogg->nstreams = ost->nstreams;
106 ogg->streams = av_realloc(ogg->streams,
107 ogg->nstreams * sizeof(*ogg->streams));
110 memcpy(ogg->streams, ost->streams,
111 ost->nstreams * sizeof(*ogg->streams));
113 av_free(old_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) {
153 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
157 for (i = 0; ogg_codecs[i]; i++)
158 if (size >= ogg_codecs[i]->magicsize &&
159 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
160 return ogg_codecs[i];
166 * Replace the current stream with a new one. This is a typical webradio
167 * situation where a new audio stream spawn (identified with a new serial) and
168 * must replace the previous one (track switch).
170 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
172 struct ogg *ogg = s->priv_data;
173 struct ogg_stream *os;
176 const struct ogg_codec *codec;
178 if (ogg->nstreams != 1) {
179 av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
180 return AVERROR_PATCHWELCOME;
183 os = &ogg->streams[0];
186 bufsize = os->bufsize;
189 if (!ogg->state || ogg->state->streams[0].private != os->private)
190 av_freep(&ogg->streams[0].private);
192 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
193 * also re-use the ogg_stream allocated buffer */
194 memset(os, 0, sizeof(*os));
196 os->bufsize = bufsize;
204 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
206 struct ogg *ogg = s->priv_data;
207 int idx = ogg->nstreams;
209 struct ogg_stream *os;
213 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
214 "in between Ogg context save/restore operations.\n");
218 /* Allocate and init a new Ogg Stream */
219 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
220 !(os = av_realloc(ogg->streams, size)))
221 return AVERROR(ENOMEM);
223 os = ogg->streams + idx;
224 memset(os, 0, sizeof(*os));
226 os->bufsize = DECODER_BUFFER_SIZE;
227 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
229 os->start_granule = OGG_NOGRANULE_VALUE;
231 return AVERROR(ENOMEM);
233 /* Create the associated AVStream */
234 st = avformat_new_stream(s, NULL);
237 return AVERROR(ENOMEM);
240 avpriv_set_pts_info(st, 64, 1, 1000000);
246 static int ogg_new_buf(struct ogg *ogg, int idx)
248 struct ogg_stream *os = ogg->streams + idx;
249 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
250 int size = os->bufpos - os->pstart;
253 memcpy(nb, os->buf + os->pstart, size);
264 static int data_packets_seen(const struct ogg *ogg)
268 for (i = 0; i < ogg->nstreams; i++)
269 if (ogg->streams[i].got_data)
274 static int ogg_read_page(AVFormatContext *s, int *sid)
276 AVIOContext *bc = s->pb;
277 struct ogg *ogg = s->priv_data;
278 struct ogg_stream *os;
287 ret = avio_read(bc, sync, 4);
289 return ret < 0 ? ret : AVERROR_EOF;
294 if (sync[sp & 3] == 'O' &&
295 sync[(sp + 1) & 3] == 'g' &&
296 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
305 } while (i++ < MAX_PAGE_SIZE);
307 if (i >= MAX_PAGE_SIZE) {
308 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
309 return AVERROR_INVALIDDATA;
312 if (avio_r8(bc) != 0) { /* version */
313 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
314 return AVERROR_INVALIDDATA;
319 serial = avio_rl32(bc);
320 avio_skip(bc, 8); /* seq, crc */
323 idx = ogg_find_stream(ogg, serial);
325 if (data_packets_seen(ogg))
326 idx = ogg_replace_stream(s, serial);
328 idx = ogg_new_stream(s, serial);
331 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
336 os = ogg->streams + idx;
337 os->page_pos = avio_tell(bc) - 27;
340 ogg_new_buf(ogg, idx);
342 ret = avio_read(bc, os->segments, nsegs);
344 return ret < 0 ? ret : AVERROR_EOF;
350 for (i = 0; i < nsegs; i++)
351 size += os->segments[i];
353 if (!(flags & OGG_FLAG_BOS))
356 if (flags & OGG_FLAG_CONT || os->incomplete) {
358 // If this is the very first segment we started
359 // playback in the middle of a continuation packet.
360 // Discard it since we missed the start of it.
361 while (os->segp < os->nsegs) {
362 int seg = os->segments[os->segp++];
367 os->sync_pos = os->page_pos;
371 os->sync_pos = os->page_pos;
374 if (os->bufsize - os->bufpos < size) {
375 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
377 return AVERROR(ENOMEM);
378 memcpy(nb, os->buf, os->bufpos);
383 ret = avio_read(bc, os->buf + os->bufpos, size);
385 return ret < 0 ? ret : AVERROR_EOF;
391 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
399 * @brief find the next Ogg packet
400 * @param *sid is set to the stream for the packet or -1 if there is
401 * no matching stream, in that case assume all other return
402 * values to be uninitialized.
403 * @return negative value on error or EOF.
405 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
408 struct ogg *ogg = s->priv_data;
410 struct ogg_stream *os;
412 int segp = 0, psize = 0;
414 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
422 ret = ogg_read_page(s, &idx);
427 os = ogg->streams + idx;
429 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
430 idx, os->pstart, os->psize, os->segp, os->nsegs);
433 if (os->header < 0) {
434 os->codec = ogg_find_codec(os->buf, os->bufpos);
436 av_log(s, AV_LOG_WARNING, "Codec not found\n");
448 while (os->segp < os->nsegs) {
449 int ss = os->segments[os->segp++];
457 if (!complete && os->segp == os->nsegs) {
459 // Do not set incomplete for empty packets.
460 // Together with the code in ogg_read_page
461 // that discards all continuation of empty packets
462 // we would get an infinite loop.
463 os->incomplete = !!os->psize;
468 if (os->granule == -1)
469 av_log(s, AV_LOG_WARNING,
470 "Page at %"PRId64" is missing granule\n",
477 os->header = os->codec->header(s, idx);
482 // We have reached the first non-header packet in this stream.
483 // Unfortunately more header packets may still follow for others,
484 // but if we continue with header parsing we may lose data packets.
487 // Update the header state for all streams and
488 // compute the data_offset.
490 s->data_offset = os->sync_pos;
492 for (i = 0; i < ogg->nstreams; i++) {
493 struct ogg_stream *cur_os = ogg->streams + i;
495 // if we have a partial non-header packet, its start is
496 // obviously at or after the data start
497 if (cur_os->incomplete)
498 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
502 os->pstart += os->psize;
508 if (os->codec && os->codec->packet)
509 os->codec->packet(s, idx);
513 *dstart = os->pstart;
517 *fpos = os->sync_pos;
518 os->pstart += os->psize;
520 if(os->pstart == os->bufpos)
521 os->bufpos = os->pstart = 0;
522 os->sync_pos = os->page_pos;
525 // determine whether there are more complete packets in this page
526 // if not, the page's granule will apply to this packet
528 for (i = os->segp; i < os->nsegs; i++)
529 if (os->segments[i] < 255) {
534 if (os->segp == os->nsegs)
540 static int ogg_get_length(AVFormatContext *s)
542 struct ogg *ogg = s->priv_data;
547 if (!s->pb->seekable)
551 if (s->duration != AV_NOPTS_VALUE)
554 size = avio_size(s->pb);
557 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
560 avio_seek(s->pb, end, SEEK_SET);
562 while (!ogg_read_page(s, &i)) {
563 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
564 ogg->streams[i].codec) {
565 s->streams[i]->duration =
566 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
567 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
568 s->streams[i]->duration -= s->streams[i]->start_time;
569 streams_left-= (ogg->streams[i].got_start==-1);
570 ogg->streams[i].got_start= 1;
571 } else if(!ogg->streams[i].got_start) {
572 ogg->streams[i].got_start= -1;
581 avio_seek (s->pb, s->data_offset, SEEK_SET);
583 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
586 pts = ogg_calc_pts(s, i, NULL);
587 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
588 s->streams[i]->duration -= pts;
589 ogg->streams[i].got_start= 1;
591 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
592 ogg->streams[i].got_start= 1;
601 static int ogg_read_close(AVFormatContext *s)
603 struct ogg *ogg = s->priv_data;
606 for (i = 0; i < ogg->nstreams; i++) {
607 av_free(ogg->streams[i].buf);
608 if (ogg->streams[i].codec &&
609 ogg->streams[i].codec->cleanup) {
610 ogg->streams[i].codec->cleanup(s, i);
612 av_free(ogg->streams[i].private);
614 av_free(ogg->streams);
618 static int ogg_read_header(AVFormatContext *s)
620 struct ogg *ogg = s->priv_data;
625 //linear headers seek from start
627 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
632 } while (!ogg->headers);
633 av_dlog(s, "found headers\n");
635 for (i = 0; i < ogg->nstreams; i++) {
636 struct ogg_stream *os = ogg->streams + i;
638 if (ogg->streams[i].header < 0) {
639 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
640 ogg->streams[i].codec = NULL;
641 } else if (os->codec && os->nb_header < os->codec->nb_header) {
642 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
644 if (os->start_granule != OGG_NOGRANULE_VALUE)
645 os->lastpts = s->streams[i]->start_time =
646 ogg_gptopts(s, i, os->start_granule, NULL);
649 //linear granulepos seek from end
655 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
657 struct ogg *ogg = s->priv_data;
658 struct ogg_stream *os = ogg->streams + idx;
659 int64_t pts = AV_NOPTS_VALUE;
662 *dts = AV_NOPTS_VALUE;
664 if (os->lastpts != AV_NOPTS_VALUE) {
666 os->lastpts = AV_NOPTS_VALUE;
668 if (os->lastdts != AV_NOPTS_VALUE) {
671 os->lastdts = AV_NOPTS_VALUE;
674 if (os->granule != -1LL) {
675 if (os->codec && os->codec->granule_is_start)
676 pts = ogg_gptopts(s, idx, os->granule, dts);
678 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
685 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
687 struct ogg *ogg = s->priv_data;
688 struct ogg_stream *os = ogg->streams + idx;
689 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
690 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
691 os->pflags ^= AV_PKT_FLAG_KEY;
692 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
693 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
698 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
701 struct ogg_stream *os;
704 int64_t fpos, pts, dts;
709 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
712 } while (idx < 0 || !s->streams[idx]);
715 os = ogg->streams + idx;
717 // pflags might not be set until after this
718 pts = ogg_calc_pts(s, idx, &dts);
719 ogg_validate_keyframe(s, idx, pstart, psize);
721 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
723 os->keyframe_seek = 0;
726 ret = av_new_packet(pkt, psize);
729 pkt->stream_index = idx;
730 memcpy(pkt->data, os->buf + pstart, psize);
734 pkt->flags = os->pflags;
735 pkt->duration = os->pduration;
741 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
742 int64_t *pos_arg, int64_t pos_limit)
744 struct ogg *ogg = s->priv_data;
745 AVIOContext *bc = s->pb;
746 int64_t pts = AV_NOPTS_VALUE;
750 avio_seek(bc, *pos_arg, SEEK_SET);
753 while ( avio_tell(bc) <= pos_limit
754 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
755 if (i == stream_index) {
756 struct ogg_stream *os = ogg->streams + stream_index;
757 pts = ogg_calc_pts(s, i, NULL);
758 ogg_validate_keyframe(s, i, pstart, psize);
759 if (os->pflags & AV_PKT_FLAG_KEY) {
761 } else if (os->keyframe_seek) {
762 // if we had a previous keyframe but no pts for it,
763 // return that keyframe with this pts value.
767 pts = AV_NOPTS_VALUE;
770 if (pts != AV_NOPTS_VALUE)
777 static int ogg_read_seek(AVFormatContext *s, int stream_index,
778 int64_t timestamp, int flags)
780 struct ogg *ogg = s->priv_data;
781 struct ogg_stream *os = ogg->streams + stream_index;
784 av_assert0(stream_index < ogg->nstreams);
785 // Ensure everything is reset even when seeking via
786 // the generated index.
789 // Try seeking to a keyframe first. If this fails (very possible),
790 // av_seek_frame will fall back to ignoring keyframes
791 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
792 && !(flags & AVSEEK_FLAG_ANY))
793 os->keyframe_seek = 1;
795 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
796 os = ogg->streams + stream_index;
798 os->keyframe_seek = 0;
802 static int ogg_probe(AVProbeData *p)
804 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
805 return AVPROBE_SCORE_MAX;
809 AVInputFormat ff_ogg_demuxer = {
811 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
812 .priv_data_size = sizeof(struct ogg),
813 .read_probe = ogg_probe,
814 .read_header = ogg_read_header,
815 .read_packet = ogg_read_packet,
816 .read_close = ogg_read_close,
817 .read_seek = ogg_read_seek,
818 .read_timestamp = ogg_read_timestamp,
820 .flags = AVFMT_GENERIC_INDEX,