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;
142 if (start_pos <= s->data_offset) {
152 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
156 for (i = 0; ogg_codecs[i]; i++)
157 if (size >= ogg_codecs[i]->magicsize &&
158 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
159 return ogg_codecs[i];
164 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
167 struct ogg *ogg = s->priv_data;
168 int idx = ogg->nstreams++;
170 struct ogg_stream *os;
172 ogg->streams = av_realloc (ogg->streams,
173 ogg->nstreams * sizeof (*ogg->streams));
174 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
175 os = ogg->streams + idx;
177 os->bufsize = DECODER_BUFFER_SIZE;
178 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
182 st = avformat_new_stream(s, NULL);
184 return AVERROR(ENOMEM);
187 avpriv_set_pts_info(st, 64, 1, 1000000);
193 static int ogg_new_buf(struct ogg *ogg, int idx)
195 struct ogg_stream *os = ogg->streams + idx;
196 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
197 int size = os->bufpos - os->pstart;
199 memcpy(nb, os->buf + os->pstart, size);
209 static int ogg_read_page(AVFormatContext *s, int *str)
211 AVIOContext *bc = s->pb;
212 struct ogg *ogg = s->priv_data;
213 struct ogg_stream *os;
222 ret = avio_read(bc, sync, 4);
224 return ret < 0 ? ret : AVERROR_EOF;
229 if (sync[sp & 3] == 'O' &&
230 sync[(sp + 1) & 3] == 'g' &&
231 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
238 }while (i++ < MAX_PAGE_SIZE);
240 if (i >= MAX_PAGE_SIZE){
241 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
242 return AVERROR_INVALIDDATA;
245 if (avio_r8(bc) != 0){ /* version */
246 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
247 return AVERROR_INVALIDDATA;
252 serial = avio_rl32 (bc);
253 avio_skip(bc, 8); /* seq, crc */
256 idx = ogg_find_stream (ogg, serial);
261 if (ogg->nstreams != 1) {
262 av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
266 for (n = 0; n < ogg->nstreams; n++) {
267 av_freep(&ogg->streams[n].buf);
268 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
269 av_freep(&ogg->streams[n].private);
273 idx = ogg_new_stream(s, serial, 0);
275 idx = ogg_new_stream(s, serial, 1);
278 av_log (s, AV_LOG_ERROR, "failed to create stream (OOM?)\n");
283 os = ogg->streams + idx;
284 os->page_pos = avio_tell(bc) - 27;
287 ogg_new_buf(ogg, idx);
289 ret = avio_read(bc, os->segments, nsegs);
291 return ret < 0 ? ret : AVERROR_EOF;
297 for (i = 0; i < nsegs; i++)
298 size += os->segments[i];
300 if (flags & OGG_FLAG_CONT || os->incomplete){
302 // If this is the very first segment we started
303 // playback in the middle of a continuation packet.
304 // Discard it since we missed the start of it.
305 while (os->segp < os->nsegs){
306 int seg = os->segments[os->segp++];
311 os->sync_pos = os->page_pos;
315 os->sync_pos = os->page_pos;
318 if (os->bufsize - os->bufpos < size){
319 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
320 memcpy (nb, os->buf, os->bufpos);
325 ret = avio_read(bc, os->buf + os->bufpos, size);
327 return ret < 0 ? ret : AVERROR_EOF;
333 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
340 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
343 struct ogg *ogg = s->priv_data;
345 struct ogg_stream *os;
347 int segp = 0, psize = 0;
349 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
355 ret = ogg_read_page(s, &idx);
360 os = ogg->streams + idx;
362 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
363 idx, os->pstart, os->psize, os->segp, os->nsegs);
367 os->codec = ogg_find_codec (os->buf, os->bufpos);
369 av_log(s, AV_LOG_WARNING, "Codec not found\n");
381 while (os->segp < os->nsegs){
382 int ss = os->segments[os->segp++];
390 if (!complete && os->segp == os->nsegs){
392 // Do not set incomplete for empty packets.
393 // Together with the code in ogg_read_page
394 // that discards all continuation of empty packets
395 // we would get an infinite loop.
396 os->incomplete = !!os->psize;
401 if (os->granule == -1)
402 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
408 os->header = os->codec->header (s, idx);
413 // We have reached the first non-header packet in this stream.
414 // Unfortunately more header packets may still follow for others,
415 // but if we continue with header parsing we may lose data packets.
418 // Update the header state for all streams and
419 // compute the data_offset.
421 s->data_offset = os->sync_pos;
422 for (i = 0; i < ogg->nstreams; i++) {
423 struct ogg_stream *cur_os = ogg->streams + i;
425 // if we have a partial non-header packet, its start is
426 // obviously at or after the data start
427 if (cur_os->incomplete)
428 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
431 os->pstart += os->psize;
437 if (os->codec && os->codec->packet)
438 os->codec->packet (s, idx);
442 *dstart = os->pstart;
446 *fpos = os->sync_pos;
447 os->pstart += os->psize;
449 if(os->pstart == os->bufpos)
450 os->bufpos = os->pstart = 0;
451 os->sync_pos = os->page_pos;
454 // determine whether there are more complete packets in this page
455 // if not, the page's granule will apply to this packet
457 for (i = os->segp; i < os->nsegs; i++)
458 if (os->segments[i] < 255) {
463 if (os->segp == os->nsegs)
469 static int ogg_get_headers(AVFormatContext *s)
471 struct ogg *ogg = s->priv_data;
475 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
478 }while (!ogg->headers);
480 av_dlog(s, "found headers\n");
485 static int ogg_get_length(AVFormatContext *s)
487 struct ogg *ogg = s->priv_data;
496 if (s->duration != AV_NOPTS_VALUE)
499 size = avio_size(s->pb);
502 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
505 avio_seek (s->pb, end, SEEK_SET);
507 while (!ogg_read_page (s, &i)){
508 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
509 ogg->streams[i].codec) {
510 s->streams[i]->duration =
511 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
512 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
513 s->streams[i]->duration -= s->streams[i]->start_time;
514 streams_left-= (ogg->streams[i].got_start==-1);
515 ogg->streams[i].got_start= 1;
516 }else if(!ogg->streams[i].got_start){
517 ogg->streams[i].got_start= -1;
526 avio_seek (s->pb, s->data_offset, SEEK_SET);
529 while (!ogg_packet(s, &i, NULL, NULL, NULL)) {
531 int64_t pts = ogg_calc_pts(s, i, NULL);
532 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
533 s->streams[i]->duration -= pts;
534 ogg->streams[i].got_start= 1;
536 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
537 ogg->streams[i].got_start= 1;
549 static int ogg_read_header(AVFormatContext *s)
551 struct ogg *ogg = s->priv_data;
554 //linear headers seek from start
555 ret = ogg_get_headers(s);
559 for (i = 0; i < ogg->nstreams; i++)
560 if (ogg->streams[i].header < 0)
561 ogg->streams[i].codec = NULL;
563 //linear granulepos seek from end
566 //fill the extradata in the per codec callbacks
570 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
572 struct ogg *ogg = s->priv_data;
573 struct ogg_stream *os = ogg->streams + idx;
574 int64_t pts = AV_NOPTS_VALUE;
577 *dts = AV_NOPTS_VALUE;
579 if (os->lastpts != AV_NOPTS_VALUE) {
581 os->lastpts = AV_NOPTS_VALUE;
583 if (os->lastdts != AV_NOPTS_VALUE) {
586 os->lastdts = AV_NOPTS_VALUE;
589 if (os->granule != -1LL) {
590 if (os->codec && os->codec->granule_is_start)
591 pts = ogg_gptopts(s, idx, os->granule, dts);
593 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
600 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
602 struct ogg *ogg = s->priv_data;
603 struct ogg_stream *os = ogg->streams + idx;
604 if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
605 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
606 os->pflags ^= AV_PKT_FLAG_KEY;
607 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
608 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
613 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
616 struct ogg_stream *os;
619 int64_t fpos, pts, dts;
624 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
627 }while (idx < 0 || !s->streams[idx]);
630 os = ogg->streams + idx;
632 // pflags might not be set until after this
633 pts = ogg_calc_pts(s, idx, &dts);
634 ogg_validate_keyframe(s, idx, pstart, psize);
636 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
638 os->keyframe_seek = 0;
641 ret = av_new_packet(pkt, psize);
644 pkt->stream_index = idx;
645 memcpy (pkt->data, os->buf + pstart, psize);
649 pkt->flags = os->pflags;
650 pkt->duration = os->pduration;
656 static int ogg_read_close(AVFormatContext *s)
658 struct ogg *ogg = s->priv_data;
661 for (i = 0; i < ogg->nstreams; i++){
662 av_free (ogg->streams[i].buf);
663 av_free (ogg->streams[i].private);
665 av_free (ogg->streams);
669 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
670 int64_t *pos_arg, int64_t pos_limit)
672 struct ogg *ogg = s->priv_data;
673 AVIOContext *bc = s->pb;
674 int64_t pts = AV_NOPTS_VALUE;
678 avio_seek(bc, *pos_arg, SEEK_SET);
681 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
682 if (i == stream_index) {
683 struct ogg_stream *os = ogg->streams + stream_index;
684 pts = ogg_calc_pts(s, i, NULL);
685 ogg_validate_keyframe(s, i, pstart, psize);
686 if (os->pflags & AV_PKT_FLAG_KEY) {
688 } else if (os->keyframe_seek) {
689 // if we had a previous keyframe but no pts for it,
690 // return that keyframe with this pts value.
694 pts = AV_NOPTS_VALUE;
697 if (pts != AV_NOPTS_VALUE)
704 static int ogg_read_seek(AVFormatContext *s, int stream_index,
705 int64_t timestamp, int flags)
707 struct ogg *ogg = s->priv_data;
708 struct ogg_stream *os = ogg->streams + stream_index;
711 av_assert0(stream_index < ogg->nstreams);
712 // Ensure everything is reset even when seeking via
713 // the generated index.
716 // Try seeking to a keyframe first. If this fails (very possible),
717 // av_seek_frame will fall back to ignoring keyframes
718 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
719 && !(flags & AVSEEK_FLAG_ANY))
720 os->keyframe_seek = 1;
722 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
723 os = ogg->streams + stream_index;
725 os->keyframe_seek = 0;
729 static int ogg_probe(AVProbeData *p)
731 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
732 return AVPROBE_SCORE_MAX;
736 AVInputFormat ff_ogg_demuxer = {
738 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
739 .priv_data_size = sizeof(struct ogg),
740 .read_probe = ogg_probe,
741 .read_header = ogg_read_header,
742 .read_packet = ogg_read_packet,
743 .read_close = ogg_read_close,
744 .read_seek = ogg_read_seek,
745 .read_timestamp = ogg_read_timestamp,
747 .flags = AVFMT_GENERIC_INDEX,