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)
159 struct ogg *ogg = s->priv_data;
160 int idx = ogg->nstreams++;
162 struct ogg_stream *os;
164 ogg->streams = av_realloc (ogg->streams,
165 ogg->nstreams * sizeof (*ogg->streams));
166 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
167 os = ogg->streams + idx;
169 os->bufsize = DECODER_BUFFER_SIZE;
170 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
174 st = avformat_new_stream(s, NULL);
176 return AVERROR(ENOMEM);
179 avpriv_set_pts_info(st, 64, 1, 1000000);
185 static int ogg_new_buf(struct ogg *ogg, int idx)
187 struct ogg_stream *os = ogg->streams + idx;
188 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
189 int size = os->bufpos - os->pstart;
191 memcpy(nb, os->buf + os->pstart, size);
201 static int ogg_read_page(AVFormatContext *s, int *str)
203 AVIOContext *bc = s->pb;
204 struct ogg *ogg = s->priv_data;
205 struct ogg_stream *os;
214 ret = avio_read(bc, sync, 4);
216 return ret < 0 ? ret : AVERROR_EOF;
221 if (sync[sp & 3] == 'O' &&
222 sync[(sp + 1) & 3] == 'g' &&
223 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
230 }while (i++ < MAX_PAGE_SIZE);
232 if (i >= MAX_PAGE_SIZE){
233 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
234 return AVERROR_INVALIDDATA;
237 if (avio_r8(bc) != 0) /* version */
238 return AVERROR_INVALIDDATA;
242 serial = avio_rl32 (bc);
243 avio_skip(bc, 8); /* seq, crc */
246 idx = ogg_find_stream (ogg, serial);
251 for (n = 0; n < ogg->nstreams; n++) {
252 av_freep(&ogg->streams[n].buf);
253 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
254 av_freep(&ogg->streams[n].private);
258 idx = ogg_new_stream(s, serial, 0);
260 idx = ogg_new_stream(s, serial, 1);
266 os = ogg->streams + idx;
267 os->page_pos = avio_tell(bc) - 27;
270 ogg_new_buf(ogg, idx);
272 ret = avio_read(bc, os->segments, nsegs);
274 return ret < 0 ? ret : AVERROR_EOF;
280 for (i = 0; i < nsegs; i++)
281 size += os->segments[i];
283 if (flags & OGG_FLAG_CONT || os->incomplete){
285 while (os->segp < os->nsegs){
286 int seg = os->segments[os->segp++];
291 os->sync_pos = os->page_pos;
295 os->sync_pos = os->page_pos;
298 if (os->bufsize - os->bufpos < size){
299 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
300 memcpy (nb, os->buf, os->bufpos);
305 ret = avio_read(bc, os->buf + os->bufpos, size);
307 return ret < 0 ? ret : AVERROR_EOF;
313 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
320 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
323 struct ogg *ogg = s->priv_data;
325 struct ogg_stream *os;
327 int segp = 0, psize = 0;
329 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
335 ret = ogg_read_page(s, &idx);
340 os = ogg->streams + idx;
342 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
343 idx, os->pstart, os->psize, os->segp, os->nsegs);
347 os->codec = ogg_find_codec (os->buf, os->bufpos);
349 av_log(s, AV_LOG_WARNING, "Codec not found\n");
361 while (os->segp < os->nsegs){
362 int ss = os->segments[os->segp++];
370 if (!complete && os->segp == os->nsegs){
376 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
377 idx, os->psize, os->pstart);
379 if (os->granule == -1)
380 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
386 os->header = os->codec->header (s, idx);
391 // We have reached the first non-header packet in this stream.
392 // Unfortunately more header packets may still follow for others,
393 // but if we continue with header parsing we may lose data packets.
396 // Update the header state for all streams and
397 // compute the data_offset.
399 s->data_offset = os->sync_pos;
400 for (i = 0; i < ogg->nstreams; i++) {
401 struct ogg_stream *cur_os = ogg->streams + i;
403 // if we have a partial non-header packet, its start is
404 // obviously at or after the data start
405 if (cur_os->incomplete)
406 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
409 os->pstart += os->psize;
415 if (os->codec && os->codec->packet)
416 os->codec->packet (s, idx);
420 *dstart = os->pstart;
424 *fpos = os->sync_pos;
425 os->pstart += os->psize;
427 os->sync_pos = os->page_pos;
430 // determine whether there are more complete packets in this page
431 // if not, the page's granule will apply to this packet
433 for (i = os->segp; i < os->nsegs; i++)
434 if (os->segments[i] < 255) {
439 if (os->segp == os->nsegs)
445 static int ogg_get_headers(AVFormatContext *s)
447 struct ogg *ogg = s->priv_data;
451 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
454 }while (!ogg->headers);
456 av_dlog(s, "found headers\n");
461 static int ogg_get_length(AVFormatContext *s)
463 struct ogg *ogg = s->priv_data;
471 if (s->duration != AV_NOPTS_VALUE)
474 size = avio_size(s->pb);
477 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
480 avio_seek (s->pb, end, SEEK_SET);
482 while (!ogg_read_page (s, &i)){
483 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
484 ogg->streams[i].codec) {
485 s->streams[i]->duration =
486 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
487 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
488 s->streams[i]->duration -= s->streams[i]->start_time;
497 static int ogg_read_header(AVFormatContext *s)
499 struct ogg *ogg = s->priv_data;
502 //linear headers seek from start
503 ret = ogg_get_headers(s);
507 for (i = 0; i < ogg->nstreams; i++)
508 if (ogg->streams[i].header < 0)
509 ogg->streams[i].codec = NULL;
511 //linear granulepos seek from end
514 //fill the extradata in the per codec callbacks
518 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
520 struct ogg *ogg = s->priv_data;
521 struct ogg_stream *os = ogg->streams + idx;
522 int64_t pts = AV_NOPTS_VALUE;
525 *dts = AV_NOPTS_VALUE;
527 if (os->lastpts != AV_NOPTS_VALUE) {
529 os->lastpts = AV_NOPTS_VALUE;
531 if (os->lastdts != AV_NOPTS_VALUE) {
534 os->lastdts = AV_NOPTS_VALUE;
537 if (os->granule != -1LL) {
538 if (os->codec && os->codec->granule_is_start)
539 pts = ogg_gptopts(s, idx, os->granule, dts);
541 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
548 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
551 struct ogg_stream *os;
554 int64_t fpos, pts, dts;
559 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
562 }while (idx < 0 || !s->streams[idx]);
565 os = ogg->streams + idx;
567 // pflags might not be set until after this
568 pts = ogg_calc_pts(s, idx, &dts);
570 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
572 os->keyframe_seek = 0;
575 ret = av_new_packet(pkt, psize);
578 pkt->stream_index = idx;
579 memcpy (pkt->data, os->buf + pstart, psize);
583 pkt->flags = os->pflags;
584 pkt->duration = os->pduration;
590 static int ogg_read_close(AVFormatContext *s)
592 struct ogg *ogg = s->priv_data;
595 for (i = 0; i < ogg->nstreams; i++){
596 av_free (ogg->streams[i].buf);
597 av_free (ogg->streams[i].private);
599 av_free (ogg->streams);
603 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
604 int64_t *pos_arg, int64_t pos_limit)
606 struct ogg *ogg = s->priv_data;
607 AVIOContext *bc = s->pb;
608 int64_t pts = AV_NOPTS_VALUE;
610 avio_seek(bc, *pos_arg, SEEK_SET);
613 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
614 if (i == stream_index) {
615 struct ogg_stream *os = ogg->streams + stream_index;
616 pts = ogg_calc_pts(s, i, NULL);
617 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
618 pts = AV_NOPTS_VALUE;
620 if (pts != AV_NOPTS_VALUE)
627 static int ogg_read_seek(AVFormatContext *s, int stream_index,
628 int64_t timestamp, int flags)
630 struct ogg *ogg = s->priv_data;
631 struct ogg_stream *os = ogg->streams + stream_index;
634 // Try seeking to a keyframe first. If this fails (very possible),
635 // av_seek_frame will fall back to ignoring keyframes
636 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
637 && !(flags & AVSEEK_FLAG_ANY))
638 os->keyframe_seek = 1;
640 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
641 os = ogg->streams + stream_index;
643 os->keyframe_seek = 0;
647 static int ogg_probe(AVProbeData *p)
649 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
650 return AVPROBE_SCORE_MAX;
654 AVInputFormat ff_ogg_demuxer = {
656 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
657 .priv_data_size = sizeof(struct ogg),
658 .read_probe = ogg_probe,
659 .read_header = ogg_read_header,
660 .read_packet = ogg_read_packet,
661 .read_close = ogg_read_close,
662 .read_seek = ogg_read_seek,
663 .read_timestamp = ogg_read_timestamp,
665 .flags = AVFMT_GENERIC_INDEX,