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[] = {
58 //FIXME We could avoid some structure duplication
59 static int ogg_save(AVFormatContext *s)
61 struct ogg *ogg = s->priv_data;
62 struct ogg_state *ost =
63 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
65 ost->pos = avio_tell (s->pb);
66 ost->curidx = ogg->curidx;
67 ost->next = ogg->state;
68 ost->nstreams = ogg->nstreams;
69 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
71 for (i = 0; i < ogg->nstreams; i++){
72 struct ogg_stream *os = ogg->streams + i;
73 os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
74 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
82 static int ogg_restore(AVFormatContext *s, int discard)
84 struct ogg *ogg = s->priv_data;
85 AVIOContext *bc = s->pb;
86 struct ogg_state *ost = ogg->state;
92 ogg->state = ost->next;
95 struct ogg_stream *old_streams = ogg->streams;
97 for (i = 0; i < ogg->nstreams; i++)
98 av_free (ogg->streams[i].buf);
100 avio_seek (bc, ost->pos, SEEK_SET);
101 ogg->curidx = ost->curidx;
102 ogg->nstreams = ost->nstreams;
103 ogg->streams = av_realloc (ogg->streams,
104 ogg->nstreams * sizeof (*ogg->streams));
107 memcpy(ogg->streams, ost->streams,
108 ost->nstreams * sizeof(*ogg->streams));
110 av_free(old_streams);
120 static int ogg_reset(struct ogg *ogg)
124 for (i = 0; i < ogg->nstreams; i++){
125 struct ogg_stream *os = ogg->streams + i;
130 os->lastpts = AV_NOPTS_VALUE;
131 os->lastdts = AV_NOPTS_VALUE;
144 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
148 for (i = 0; ogg_codecs[i]; i++)
149 if (size >= ogg_codecs[i]->magicsize &&
150 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
151 return ogg_codecs[i];
156 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
159 struct ogg *ogg = s->priv_data;
160 int idx = ogg->nstreams++;
162 struct ogg_stream *os;
164 ogg->streams = av_realloc (ogg->streams,
165 ogg->nstreams * sizeof (*ogg->streams));
166 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
167 os = ogg->streams + idx;
169 os->bufsize = DECODER_BUFFER_SIZE;
170 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
174 st = avformat_new_stream(s, NULL);
176 return AVERROR(ENOMEM);
179 avpriv_set_pts_info(st, 64, 1, 1000000);
185 static int ogg_new_buf(struct ogg *ogg, int idx)
187 struct ogg_stream *os = ogg->streams + idx;
188 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
189 int size = os->bufpos - os->pstart;
191 memcpy(nb, os->buf + os->pstart, size);
201 static int ogg_read_page(AVFormatContext *s, int *str)
203 AVIOContext *bc = s->pb;
204 struct ogg *ogg = s->priv_data;
205 struct ogg_stream *os;
214 ret = avio_read(bc, sync, 4);
216 return ret < 0 ? ret : AVERROR_EOF;
221 if (sync[sp & 3] == 'O' &&
222 sync[(sp + 1) & 3] == 'g' &&
223 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
230 }while (i++ < MAX_PAGE_SIZE);
232 if (i >= MAX_PAGE_SIZE){
233 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
234 return AVERROR_INVALIDDATA;
237 if (avio_r8(bc) != 0) /* version */
238 return AVERROR_INVALIDDATA;
242 serial = avio_rl32 (bc);
243 avio_skip(bc, 8); /* seq, crc */
246 idx = ogg_find_stream (ogg, serial);
251 if (ogg->nstreams != 1)
254 for (n = 0; n < ogg->nstreams; n++) {
255 av_freep(&ogg->streams[n].buf);
256 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
257 av_freep(&ogg->streams[n].private);
261 idx = ogg_new_stream(s, serial, 0);
263 idx = ogg_new_stream(s, serial, 1);
269 os = ogg->streams + idx;
270 os->page_pos = avio_tell(bc) - 27;
273 ogg_new_buf(ogg, idx);
275 ret = avio_read(bc, os->segments, nsegs);
277 return ret < 0 ? ret : AVERROR_EOF;
283 for (i = 0; i < nsegs; i++)
284 size += os->segments[i];
286 if (flags & OGG_FLAG_CONT || os->incomplete){
288 // If this is the very first segment we started
289 // playback in the middle of a continuation packet.
290 // Discard it since we missed the start of it.
291 while (os->segp < os->nsegs){
292 int seg = os->segments[os->segp++];
297 os->sync_pos = os->page_pos;
301 os->sync_pos = os->page_pos;
304 if (os->bufsize - os->bufpos < size){
305 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
306 memcpy (nb, os->buf, os->bufpos);
311 ret = avio_read(bc, os->buf + os->bufpos, size);
313 return ret < 0 ? ret : AVERROR_EOF;
319 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
326 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
329 struct ogg *ogg = s->priv_data;
331 struct ogg_stream *os;
333 int segp = 0, psize = 0;
335 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
341 ret = ogg_read_page(s, &idx);
346 os = ogg->streams + idx;
348 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
349 idx, os->pstart, os->psize, os->segp, os->nsegs);
353 os->codec = ogg_find_codec (os->buf, os->bufpos);
355 av_log(s, AV_LOG_WARNING, "Codec not found\n");
367 while (os->segp < os->nsegs){
368 int ss = os->segments[os->segp++];
376 if (!complete && os->segp == os->nsegs){
378 // Do not set incomplete for empty packets.
379 // Together with the code in ogg_read_page
380 // that discards all continuation of empty packets
381 // we would get an infinite loop.
382 os->incomplete = !!os->psize;
387 if (os->granule == -1)
388 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
394 os->header = os->codec->header (s, idx);
399 // We have reached the first non-header packet in this stream.
400 // Unfortunately more header packets may still follow for others,
401 // but if we continue with header parsing we may lose data packets.
404 // Update the header state for all streams and
405 // compute the data_offset.
407 s->data_offset = os->sync_pos;
408 for (i = 0; i < ogg->nstreams; i++) {
409 struct ogg_stream *cur_os = ogg->streams + i;
411 // if we have a partial non-header packet, its start is
412 // obviously at or after the data start
413 if (cur_os->incomplete)
414 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
417 os->pstart += os->psize;
423 if (os->codec && os->codec->packet)
424 os->codec->packet (s, idx);
428 *dstart = os->pstart;
432 *fpos = os->sync_pos;
433 os->pstart += os->psize;
435 if(os->pstart == os->bufpos)
436 os->bufpos = os->pstart = 0;
437 os->sync_pos = os->page_pos;
440 // determine whether there are more complete packets in this page
441 // if not, the page's granule will apply to this packet
443 for (i = os->segp; i < os->nsegs; i++)
444 if (os->segments[i] < 255) {
449 if (os->segp == os->nsegs)
455 static int ogg_get_headers(AVFormatContext *s)
457 struct ogg *ogg = s->priv_data;
461 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
464 }while (!ogg->headers);
466 av_dlog(s, "found headers\n");
471 static int ogg_get_length(AVFormatContext *s)
473 struct ogg *ogg = s->priv_data;
482 if (s->duration != AV_NOPTS_VALUE)
485 size = avio_size(s->pb);
488 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
491 avio_seek (s->pb, end, SEEK_SET);
493 while (!ogg_read_page (s, &i)){
494 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
495 ogg->streams[i].codec) {
496 s->streams[i]->duration =
497 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
498 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
499 s->streams[i]->duration -= s->streams[i]->start_time;
500 streams_left-= (ogg->streams[i].got_start==-1);
501 ogg->streams[i].got_start= 1;
502 }else if(!ogg->streams[i].got_start){
503 ogg->streams[i].got_start= -1;
512 avio_seek (s->pb, 0, SEEK_SET);
513 while (!ogg_read_page (s, &i)){
514 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
515 ogg->streams[i].codec) {
516 if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
517 int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
518 if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
519 s->streams[i]->duration -= start;
520 ogg->streams[i].got_start= 1;
532 static int ogg_read_header(AVFormatContext *s)
534 struct ogg *ogg = s->priv_data;
537 //linear headers seek from start
538 ret = ogg_get_headers(s);
542 for (i = 0; i < ogg->nstreams; i++)
543 if (ogg->streams[i].header < 0)
544 ogg->streams[i].codec = NULL;
546 //linear granulepos seek from end
549 //fill the extradata in the per codec callbacks
553 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
555 struct ogg *ogg = s->priv_data;
556 struct ogg_stream *os = ogg->streams + idx;
557 int64_t pts = AV_NOPTS_VALUE;
560 *dts = AV_NOPTS_VALUE;
562 if (os->lastpts != AV_NOPTS_VALUE) {
564 os->lastpts = AV_NOPTS_VALUE;
566 if (os->lastdts != AV_NOPTS_VALUE) {
569 os->lastdts = AV_NOPTS_VALUE;
572 if (os->granule != -1LL) {
573 if (os->codec && os->codec->granule_is_start)
574 pts = ogg_gptopts(s, idx, os->granule, dts);
576 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
583 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
585 struct ogg *ogg = s->priv_data;
586 struct ogg_stream *os = ogg->streams + idx;
587 if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
588 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
589 os->pflags ^= AV_PKT_FLAG_KEY;
590 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
591 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
596 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
599 struct ogg_stream *os;
602 int64_t fpos, pts, dts;
607 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
610 }while (idx < 0 || !s->streams[idx]);
613 os = ogg->streams + idx;
615 // pflags might not be set until after this
616 pts = ogg_calc_pts(s, idx, &dts);
617 ogg_validate_keyframe(s, idx, pstart, psize);
619 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
621 os->keyframe_seek = 0;
624 ret = av_new_packet(pkt, psize);
627 pkt->stream_index = idx;
628 memcpy (pkt->data, os->buf + pstart, psize);
632 pkt->flags = os->pflags;
633 pkt->duration = os->pduration;
639 static int ogg_read_close(AVFormatContext *s)
641 struct ogg *ogg = s->priv_data;
644 for (i = 0; i < ogg->nstreams; i++){
645 av_free (ogg->streams[i].buf);
646 av_free (ogg->streams[i].private);
648 av_free (ogg->streams);
652 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
653 int64_t *pos_arg, int64_t pos_limit)
655 struct ogg *ogg = s->priv_data;
656 AVIOContext *bc = s->pb;
657 int64_t pts = AV_NOPTS_VALUE;
661 avio_seek(bc, *pos_arg, SEEK_SET);
664 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
665 if (i == stream_index) {
666 struct ogg_stream *os = ogg->streams + stream_index;
667 pts = ogg_calc_pts(s, i, NULL);
668 ogg_validate_keyframe(s, i, pstart, psize);
669 if (os->pflags & AV_PKT_FLAG_KEY) {
671 } else if (os->keyframe_seek) {
672 // if we had a previous keyframe but no pts for it,
673 // return that keyframe with this pts value.
677 pts = AV_NOPTS_VALUE;
680 if (pts != AV_NOPTS_VALUE)
687 static int ogg_read_seek(AVFormatContext *s, int stream_index,
688 int64_t timestamp, int flags)
690 struct ogg *ogg = s->priv_data;
691 struct ogg_stream *os = ogg->streams + stream_index;
694 av_assert0(stream_index < ogg->nstreams);
695 // Ensure everything is reset even when seeking via
696 // the generated index.
699 // Try seeking to a keyframe first. If this fails (very possible),
700 // av_seek_frame will fall back to ignoring keyframes
701 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
702 && !(flags & AVSEEK_FLAG_ANY))
703 os->keyframe_seek = 1;
705 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
706 os = ogg->streams + stream_index;
708 os->keyframe_seek = 0;
712 static int ogg_probe(AVProbeData *p)
714 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
715 return AVPROBE_SCORE_MAX;
719 AVInputFormat ff_ogg_demuxer = {
721 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
722 .priv_data_size = sizeof(struct ogg),
723 .read_probe = ogg_probe,
724 .read_header = ogg_read_header,
725 .read_packet = ogg_read_packet,
726 .read_close = ogg_read_close,
727 .read_seek = ogg_read_seek,
728 .read_timestamp = ogg_read_timestamp,
730 .flags = AVFMT_GENERIC_INDEX,