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;
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;
188 if (!ogg->state || ogg->state->streams[0].private != os->private)
189 av_freep(&ogg->streams[0].private);
191 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
192 * also re-use the ogg_stream allocated buffer */
193 memset(os, 0, sizeof(*os));
195 os->bufsize = bufsize;
202 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
204 struct ogg *ogg = s->priv_data;
205 int idx = ogg->nstreams;
207 struct ogg_stream *os;
211 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
212 "in between Ogg context save/restore operations.\n");
216 /* Allocate and init a new Ogg Stream */
217 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
218 !(os = av_realloc(ogg->streams, size)))
219 return AVERROR(ENOMEM);
221 os = ogg->streams + idx;
222 memset(os, 0, sizeof(*os));
224 os->bufsize = DECODER_BUFFER_SIZE;
225 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
227 os->start_granule = OGG_NOGRANULE_VALUE;
229 return AVERROR(ENOMEM);
231 /* Create the associated AVStream */
232 st = avformat_new_stream(s, NULL);
235 return AVERROR(ENOMEM);
238 avpriv_set_pts_info(st, 64, 1, 1000000);
244 static int ogg_new_buf(struct ogg *ogg, int idx)
246 struct ogg_stream *os = ogg->streams + idx;
247 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
248 int size = os->bufpos - os->pstart;
250 memcpy(nb, os->buf + os->pstart, size);
260 static int data_packets_seen(const struct ogg *ogg)
264 for (i = 0; i < ogg->nstreams; i++)
265 if (ogg->streams[i].got_data)
270 static int ogg_read_page(AVFormatContext *s, int *sid)
272 AVIOContext *bc = s->pb;
273 struct ogg *ogg = s->priv_data;
274 struct ogg_stream *os;
283 ret = avio_read(bc, sync, 4);
285 return ret < 0 ? ret : AVERROR_EOF;
290 if (sync[sp & 3] == 'O' &&
291 sync[(sp + 1) & 3] == 'g' &&
292 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
299 }while (i++ < MAX_PAGE_SIZE);
301 if (i >= MAX_PAGE_SIZE){
302 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
303 return AVERROR_INVALIDDATA;
306 if (avio_r8(bc) != 0){ /* version */
307 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
308 return AVERROR_INVALIDDATA;
313 serial = avio_rl32 (bc);
314 avio_skip(bc, 8); /* seq, crc */
317 idx = ogg_find_stream (ogg, serial);
319 if (data_packets_seen(ogg))
320 idx = ogg_replace_stream(s, serial);
322 idx = ogg_new_stream(s, serial);
325 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
330 os = ogg->streams + idx;
331 os->page_pos = avio_tell(bc) - 27;
334 ogg_new_buf(ogg, idx);
336 ret = avio_read(bc, os->segments, nsegs);
338 return ret < 0 ? ret : AVERROR_EOF;
344 for (i = 0; i < nsegs; i++)
345 size += os->segments[i];
347 if (!(flags & OGG_FLAG_BOS))
350 if (flags & OGG_FLAG_CONT || os->incomplete){
352 // If this is the very first segment we started
353 // playback in the middle of a continuation packet.
354 // Discard it since we missed the start of it.
355 while (os->segp < os->nsegs){
356 int seg = os->segments[os->segp++];
361 os->sync_pos = os->page_pos;
365 os->sync_pos = os->page_pos;
368 if (os->bufsize - os->bufpos < size){
369 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
370 memcpy (nb, os->buf, os->bufpos);
375 ret = avio_read(bc, os->buf + os->bufpos, size);
377 return ret < 0 ? ret : AVERROR_EOF;
383 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
391 * @brief find the next Ogg packet
392 * @param *sid is set to the stream for the packet or -1 if there is
393 * no matching stream, in that case assume all other return
394 * values to be uninitialized.
395 * @return negative value on error or EOF.
397 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
400 struct ogg *ogg = s->priv_data;
402 struct ogg_stream *os;
404 int segp = 0, psize = 0;
406 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
414 ret = ogg_read_page(s, &idx);
419 os = ogg->streams + idx;
421 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
422 idx, os->pstart, os->psize, os->segp, os->nsegs);
426 os->codec = ogg_find_codec (os->buf, os->bufpos);
428 av_log(s, AV_LOG_WARNING, "Codec not found\n");
440 while (os->segp < os->nsegs){
441 int ss = os->segments[os->segp++];
449 if (!complete && os->segp == os->nsegs){
451 // Do not set incomplete for empty packets.
452 // Together with the code in ogg_read_page
453 // that discards all continuation of empty packets
454 // we would get an infinite loop.
455 os->incomplete = !!os->psize;
460 if (os->granule == -1)
461 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
467 os->header = os->codec->header (s, idx);
472 // We have reached the first non-header packet in this stream.
473 // Unfortunately more header packets may still follow for others,
474 // but if we continue with header parsing we may lose data packets.
477 // Update the header state for all streams and
478 // compute the data_offset.
480 s->data_offset = os->sync_pos;
481 for (i = 0; i < ogg->nstreams; i++) {
482 struct ogg_stream *cur_os = ogg->streams + i;
484 // if we have a partial non-header packet, its start is
485 // obviously at or after the data start
486 if (cur_os->incomplete)
487 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
491 os->pstart += os->psize;
497 if (os->codec && os->codec->packet)
498 os->codec->packet (s, idx);
502 *dstart = os->pstart;
506 *fpos = os->sync_pos;
507 os->pstart += os->psize;
509 if(os->pstart == os->bufpos)
510 os->bufpos = os->pstart = 0;
511 os->sync_pos = os->page_pos;
514 // determine whether there are more complete packets in this page
515 // if not, the page's granule will apply to this packet
517 for (i = os->segp; i < os->nsegs; i++)
518 if (os->segments[i] < 255) {
523 if (os->segp == os->nsegs)
529 static int ogg_get_length(AVFormatContext *s)
531 struct ogg *ogg = s->priv_data;
540 if (s->duration != AV_NOPTS_VALUE)
543 size = avio_size(s->pb);
546 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
549 avio_seek (s->pb, end, SEEK_SET);
551 while (!ogg_read_page (s, &i)){
552 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
553 ogg->streams[i].codec) {
554 s->streams[i]->duration =
555 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
556 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
557 s->streams[i]->duration -= s->streams[i]->start_time;
558 streams_left-= (ogg->streams[i].got_start==-1);
559 ogg->streams[i].got_start= 1;
560 }else if(!ogg->streams[i].got_start){
561 ogg->streams[i].got_start= -1;
570 avio_seek (s->pb, s->data_offset, SEEK_SET);
572 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
575 pts = ogg_calc_pts(s, i, NULL);
576 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
577 s->streams[i]->duration -= pts;
578 ogg->streams[i].got_start= 1;
580 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
581 ogg->streams[i].got_start= 1;
590 static int ogg_read_header(AVFormatContext *s)
592 struct ogg *ogg = s->priv_data;
597 //linear headers seek from start
599 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
604 } while (!ogg->headers);
605 av_dlog(s, "found headers\n");
607 for (i = 0; i < ogg->nstreams; i++) {
608 struct ogg_stream *os = ogg->streams + i;
610 if (ogg->streams[i].header < 0) {
611 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
612 ogg->streams[i].codec = NULL;
613 } else if (os->codec && os->nb_header < os->codec->nb_header) {
614 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
616 if (os->start_granule != OGG_NOGRANULE_VALUE)
617 os->lastpts = s->streams[i]->start_time =
618 ogg_gptopts(s, i, os->start_granule, NULL);
621 //linear granulepos seek from end
627 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
629 struct ogg *ogg = s->priv_data;
630 struct ogg_stream *os = ogg->streams + idx;
631 int64_t pts = AV_NOPTS_VALUE;
634 *dts = AV_NOPTS_VALUE;
636 if (os->lastpts != AV_NOPTS_VALUE) {
638 os->lastpts = AV_NOPTS_VALUE;
640 if (os->lastdts != AV_NOPTS_VALUE) {
643 os->lastdts = AV_NOPTS_VALUE;
646 if (os->granule != -1LL) {
647 if (os->codec && os->codec->granule_is_start)
648 pts = ogg_gptopts(s, idx, os->granule, dts);
650 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
657 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
659 struct ogg *ogg = s->priv_data;
660 struct ogg_stream *os = ogg->streams + idx;
661 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
662 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
663 os->pflags ^= AV_PKT_FLAG_KEY;
664 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
665 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
670 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
673 struct ogg_stream *os;
676 int64_t fpos, pts, dts;
681 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
684 }while (idx < 0 || !s->streams[idx]);
687 os = ogg->streams + idx;
689 // pflags might not be set until after this
690 pts = ogg_calc_pts(s, idx, &dts);
691 ogg_validate_keyframe(s, idx, pstart, psize);
693 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
695 os->keyframe_seek = 0;
698 ret = av_new_packet(pkt, psize);
701 pkt->stream_index = idx;
702 memcpy (pkt->data, os->buf + pstart, psize);
706 pkt->flags = os->pflags;
707 pkt->duration = os->pduration;
713 static int ogg_read_close(AVFormatContext *s)
715 struct ogg *ogg = s->priv_data;
718 for (i = 0; i < ogg->nstreams; i++){
719 av_free (ogg->streams[i].buf);
720 av_free (ogg->streams[i].private);
722 av_free (ogg->streams);
726 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
727 int64_t *pos_arg, int64_t pos_limit)
729 struct ogg *ogg = s->priv_data;
730 AVIOContext *bc = s->pb;
731 int64_t pts = AV_NOPTS_VALUE;
735 avio_seek(bc, *pos_arg, SEEK_SET);
738 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
739 if (i == stream_index) {
740 struct ogg_stream *os = ogg->streams + stream_index;
741 pts = ogg_calc_pts(s, i, NULL);
742 ogg_validate_keyframe(s, i, pstart, psize);
743 if (os->pflags & AV_PKT_FLAG_KEY) {
745 } else if (os->keyframe_seek) {
746 // if we had a previous keyframe but no pts for it,
747 // return that keyframe with this pts value.
751 pts = AV_NOPTS_VALUE;
754 if (pts != AV_NOPTS_VALUE)
761 static int ogg_read_seek(AVFormatContext *s, int stream_index,
762 int64_t timestamp, int flags)
764 struct ogg *ogg = s->priv_data;
765 struct ogg_stream *os = ogg->streams + stream_index;
768 av_assert0(stream_index < ogg->nstreams);
769 // Ensure everything is reset even when seeking via
770 // the generated index.
773 // Try seeking to a keyframe first. If this fails (very possible),
774 // av_seek_frame will fall back to ignoring keyframes
775 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
776 && !(flags & AVSEEK_FLAG_ANY))
777 os->keyframe_seek = 1;
779 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
780 os = ogg->streams + stream_index;
782 os->keyframe_seek = 0;
786 static int ogg_probe(AVProbeData *p)
788 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
789 return AVPROBE_SCORE_MAX;
793 AVInputFormat ff_ogg_demuxer = {
795 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
796 .priv_data_size = sizeof(struct ogg),
797 .read_probe = ogg_probe,
798 .read_header = ogg_read_header,
799 .read_packet = ogg_read_packet,
800 .read_close = ogg_read_close,
801 .read_seek = ogg_read_seek,
802 .read_timestamp = ogg_read_timestamp,
804 .flags = AVFMT_GENERIC_INDEX,