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.
32 #include "libavutil/avassert.h"
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[] = {
59 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
60 static int ogg_read_close(AVFormatContext *s);
62 //FIXME We could avoid some structure duplication
63 static int ogg_save(AVFormatContext *s)
65 struct ogg *ogg = s->priv_data;
66 struct ogg_state *ost =
67 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
69 ost->pos = avio_tell (s->pb);
70 ost->curidx = ogg->curidx;
71 ost->next = ogg->state;
72 ost->nstreams = ogg->nstreams;
73 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
75 for (i = 0; i < ogg->nstreams; i++){
76 struct ogg_stream *os = ogg->streams + i;
77 os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
78 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
86 static int ogg_restore(AVFormatContext *s, int discard)
88 struct ogg *ogg = s->priv_data;
89 AVIOContext *bc = s->pb;
90 struct ogg_state *ost = ogg->state;
96 ogg->state = ost->next;
99 struct ogg_stream *old_streams = ogg->streams;
101 for (i = 0; i < ogg->nstreams; i++)
102 av_free (ogg->streams[i].buf);
104 avio_seek (bc, ost->pos, SEEK_SET);
105 ogg->curidx = ost->curidx;
106 ogg->nstreams = ost->nstreams;
107 ogg->streams = av_realloc (ogg->streams,
108 ogg->nstreams * sizeof (*ogg->streams));
111 memcpy(ogg->streams, ost->streams,
112 ost->nstreams * sizeof(*ogg->streams));
114 av_free(old_streams);
124 static int ogg_reset(AVFormatContext *s)
126 struct ogg *ogg = s->priv_data;
128 int64_t start_pos = avio_tell(s->pb);
130 for (i = 0; i < ogg->nstreams; i++){
131 struct ogg_stream *os = ogg->streams + i;
136 os->lastpts = AV_NOPTS_VALUE;
137 os->lastdts = AV_NOPTS_VALUE;
144 if (start_pos <= s->data_offset) {
154 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
158 for (i = 0; ogg_codecs[i]; i++)
159 if (size >= ogg_codecs[i]->magicsize &&
160 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
161 return ogg_codecs[i];
167 * Replace the current stream with a new one. This is a typical webradio
168 * situation where a new audio stream spawn (identified with a new serial) and
169 * must replace the previous one (track switch).
171 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
173 struct ogg *ogg = s->priv_data;
174 struct ogg_stream *os;
177 struct ogg_codec *codec;
179 if (ogg->nstreams != 1) {
180 av_log_missing_feature(s, "Changing stream parameters in multistream ogg", 0);
181 return AVERROR_PATCHWELCOME;
184 os = &ogg->streams[0];
187 bufsize = os->bufsize;
190 if (!ogg->state || ogg->state->streams[0].private != os->private)
191 av_freep(&ogg->streams[0].private);
193 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
194 * also re-use the ogg_stream allocated buffer */
195 memset(os, 0, sizeof(*os));
197 os->bufsize = bufsize;
205 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
207 struct ogg *ogg = s->priv_data;
208 int idx = ogg->nstreams;
210 struct ogg_stream *os;
214 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
215 "in between Ogg context save/restore operations.\n");
219 /* Allocate and init a new Ogg Stream */
220 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
221 !(os = av_realloc(ogg->streams, size)))
222 return AVERROR(ENOMEM);
224 os = ogg->streams + idx;
225 memset(os, 0, sizeof(*os));
227 os->bufsize = DECODER_BUFFER_SIZE;
228 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
230 os->start_granule = OGG_NOGRANULE_VALUE;
232 return AVERROR(ENOMEM);
234 /* Create the associated AVStream */
235 st = avformat_new_stream(s, NULL);
238 return AVERROR(ENOMEM);
241 avpriv_set_pts_info(st, 64, 1, 1000000);
247 static int ogg_new_buf(struct ogg *ogg, int idx)
249 struct ogg_stream *os = ogg->streams + idx;
250 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
251 int size = os->bufpos - os->pstart;
253 memcpy(nb, os->buf + os->pstart, size);
263 static int data_packets_seen(const struct ogg *ogg)
267 for (i = 0; i < ogg->nstreams; i++)
268 if (ogg->streams[i].got_data)
273 static int ogg_read_page(AVFormatContext *s, int *sid)
275 AVIOContext *bc = s->pb;
276 struct ogg *ogg = s->priv_data;
277 struct ogg_stream *os;
286 ret = avio_read(bc, sync, 4);
288 return ret < 0 ? ret : AVERROR_EOF;
293 if (sync[sp & 3] == 'O' &&
294 sync[(sp + 1) & 3] == 'g' &&
295 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
302 }while (i++ < MAX_PAGE_SIZE);
304 if (i >= MAX_PAGE_SIZE){
305 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
306 return AVERROR_INVALIDDATA;
309 if (avio_r8(bc) != 0){ /* version */
310 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
311 return AVERROR_INVALIDDATA;
316 serial = avio_rl32 (bc);
317 avio_skip(bc, 8); /* seq, crc */
320 idx = ogg_find_stream (ogg, serial);
322 if (data_packets_seen(ogg))
323 idx = ogg_replace_stream(s, serial);
325 idx = ogg_new_stream(s, serial);
328 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
333 os = ogg->streams + idx;
334 os->page_pos = avio_tell(bc) - 27;
337 ogg_new_buf(ogg, idx);
339 ret = avio_read(bc, os->segments, nsegs);
341 return ret < 0 ? ret : AVERROR_EOF;
347 for (i = 0; i < nsegs; i++)
348 size += os->segments[i];
350 if (!(flags & OGG_FLAG_BOS))
353 if (flags & OGG_FLAG_CONT || os->incomplete){
355 // If this is the very first segment we started
356 // playback in the middle of a continuation packet.
357 // Discard it since we missed the start of it.
358 while (os->segp < os->nsegs){
359 int seg = os->segments[os->segp++];
364 os->sync_pos = os->page_pos;
368 os->sync_pos = os->page_pos;
371 if (os->bufsize - os->bufpos < size){
372 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
373 memcpy (nb, os->buf, os->bufpos);
378 ret = avio_read(bc, os->buf + os->bufpos, size);
380 return ret < 0 ? ret : AVERROR_EOF;
386 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
394 * @brief find the next Ogg packet
395 * @param *sid is set to the stream for the packet or -1 if there is
396 * no matching stream, in that case assume all other return
397 * values to be uninitialized.
398 * @return negative value on error or EOF.
400 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
403 struct ogg *ogg = s->priv_data;
405 struct ogg_stream *os;
407 int segp = 0, psize = 0;
409 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
417 ret = ogg_read_page(s, &idx);
422 os = ogg->streams + idx;
424 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
425 idx, os->pstart, os->psize, os->segp, os->nsegs);
429 os->codec = ogg_find_codec (os->buf, os->bufpos);
431 av_log(s, AV_LOG_WARNING, "Codec not found\n");
443 while (os->segp < os->nsegs){
444 int ss = os->segments[os->segp++];
452 if (!complete && os->segp == os->nsegs){
454 // Do not set incomplete for empty packets.
455 // Together with the code in ogg_read_page
456 // that discards all continuation of empty packets
457 // we would get an infinite loop.
458 os->incomplete = !!os->psize;
463 if (os->granule == -1)
464 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
470 os->header = os->codec->header (s, idx);
475 // We have reached the first non-header packet in this stream.
476 // Unfortunately more header packets may still follow for others,
477 // but if we continue with header parsing we may lose data packets.
480 // Update the header state for all streams and
481 // compute the data_offset.
483 s->data_offset = os->sync_pos;
484 for (i = 0; i < ogg->nstreams; i++) {
485 struct ogg_stream *cur_os = ogg->streams + i;
487 // if we have a partial non-header packet, its start is
488 // obviously at or after the data start
489 if (cur_os->incomplete)
490 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
494 os->pstart += os->psize;
500 if (os->codec && os->codec->packet)
501 os->codec->packet (s, idx);
505 *dstart = os->pstart;
509 *fpos = os->sync_pos;
510 os->pstart += os->psize;
512 if(os->pstart == os->bufpos)
513 os->bufpos = os->pstart = 0;
514 os->sync_pos = os->page_pos;
517 // determine whether there are more complete packets in this page
518 // if not, the page's granule will apply to this packet
520 for (i = os->segp; i < os->nsegs; i++)
521 if (os->segments[i] < 255) {
526 if (os->segp == os->nsegs)
532 static int ogg_get_length(AVFormatContext *s)
534 struct ogg *ogg = s->priv_data;
543 if (s->duration != AV_NOPTS_VALUE)
546 size = avio_size(s->pb);
549 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
552 avio_seek (s->pb, end, SEEK_SET);
554 while (!ogg_read_page (s, &i)){
555 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
556 ogg->streams[i].codec) {
557 s->streams[i]->duration =
558 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
559 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
560 s->streams[i]->duration -= s->streams[i]->start_time;
561 streams_left-= (ogg->streams[i].got_start==-1);
562 ogg->streams[i].got_start= 1;
563 }else if(!ogg->streams[i].got_start){
564 ogg->streams[i].got_start= -1;
573 avio_seek (s->pb, s->data_offset, SEEK_SET);
575 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
578 pts = ogg_calc_pts(s, i, NULL);
579 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
580 s->streams[i]->duration -= pts;
581 ogg->streams[i].got_start= 1;
583 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
584 ogg->streams[i].got_start= 1;
593 static int ogg_read_header(AVFormatContext *s)
595 struct ogg *ogg = s->priv_data;
600 //linear headers seek from start
602 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
607 } while (!ogg->headers);
608 av_dlog(s, "found headers\n");
610 for (i = 0; i < ogg->nstreams; i++) {
611 struct ogg_stream *os = ogg->streams + i;
613 if (ogg->streams[i].header < 0) {
614 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
615 ogg->streams[i].codec = NULL;
616 } else if (os->codec && os->nb_header < os->codec->nb_header) {
617 av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
619 if (os->start_granule != OGG_NOGRANULE_VALUE)
620 os->lastpts = s->streams[i]->start_time =
621 ogg_gptopts(s, i, os->start_granule, NULL);
624 //linear granulepos seek from end
630 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
632 struct ogg *ogg = s->priv_data;
633 struct ogg_stream *os = ogg->streams + idx;
634 int64_t pts = AV_NOPTS_VALUE;
637 *dts = AV_NOPTS_VALUE;
639 if (os->lastpts != AV_NOPTS_VALUE) {
641 os->lastpts = AV_NOPTS_VALUE;
643 if (os->lastdts != AV_NOPTS_VALUE) {
646 os->lastdts = AV_NOPTS_VALUE;
649 if (os->granule != -1LL) {
650 if (os->codec && os->codec->granule_is_start)
651 pts = ogg_gptopts(s, idx, os->granule, dts);
653 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
660 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
662 struct ogg *ogg = s->priv_data;
663 struct ogg_stream *os = ogg->streams + idx;
664 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
665 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
666 os->pflags ^= AV_PKT_FLAG_KEY;
667 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
668 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
673 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
676 struct ogg_stream *os;
679 int64_t fpos, pts, dts;
684 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
687 }while (idx < 0 || !s->streams[idx]);
690 os = ogg->streams + idx;
692 // pflags might not be set until after this
693 pts = ogg_calc_pts(s, idx, &dts);
694 ogg_validate_keyframe(s, idx, pstart, psize);
696 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
698 os->keyframe_seek = 0;
701 ret = av_new_packet(pkt, psize);
704 pkt->stream_index = idx;
705 memcpy (pkt->data, os->buf + pstart, psize);
709 pkt->flags = os->pflags;
710 pkt->duration = os->pduration;
716 static int ogg_read_close(AVFormatContext *s)
718 struct ogg *ogg = s->priv_data;
721 for (i = 0; i < ogg->nstreams; i++){
722 av_free (ogg->streams[i].buf);
723 av_free (ogg->streams[i].private);
725 av_free (ogg->streams);
729 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
730 int64_t *pos_arg, int64_t pos_limit)
732 struct ogg *ogg = s->priv_data;
733 AVIOContext *bc = s->pb;
734 int64_t pts = AV_NOPTS_VALUE;
738 avio_seek(bc, *pos_arg, SEEK_SET);
741 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
742 if (i == stream_index) {
743 struct ogg_stream *os = ogg->streams + stream_index;
744 pts = ogg_calc_pts(s, i, NULL);
745 ogg_validate_keyframe(s, i, pstart, psize);
746 if (os->pflags & AV_PKT_FLAG_KEY) {
748 } else if (os->keyframe_seek) {
749 // if we had a previous keyframe but no pts for it,
750 // return that keyframe with this pts value.
754 pts = AV_NOPTS_VALUE;
757 if (pts != AV_NOPTS_VALUE)
764 static int ogg_read_seek(AVFormatContext *s, int stream_index,
765 int64_t timestamp, int flags)
767 struct ogg *ogg = s->priv_data;
768 struct ogg_stream *os = ogg->streams + stream_index;
771 av_assert0(stream_index < ogg->nstreams);
772 // Ensure everything is reset even when seeking via
773 // the generated index.
776 // Try seeking to a keyframe first. If this fails (very possible),
777 // av_seek_frame will fall back to ignoring keyframes
778 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
779 && !(flags & AVSEEK_FLAG_ANY))
780 os->keyframe_seek = 1;
782 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
783 os = ogg->streams + stream_index;
785 os->keyframe_seek = 0;
789 static int ogg_probe(AVProbeData *p)
791 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
792 return AVPROBE_SCORE_MAX;
796 AVInputFormat ff_ogg_demuxer = {
798 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
799 .priv_data_size = sizeof(struct ogg),
800 .read_probe = ogg_probe,
801 .read_header = ogg_read_header,
802 .read_packet = ogg_read_packet,
803 .read_close = ogg_read_close,
804 .read_seek = ogg_read_seek,
805 .read_timestamp = ogg_read_timestamp,
807 .flags = AVFMT_GENERIC_INDEX,