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;
177 if (ogg->nstreams != 1) {
178 av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
179 return AVERROR_PATCHWELCOME;
182 os = &ogg->streams[0];
185 bufsize = os->bufsize;
187 if (!ogg->state || ogg->state->streams[0].private != os->private)
188 av_freep(&ogg->streams[0].private);
190 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
191 * also re-use the ogg_stream allocated buffer */
192 memset(os, 0, sizeof(*os));
194 os->bufsize = bufsize;
201 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
203 struct ogg *ogg = s->priv_data;
204 int idx = ogg->nstreams;
206 struct ogg_stream *os;
210 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
211 "in between Ogg context save/restore operations.\n");
215 /* Allocate and init a new Ogg Stream */
216 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
217 !(os = av_realloc(ogg->streams, size)))
218 return AVERROR(ENOMEM);
220 os = ogg->streams + idx;
221 memset(os, 0, sizeof(*os));
223 os->bufsize = DECODER_BUFFER_SIZE;
224 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
226 os->start_granule = OGG_NOGRANULE_VALUE;
228 return AVERROR(ENOMEM);
230 /* Create the associated AVStream */
231 st = avformat_new_stream(s, NULL);
234 return AVERROR(ENOMEM);
237 avpriv_set_pts_info(st, 64, 1, 1000000);
243 static int ogg_new_buf(struct ogg *ogg, int idx)
245 struct ogg_stream *os = ogg->streams + idx;
246 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
247 int size = os->bufpos - os->pstart;
249 memcpy(nb, os->buf + os->pstart, size);
259 static int data_packets_seen(const struct ogg *ogg)
263 for (i = 0; i < ogg->nstreams; i++)
264 if (ogg->streams[i].got_data)
269 static int ogg_read_page(AVFormatContext *s, int *sid)
271 AVIOContext *bc = s->pb;
272 struct ogg *ogg = s->priv_data;
273 struct ogg_stream *os;
282 ret = avio_read(bc, sync, 4);
284 return ret < 0 ? ret : AVERROR_EOF;
289 if (sync[sp & 3] == 'O' &&
290 sync[(sp + 1) & 3] == 'g' &&
291 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
298 }while (i++ < MAX_PAGE_SIZE);
300 if (i >= MAX_PAGE_SIZE){
301 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
302 return AVERROR_INVALIDDATA;
305 if (avio_r8(bc) != 0){ /* version */
306 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
307 return AVERROR_INVALIDDATA;
312 serial = avio_rl32 (bc);
313 avio_skip(bc, 8); /* seq, crc */
316 idx = ogg_find_stream (ogg, serial);
318 if (data_packets_seen(ogg))
319 idx = ogg_replace_stream(s, serial);
321 idx = ogg_new_stream(s, serial);
324 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
329 os = ogg->streams + idx;
330 os->page_pos = avio_tell(bc) - 27;
333 ogg_new_buf(ogg, idx);
335 ret = avio_read(bc, os->segments, nsegs);
337 return ret < 0 ? ret : AVERROR_EOF;
343 for (i = 0; i < nsegs; i++)
344 size += os->segments[i];
346 if (!(flags & OGG_FLAG_BOS))
349 if (flags & OGG_FLAG_CONT || os->incomplete){
351 // If this is the very first segment we started
352 // playback in the middle of a continuation packet.
353 // Discard it since we missed the start of it.
354 while (os->segp < os->nsegs){
355 int seg = os->segments[os->segp++];
360 os->sync_pos = os->page_pos;
364 os->sync_pos = os->page_pos;
367 if (os->bufsize - os->bufpos < size){
368 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
369 memcpy (nb, os->buf, os->bufpos);
374 ret = avio_read(bc, os->buf + os->bufpos, size);
376 return ret < 0 ? ret : AVERROR_EOF;
382 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
390 * @brief find the next Ogg packet
391 * @param *sid is set to the stream for the packet or -1 if there is
392 * no matching stream, in that case assume all other return
393 * values to be uninitialized.
394 * @return negative value on error or EOF.
396 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
399 struct ogg *ogg = s->priv_data;
401 struct ogg_stream *os;
403 int segp = 0, psize = 0;
405 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
413 ret = ogg_read_page(s, &idx);
418 os = ogg->streams + idx;
420 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
421 idx, os->pstart, os->psize, os->segp, os->nsegs);
425 os->codec = ogg_find_codec (os->buf, os->bufpos);
427 av_log(s, AV_LOG_WARNING, "Codec not found\n");
439 while (os->segp < os->nsegs){
440 int ss = os->segments[os->segp++];
448 if (!complete && os->segp == os->nsegs){
450 // Do not set incomplete for empty packets.
451 // Together with the code in ogg_read_page
452 // that discards all continuation of empty packets
453 // we would get an infinite loop.
454 os->incomplete = !!os->psize;
459 if (os->granule == -1)
460 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
466 os->header = os->codec->header (s, idx);
471 // We have reached the first non-header packet in this stream.
472 // Unfortunately more header packets may still follow for others,
473 // but if we continue with header parsing we may lose data packets.
476 // Update the header state for all streams and
477 // compute the data_offset.
479 s->data_offset = os->sync_pos;
480 for (i = 0; i < ogg->nstreams; i++) {
481 struct ogg_stream *cur_os = ogg->streams + i;
483 // if we have a partial non-header packet, its start is
484 // obviously at or after the data start
485 if (cur_os->incomplete)
486 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
490 os->pstart += os->psize;
496 if (os->codec && os->codec->packet)
497 os->codec->packet (s, idx);
501 *dstart = os->pstart;
505 *fpos = os->sync_pos;
506 os->pstart += os->psize;
508 if(os->pstart == os->bufpos)
509 os->bufpos = os->pstart = 0;
510 os->sync_pos = os->page_pos;
513 // determine whether there are more complete packets in this page
514 // if not, the page's granule will apply to this packet
516 for (i = os->segp; i < os->nsegs; i++)
517 if (os->segments[i] < 255) {
522 if (os->segp == os->nsegs)
528 static int ogg_get_length(AVFormatContext *s)
530 struct ogg *ogg = s->priv_data;
539 if (s->duration != AV_NOPTS_VALUE)
542 size = avio_size(s->pb);
545 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
548 avio_seek (s->pb, end, SEEK_SET);
550 while (!ogg_read_page (s, &i)){
551 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
552 ogg->streams[i].codec) {
553 s->streams[i]->duration =
554 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
555 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
556 s->streams[i]->duration -= s->streams[i]->start_time;
557 streams_left-= (ogg->streams[i].got_start==-1);
558 ogg->streams[i].got_start= 1;
559 }else if(!ogg->streams[i].got_start){
560 ogg->streams[i].got_start= -1;
569 avio_seek (s->pb, s->data_offset, SEEK_SET);
571 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
574 pts = ogg_calc_pts(s, i, NULL);
575 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
576 s->streams[i]->duration -= pts;
577 ogg->streams[i].got_start= 1;
579 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
580 ogg->streams[i].got_start= 1;
589 static int ogg_read_header(AVFormatContext *s)
591 struct ogg *ogg = s->priv_data;
596 //linear headers seek from start
598 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
601 } while (!ogg->headers);
602 av_dlog(s, "found headers\n");
604 for (i = 0; i < ogg->nstreams; i++) {
605 struct ogg_stream *os = ogg->streams + i;
607 if (ogg->streams[i].header < 0) {
608 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
609 ogg->streams[i].codec = NULL;
610 } else if (os->codec && os->nb_header < os->codec->nb_header) {
611 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
613 if (os->start_granule != OGG_NOGRANULE_VALUE)
614 os->lastpts = s->streams[i]->start_time =
615 ogg_gptopts(s, i, os->start_granule, NULL);
618 //linear granulepos seek from end
624 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
626 struct ogg *ogg = s->priv_data;
627 struct ogg_stream *os = ogg->streams + idx;
628 int64_t pts = AV_NOPTS_VALUE;
631 *dts = AV_NOPTS_VALUE;
633 if (os->lastpts != AV_NOPTS_VALUE) {
635 os->lastpts = AV_NOPTS_VALUE;
637 if (os->lastdts != AV_NOPTS_VALUE) {
640 os->lastdts = AV_NOPTS_VALUE;
643 if (os->granule != -1LL) {
644 if (os->codec && os->codec->granule_is_start)
645 pts = ogg_gptopts(s, idx, os->granule, dts);
647 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
654 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
656 struct ogg *ogg = s->priv_data;
657 struct ogg_stream *os = ogg->streams + idx;
658 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
659 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
660 os->pflags ^= AV_PKT_FLAG_KEY;
661 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
662 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
667 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
670 struct ogg_stream *os;
673 int64_t fpos, pts, dts;
678 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
681 }while (idx < 0 || !s->streams[idx]);
684 os = ogg->streams + idx;
686 // pflags might not be set until after this
687 pts = ogg_calc_pts(s, idx, &dts);
688 ogg_validate_keyframe(s, idx, pstart, psize);
690 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
692 os->keyframe_seek = 0;
695 ret = av_new_packet(pkt, psize);
698 pkt->stream_index = idx;
699 memcpy (pkt->data, os->buf + pstart, psize);
703 pkt->flags = os->pflags;
704 pkt->duration = os->pduration;
710 static int ogg_read_close(AVFormatContext *s)
712 struct ogg *ogg = s->priv_data;
715 for (i = 0; i < ogg->nstreams; i++){
716 av_free (ogg->streams[i].buf);
717 av_free (ogg->streams[i].private);
719 av_free (ogg->streams);
723 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
724 int64_t *pos_arg, int64_t pos_limit)
726 struct ogg *ogg = s->priv_data;
727 AVIOContext *bc = s->pb;
728 int64_t pts = AV_NOPTS_VALUE;
732 avio_seek(bc, *pos_arg, SEEK_SET);
735 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
736 if (i == stream_index) {
737 struct ogg_stream *os = ogg->streams + stream_index;
738 pts = ogg_calc_pts(s, i, NULL);
739 ogg_validate_keyframe(s, i, pstart, psize);
740 if (os->pflags & AV_PKT_FLAG_KEY) {
742 } else if (os->keyframe_seek) {
743 // if we had a previous keyframe but no pts for it,
744 // return that keyframe with this pts value.
748 pts = AV_NOPTS_VALUE;
751 if (pts != AV_NOPTS_VALUE)
758 static int ogg_read_seek(AVFormatContext *s, int stream_index,
759 int64_t timestamp, int flags)
761 struct ogg *ogg = s->priv_data;
762 struct ogg_stream *os = ogg->streams + stream_index;
765 av_assert0(stream_index < ogg->nstreams);
766 // Ensure everything is reset even when seeking via
767 // the generated index.
770 // Try seeking to a keyframe first. If this fails (very possible),
771 // av_seek_frame will fall back to ignoring keyframes
772 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
773 && !(flags & AVSEEK_FLAG_ANY))
774 os->keyframe_seek = 1;
776 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
777 os = ogg->streams + stream_index;
779 os->keyframe_seek = 0;
783 static int ogg_probe(AVProbeData *p)
785 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
786 return AVPROBE_SCORE_MAX;
790 AVInputFormat ff_ogg_demuxer = {
792 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
793 .priv_data_size = sizeof(struct ogg),
794 .read_probe = ogg_probe,
795 .read_header = ogg_read_header,
796 .read_packet = ogg_read_packet,
797 .read_close = ogg_read_close,
798 .read_seek = ogg_read_seek,
799 .read_timestamp = ogg_read_timestamp,
801 .flags = AVFMT_GENERIC_INDEX,