2 * Ogg bitstream support
3 * Luca Barbato <lu_zero@gentoo.org>
4 * Based on tcvp implementation
9 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 DEALINGS IN THE SOFTWARE.
37 #include "vorbiscomment.h"
39 #define MAX_PAGE_SIZE 65307
40 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
42 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_malloc (os->bufsize);
75 memset (os->buf, 0, os->bufsize);
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(struct ogg *ogg)
126 for (i = 0; i < ogg->nstreams; i++){
127 struct ogg_stream *os = ogg->streams + i;
132 os->lastpts = AV_NOPTS_VALUE;
133 os->lastdts = AV_NOPTS_VALUE;
146 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
150 for (i = 0; ogg_codecs[i]; i++)
151 if (size >= ogg_codecs[i]->magicsize &&
152 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
153 return ogg_codecs[i];
158 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
161 struct ogg *ogg = s->priv_data;
162 int idx = ogg->nstreams++;
164 struct ogg_stream *os;
166 ogg->streams = av_realloc (ogg->streams,
167 ogg->nstreams * sizeof (*ogg->streams));
168 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);
176 st = avformat_new_stream(s, NULL);
178 return AVERROR(ENOMEM);
181 av_set_pts_info(st, 64, 1, 1000000);
187 static int ogg_new_buf(struct ogg *ogg, int idx)
189 struct ogg_stream *os = ogg->streams + idx;
190 uint8_t *nb = av_malloc(os->bufsize);
191 int size = os->bufpos - os->pstart;
193 memcpy(nb, os->buf + os->pstart, size);
203 static int ogg_read_page(AVFormatContext *s, int *str)
205 AVIOContext *bc = s->pb;
206 struct ogg *ogg = s->priv_data;
207 struct ogg_stream *os;
216 ret = avio_read(bc, sync, 4);
218 return ret < 0 ? ret : AVERROR_EOF;
223 if (sync[sp & 3] == 'O' &&
224 sync[(sp + 1) & 3] == 'g' &&
225 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
232 }while (i++ < MAX_PAGE_SIZE);
234 if (i >= MAX_PAGE_SIZE){
235 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
236 return AVERROR_INVALIDDATA;
239 if (avio_r8(bc) != 0) /* version */
240 return AVERROR_INVALIDDATA;
244 serial = avio_rl32 (bc);
245 avio_skip(bc, 8); /* seq, crc */
248 idx = ogg_find_stream (ogg, serial);
253 for (n = 0; n < ogg->nstreams; n++) {
254 av_freep(&ogg->streams[n].buf);
255 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
256 av_freep(&ogg->streams[n].private);
260 idx = ogg_new_stream(s, serial, 0);
262 idx = ogg_new_stream(s, serial, 1);
268 os = ogg->streams + idx;
269 os->page_pos = avio_tell(bc) - 27;
272 ogg_new_buf(ogg, idx);
274 ret = avio_read(bc, os->segments, nsegs);
276 return ret < 0 ? ret : AVERROR_EOF;
282 for (i = 0; i < nsegs; i++)
283 size += os->segments[i];
285 if (flags & OGG_FLAG_CONT || os->incomplete){
287 while (os->segp < os->nsegs){
288 int seg = os->segments[os->segp++];
293 os->sync_pos = os->page_pos;
297 os->sync_pos = os->page_pos;
300 if (os->bufsize - os->bufpos < size){
301 uint8_t *nb = av_malloc (os->bufsize *= 2);
302 memcpy (nb, os->buf, os->bufpos);
307 ret = avio_read(bc, os->buf + os->bufpos, size);
309 return ret < 0 ? ret : AVERROR_EOF;
321 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
324 struct ogg *ogg = s->priv_data;
326 struct ogg_stream *os;
328 int segp = 0, psize = 0;
330 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
336 ret = ogg_read_page(s, &idx);
341 os = ogg->streams + idx;
343 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
344 idx, os->pstart, os->psize, os->segp, os->nsegs);
348 os->codec = ogg_find_codec (os->buf, os->bufpos);
350 av_log(s, AV_LOG_WARNING, "Codec not found\n");
362 while (os->segp < os->nsegs){
363 int ss = os->segments[os->segp++];
371 if (!complete && os->segp == os->nsegs){
377 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
378 idx, os->psize, os->pstart);
380 if (os->granule == -1)
381 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
387 os->header = os->codec->header (s, idx);
392 // We have reached the first non-header packet in this stream.
393 // Unfortunately more header packets may still follow for others,
394 // but if we continue with header parsing we may lose data packets.
397 // Update the header state for all streams and
398 // compute the data_offset.
400 s->data_offset = os->sync_pos;
401 for (i = 0; i < ogg->nstreams; i++) {
402 struct ogg_stream *cur_os = ogg->streams + i;
404 // if we have a partial non-header packet, its start is
405 // obviously at or after the data start
406 if (cur_os->incomplete)
407 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
410 os->pstart += os->psize;
416 if (os->codec && os->codec->packet)
417 os->codec->packet (s, idx);
421 *dstart = os->pstart;
425 *fpos = os->sync_pos;
426 os->pstart += os->psize;
428 os->sync_pos = os->page_pos;
431 // determine whether there are more complete packets in this page
432 // if not, the page's granule will apply to this packet
434 for (i = os->segp; i < os->nsegs; i++)
435 if (os->segments[i] < 255) {
440 if (os->segp == os->nsegs)
446 static int ogg_get_headers(AVFormatContext *s)
448 struct ogg *ogg = s->priv_data;
452 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
455 }while (!ogg->headers);
457 av_dlog(s, "found headers\n");
462 static int ogg_get_length(AVFormatContext *s)
464 struct ogg *ogg = s->priv_data;
472 if (s->duration != AV_NOPTS_VALUE)
475 size = avio_size(s->pb);
478 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
481 avio_seek (s->pb, end, SEEK_SET);
483 while (!ogg_read_page (s, &i)){
484 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
485 ogg->streams[i].codec) {
486 s->streams[i]->duration =
487 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
488 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
489 s->streams[i]->duration -= s->streams[i]->start_time;
498 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
500 struct ogg *ogg = s->priv_data;
503 //linear headers seek from start
504 ret = ogg_get_headers(s);
508 for (i = 0; i < ogg->nstreams; i++)
509 if (ogg->streams[i].header < 0)
510 ogg->streams[i].codec = NULL;
512 //linear granulepos seek from end
515 //fill the extradata in the per codec callbacks
519 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
521 struct ogg *ogg = s->priv_data;
522 struct ogg_stream *os = ogg->streams + idx;
523 int64_t pts = AV_NOPTS_VALUE;
526 *dts = AV_NOPTS_VALUE;
528 if (os->lastpts != AV_NOPTS_VALUE) {
530 os->lastpts = AV_NOPTS_VALUE;
532 if (os->lastdts != AV_NOPTS_VALUE) {
535 os->lastdts = AV_NOPTS_VALUE;
538 if (os->granule != -1LL) {
539 if (os->codec && os->codec->granule_is_start)
540 pts = ogg_gptopts(s, idx, os->granule, dts);
542 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
549 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
552 struct ogg_stream *os;
555 int64_t fpos, pts, dts;
560 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
563 }while (idx < 0 || !s->streams[idx]);
566 os = ogg->streams + idx;
568 // pflags might not be set until after this
569 pts = ogg_calc_pts(s, idx, &dts);
571 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
573 os->keyframe_seek = 0;
576 ret = av_new_packet(pkt, psize);
579 pkt->stream_index = idx;
580 memcpy (pkt->data, os->buf + pstart, psize);
584 pkt->flags = os->pflags;
585 pkt->duration = os->pduration;
591 static int ogg_read_close(AVFormatContext *s)
593 struct ogg *ogg = s->priv_data;
596 for (i = 0; i < ogg->nstreams; i++){
597 av_free (ogg->streams[i].buf);
598 av_free (ogg->streams[i].private);
600 av_free (ogg->streams);
604 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
605 int64_t *pos_arg, int64_t pos_limit)
607 struct ogg *ogg = s->priv_data;
608 AVIOContext *bc = s->pb;
609 int64_t pts = AV_NOPTS_VALUE;
611 avio_seek(bc, *pos_arg, SEEK_SET);
614 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
615 if (i == stream_index) {
616 struct ogg_stream *os = ogg->streams + stream_index;
617 pts = ogg_calc_pts(s, i, NULL);
618 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
619 pts = AV_NOPTS_VALUE;
621 if (pts != AV_NOPTS_VALUE)
628 static int ogg_read_seek(AVFormatContext *s, int stream_index,
629 int64_t timestamp, int flags)
631 struct ogg *ogg = s->priv_data;
632 struct ogg_stream *os = ogg->streams + stream_index;
635 // Try seeking to a keyframe first. If this fails (very possible),
636 // av_seek_frame will fall back to ignoring keyframes
637 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
638 && !(flags & AVSEEK_FLAG_ANY))
639 os->keyframe_seek = 1;
641 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
642 os = ogg->streams + stream_index;
644 os->keyframe_seek = 0;
648 static int ogg_probe(AVProbeData *p)
650 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
651 return AVPROBE_SCORE_MAX;
655 AVInputFormat ff_ogg_demuxer = {
657 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
658 .priv_data_size = sizeof(struct ogg),
659 .read_probe = ogg_probe,
660 .read_header = ogg_read_header,
661 .read_packet = ogg_read_packet,
662 .read_close = ogg_read_close,
663 .read_seek = ogg_read_seek,
664 .read_timestamp = ogg_read_timestamp,
666 .flags = AVFMT_GENERIC_INDEX,