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 av_freep(&ogg->streams[n].private);
247 idx = ogg_new_stream(s, serial, 0);
249 idx = ogg_new_stream(s, serial, 1);
255 os = ogg->streams + idx;
256 os->page_pos = avio_tell(bc) - 27;
259 ogg_new_buf(ogg, idx);
261 ret = avio_read (bc, os->segments, nsegs);
263 return ret < 0 ? ret : AVERROR_EOF;
269 for (i = 0; i < nsegs; i++)
270 size += os->segments[i];
272 if (flags & OGG_FLAG_CONT || os->incomplete){
274 while (os->segp < os->nsegs){
275 int seg = os->segments[os->segp++];
280 os->sync_pos = os->page_pos;
284 os->sync_pos = os->page_pos;
287 if (os->bufsize - os->bufpos < size){
288 uint8_t *nb = av_malloc (os->bufsize *= 2);
289 memcpy (nb, os->buf, os->bufpos);
294 ret = avio_read (bc, os->buf + os->bufpos, size);
296 return ret < 0 ? ret : AVERROR_EOF;
308 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
311 struct ogg *ogg = s->priv_data;
313 struct ogg_stream *os;
315 int segp = 0, psize = 0;
317 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
323 ret = ogg_read_page (s, &idx);
328 os = ogg->streams + idx;
330 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
331 idx, os->pstart, os->psize, os->segp, os->nsegs);
335 os->codec = ogg_find_codec (os->buf, os->bufpos);
337 av_log(s, AV_LOG_WARNING, "Codec not found\n");
349 while (os->segp < os->nsegs){
350 int ss = os->segments[os->segp++];
358 if (!complete && os->segp == os->nsegs){
365 if (os->granule == -1)
366 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
372 os->header = os->codec->header (s, idx);
377 // We have reached the first non-header packet in this stream.
378 // Unfortunately more header packets may still follow for others,
379 // but if we continue with header parsing we may lose data packets.
382 // Update the header state for all streams and
383 // compute the data_offset.
385 s->data_offset = os->sync_pos;
386 for (i = 0; i < ogg->nstreams; i++) {
387 struct ogg_stream *cur_os = ogg->streams + i;
389 // if we have a partial non-header packet, its start is
390 // obviously at or after the data start
391 if (cur_os->incomplete)
392 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
395 os->pstart += os->psize;
401 if (os->codec && os->codec->packet)
402 os->codec->packet (s, idx);
406 *dstart = os->pstart;
410 *fpos = os->sync_pos;
411 os->pstart += os->psize;
413 if(os->pstart == os->bufpos)
414 os->bufpos = os->pstart = 0;
415 os->sync_pos = os->page_pos;
418 // determine whether there are more complete packets in this page
419 // if not, the page's granule will apply to this packet
421 for (i = os->segp; i < os->nsegs; i++)
422 if (os->segments[i] < 255) {
427 if (os->segp == os->nsegs)
433 static int ogg_get_headers(AVFormatContext *s)
435 struct ogg *ogg = s->priv_data;
439 ret = ogg_packet (s, NULL, NULL, NULL, NULL);
442 }while (!ogg->headers);
444 av_dlog(s, "found headers\n");
449 static int ogg_get_length(AVFormatContext *s)
451 struct ogg *ogg = s->priv_data;
459 if (s->duration != AV_NOPTS_VALUE)
462 size = avio_size(s->pb);
465 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
468 avio_seek (s->pb, end, SEEK_SET);
470 while (!ogg_read_page (s, &i)){
471 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
472 ogg->streams[i].codec) {
473 s->streams[i]->duration =
474 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
475 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
476 s->streams[i]->duration -= s->streams[i]->start_time;
483 avio_seek (s->pb, 0, SEEK_SET);
484 while (!ogg_read_page (s, &i)){
485 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
486 ogg->streams[i].codec) {
487 s->streams[i]->duration -=
488 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
497 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
499 struct ogg *ogg = s->priv_data;
502 //linear headers seek from start
503 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 if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
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 if (av_new_packet (pkt, psize) < 0)
577 pkt->stream_index = idx;
578 memcpy (pkt->data, os->buf + pstart, psize);
582 pkt->flags = os->pflags;
583 pkt->duration = os->pduration;
589 static int ogg_read_close(AVFormatContext *s)
591 struct ogg *ogg = s->priv_data;
594 for (i = 0; i < ogg->nstreams; i++){
595 av_free (ogg->streams[i].buf);
596 av_free (ogg->streams[i].private);
598 av_free (ogg->streams);
602 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
603 int64_t *pos_arg, int64_t pos_limit)
605 struct ogg *ogg = s->priv_data;
606 struct ogg_stream *os = ogg->streams + stream_index;
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 pts = ogg_calc_pts(s, i, NULL);
616 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
617 pts = AV_NOPTS_VALUE;
619 if (pts != AV_NOPTS_VALUE)
626 static int ogg_read_seek(AVFormatContext *s, int stream_index,
627 int64_t timestamp, int flags)
629 struct ogg *ogg = s->priv_data;
630 struct ogg_stream *os = ogg->streams + stream_index;
633 // Try seeking to a keyframe first. If this fails (very possible),
634 // av_seek_frame will fall back to ignoring keyframes
635 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
636 && !(flags & AVSEEK_FLAG_ANY))
637 os->keyframe_seek = 1;
639 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
641 os->keyframe_seek = 0;
645 static int ogg_probe(AVProbeData *p)
647 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
648 return AVPROBE_SCORE_MAX;
652 AVInputFormat ff_ogg_demuxer = {
654 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
655 .priv_data_size = sizeof(struct ogg),
656 .read_probe = ogg_probe,
657 .read_header = ogg_read_header,
658 .read_packet = ogg_read_packet,
659 .read_close = ogg_read_close,
660 .read_seek = ogg_read_seek,
661 .read_timestamp = ogg_read_timestamp,
663 .flags = AVFMT_GENERIC_INDEX,