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[] = {
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;
98 for (i = 0; i < ogg->nstreams; i++)
99 av_free(ogg->streams[i].buf);
101 avio_seek(bc, ost->pos, SEEK_SET);
102 ogg->curidx = ost->curidx;
103 ogg->nstreams = ost->nstreams;
104 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
105 sizeof(*ogg->streams))) < 0) {
109 memcpy(ogg->streams, ost->streams,
110 ost->nstreams * sizeof(*ogg->streams));
118 static int ogg_reset(struct ogg *ogg)
122 for (i = 0; i < ogg->nstreams; i++) {
123 struct ogg_stream *os = ogg->streams + i;
128 os->lastpts = AV_NOPTS_VALUE;
129 os->lastdts = AV_NOPTS_VALUE;
142 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
146 for (i = 0; ogg_codecs[i]; i++)
147 if (size >= ogg_codecs[i]->magicsize &&
148 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
149 return ogg_codecs[i];
154 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
156 struct ogg *ogg = s->priv_data;
157 int idx = ogg->nstreams++;
159 struct ogg_stream *os;
161 os = av_realloc(ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
164 return AVERROR(ENOMEM);
168 memset(ogg->streams + idx, 0, sizeof(*ogg->streams));
170 os = ogg->streams + idx;
172 os->bufsize = DECODER_BUFFER_SIZE;
173 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
175 os->start_granule = OGG_NOGRANULE_VALUE;
178 st = avformat_new_stream(s, NULL);
180 return AVERROR(ENOMEM);
183 avpriv_set_pts_info(st, 64, 1, 1000000);
189 static int ogg_new_buf(struct ogg *ogg, int idx)
191 struct ogg_stream *os = ogg->streams + idx;
192 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
193 int size = os->bufpos - os->pstart;
196 memcpy(nb, os->buf + os->pstart, size);
207 static int ogg_read_page(AVFormatContext *s, int *str)
209 AVIOContext *bc = s->pb;
210 struct ogg *ogg = s->priv_data;
211 struct ogg_stream *os;
220 ret = avio_read(bc, sync, 4);
222 return ret < 0 ? ret : AVERROR_EOF;
227 if (sync[sp & 3] == 'O' &&
228 sync[(sp + 1) & 3] == 'g' &&
229 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, "cannot find sync word\n");
242 return AVERROR_INVALIDDATA;
245 if (avio_r8(bc) != 0) /* version */
246 return AVERROR_INVALIDDATA;
250 serial = avio_rl32(bc);
251 avio_skip(bc, 8); /* seq, crc */
254 idx = ogg_find_stream(ogg, serial);
259 for (n = 0; n < ogg->nstreams; n++) {
260 av_freep(&ogg->streams[n].buf);
262 ogg->state->streams[n].private != ogg->streams[n].private)
263 av_freep(&ogg->streams[n].private);
269 idx = ogg_new_stream(s, serial, 0);
271 idx = ogg_new_stream(s, serial, 1);
277 os = ogg->streams + idx;
278 os->page_pos = avio_tell(bc) - 27;
281 ogg_new_buf(ogg, idx);
283 ret = avio_read(bc, os->segments, nsegs);
285 return ret < 0 ? ret : AVERROR_EOF;
291 for (i = 0; i < nsegs; i++)
292 size += os->segments[i];
294 if (flags & OGG_FLAG_CONT || os->incomplete) {
296 while (os->segp < os->nsegs) {
297 int seg = os->segments[os->segp++];
302 os->sync_pos = os->page_pos;
306 os->sync_pos = os->page_pos;
309 if (os->bufsize - os->bufpos < size) {
310 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
312 return AVERROR(ENOMEM);
313 memcpy(nb, os->buf, os->bufpos);
318 ret = avio_read(bc, os->buf + os->bufpos, size);
320 return ret < 0 ? ret : AVERROR_EOF;
326 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
333 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
336 struct ogg *ogg = s->priv_data;
338 struct ogg_stream *os;
340 int segp = 0, psize = 0;
342 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
348 ret = ogg_read_page(s, &idx);
353 os = ogg->streams + idx;
355 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
356 idx, os->pstart, os->psize, os->segp, os->nsegs);
359 if (os->header < 0) {
360 os->codec = ogg_find_codec(os->buf, os->bufpos);
362 av_log(s, AV_LOG_WARNING, "Codec not found\n");
374 while (os->segp < os->nsegs) {
375 int ss = os->segments[os->segp++];
383 if (!complete && os->segp == os->nsegs) {
385 // Do not set incomplete for empty packets.
386 // Together with the code in ogg_read_page
387 // that discards all continuation of empty packets
388 // we would get an infinite loop.
389 os->incomplete = !!os->psize;
393 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
394 idx, os->psize, os->pstart);
396 if (os->granule == -1)
397 av_log(s, AV_LOG_WARNING,
398 "Page at %"PRId64" is missing granule\n",
405 os->header = os->codec->header(s, idx);
410 // We have reached the first non-header packet in this stream.
411 // Unfortunately more header packets may still follow for others,
412 // but if we continue with header parsing we may lose data packets.
415 // Update the header state for all streams and
416 // compute the data_offset.
417 if (!s->internal->data_offset)
418 s->internal->data_offset = os->sync_pos;
420 for (i = 0; i < ogg->nstreams; i++) {
421 struct ogg_stream *cur_os = ogg->streams + i;
423 // if we have a partial non-header packet, its start is
424 // obviously at or after the data start
425 if (cur_os->incomplete)
426 s->internal->data_offset = FFMIN(s->internal->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 os->sync_pos = os->page_pos;
451 // determine whether there are more complete packets in this page
452 // if not, the page's granule will apply to this packet
454 for (i = os->segp; i < os->nsegs; i++)
455 if (os->segments[i] < 255) {
460 if (os->segp == os->nsegs)
466 static int ogg_get_headers(AVFormatContext *s)
468 struct ogg *ogg = s->priv_data;
472 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
475 } while (!ogg->headers);
477 for (i = 0; i < ogg->nstreams; i++) {
478 struct ogg_stream *os = ogg->streams + i;
480 if (os->codec && os->codec->nb_header &&
481 os->nb_header < os->codec->nb_header) {
482 av_log(s, AV_LOG_ERROR,
483 "Headers mismatch for stream %d: "
484 "expected %d received %d.\n",
485 i, os->codec->nb_header, os->nb_header);
486 if (s->error_recognition & AV_EF_EXPLODE)
487 return AVERROR_INVALIDDATA;
489 if (os->start_granule != OGG_NOGRANULE_VALUE)
490 os->lastpts = s->streams[i]->start_time =
491 ogg_gptopts(s, i, os->start_granule, NULL);
493 av_dlog(s, "found headers\n");
498 static int ogg_get_length(AVFormatContext *s)
500 struct ogg *ogg = s->priv_data;
504 if (!s->pb->seekable)
508 if (s->duration != AV_NOPTS_VALUE)
511 size = avio_size(s->pb);
514 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
517 avio_seek(s->pb, end, SEEK_SET);
519 while (!ogg_read_page(s, &i)) {
520 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
521 ogg->streams[i].codec) {
522 s->streams[i]->duration =
523 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
524 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
525 s->streams[i]->duration -= s->streams[i]->start_time;
534 static int ogg_read_close(AVFormatContext *s)
536 struct ogg *ogg = s->priv_data;
539 for (i = 0; i < ogg->nstreams; i++) {
540 av_free(ogg->streams[i].buf);
541 if (ogg->streams[i].codec &&
542 ogg->streams[i].codec->cleanup) {
543 ogg->streams[i].codec->cleanup(s, i);
545 av_free(ogg->streams[i].private);
547 av_free(ogg->streams);
551 static int ogg_read_header(AVFormatContext *s)
553 struct ogg *ogg = s->priv_data;
556 //linear headers seek from start
557 ret = ogg_get_headers(s);
563 for (i = 0; i < ogg->nstreams; i++)
564 if (ogg->streams[i].header < 0)
565 ogg->streams[i].codec = NULL;
567 //linear granulepos seek from end
570 //fill the extradata in the per codec callbacks
574 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
576 struct ogg *ogg = s->priv_data;
577 struct ogg_stream *os = ogg->streams + idx;
578 int64_t pts = AV_NOPTS_VALUE;
581 *dts = AV_NOPTS_VALUE;
583 if (os->lastpts != AV_NOPTS_VALUE) {
585 os->lastpts = AV_NOPTS_VALUE;
587 if (os->lastdts != AV_NOPTS_VALUE) {
590 os->lastdts = AV_NOPTS_VALUE;
593 if (os->granule != -1LL) {
594 if (os->codec && os->codec->granule_is_start)
595 pts = ogg_gptopts(s, idx, os->granule, dts);
597 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
604 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
607 struct ogg_stream *os;
610 int64_t fpos, pts, dts;
615 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
618 } while (idx < 0 || !s->streams[idx]);
621 os = ogg->streams + idx;
623 // pflags might not be set until after this
624 pts = ogg_calc_pts(s, idx, &dts);
626 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
628 os->keyframe_seek = 0;
631 ret = av_new_packet(pkt, psize);
634 pkt->stream_index = idx;
635 memcpy(pkt->data, os->buf + pstart, psize);
639 pkt->flags = os->pflags;
640 pkt->duration = os->pduration;
646 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
647 int64_t *pos_arg, int64_t pos_limit)
649 struct ogg *ogg = s->priv_data;
650 AVIOContext *bc = s->pb;
651 int64_t pts = AV_NOPTS_VALUE;
653 avio_seek(bc, *pos_arg, SEEK_SET);
656 while (avio_tell(bc) < pos_limit &&
657 !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
658 if (i == stream_index) {
659 struct ogg_stream *os = ogg->streams + stream_index;
660 pts = ogg_calc_pts(s, i, NULL);
661 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
662 pts = AV_NOPTS_VALUE;
664 if (pts != AV_NOPTS_VALUE)
671 static int ogg_read_seek(AVFormatContext *s, int stream_index,
672 int64_t timestamp, int flags)
674 struct ogg *ogg = s->priv_data;
675 struct ogg_stream *os = ogg->streams + stream_index;
678 // Try seeking to a keyframe first. If this fails (very possible),
679 // av_seek_frame will fall back to ignoring keyframes
680 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
681 && !(flags & AVSEEK_FLAG_ANY))
682 os->keyframe_seek = 1;
684 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
685 os = ogg->streams + stream_index;
687 os->keyframe_seek = 0;
691 static int ogg_probe(AVProbeData *p)
693 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
694 return AVPROBE_SCORE_MAX;
698 AVInputFormat ff_ogg_demuxer = {
700 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
701 .priv_data_size = sizeof(struct ogg),
702 .read_probe = ogg_probe,
703 .read_header = ogg_read_header,
704 .read_packet = ogg_read_packet,
705 .read_close = ogg_read_close,
706 .read_seek = ogg_read_seek,
707 .read_timestamp = ogg_read_timestamp,
709 .flags = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,