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 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
60 //FIXME We could avoid some structure duplication
61 static int ogg_save(AVFormatContext *s)
63 struct ogg *ogg = s->priv_data;
64 struct ogg_state *ost =
65 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
67 ost->pos = avio_tell (s->pb);
68 ost->curidx = ogg->curidx;
69 ost->next = ogg->state;
70 ost->nstreams = ogg->nstreams;
71 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
73 for (i = 0; i < ogg->nstreams; i++){
74 struct ogg_stream *os = ogg->streams + i;
75 os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
76 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
84 static int ogg_restore(AVFormatContext *s, int discard)
86 struct ogg *ogg = s->priv_data;
87 AVIOContext *bc = s->pb;
88 struct ogg_state *ost = ogg->state;
94 ogg->state = ost->next;
97 struct ogg_stream *old_streams = ogg->streams;
99 for (i = 0; i < ogg->nstreams; i++)
100 av_free (ogg->streams[i].buf);
102 avio_seek (bc, ost->pos, SEEK_SET);
103 ogg->curidx = ost->curidx;
104 ogg->nstreams = ost->nstreams;
105 ogg->streams = av_realloc (ogg->streams,
106 ogg->nstreams * sizeof (*ogg->streams));
109 memcpy(ogg->streams, ost->streams,
110 ost->nstreams * sizeof(*ogg->streams));
112 av_free(old_streams);
122 static int ogg_reset(AVFormatContext *s)
124 struct ogg *ogg = s->priv_data;
126 int64_t start_pos = avio_tell(s->pb);
128 for (i = 0; i < ogg->nstreams; i++){
129 struct ogg_stream *os = ogg->streams + i;
134 os->lastpts = AV_NOPTS_VALUE;
135 os->lastdts = AV_NOPTS_VALUE;
141 if (start_pos <= s->data_offset) {
151 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
155 for (i = 0; ogg_codecs[i]; i++)
156 if (size >= ogg_codecs[i]->magicsize &&
157 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
158 return ogg_codecs[i];
163 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
166 struct ogg *ogg = s->priv_data;
167 int idx = ogg->nstreams++;
169 struct ogg_stream *os;
171 ogg->streams = av_realloc (ogg->streams,
172 ogg->nstreams * sizeof (*ogg->streams));
173 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
174 os = ogg->streams + idx;
176 os->bufsize = DECODER_BUFFER_SIZE;
177 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
181 st = avformat_new_stream(s, NULL);
183 return AVERROR(ENOMEM);
186 avpriv_set_pts_info(st, 64, 1, 1000000);
192 static int ogg_new_buf(struct ogg *ogg, int idx)
194 struct ogg_stream *os = ogg->streams + idx;
195 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
196 int size = os->bufpos - os->pstart;
198 memcpy(nb, os->buf + os->pstart, size);
208 static int ogg_read_page(AVFormatContext *s, int *str)
210 AVIOContext *bc = s->pb;
211 struct ogg *ogg = s->priv_data;
212 struct ogg_stream *os;
221 ret = avio_read(bc, sync, 4);
223 return ret < 0 ? ret : AVERROR_EOF;
228 if (sync[sp & 3] == 'O' &&
229 sync[(sp + 1) & 3] == 'g' &&
230 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
237 }while (i++ < MAX_PAGE_SIZE);
239 if (i >= MAX_PAGE_SIZE){
240 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
241 return AVERROR_INVALIDDATA;
244 if (avio_r8(bc) != 0){ /* version */
245 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
246 return AVERROR_INVALIDDATA;
251 serial = avio_rl32 (bc);
252 avio_skip(bc, 8); /* seq, crc */
255 idx = ogg_find_stream (ogg, serial);
260 if (ogg->nstreams != 1) {
261 av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
265 for (n = 0; n < ogg->nstreams; n++) {
266 av_freep(&ogg->streams[n].buf);
267 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
268 av_freep(&ogg->streams[n].private);
272 idx = ogg_new_stream(s, serial, 0);
274 idx = ogg_new_stream(s, serial, 1);
277 av_log (s, AV_LOG_ERROR, "failed to create stream (OOM?)\n");
282 os = ogg->streams + idx;
283 os->page_pos = avio_tell(bc) - 27;
286 ogg_new_buf(ogg, idx);
288 ret = avio_read(bc, os->segments, nsegs);
290 return ret < 0 ? ret : AVERROR_EOF;
296 for (i = 0; i < nsegs; i++)
297 size += os->segments[i];
299 if (flags & OGG_FLAG_CONT || os->incomplete){
301 // If this is the very first segment we started
302 // playback in the middle of a continuation packet.
303 // Discard it since we missed the start of it.
304 while (os->segp < os->nsegs){
305 int seg = os->segments[os->segp++];
310 os->sync_pos = os->page_pos;
314 os->sync_pos = os->page_pos;
317 if (os->bufsize - os->bufpos < size){
318 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
319 memcpy (nb, os->buf, os->bufpos);
324 ret = avio_read(bc, os->buf + os->bufpos, size);
326 return ret < 0 ? ret : AVERROR_EOF;
332 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
339 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
342 struct ogg *ogg = s->priv_data;
344 struct ogg_stream *os;
346 int segp = 0, psize = 0;
348 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
354 ret = ogg_read_page(s, &idx);
359 os = ogg->streams + idx;
361 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
362 idx, os->pstart, os->psize, os->segp, os->nsegs);
366 os->codec = ogg_find_codec (os->buf, os->bufpos);
368 av_log(s, AV_LOG_WARNING, "Codec not found\n");
380 while (os->segp < os->nsegs){
381 int ss = os->segments[os->segp++];
389 if (!complete && os->segp == os->nsegs){
391 // Do not set incomplete for empty packets.
392 // Together with the code in ogg_read_page
393 // that discards all continuation of empty packets
394 // we would get an infinite loop.
395 os->incomplete = !!os->psize;
400 if (os->granule == -1)
401 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
407 os->header = os->codec->header (s, idx);
412 // We have reached the first non-header packet in this stream.
413 // Unfortunately more header packets may still follow for others,
414 // but if we continue with header parsing we may lose data packets.
417 // Update the header state for all streams and
418 // compute the data_offset.
420 s->data_offset = os->sync_pos;
421 for (i = 0; i < ogg->nstreams; i++) {
422 struct ogg_stream *cur_os = ogg->streams + i;
424 // if we have a partial non-header packet, its start is
425 // obviously at or after the data start
426 if (cur_os->incomplete)
427 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
430 os->pstart += os->psize;
436 if (os->codec && os->codec->packet)
437 os->codec->packet (s, idx);
441 *dstart = os->pstart;
445 *fpos = os->sync_pos;
446 os->pstart += os->psize;
448 if(os->pstart == os->bufpos)
449 os->bufpos = os->pstart = 0;
450 os->sync_pos = os->page_pos;
453 // determine whether there are more complete packets in this page
454 // if not, the page's granule will apply to this packet
456 for (i = os->segp; i < os->nsegs; i++)
457 if (os->segments[i] < 255) {
462 if (os->segp == os->nsegs)
468 static int ogg_get_headers(AVFormatContext *s)
470 struct ogg *ogg = s->priv_data;
474 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
477 }while (!ogg->headers);
479 av_dlog(s, "found headers\n");
484 static int ogg_get_length(AVFormatContext *s)
486 struct ogg *ogg = s->priv_data;
495 if (s->duration != AV_NOPTS_VALUE)
498 size = avio_size(s->pb);
501 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
504 avio_seek (s->pb, end, SEEK_SET);
506 while (!ogg_read_page (s, &i)){
507 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
508 ogg->streams[i].codec) {
509 s->streams[i]->duration =
510 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
511 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
512 s->streams[i]->duration -= s->streams[i]->start_time;
513 streams_left-= (ogg->streams[i].got_start==-1);
514 ogg->streams[i].got_start= 1;
515 }else if(!ogg->streams[i].got_start){
516 ogg->streams[i].got_start= -1;
525 avio_seek (s->pb, s->data_offset, SEEK_SET);
527 while (!ogg_packet(s, &i, NULL, NULL, NULL)) {
528 int64_t pts = ogg_calc_pts(s, i, NULL);
529 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
530 s->streams[i]->duration -= pts;
531 ogg->streams[i].got_start= 1;
533 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
534 ogg->streams[i].got_start= 1;
545 static int ogg_read_header(AVFormatContext *s)
547 struct ogg *ogg = s->priv_data;
550 //linear headers seek from start
551 ret = ogg_get_headers(s);
555 for (i = 0; i < ogg->nstreams; i++)
556 if (ogg->streams[i].header < 0)
557 ogg->streams[i].codec = NULL;
559 //linear granulepos seek from end
562 //fill the extradata in the per codec callbacks
566 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
568 struct ogg *ogg = s->priv_data;
569 struct ogg_stream *os = ogg->streams + idx;
570 int64_t pts = AV_NOPTS_VALUE;
573 *dts = AV_NOPTS_VALUE;
575 if (os->lastpts != AV_NOPTS_VALUE) {
577 os->lastpts = AV_NOPTS_VALUE;
579 if (os->lastdts != AV_NOPTS_VALUE) {
582 os->lastdts = AV_NOPTS_VALUE;
585 if (os->granule != -1LL) {
586 if (os->codec && os->codec->granule_is_start)
587 pts = ogg_gptopts(s, idx, os->granule, dts);
589 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
596 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
598 struct ogg *ogg = s->priv_data;
599 struct ogg_stream *os = ogg->streams + idx;
600 if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
601 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
602 os->pflags ^= AV_PKT_FLAG_KEY;
603 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
604 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
609 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
612 struct ogg_stream *os;
615 int64_t fpos, pts, dts;
620 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
623 }while (idx < 0 || !s->streams[idx]);
626 os = ogg->streams + idx;
628 // pflags might not be set until after this
629 pts = ogg_calc_pts(s, idx, &dts);
630 ogg_validate_keyframe(s, idx, pstart, psize);
632 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
634 os->keyframe_seek = 0;
637 ret = av_new_packet(pkt, psize);
640 pkt->stream_index = idx;
641 memcpy (pkt->data, os->buf + pstart, psize);
645 pkt->flags = os->pflags;
646 pkt->duration = os->pduration;
652 static int ogg_read_close(AVFormatContext *s)
654 struct ogg *ogg = s->priv_data;
657 for (i = 0; i < ogg->nstreams; i++){
658 av_free (ogg->streams[i].buf);
659 av_free (ogg->streams[i].private);
661 av_free (ogg->streams);
665 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
666 int64_t *pos_arg, int64_t pos_limit)
668 struct ogg *ogg = s->priv_data;
669 AVIOContext *bc = s->pb;
670 int64_t pts = AV_NOPTS_VALUE;
674 avio_seek(bc, *pos_arg, SEEK_SET);
677 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
678 if (i == stream_index) {
679 struct ogg_stream *os = ogg->streams + stream_index;
680 pts = ogg_calc_pts(s, i, NULL);
681 ogg_validate_keyframe(s, i, pstart, psize);
682 if (os->pflags & AV_PKT_FLAG_KEY) {
684 } else if (os->keyframe_seek) {
685 // if we had a previous keyframe but no pts for it,
686 // return that keyframe with this pts value.
690 pts = AV_NOPTS_VALUE;
693 if (pts != AV_NOPTS_VALUE)
700 static int ogg_read_seek(AVFormatContext *s, int stream_index,
701 int64_t timestamp, int flags)
703 struct ogg *ogg = s->priv_data;
704 struct ogg_stream *os = ogg->streams + stream_index;
707 av_assert0(stream_index < ogg->nstreams);
708 // Ensure everything is reset even when seeking via
709 // the generated index.
712 // Try seeking to a keyframe first. If this fails (very possible),
713 // av_seek_frame will fall back to ignoring keyframes
714 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
715 && !(flags & AVSEEK_FLAG_ANY))
716 os->keyframe_seek = 1;
718 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
719 os = ogg->streams + stream_index;
721 os->keyframe_seek = 0;
725 static int ogg_probe(AVProbeData *p)
727 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
728 return AVPROBE_SCORE_MAX;
732 AVInputFormat ff_ogg_demuxer = {
734 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
735 .priv_data_size = sizeof(struct ogg),
736 .read_probe = ogg_probe,
737 .read_header = ogg_read_header,
738 .read_packet = ogg_read_packet,
739 .read_close = ogg_read_close,
740 .read_seek = ogg_read_seek,
741 .read_timestamp = ogg_read_timestamp,
743 .flags = AVFMT_GENERIC_INDEX,