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[] = {
57 //FIXME We could avoid some structure duplication
58 static int ogg_save(AVFormatContext *s)
60 struct ogg *ogg = s->priv_data;
61 struct ogg_state *ost =
62 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
64 ost->pos = avio_tell (s->pb);
65 ost->curidx = ogg->curidx;
66 ost->next = ogg->state;
67 ost->nstreams = ogg->nstreams;
68 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
70 for (i = 0; i < ogg->nstreams; i++){
71 struct ogg_stream *os = ogg->streams + i;
72 os->buf = av_malloc (os->bufsize);
73 memset (os->buf, 0, os->bufsize);
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 for (i = 0; i < ogg->nstreams; i++)
96 av_free (ogg->streams[i].buf);
98 avio_seek (bc, ost->pos, SEEK_SET);
99 ogg->curidx = ost->curidx;
100 ogg->nstreams = ost->nstreams;
101 memcpy(ogg->streams, ost->streams,
102 ost->nstreams * sizeof(*ogg->streams));
110 static int ogg_reset(struct ogg *ogg)
114 for (i = 0; i < ogg->nstreams; i++){
115 struct ogg_stream *os = ogg->streams + i;
120 os->lastpts = AV_NOPTS_VALUE;
121 os->lastdts = AV_NOPTS_VALUE;
134 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
138 for (i = 0; ogg_codecs[i]; i++)
139 if (size >= ogg_codecs[i]->magicsize &&
140 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
141 return ogg_codecs[i];
146 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
149 struct ogg *ogg = s->priv_data;
150 int idx = ogg->nstreams++;
152 struct ogg_stream *os;
154 ogg->streams = av_realloc (ogg->streams,
155 ogg->nstreams * sizeof (*ogg->streams));
156 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
157 os = ogg->streams + idx;
159 os->bufsize = DECODER_BUFFER_SIZE;
160 os->buf = av_malloc(os->bufsize);
164 st = av_new_stream(s, idx);
166 return AVERROR(ENOMEM);
168 av_set_pts_info(st, 64, 1, 1000000);
174 static int ogg_new_buf(struct ogg *ogg, int idx)
176 struct ogg_stream *os = ogg->streams + idx;
177 uint8_t *nb = av_malloc(os->bufsize);
178 int size = os->bufpos - os->pstart;
180 memcpy(nb, os->buf + os->pstart, size);
190 static int ogg_read_page(AVFormatContext *s, int *str)
192 AVIOContext *bc = s->pb;
193 struct ogg *ogg = s->priv_data;
194 struct ogg_stream *os;
203 if (avio_read (bc, sync, 4) < 4)
209 if (sync[sp & 3] == 'O' &&
210 sync[(sp + 1) & 3] == 'g' &&
211 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
218 }while (i++ < MAX_PAGE_SIZE);
220 if (i >= MAX_PAGE_SIZE){
221 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
225 if (avio_r8(bc) != 0) /* version */
230 serial = avio_rl32 (bc);
231 avio_skip(bc, 8); /* seq, crc */
234 idx = ogg_find_stream (ogg, serial);
239 for (n = 0; n < ogg->nstreams; n++) {
240 av_freep(&ogg->streams[n].buf);
241 av_freep(&ogg->streams[n].private);
245 idx = ogg_new_stream(s, serial, 0);
247 idx = ogg_new_stream(s, serial, 1);
253 os = ogg->streams + idx;
254 os->page_pos = avio_tell(bc) - 27;
257 ogg_new_buf(ogg, idx);
259 if (avio_read (bc, os->segments, nsegs) < nsegs)
266 for (i = 0; i < nsegs; i++)
267 size += os->segments[i];
269 if (flags & OGG_FLAG_CONT || os->incomplete){
271 while (os->segp < os->nsegs){
272 int seg = os->segments[os->segp++];
277 os->sync_pos = os->page_pos;
281 os->sync_pos = os->page_pos;
284 if (os->bufsize - os->bufpos < size){
285 uint8_t *nb = av_malloc (os->bufsize *= 2);
286 memcpy (nb, os->buf, os->bufpos);
291 if (avio_read (bc, os->buf + os->bufpos, size) < size)
304 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
307 struct ogg *ogg = s->priv_data;
309 struct ogg_stream *os;
311 int segp = 0, psize = 0;
313 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
319 if (ogg_read_page (s, &idx) < 0)
323 os = ogg->streams + idx;
325 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
326 idx, os->pstart, os->psize, os->segp, os->nsegs);
330 os->codec = ogg_find_codec (os->buf, os->bufpos);
343 while (os->segp < os->nsegs){
344 int ss = os->segments[os->segp++];
352 if (!complete && os->segp == os->nsegs){
358 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
359 idx, os->psize, os->pstart);
361 if (os->granule == -1)
362 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
368 os->header = os->codec->header (s, idx);
373 // We have reached the first non-header packet in this stream.
374 // Unfortunately more header packets may still follow for others,
375 // so we reset this later unless we are done with the headers
379 // Update the header state for all streams and
380 // compute the data_offset.
382 s->data_offset = os->sync_pos;
383 for (i = 0; i < ogg->nstreams; i++) {
384 struct ogg_stream *cur_os = ogg->streams + i;
385 if (cur_os->header > 0)
388 // if we have a partial non-header packet, its start is
389 // obviously at or after the data start
390 if (cur_os->incomplete)
391 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
394 os->pstart += os->psize;
400 if (os->codec && os->codec->packet)
401 os->codec->packet (s, idx);
405 *dstart = os->pstart;
409 *fpos = os->sync_pos;
410 os->pstart += os->psize;
412 os->sync_pos = os->page_pos;
415 // determine whether there are more complete packets in this page
416 // if not, the page's granule will apply to this packet
418 for (i = os->segp; i < os->nsegs; i++)
419 if (os->segments[i] < 255) {
424 if (os->segp == os->nsegs)
430 static int ogg_get_headers(AVFormatContext *s)
432 struct ogg *ogg = s->priv_data;
435 if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
437 }while (!ogg->headers);
439 av_dlog(s, "found headers\n");
444 static int ogg_get_length(AVFormatContext *s)
446 struct ogg *ogg = s->priv_data;
454 if (s->duration != AV_NOPTS_VALUE)
457 size = avio_size(s->pb);
460 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
463 avio_seek (s->pb, end, SEEK_SET);
465 while (!ogg_read_page (s, &i)){
466 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
467 ogg->streams[i].codec) {
468 s->streams[i]->duration =
469 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
470 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
471 s->streams[i]->duration -= s->streams[i]->start_time;
480 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
482 struct ogg *ogg = s->priv_data;
485 //linear headers seek from start
486 if (ogg_get_headers (s) < 0){
490 for (i = 0; i < ogg->nstreams; i++)
491 if (ogg->streams[i].header < 0)
492 ogg->streams[i].codec = NULL;
494 //linear granulepos seek from end
497 //fill the extradata in the per codec callbacks
501 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
503 struct ogg *ogg = s->priv_data;
504 struct ogg_stream *os = ogg->streams + idx;
505 int64_t pts = AV_NOPTS_VALUE;
508 *dts = AV_NOPTS_VALUE;
510 if (os->lastpts != AV_NOPTS_VALUE) {
512 os->lastpts = AV_NOPTS_VALUE;
514 if (os->lastdts != AV_NOPTS_VALUE) {
517 os->lastdts = AV_NOPTS_VALUE;
520 if (os->granule != -1LL) {
521 if (os->codec && os->codec->granule_is_start)
522 pts = ogg_gptopts(s, idx, os->granule, dts);
524 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
531 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
534 struct ogg_stream *os;
537 int64_t fpos, pts, dts;
542 if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
544 }while (idx < 0 || !s->streams[idx]);
547 os = ogg->streams + idx;
549 // pflags might not be set until after this
550 pts = ogg_calc_pts(s, idx, &dts);
552 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
554 os->keyframe_seek = 0;
557 if (av_new_packet (pkt, psize) < 0)
559 pkt->stream_index = idx;
560 memcpy (pkt->data, os->buf + pstart, psize);
564 pkt->flags = os->pflags;
565 pkt->duration = os->pduration;
571 static int ogg_read_close(AVFormatContext *s)
573 struct ogg *ogg = s->priv_data;
576 for (i = 0; i < ogg->nstreams; i++){
577 av_free (ogg->streams[i].buf);
578 av_free (ogg->streams[i].private);
580 av_free (ogg->streams);
584 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
585 int64_t *pos_arg, int64_t pos_limit)
587 struct ogg *ogg = s->priv_data;
588 struct ogg_stream *os = ogg->streams + stream_index;
589 AVIOContext *bc = s->pb;
590 int64_t pts = AV_NOPTS_VALUE;
592 avio_seek(bc, *pos_arg, SEEK_SET);
595 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
596 if (i == stream_index) {
597 pts = ogg_calc_pts(s, i, NULL);
598 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
599 pts = AV_NOPTS_VALUE;
601 if (pts != AV_NOPTS_VALUE)
608 static int ogg_read_seek(AVFormatContext *s, int stream_index,
609 int64_t timestamp, int flags)
611 struct ogg *ogg = s->priv_data;
612 struct ogg_stream *os = ogg->streams + stream_index;
615 // Try seeking to a keyframe first. If this fails (very possible),
616 // av_seek_frame will fall back to ignoring keyframes
617 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
618 && !(flags & AVSEEK_FLAG_ANY))
619 os->keyframe_seek = 1;
621 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
623 os->keyframe_seek = 0;
627 static int ogg_probe(AVProbeData *p)
629 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
630 return AVPROBE_SCORE_MAX;
634 AVInputFormat ff_ogg_demuxer = {
636 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
637 .priv_data_size = sizeof(struct ogg),
638 .read_probe = ogg_probe,
639 .read_header = ogg_read_header,
640 .read_packet = ogg_read_packet,
641 .read_close = ogg_read_close,
642 .read_seek = ogg_read_seek,
643 .read_timestamp = ogg_read_timestamp,
645 .flags = AVFMT_GENERIC_INDEX,