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;
206 ret = avio_read (bc, sync, 4);
208 return ret < 0 ? ret : AVERROR_EOF;
213 if (sync[sp & 3] == 'O' &&
214 sync[(sp + 1) & 3] == 'g' &&
215 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
222 }while (i++ < MAX_PAGE_SIZE);
224 if (i >= MAX_PAGE_SIZE){
225 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
226 return AVERROR_INVALIDDATA;
229 if (avio_r8(bc) != 0) /* version */
230 return AVERROR_INVALIDDATA;
234 serial = avio_rl32 (bc);
235 seq = avio_rl32 (bc);
236 crc = avio_rl32 (bc);
239 idx = ogg_find_stream (ogg, serial);
244 for (n = 0; n < ogg->nstreams; n++) {
245 av_freep(&ogg->streams[n].buf);
246 av_freep(&ogg->streams[n].private);
250 idx = ogg_new_stream(s, serial, 0);
252 idx = ogg_new_stream(s, serial, 1);
258 os = ogg->streams + idx;
259 os->page_pos = avio_tell(bc) - 27;
262 ogg_new_buf(ogg, idx);
264 ret = avio_read (bc, os->segments, nsegs);
266 return ret < 0 ? ret : AVERROR_EOF;
272 for (i = 0; i < nsegs; i++)
273 size += os->segments[i];
275 if (flags & OGG_FLAG_CONT || os->incomplete){
277 while (os->segp < os->nsegs){
278 int seg = os->segments[os->segp++];
283 os->sync_pos = os->page_pos;
287 os->sync_pos = os->page_pos;
290 if (os->bufsize - os->bufpos < size){
291 uint8_t *nb = av_malloc (os->bufsize *= 2);
292 memcpy (nb, os->buf, os->bufpos);
297 ret = avio_read (bc, os->buf + os->bufpos, size);
299 return ret < 0 ? ret : AVERROR_EOF;
311 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
314 struct ogg *ogg = s->priv_data;
316 struct ogg_stream *os;
318 int segp = 0, psize = 0;
320 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
326 ret = ogg_read_page (s, &idx);
331 os = ogg->streams + idx;
333 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
334 idx, os->pstart, os->psize, os->segp, os->nsegs);
338 os->codec = ogg_find_codec (os->buf, os->bufpos);
340 av_log(s, AV_LOG_WARNING, "Codec not found\n");
352 while (os->segp < os->nsegs){
353 int ss = os->segments[os->segp++];
361 if (!complete && os->segp == os->nsegs){
367 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
368 idx, os->psize, os->pstart);
370 if (os->granule == -1)
371 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
377 os->header = os->codec->header (s, idx);
382 // We have reached the first non-header packet in this stream.
383 // Unfortunately more header packets may still follow for others,
384 // but if we continue with header parsing we may lose data packets.
387 // Update the header state for all streams and
388 // compute the data_offset.
390 s->data_offset = os->sync_pos;
391 for (i = 0; i < ogg->nstreams; i++) {
392 struct ogg_stream *cur_os = ogg->streams + i;
394 // if we have a partial non-header packet, its start is
395 // obviously at or after the data start
396 if (cur_os->incomplete)
397 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
400 os->pstart += os->psize;
406 if (os->codec && os->codec->packet)
407 os->codec->packet (s, idx);
411 *dstart = os->pstart;
415 *fpos = os->sync_pos;
416 os->pstart += os->psize;
418 os->sync_pos = os->page_pos;
421 // determine whether there are more complete packets in this page
422 // if not, the page's granule will apply to this packet
424 for (i = os->segp; i < os->nsegs; i++)
425 if (os->segments[i] < 255) {
430 if (os->segp == os->nsegs)
436 static int ogg_get_headers(AVFormatContext *s)
438 struct ogg *ogg = s->priv_data;
442 ret = ogg_packet (s, NULL, NULL, NULL, NULL);
445 }while (!ogg->headers);
447 av_dlog(s, "found headers\n");
452 static int ogg_get_length(AVFormatContext *s)
454 struct ogg *ogg = s->priv_data;
462 if (s->duration != AV_NOPTS_VALUE)
465 size = avio_size(s->pb);
468 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
471 avio_seek (s->pb, end, SEEK_SET);
473 while (!ogg_read_page (s, &i)){
474 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
475 ogg->streams[i].codec) {
476 s->streams[i]->duration =
477 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
478 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
479 s->streams[i]->duration -= s->streams[i]->start_time;
486 avio_seek (s->pb, 0, SEEK_SET);
487 while (!ogg_read_page (s, &i)){
488 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
489 ogg->streams[i].codec) {
490 s->streams[i]->duration -=
491 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
500 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
502 struct ogg *ogg = s->priv_data;
505 //linear headers seek from start
506 ret = ogg_get_headers (s);
511 for (i = 0; i < ogg->nstreams; i++)
512 if (ogg->streams[i].header < 0)
513 ogg->streams[i].codec = NULL;
515 //linear granulepos seek from end
518 //fill the extradata in the per codec callbacks
522 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
524 struct ogg *ogg = s->priv_data;
525 struct ogg_stream *os = ogg->streams + idx;
526 int64_t pts = AV_NOPTS_VALUE;
529 *dts = AV_NOPTS_VALUE;
531 if (os->lastpts != AV_NOPTS_VALUE) {
533 os->lastpts = AV_NOPTS_VALUE;
535 if (os->lastdts != AV_NOPTS_VALUE) {
538 os->lastdts = AV_NOPTS_VALUE;
541 if (os->granule != -1LL) {
542 if (os->codec && os->codec->granule_is_start)
543 pts = ogg_gptopts(s, idx, os->granule, dts);
545 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
552 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
555 struct ogg_stream *os;
558 int64_t fpos, pts, dts;
563 if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
565 }while (idx < 0 || !s->streams[idx]);
568 os = ogg->streams + idx;
570 // pflags might not be set until after this
571 pts = ogg_calc_pts(s, idx, &dts);
573 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
575 os->keyframe_seek = 0;
578 if (av_new_packet (pkt, psize) < 0)
580 pkt->stream_index = idx;
581 memcpy (pkt->data, os->buf + pstart, psize);
585 pkt->flags = os->pflags;
586 pkt->duration = os->pduration;
592 static int ogg_read_close(AVFormatContext *s)
594 struct ogg *ogg = s->priv_data;
597 for (i = 0; i < ogg->nstreams; i++){
598 av_free (ogg->streams[i].buf);
599 av_free (ogg->streams[i].private);
601 av_free (ogg->streams);
605 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
606 int64_t *pos_arg, int64_t pos_limit)
608 struct ogg *ogg = s->priv_data;
609 struct ogg_stream *os = ogg->streams + stream_index;
610 AVIOContext *bc = s->pb;
611 int64_t pts = AV_NOPTS_VALUE;
613 avio_seek(bc, *pos_arg, SEEK_SET);
616 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
617 if (i == stream_index) {
618 pts = ogg_calc_pts(s, i, NULL);
619 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
620 pts = AV_NOPTS_VALUE;
622 if (pts != AV_NOPTS_VALUE)
629 static int ogg_read_seek(AVFormatContext *s, int stream_index,
630 int64_t timestamp, int flags)
632 struct ogg *ogg = s->priv_data;
633 struct ogg_stream *os = ogg->streams + stream_index;
636 // Try seeking to a keyframe first. If this fails (very possible),
637 // av_seek_frame will fall back to ignoring keyframes
638 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
639 && !(flags & AVSEEK_FLAG_ANY))
640 os->keyframe_seek = 1;
642 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
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,