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);
528 while (!ogg_packet(s, &i, NULL, NULL, NULL)) {
529 int64_t pts = ogg_calc_pts(s, i, NULL);
530 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
531 s->streams[i]->duration -= pts;
532 ogg->streams[i].got_start= 1;
534 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
535 ogg->streams[i].got_start= 1;
546 static int ogg_read_header(AVFormatContext *s)
548 struct ogg *ogg = s->priv_data;
551 //linear headers seek from start
552 ret = ogg_get_headers(s);
556 for (i = 0; i < ogg->nstreams; i++)
557 if (ogg->streams[i].header < 0)
558 ogg->streams[i].codec = NULL;
560 //linear granulepos seek from end
563 //fill the extradata in the per codec callbacks
567 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
569 struct ogg *ogg = s->priv_data;
570 struct ogg_stream *os = ogg->streams + idx;
571 int64_t pts = AV_NOPTS_VALUE;
574 *dts = AV_NOPTS_VALUE;
576 if (os->lastpts != AV_NOPTS_VALUE) {
578 os->lastpts = AV_NOPTS_VALUE;
580 if (os->lastdts != AV_NOPTS_VALUE) {
583 os->lastdts = AV_NOPTS_VALUE;
586 if (os->granule != -1LL) {
587 if (os->codec && os->codec->granule_is_start)
588 pts = ogg_gptopts(s, idx, os->granule, dts);
590 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
597 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
599 struct ogg *ogg = s->priv_data;
600 struct ogg_stream *os = ogg->streams + idx;
601 if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
602 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
603 os->pflags ^= AV_PKT_FLAG_KEY;
604 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
605 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
610 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
613 struct ogg_stream *os;
616 int64_t fpos, pts, dts;
621 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
624 }while (idx < 0 || !s->streams[idx]);
627 os = ogg->streams + idx;
629 // pflags might not be set until after this
630 pts = ogg_calc_pts(s, idx, &dts);
631 ogg_validate_keyframe(s, idx, pstart, psize);
633 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
635 os->keyframe_seek = 0;
638 ret = av_new_packet(pkt, psize);
641 pkt->stream_index = idx;
642 memcpy (pkt->data, os->buf + pstart, psize);
646 pkt->flags = os->pflags;
647 pkt->duration = os->pduration;
653 static int ogg_read_close(AVFormatContext *s)
655 struct ogg *ogg = s->priv_data;
658 for (i = 0; i < ogg->nstreams; i++){
659 av_free (ogg->streams[i].buf);
660 av_free (ogg->streams[i].private);
662 av_free (ogg->streams);
666 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
667 int64_t *pos_arg, int64_t pos_limit)
669 struct ogg *ogg = s->priv_data;
670 AVIOContext *bc = s->pb;
671 int64_t pts = AV_NOPTS_VALUE;
675 avio_seek(bc, *pos_arg, SEEK_SET);
678 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
679 if (i == stream_index) {
680 struct ogg_stream *os = ogg->streams + stream_index;
681 pts = ogg_calc_pts(s, i, NULL);
682 ogg_validate_keyframe(s, i, pstart, psize);
683 if (os->pflags & AV_PKT_FLAG_KEY) {
685 } else if (os->keyframe_seek) {
686 // if we had a previous keyframe but no pts for it,
687 // return that keyframe with this pts value.
691 pts = AV_NOPTS_VALUE;
694 if (pts != AV_NOPTS_VALUE)
701 static int ogg_read_seek(AVFormatContext *s, int stream_index,
702 int64_t timestamp, int flags)
704 struct ogg *ogg = s->priv_data;
705 struct ogg_stream *os = ogg->streams + stream_index;
708 av_assert0(stream_index < ogg->nstreams);
709 // Ensure everything is reset even when seeking via
710 // the generated index.
713 // Try seeking to a keyframe first. If this fails (very possible),
714 // av_seek_frame will fall back to ignoring keyframes
715 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
716 && !(flags & AVSEEK_FLAG_ANY))
717 os->keyframe_seek = 1;
719 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
720 os = ogg->streams + stream_index;
722 os->keyframe_seek = 0;
726 static int ogg_probe(AVProbeData *p)
728 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
729 return AVPROBE_SCORE_MAX;
733 AVInputFormat ff_ogg_demuxer = {
735 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
736 .priv_data_size = sizeof(struct ogg),
737 .read_probe = ogg_probe,
738 .read_header = ogg_read_header,
739 .read_packet = ogg_read_packet,
740 .read_close = ogg_read_close,
741 .read_seek = ogg_read_seek,
742 .read_timestamp = ogg_read_timestamp,
744 .flags = AVFMT_GENERIC_INDEX,