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.
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 //FIXME We could avoid some structure duplication
60 static int ogg_save(AVFormatContext *s)
62 struct ogg *ogg = s->priv_data;
63 struct ogg_state *ost =
64 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
66 ost->pos = avio_tell(s->pb);
67 ost->curidx = ogg->curidx;
68 ost->next = ogg->state;
69 ost->nstreams = ogg->nstreams;
70 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
72 for (i = 0; i < ogg->nstreams; i++) {
73 struct ogg_stream *os = ogg->streams + i;
74 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
75 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
83 static int ogg_restore(AVFormatContext *s, int discard)
85 struct ogg *ogg = s->priv_data;
86 AVIOContext *bc = s->pb;
87 struct ogg_state *ost = ogg->state;
93 ogg->state = ost->next;
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 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
104 sizeof(*ogg->streams))) < 0) {
108 memcpy(ogg->streams, ost->streams,
109 ost->nstreams * sizeof(*ogg->streams));
117 static int ogg_reset(struct ogg *ogg)
121 for (i = 0; i < ogg->nstreams; i++) {
122 struct ogg_stream *os = ogg->streams + i;
127 os->lastpts = AV_NOPTS_VALUE;
128 os->lastdts = AV_NOPTS_VALUE;
141 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
145 for (i = 0; ogg_codecs[i]; i++)
146 if (size >= ogg_codecs[i]->magicsize &&
147 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
148 return ogg_codecs[i];
153 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
155 struct ogg *ogg = s->priv_data;
156 int idx = ogg->nstreams++;
158 struct ogg_stream *os;
160 os = av_realloc(ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
163 return AVERROR(ENOMEM);
167 memset(ogg->streams + idx, 0, sizeof(*ogg->streams));
169 os = ogg->streams + idx;
171 os->bufsize = DECODER_BUFFER_SIZE;
172 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
174 os->start_granule = OGG_NOGRANULE_VALUE;
177 st = avformat_new_stream(s, NULL);
179 return AVERROR(ENOMEM);
182 avpriv_set_pts_info(st, 64, 1, 1000000);
188 static int ogg_new_buf(struct ogg *ogg, int idx)
190 struct ogg_stream *os = ogg->streams + idx;
191 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
192 int size = os->bufpos - os->pstart;
195 memcpy(nb, os->buf + os->pstart, size);
206 static int ogg_read_page(AVFormatContext *s, int *str)
208 AVIOContext *bc = s->pb;
209 struct ogg *ogg = s->priv_data;
210 struct ogg_stream *os;
219 ret = avio_read(bc, sync, 4);
221 return ret < 0 ? ret : AVERROR_EOF;
226 if (sync[sp & 3] == 'O' &&
227 sync[(sp + 1) & 3] == 'g' &&
228 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, "cannot find sync word\n");
241 return AVERROR_INVALIDDATA;
244 if (avio_r8(bc) != 0) /* version */
245 return AVERROR_INVALIDDATA;
249 serial = avio_rl32(bc);
250 avio_skip(bc, 8); /* seq, crc */
253 idx = ogg_find_stream(ogg, serial);
258 for (n = 0; n < ogg->nstreams; n++) {
259 av_freep(&ogg->streams[n].buf);
261 ogg->state->streams[n].private != ogg->streams[n].private)
262 av_freep(&ogg->streams[n].private);
268 idx = ogg_new_stream(s, serial, 0);
270 idx = ogg_new_stream(s, serial, 1);
276 os = ogg->streams + idx;
277 os->page_pos = avio_tell(bc) - 27;
280 ogg_new_buf(ogg, idx);
282 ret = avio_read(bc, os->segments, nsegs);
284 return ret < 0 ? ret : AVERROR_EOF;
290 for (i = 0; i < nsegs; i++)
291 size += os->segments[i];
293 if (flags & OGG_FLAG_CONT || os->incomplete) {
295 while (os->segp < os->nsegs) {
296 int seg = os->segments[os->segp++];
301 os->sync_pos = os->page_pos;
305 os->sync_pos = os->page_pos;
308 if (os->bufsize - os->bufpos < size) {
309 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
311 return AVERROR(ENOMEM);
312 memcpy(nb, os->buf, os->bufpos);
317 ret = avio_read(bc, os->buf + os->bufpos, size);
319 return ret < 0 ? ret : AVERROR_EOF;
325 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
332 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
335 struct ogg *ogg = s->priv_data;
337 struct ogg_stream *os;
339 int segp = 0, psize = 0;
341 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
347 ret = ogg_read_page(s, &idx);
352 os = ogg->streams + idx;
354 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
355 idx, os->pstart, os->psize, os->segp, os->nsegs);
358 if (os->header < 0) {
359 os->codec = ogg_find_codec(os->buf, os->bufpos);
361 av_log(s, AV_LOG_WARNING, "Codec not found\n");
373 while (os->segp < os->nsegs) {
374 int ss = os->segments[os->segp++];
382 if (!complete && os->segp == os->nsegs) {
384 // Do not set incomplete for empty packets.
385 // Together with the code in ogg_read_page
386 // that discards all continuation of empty packets
387 // we would get an infinite loop.
388 os->incomplete = !!os->psize;
392 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
393 idx, os->psize, os->pstart);
395 if (os->granule == -1)
396 av_log(s, AV_LOG_WARNING,
397 "Page at %"PRId64" is missing granule\n",
404 os->header = os->codec->header(s, idx);
409 // We have reached the first non-header packet in this stream.
410 // Unfortunately more header packets may still follow for others,
411 // but if we continue with header parsing we may lose data packets.
414 // Update the header state for all streams and
415 // compute the data_offset.
417 s->data_offset = os->sync_pos;
419 for (i = 0; i < ogg->nstreams; i++) {
420 struct ogg_stream *cur_os = ogg->streams + i;
422 // if we have a partial non-header packet, its start is
423 // obviously at or after the data start
424 if (cur_os->incomplete)
425 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
429 os->pstart += os->psize;
435 if (os->codec && os->codec->packet)
436 os->codec->packet(s, idx);
440 *dstart = os->pstart;
444 *fpos = os->sync_pos;
445 os->pstart += os->psize;
447 os->sync_pos = os->page_pos;
450 // determine whether there are more complete packets in this page
451 // if not, the page's granule will apply to this packet
453 for (i = os->segp; i < os->nsegs; i++)
454 if (os->segments[i] < 255) {
459 if (os->segp == os->nsegs)
465 static int ogg_get_headers(AVFormatContext *s)
467 struct ogg *ogg = s->priv_data;
471 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
474 } while (!ogg->headers);
476 for (i = 0; i < ogg->nstreams; i++) {
477 struct ogg_stream *os = ogg->streams + i;
479 if (os->codec && os->codec->nb_header &&
480 os->nb_header < os->codec->nb_header) {
481 av_log(s, AV_LOG_ERROR,
482 "Headers mismatch for stream %d: "
483 "expected %d received %d.\n",
484 i, os->codec->nb_header, os->nb_header);
485 if (s->error_recognition & AV_EF_EXPLODE)
486 return AVERROR_INVALIDDATA;
488 if (os->start_granule != OGG_NOGRANULE_VALUE)
489 os->lastpts = s->streams[i]->start_time =
490 ogg_gptopts(s, i, os->start_granule, NULL);
492 av_dlog(s, "found headers\n");
497 static int ogg_get_length(AVFormatContext *s)
499 struct ogg *ogg = s->priv_data;
503 if (!s->pb->seekable)
507 if (s->duration != AV_NOPTS_VALUE)
510 size = avio_size(s->pb);
513 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
516 avio_seek(s->pb, end, SEEK_SET);
518 while (!ogg_read_page(s, &i)) {
519 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
520 ogg->streams[i].codec) {
521 s->streams[i]->duration =
522 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
523 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
524 s->streams[i]->duration -= s->streams[i]->start_time;
533 static int ogg_read_close(AVFormatContext *s)
535 struct ogg *ogg = s->priv_data;
538 for (i = 0; i < ogg->nstreams; i++) {
539 av_free(ogg->streams[i].buf);
540 if (ogg->streams[i].codec &&
541 ogg->streams[i].codec->cleanup) {
542 ogg->streams[i].codec->cleanup(s, i);
544 av_free(ogg->streams[i].private);
546 av_free(ogg->streams);
550 static int ogg_read_header(AVFormatContext *s)
552 struct ogg *ogg = s->priv_data;
555 //linear headers seek from start
556 ret = ogg_get_headers(s);
562 for (i = 0; i < ogg->nstreams; i++)
563 if (ogg->streams[i].header < 0)
564 ogg->streams[i].codec = NULL;
566 //linear granulepos seek from end
569 //fill the extradata in the per codec callbacks
573 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
575 struct ogg *ogg = s->priv_data;
576 struct ogg_stream *os = ogg->streams + idx;
577 int64_t pts = AV_NOPTS_VALUE;
580 *dts = AV_NOPTS_VALUE;
582 if (os->lastpts != AV_NOPTS_VALUE) {
584 os->lastpts = AV_NOPTS_VALUE;
586 if (os->lastdts != AV_NOPTS_VALUE) {
589 os->lastdts = AV_NOPTS_VALUE;
592 if (os->granule != -1LL) {
593 if (os->codec && os->codec->granule_is_start)
594 pts = ogg_gptopts(s, idx, os->granule, dts);
596 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
603 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
606 struct ogg_stream *os;
609 int64_t fpos, pts, dts;
614 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
617 } while (idx < 0 || !s->streams[idx]);
620 os = ogg->streams + idx;
622 // pflags might not be set until after this
623 pts = ogg_calc_pts(s, idx, &dts);
625 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
627 os->keyframe_seek = 0;
630 ret = av_new_packet(pkt, psize);
633 pkt->stream_index = idx;
634 memcpy(pkt->data, os->buf + pstart, psize);
638 pkt->flags = os->pflags;
639 pkt->duration = os->pduration;
645 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
646 int64_t *pos_arg, int64_t pos_limit)
648 struct ogg *ogg = s->priv_data;
649 AVIOContext *bc = s->pb;
650 int64_t pts = AV_NOPTS_VALUE;
652 avio_seek(bc, *pos_arg, SEEK_SET);
655 while (avio_tell(bc) < pos_limit &&
656 !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
657 if (i == stream_index) {
658 struct ogg_stream *os = ogg->streams + stream_index;
659 pts = ogg_calc_pts(s, i, NULL);
660 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
661 pts = AV_NOPTS_VALUE;
663 if (pts != AV_NOPTS_VALUE)
670 static int ogg_read_seek(AVFormatContext *s, int stream_index,
671 int64_t timestamp, int flags)
673 struct ogg *ogg = s->priv_data;
674 struct ogg_stream *os = ogg->streams + stream_index;
677 // Try seeking to a keyframe first. If this fails (very possible),
678 // av_seek_frame will fall back to ignoring keyframes
679 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
680 && !(flags & AVSEEK_FLAG_ANY))
681 os->keyframe_seek = 1;
683 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
684 os = ogg->streams + stream_index;
686 os->keyframe_seek = 0;
690 static int ogg_probe(AVProbeData *p)
692 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
693 return AVPROBE_SCORE_MAX;
697 AVInputFormat ff_ogg_demuxer = {
699 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
700 .priv_data_size = sizeof(struct ogg),
701 .read_probe = ogg_probe,
702 .read_header = ogg_read_header,
703 .read_packet = ogg_read_packet,
704 .read_close = ogg_read_close,
705 .read_seek = ogg_read_seek,
706 .read_timestamp = ogg_read_timestamp,
708 .flags = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,