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.
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_malloc (os->bufsize);
74 memset (os->buf, 0, os->bufsize);
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;
96 for (i = 0; i < ogg->nstreams; i++)
97 av_free (ogg->streams[i].buf);
99 avio_seek (bc, ost->pos, SEEK_SET);
100 ogg->curidx = ost->curidx;
101 ogg->nstreams = ost->nstreams;
102 memcpy(ogg->streams, ost->streams,
103 ost->nstreams * sizeof(*ogg->streams));
111 static int ogg_reset(struct ogg *ogg)
115 for (i = 0; i < ogg->nstreams; i++){
116 struct ogg_stream *os = ogg->streams + i;
121 os->lastpts = AV_NOPTS_VALUE;
122 os->lastdts = AV_NOPTS_VALUE;
135 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
139 for (i = 0; ogg_codecs[i]; i++)
140 if (size >= ogg_codecs[i]->magicsize &&
141 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
142 return ogg_codecs[i];
147 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
150 struct ogg *ogg = s->priv_data;
151 int idx = ogg->nstreams++;
153 struct ogg_stream *os;
155 ogg->streams = av_realloc (ogg->streams,
156 ogg->nstreams * sizeof (*ogg->streams));
157 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
158 os = ogg->streams + idx;
160 os->bufsize = DECODER_BUFFER_SIZE;
161 os->buf = av_malloc(os->bufsize);
165 st = av_new_stream(s, idx);
167 return AVERROR(ENOMEM);
169 av_set_pts_info(st, 64, 1, 1000000);
175 static int ogg_new_buf(struct ogg *ogg, int idx)
177 struct ogg_stream *os = ogg->streams + idx;
178 uint8_t *nb = av_malloc(os->bufsize);
179 int size = os->bufpos - os->pstart;
181 memcpy(nb, os->buf + os->pstart, size);
191 static int ogg_read_page(AVFormatContext *s, int *str)
193 AVIOContext *bc = s->pb;
194 struct ogg *ogg = s->priv_data;
195 struct ogg_stream *os;
204 ret = avio_read(bc, sync, 4);
206 return ret < 0 ? ret : AVERROR_EOF;
211 if (sync[sp & 3] == 'O' &&
212 sync[(sp + 1) & 3] == 'g' &&
213 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
220 }while (i++ < MAX_PAGE_SIZE);
222 if (i >= MAX_PAGE_SIZE){
223 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
224 return AVERROR_INVALIDDATA;
227 if (avio_r8(bc) != 0) /* version */
228 return AVERROR_INVALIDDATA;
232 serial = avio_rl32 (bc);
233 avio_skip(bc, 8); /* seq, crc */
236 idx = ogg_find_stream (ogg, serial);
241 for (n = 0; n < ogg->nstreams; n++) {
242 av_freep(&ogg->streams[n].buf);
243 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
244 av_freep(&ogg->streams[n].private);
248 idx = ogg_new_stream(s, serial, 0);
250 idx = ogg_new_stream(s, serial, 1);
256 os = ogg->streams + idx;
257 os->page_pos = avio_tell(bc) - 27;
260 ogg_new_buf(ogg, idx);
262 ret = avio_read(bc, os->segments, nsegs);
264 return ret < 0 ? ret : AVERROR_EOF;
270 for (i = 0; i < nsegs; i++)
271 size += os->segments[i];
273 if (flags & OGG_FLAG_CONT || os->incomplete){
275 while (os->segp < os->nsegs){
276 int seg = os->segments[os->segp++];
281 os->sync_pos = os->page_pos;
285 os->sync_pos = os->page_pos;
288 if (os->bufsize - os->bufpos < size){
289 uint8_t *nb = av_malloc (os->bufsize *= 2);
290 memcpy (nb, os->buf, os->bufpos);
295 ret = avio_read(bc, os->buf + os->bufpos, size);
297 return ret < 0 ? ret : AVERROR_EOF;
309 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
312 struct ogg *ogg = s->priv_data;
314 struct ogg_stream *os;
316 int segp = 0, psize = 0;
318 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
324 ret = ogg_read_page(s, &idx);
329 os = ogg->streams + idx;
331 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
332 idx, os->pstart, os->psize, os->segp, os->nsegs);
336 os->codec = ogg_find_codec (os->buf, os->bufpos);
338 av_log(s, AV_LOG_WARNING, "Codec not found\n");
350 while (os->segp < os->nsegs){
351 int ss = os->segments[os->segp++];
359 if (!complete && os->segp == os->nsegs){
366 if (os->granule == -1)
367 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
373 os->header = os->codec->header (s, idx);
378 // We have reached the first non-header packet in this stream.
379 // Unfortunately more header packets may still follow for others,
380 // but if we continue with header parsing we may lose data packets.
383 // Update the header state for all streams and
384 // compute the data_offset.
386 s->data_offset = os->sync_pos;
387 for (i = 0; i < ogg->nstreams; i++) {
388 struct ogg_stream *cur_os = ogg->streams + i;
390 // if we have a partial non-header packet, its start is
391 // obviously at or after the data start
392 if (cur_os->incomplete)
393 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
396 os->pstart += os->psize;
402 if (os->codec && os->codec->packet)
403 os->codec->packet (s, idx);
407 *dstart = os->pstart;
411 *fpos = os->sync_pos;
412 os->pstart += os->psize;
414 if(os->pstart == os->bufpos)
415 os->bufpos = os->pstart = 0;
416 os->sync_pos = os->page_pos;
419 // determine whether there are more complete packets in this page
420 // if not, the page's granule will apply to this packet
422 for (i = os->segp; i < os->nsegs; i++)
423 if (os->segments[i] < 255) {
428 if (os->segp == os->nsegs)
434 static int ogg_get_headers(AVFormatContext *s)
436 struct ogg *ogg = s->priv_data;
440 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
443 }while (!ogg->headers);
445 av_dlog(s, "found headers\n");
450 static int ogg_get_length(AVFormatContext *s)
452 struct ogg *ogg = s->priv_data;
461 if (s->duration != AV_NOPTS_VALUE)
464 size = avio_size(s->pb);
467 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
470 avio_seek (s->pb, end, SEEK_SET);
472 while (!ogg_read_page (s, &i)){
473 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
474 ogg->streams[i].codec) {
475 s->streams[i]->duration =
476 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
477 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
478 s->streams[i]->duration -= s->streams[i]->start_time;
479 streams_left-= (ogg->streams[i].got_start==-1);
480 ogg->streams[i].got_start= 1;
481 }else if(!ogg->streams[i].got_start){
482 ogg->streams[i].got_start= -1;
491 avio_seek (s->pb, 0, SEEK_SET);
492 while (!ogg_read_page (s, &i)){
493 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
494 ogg->streams[i].codec) {
495 if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
496 int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
497 if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
498 s->streams[i]->duration -= start;
499 ogg->streams[i].got_start= 1;
511 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
513 struct ogg *ogg = s->priv_data;
516 //linear headers seek from start
517 ret = ogg_get_headers(s);
521 for (i = 0; i < ogg->nstreams; i++)
522 if (ogg->streams[i].header < 0)
523 ogg->streams[i].codec = NULL;
525 //linear granulepos seek from end
528 //fill the extradata in the per codec callbacks
532 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
534 struct ogg *ogg = s->priv_data;
535 struct ogg_stream *os = ogg->streams + idx;
536 int64_t pts = AV_NOPTS_VALUE;
539 *dts = AV_NOPTS_VALUE;
541 if (os->lastpts != AV_NOPTS_VALUE) {
543 os->lastpts = AV_NOPTS_VALUE;
545 if (os->lastdts != AV_NOPTS_VALUE) {
548 os->lastdts = AV_NOPTS_VALUE;
551 if (os->granule != -1LL) {
552 if (os->codec && os->codec->granule_is_start)
553 pts = ogg_gptopts(s, idx, os->granule, dts);
555 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
562 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
565 struct ogg_stream *os;
568 int64_t fpos, pts, dts;
573 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
576 }while (idx < 0 || !s->streams[idx]);
579 os = ogg->streams + idx;
581 // pflags might not be set until after this
582 pts = ogg_calc_pts(s, idx, &dts);
584 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
586 os->keyframe_seek = 0;
589 ret = av_new_packet(pkt, psize);
592 pkt->stream_index = idx;
593 memcpy (pkt->data, os->buf + pstart, psize);
597 pkt->flags = os->pflags;
598 pkt->duration = os->pduration;
604 static int ogg_read_close(AVFormatContext *s)
606 struct ogg *ogg = s->priv_data;
609 for (i = 0; i < ogg->nstreams; i++){
610 av_free (ogg->streams[i].buf);
611 av_free (ogg->streams[i].private);
613 av_free (ogg->streams);
617 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
618 int64_t *pos_arg, int64_t pos_limit)
620 struct ogg *ogg = s->priv_data;
621 AVIOContext *bc = s->pb;
622 int64_t pts = AV_NOPTS_VALUE;
624 avio_seek(bc, *pos_arg, SEEK_SET);
627 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
628 if (i == stream_index) {
629 struct ogg_stream *os = ogg->streams + stream_index;
630 pts = ogg_calc_pts(s, i, NULL);
631 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
632 pts = AV_NOPTS_VALUE;
634 if (pts != AV_NOPTS_VALUE)
641 static int ogg_read_seek(AVFormatContext *s, int stream_index,
642 int64_t timestamp, int flags)
644 struct ogg *ogg = s->priv_data;
645 struct ogg_stream *os = ogg->streams + stream_index;
648 // Try seeking to a keyframe first. If this fails (very possible),
649 // av_seek_frame will fall back to ignoring keyframes
650 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
651 && !(flags & AVSEEK_FLAG_ANY))
652 os->keyframe_seek = 1;
654 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
655 os = ogg->streams + stream_index;
657 os->keyframe_seek = 0;
661 static int ogg_probe(AVProbeData *p)
663 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
664 return AVPROBE_SCORE_MAX;
668 AVInputFormat ff_ogg_demuxer = {
670 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
671 .priv_data_size = sizeof(struct ogg),
672 .read_probe = ogg_probe,
673 .read_header = ogg_read_header,
674 .read_packet = ogg_read_packet,
675 .read_close = ogg_read_close,
676 .read_seek = ogg_read_seek,
677 .read_timestamp = ogg_read_timestamp,
679 .flags = AVFMT_GENERIC_INDEX,