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);
61 //FIXME We could avoid some structure duplication
62 static int ogg_save(AVFormatContext *s)
64 struct ogg *ogg = s->priv_data;
65 struct ogg_state *ost =
66 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
68 ost->pos = avio_tell (s->pb);
69 ost->curidx = ogg->curidx;
70 ost->next = ogg->state;
71 ost->nstreams = ogg->nstreams;
72 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
74 for (i = 0; i < ogg->nstreams; i++){
75 struct ogg_stream *os = ogg->streams + i;
76 os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
77 memcpy (os->buf, ost->streams[i].buf, os->bufpos);
85 static int ogg_restore(AVFormatContext *s, int discard)
87 struct ogg *ogg = s->priv_data;
88 AVIOContext *bc = s->pb;
89 struct ogg_state *ost = ogg->state;
95 ogg->state = ost->next;
98 struct ogg_stream *old_streams = ogg->streams;
100 for (i = 0; i < ogg->nstreams; i++)
101 av_free (ogg->streams[i].buf);
103 avio_seek (bc, ost->pos, SEEK_SET);
104 ogg->curidx = ost->curidx;
105 ogg->nstreams = ost->nstreams;
106 ogg->streams = av_realloc (ogg->streams,
107 ogg->nstreams * sizeof (*ogg->streams));
110 memcpy(ogg->streams, ost->streams,
111 ost->nstreams * sizeof(*ogg->streams));
113 av_free(old_streams);
123 static int ogg_reset(AVFormatContext *s)
125 struct ogg *ogg = s->priv_data;
127 int64_t start_pos = avio_tell(s->pb);
129 for (i = 0; i < ogg->nstreams; i++){
130 struct ogg_stream *os = ogg->streams + i;
135 os->lastpts = AV_NOPTS_VALUE;
136 os->lastdts = AV_NOPTS_VALUE;
142 if (start_pos <= s->data_offset) {
152 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
156 for (i = 0; ogg_codecs[i]; i++)
157 if (size >= ogg_codecs[i]->magicsize &&
158 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
159 return ogg_codecs[i];
165 * Replace the current stream with a new one. This is a typical webradio
166 * situation where a new audio stream spawn (identified with a new serial) and
167 * must replace the previous one (track switch).
169 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
171 struct ogg *ogg = s->priv_data;
172 struct ogg_stream *os;
176 if (ogg->nstreams != 1) {
177 av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
178 return AVERROR_PATCHWELCOME;
181 os = &ogg->streams[0];
184 bufsize = os->bufsize;
186 if (!ogg->state || ogg->state->streams[0].private != os->private)
187 av_freep(&ogg->streams[0].private);
189 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
190 * also re-use the ogg_stream allocated buffer */
191 memset(os, 0, sizeof(*os));
193 os->bufsize = bufsize;
200 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
202 struct ogg *ogg = s->priv_data;
203 int idx = ogg->nstreams;
205 struct ogg_stream *os;
208 /* Allocate and init a new Ogg Stream */
209 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
210 !(os = av_realloc(ogg->streams, size)))
211 return AVERROR(ENOMEM);
213 os = ogg->streams + idx;
214 memset(os, 0, sizeof(*os));
216 os->bufsize = DECODER_BUFFER_SIZE;
217 os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
220 return AVERROR(ENOMEM);
222 /* Create the associated AVStream */
223 st = avformat_new_stream(s, NULL);
226 return AVERROR(ENOMEM);
229 avpriv_set_pts_info(st, 64, 1, 1000000);
235 static int ogg_new_buf(struct ogg *ogg, int idx)
237 struct ogg_stream *os = ogg->streams + idx;
238 uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
239 int size = os->bufpos - os->pstart;
241 memcpy(nb, os->buf + os->pstart, size);
251 static int ogg_read_page(AVFormatContext *s, int *sid)
253 AVIOContext *bc = s->pb;
254 struct ogg *ogg = s->priv_data;
255 struct ogg_stream *os;
264 ret = avio_read(bc, sync, 4);
266 return ret < 0 ? ret : AVERROR_EOF;
271 if (sync[sp & 3] == 'O' &&
272 sync[(sp + 1) & 3] == 'g' &&
273 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
280 }while (i++ < MAX_PAGE_SIZE);
282 if (i >= MAX_PAGE_SIZE){
283 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
284 return AVERROR_INVALIDDATA;
287 if (avio_r8(bc) != 0){ /* version */
288 av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
289 return AVERROR_INVALIDDATA;
294 serial = avio_rl32 (bc);
295 avio_skip(bc, 8); /* seq, crc */
298 idx = ogg_find_stream (ogg, serial);
301 idx = ogg_replace_stream(s, serial);
303 idx = ogg_new_stream(s, serial);
306 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
311 os = ogg->streams + idx;
312 os->page_pos = avio_tell(bc) - 27;
315 ogg_new_buf(ogg, idx);
317 ret = avio_read(bc, os->segments, nsegs);
319 return ret < 0 ? ret : AVERROR_EOF;
325 for (i = 0; i < nsegs; i++)
326 size += os->segments[i];
328 if (flags & OGG_FLAG_CONT || os->incomplete){
330 // If this is the very first segment we started
331 // playback in the middle of a continuation packet.
332 // Discard it since we missed the start of it.
333 while (os->segp < os->nsegs){
334 int seg = os->segments[os->segp++];
339 os->sync_pos = os->page_pos;
343 os->sync_pos = os->page_pos;
346 if (os->bufsize - os->bufpos < size){
347 uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
348 memcpy (nb, os->buf, os->bufpos);
353 ret = avio_read(bc, os->buf + os->bufpos, size);
355 return ret < 0 ? ret : AVERROR_EOF;
361 memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
369 * @brief find the next Ogg packet
370 * @param *sid is set to the stream for the packet or -1 if there is
371 * no matching stream, in that case assume all other return
372 * values to be uninitialized.
373 * @return negative value on error or EOF.
375 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
378 struct ogg *ogg = s->priv_data;
380 struct ogg_stream *os;
382 int segp = 0, psize = 0;
384 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
392 ret = ogg_read_page(s, &idx);
397 os = ogg->streams + idx;
399 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
400 idx, os->pstart, os->psize, os->segp, os->nsegs);
404 os->codec = ogg_find_codec (os->buf, os->bufpos);
406 av_log(s, AV_LOG_WARNING, "Codec not found\n");
418 while (os->segp < os->nsegs){
419 int ss = os->segments[os->segp++];
427 if (!complete && os->segp == os->nsegs){
429 // Do not set incomplete for empty packets.
430 // Together with the code in ogg_read_page
431 // that discards all continuation of empty packets
432 // we would get an infinite loop.
433 os->incomplete = !!os->psize;
438 if (os->granule == -1)
439 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
445 os->header = os->codec->header (s, idx);
450 // We have reached the first non-header packet in this stream.
451 // Unfortunately more header packets may still follow for others,
452 // but if we continue with header parsing we may lose data packets.
455 // Update the header state for all streams and
456 // compute the data_offset.
458 s->data_offset = os->sync_pos;
459 for (i = 0; i < ogg->nstreams; i++) {
460 struct ogg_stream *cur_os = ogg->streams + i;
462 // if we have a partial non-header packet, its start is
463 // obviously at or after the data start
464 if (cur_os->incomplete)
465 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
468 os->pstart += os->psize;
474 if (os->codec && os->codec->packet)
475 os->codec->packet (s, idx);
479 *dstart = os->pstart;
483 *fpos = os->sync_pos;
484 os->pstart += os->psize;
486 if(os->pstart == os->bufpos)
487 os->bufpos = os->pstart = 0;
488 os->sync_pos = os->page_pos;
491 // determine whether there are more complete packets in this page
492 // if not, the page's granule will apply to this packet
494 for (i = os->segp; i < os->nsegs; i++)
495 if (os->segments[i] < 255) {
500 if (os->segp == os->nsegs)
506 static int ogg_get_length(AVFormatContext *s)
508 struct ogg *ogg = s->priv_data;
517 if (s->duration != AV_NOPTS_VALUE)
520 size = avio_size(s->pb);
523 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
526 avio_seek (s->pb, end, SEEK_SET);
528 while (!ogg_read_page (s, &i)){
529 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
530 ogg->streams[i].codec) {
531 s->streams[i]->duration =
532 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
533 if (s->streams[i]->start_time != AV_NOPTS_VALUE){
534 s->streams[i]->duration -= s->streams[i]->start_time;
535 streams_left-= (ogg->streams[i].got_start==-1);
536 ogg->streams[i].got_start= 1;
537 }else if(!ogg->streams[i].got_start){
538 ogg->streams[i].got_start= -1;
547 avio_seek (s->pb, s->data_offset, SEEK_SET);
549 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
552 pts = ogg_calc_pts(s, i, NULL);
553 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
554 s->streams[i]->duration -= pts;
555 ogg->streams[i].got_start= 1;
557 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start){
558 ogg->streams[i].got_start= 1;
567 static int ogg_read_header(AVFormatContext *s)
569 struct ogg *ogg = s->priv_data;
574 //linear headers seek from start
576 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
579 } while (!ogg->headers);
580 av_dlog(s, "found headers\n");
582 for (i = 0; i < ogg->nstreams; i++)
583 if (ogg->streams[i].header < 0)
584 ogg->streams[i].codec = NULL;
586 //linear granulepos seek from end
592 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
594 struct ogg *ogg = s->priv_data;
595 struct ogg_stream *os = ogg->streams + idx;
596 int64_t pts = AV_NOPTS_VALUE;
599 *dts = AV_NOPTS_VALUE;
601 if (os->lastpts != AV_NOPTS_VALUE) {
603 os->lastpts = AV_NOPTS_VALUE;
605 if (os->lastdts != AV_NOPTS_VALUE) {
608 os->lastdts = AV_NOPTS_VALUE;
611 if (os->granule != -1LL) {
612 if (os->codec && os->codec->granule_is_start)
613 pts = ogg_gptopts(s, idx, os->granule, dts);
615 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
622 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
624 struct ogg *ogg = s->priv_data;
625 struct ogg_stream *os = ogg->streams + idx;
626 if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
627 if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
628 os->pflags ^= AV_PKT_FLAG_KEY;
629 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
630 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
635 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
638 struct ogg_stream *os;
641 int64_t fpos, pts, dts;
646 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
649 }while (idx < 0 || !s->streams[idx]);
652 os = ogg->streams + idx;
654 // pflags might not be set until after this
655 pts = ogg_calc_pts(s, idx, &dts);
656 ogg_validate_keyframe(s, idx, pstart, psize);
658 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
660 os->keyframe_seek = 0;
663 ret = av_new_packet(pkt, psize);
666 pkt->stream_index = idx;
667 memcpy (pkt->data, os->buf + pstart, psize);
671 pkt->flags = os->pflags;
672 pkt->duration = os->pduration;
678 static int ogg_read_close(AVFormatContext *s)
680 struct ogg *ogg = s->priv_data;
683 for (i = 0; i < ogg->nstreams; i++){
684 av_free (ogg->streams[i].buf);
685 av_free (ogg->streams[i].private);
687 av_free (ogg->streams);
691 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
692 int64_t *pos_arg, int64_t pos_limit)
694 struct ogg *ogg = s->priv_data;
695 AVIOContext *bc = s->pb;
696 int64_t pts = AV_NOPTS_VALUE;
700 avio_seek(bc, *pos_arg, SEEK_SET);
703 while (avio_tell(bc) <= pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
704 if (i == stream_index) {
705 struct ogg_stream *os = ogg->streams + stream_index;
706 pts = ogg_calc_pts(s, i, NULL);
707 ogg_validate_keyframe(s, i, pstart, psize);
708 if (os->pflags & AV_PKT_FLAG_KEY) {
710 } else if (os->keyframe_seek) {
711 // if we had a previous keyframe but no pts for it,
712 // return that keyframe with this pts value.
716 pts = AV_NOPTS_VALUE;
719 if (pts != AV_NOPTS_VALUE)
726 static int ogg_read_seek(AVFormatContext *s, int stream_index,
727 int64_t timestamp, int flags)
729 struct ogg *ogg = s->priv_data;
730 struct ogg_stream *os = ogg->streams + stream_index;
733 av_assert0(stream_index < ogg->nstreams);
734 // Ensure everything is reset even when seeking via
735 // the generated index.
738 // Try seeking to a keyframe first. If this fails (very possible),
739 // av_seek_frame will fall back to ignoring keyframes
740 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
741 && !(flags & AVSEEK_FLAG_ANY))
742 os->keyframe_seek = 1;
744 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
745 os = ogg->streams + stream_index;
747 os->keyframe_seek = 0;
751 static int ogg_probe(AVProbeData *p)
753 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
754 return AVPROBE_SCORE_MAX;
758 AVInputFormat ff_ogg_demuxer = {
760 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
761 .priv_data_size = sizeof(struct ogg),
762 .read_probe = ogg_probe,
763 .read_header = ogg_read_header,
764 .read_packet = ogg_read_packet,
765 .read_close = ogg_read_close,
766 .read_seek = ogg_read_seek,
767 .read_timestamp = ogg_read_timestamp,
769 .flags = AVFMT_GENERIC_INDEX,