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[] = {
58 //FIXME We could avoid some structure duplication
59 static int ogg_save(AVFormatContext *s)
61 struct ogg *ogg = s->priv_data;
62 struct ogg_state *ost =
63 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
65 ost->pos = avio_tell(s->pb);
66 ost->curidx = ogg->curidx;
67 ost->next = ogg->state;
68 ost->nstreams = ogg->nstreams;
69 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
71 for (i = 0; i < ogg->nstreams; i++) {
72 struct ogg_stream *os = ogg->streams + i;
73 os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
74 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
82 static int ogg_restore(AVFormatContext *s, int discard)
84 struct ogg *ogg = s->priv_data;
85 AVIOContext *bc = s->pb;
86 struct ogg_state *ost = ogg->state;
92 ogg->state = ost->next;
95 struct ogg_stream *old_streams = ogg->streams;
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 ogg->streams = av_realloc(ogg->streams,
104 ogg->nstreams * sizeof(*ogg->streams));
107 memcpy(ogg->streams, ost->streams,
108 ost->nstreams * sizeof(*ogg->streams));
110 av_free(old_streams);
120 static int ogg_reset(struct ogg *ogg)
124 for (i = 0; i < ogg->nstreams; i++) {
125 struct ogg_stream *os = ogg->streams + i;
130 os->lastpts = AV_NOPTS_VALUE;
131 os->lastdts = AV_NOPTS_VALUE;
144 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
148 for (i = 0; ogg_codecs[i]; i++)
149 if (size >= ogg_codecs[i]->magicsize &&
150 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
151 return ogg_codecs[i];
156 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
158 struct ogg *ogg = s->priv_data;
159 int idx = ogg->nstreams++;
161 struct ogg_stream *os;
163 os = av_realloc(ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
166 return AVERROR(ENOMEM);
170 memset(ogg->streams + idx, 0, sizeof(*ogg->streams));
172 os = ogg->streams + idx;
174 os->bufsize = DECODER_BUFFER_SIZE;
175 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
177 os->start_granule = OGG_NOGRANULE_VALUE;
180 st = avformat_new_stream(s, NULL);
182 return AVERROR(ENOMEM);
185 avpriv_set_pts_info(st, 64, 1, 1000000);
191 static int ogg_new_buf(struct ogg *ogg, int idx)
193 struct ogg_stream *os = ogg->streams + idx;
194 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
195 int size = os->bufpos - os->pstart;
198 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')
240 } while (i++ < MAX_PAGE_SIZE);
242 if (i >= MAX_PAGE_SIZE) {
243 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
244 return AVERROR_INVALIDDATA;
247 if (avio_r8(bc) != 0) /* version */
248 return AVERROR_INVALIDDATA;
252 serial = avio_rl32(bc);
253 avio_skip(bc, 8); /* seq, crc */
256 idx = ogg_find_stream(ogg, serial);
261 for (n = 0; n < ogg->nstreams; n++) {
262 av_freep(&ogg->streams[n].buf);
264 ogg->state->streams[n].private != ogg->streams[n].private)
265 av_freep(&ogg->streams[n].private);
271 idx = ogg_new_stream(s, serial, 0);
273 idx = ogg_new_stream(s, serial, 1);
279 os = ogg->streams + idx;
280 os->page_pos = avio_tell(bc) - 27;
283 ogg_new_buf(ogg, idx);
285 ret = avio_read(bc, os->segments, nsegs);
287 return ret < 0 ? ret : AVERROR_EOF;
293 for (i = 0; i < nsegs; i++)
294 size += os->segments[i];
296 if (flags & OGG_FLAG_CONT || os->incomplete) {
298 while (os->segp < os->nsegs) {
299 int seg = os->segments[os->segp++];
304 os->sync_pos = os->page_pos;
308 os->sync_pos = os->page_pos;
311 if (os->bufsize - os->bufpos < size) {
312 uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
314 return AVERROR(ENOMEM);
315 memcpy(nb, os->buf, os->bufpos);
320 ret = avio_read(bc, os->buf + os->bufpos, size);
322 return ret < 0 ? ret : AVERROR_EOF;
328 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
335 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
338 struct ogg *ogg = s->priv_data;
340 struct ogg_stream *os;
342 int segp = 0, psize = 0;
344 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
350 ret = ogg_read_page(s, &idx);
355 os = ogg->streams + idx;
357 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
358 idx, os->pstart, os->psize, os->segp, os->nsegs);
361 if (os->header < 0) {
362 os->codec = ogg_find_codec(os->buf, os->bufpos);
364 av_log(s, AV_LOG_WARNING, "Codec not found\n");
376 while (os->segp < os->nsegs) {
377 int ss = os->segments[os->segp++];
385 if (!complete && os->segp == os->nsegs) {
387 // Do not set incomplete for empty packets.
388 // Together with the code in ogg_read_page
389 // that discards all continuation of empty packets
390 // we would get an infinite loop.
391 os->incomplete = !!os->psize;
395 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
396 idx, os->psize, os->pstart);
398 if (os->granule == -1)
399 av_log(s, AV_LOG_WARNING,
400 "Page at %"PRId64" is missing granule\n",
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;
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);
432 os->pstart += os->psize;
438 if (os->codec && os->codec->packet)
439 os->codec->packet(s, idx);
443 *dstart = os->pstart;
447 *fpos = os->sync_pos;
448 os->pstart += os->psize;
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 for (i = 0; i < ogg->nstreams; i++) {
480 struct ogg_stream *os = ogg->streams + i;
482 if (os->codec && os->codec->nb_header &&
483 os->nb_header < os->codec->nb_header) {
484 av_log(s, AV_LOG_ERROR,
485 "Headers mismatch for stream %d: "
486 "expected %d received %d.\n",
487 i, os->codec->nb_header, os->nb_header);
488 if (s->error_recognition & AV_EF_EXPLODE)
489 return AVERROR_INVALIDDATA;
491 if (os->start_granule != OGG_NOGRANULE_VALUE)
492 os->lastpts = s->streams[i]->start_time =
493 ogg_gptopts(s, i, os->start_granule, NULL);
495 av_dlog(s, "found headers\n");
500 static int ogg_get_length(AVFormatContext *s)
502 struct ogg *ogg = s->priv_data;
506 if (!s->pb->seekable)
510 if (s->duration != AV_NOPTS_VALUE)
513 size = avio_size(s->pb);
516 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
519 avio_seek(s->pb, end, SEEK_SET);
521 while (!ogg_read_page(s, &i)) {
522 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
523 ogg->streams[i].codec) {
524 s->streams[i]->duration =
525 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
526 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
527 s->streams[i]->duration -= s->streams[i]->start_time;
536 static int ogg_read_close(AVFormatContext *s)
538 struct ogg *ogg = s->priv_data;
541 for (i = 0; i < ogg->nstreams; i++) {
542 av_free(ogg->streams[i].buf);
543 if (ogg->streams[i].codec &&
544 ogg->streams[i].codec->cleanup) {
545 ogg->streams[i].codec->cleanup(s, i);
547 av_free(ogg->streams[i].private);
549 av_free(ogg->streams);
553 static int ogg_read_header(AVFormatContext *s)
555 struct ogg *ogg = s->priv_data;
558 //linear headers seek from start
559 ret = ogg_get_headers(s);
565 for (i = 0; i < ogg->nstreams; i++)
566 if (ogg->streams[i].header < 0)
567 ogg->streams[i].codec = NULL;
569 //linear granulepos seek from end
572 //fill the extradata in the per codec callbacks
576 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
578 struct ogg *ogg = s->priv_data;
579 struct ogg_stream *os = ogg->streams + idx;
580 int64_t pts = AV_NOPTS_VALUE;
583 *dts = AV_NOPTS_VALUE;
585 if (os->lastpts != AV_NOPTS_VALUE) {
587 os->lastpts = AV_NOPTS_VALUE;
589 if (os->lastdts != AV_NOPTS_VALUE) {
592 os->lastdts = AV_NOPTS_VALUE;
595 if (os->granule != -1LL) {
596 if (os->codec && os->codec->granule_is_start)
597 pts = ogg_gptopts(s, idx, os->granule, dts);
599 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
606 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
609 struct ogg_stream *os;
612 int64_t fpos, pts, dts;
617 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
620 } while (idx < 0 || !s->streams[idx]);
623 os = ogg->streams + idx;
625 // pflags might not be set until after this
626 pts = ogg_calc_pts(s, idx, &dts);
628 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
630 os->keyframe_seek = 0;
633 ret = av_new_packet(pkt, psize);
636 pkt->stream_index = idx;
637 memcpy(pkt->data, os->buf + pstart, psize);
641 pkt->flags = os->pflags;
642 pkt->duration = os->pduration;
648 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
649 int64_t *pos_arg, int64_t pos_limit)
651 struct ogg *ogg = s->priv_data;
652 AVIOContext *bc = s->pb;
653 int64_t pts = AV_NOPTS_VALUE;
655 avio_seek(bc, *pos_arg, SEEK_SET);
658 while (avio_tell(bc) < pos_limit &&
659 !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
660 if (i == stream_index) {
661 struct ogg_stream *os = ogg->streams + stream_index;
662 pts = ogg_calc_pts(s, i, NULL);
663 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
664 pts = AV_NOPTS_VALUE;
666 if (pts != AV_NOPTS_VALUE)
673 static int ogg_read_seek(AVFormatContext *s, int stream_index,
674 int64_t timestamp, int flags)
676 struct ogg *ogg = s->priv_data;
677 struct ogg_stream *os = ogg->streams + stream_index;
680 // Try seeking to a keyframe first. If this fails (very possible),
681 // av_seek_frame will fall back to ignoring keyframes
682 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
683 && !(flags & AVSEEK_FLAG_ANY))
684 os->keyframe_seek = 1;
686 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
687 os = ogg->streams + stream_index;
689 os->keyframe_seek = 0;
693 static int ogg_probe(AVProbeData *p)
695 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
696 return AVPROBE_SCORE_MAX;
700 AVInputFormat ff_ogg_demuxer = {
702 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
703 .priv_data_size = sizeof(struct ogg),
704 .read_probe = ogg_probe,
705 .read_header = ogg_read_header,
706 .read_packet = ogg_read_packet,
707 .read_close = ogg_read_close,
708 .read_seek = ogg_read_seek,
709 .read_timestamp = ogg_read_timestamp,
711 .flags = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,