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
if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
242
av_freep(&ogg->streams[n].private);
246
idx = ogg_new_stream(s, serial, 0);
248
idx = ogg_new_stream(s, serial, 1);
254
os = ogg->streams + idx;
255
os->page_pos = avio_tell(bc) - 27;
258
ogg_new_buf(ogg, idx);
260
if (avio_read (bc, os->segments, nsegs) < nsegs)
267
for (i = 0; i < nsegs; i++)
268
size += os->segments[i];
270
if (flags & OGG_FLAG_CONT || os->incomplete){
272
while (os->segp < os->nsegs){
273
int seg = os->segments[os->segp++];
278
os->sync_pos = os->page_pos;
282
os->sync_pos = os->page_pos;
285
if (os->bufsize - os->bufpos < size){
286
uint8_t *nb = av_malloc (os->bufsize *= 2);
287
memcpy (nb, os->buf, os->bufpos);
292
if (avio_read (bc, os->buf + os->bufpos, size) < size)
305
static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
308
struct ogg *ogg = s->priv_data;
310
struct ogg_stream *os;
312
int segp = 0, psize = 0;
314
av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
320
if (ogg_read_page (s, &idx) < 0)
324
os = ogg->streams + idx;
326
av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
327
idx, os->pstart, os->psize, os->segp, os->nsegs);
331
os->codec = ogg_find_codec (os->buf, os->bufpos);
344
while (os->segp < os->nsegs){
345
int ss = os->segments[os->segp++];
353
if (!complete && os->segp == os->nsegs){
359
av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
360
idx, os->psize, os->pstart);
362
if (os->granule == -1)
363
av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
369
os->header = os->codec->header (s, idx);
374
// We have reached the first non-header packet in this stream.
375
// Unfortunately more header packets may still follow for others,
376
// but if we continue with header parsing we may lose data packets.
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;
386
// if we have a partial non-header packet, its start is
387
// obviously at or after the data start
388
if (cur_os->incomplete)
389
s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
392
os->pstart += os->psize;
398
if (os->codec && os->codec->packet)
399
os->codec->packet (s, idx);
403
*dstart = os->pstart;
407
*fpos = os->sync_pos;
408
os->pstart += os->psize;
410
os->sync_pos = os->page_pos;
413
// determine whether there are more complete packets in this page
414
// if not, the page's granule will apply to this packet
416
for (i = os->segp; i < os->nsegs; i++)
417
if (os->segments[i] < 255) {
422
if (os->segp == os->nsegs)
428
static int ogg_get_headers(AVFormatContext *s)
430
struct ogg *ogg = s->priv_data;
433
if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
435
}while (!ogg->headers);
437
av_dlog(s, "found headers\n");
442
static int ogg_get_length(AVFormatContext *s)
444
struct ogg *ogg = s->priv_data;
452
if (s->duration != AV_NOPTS_VALUE)
455
size = avio_size(s->pb);
458
end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
461
avio_seek (s->pb, end, SEEK_SET);
463
while (!ogg_read_page (s, &i)){
464
if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
465
ogg->streams[i].codec) {
466
s->streams[i]->duration =
467
ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
468
if (s->streams[i]->start_time != AV_NOPTS_VALUE)
469
s->streams[i]->duration -= s->streams[i]->start_time;
478
static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
480
struct ogg *ogg = s->priv_data;
483
//linear headers seek from start
484
if (ogg_get_headers (s) < 0){
488
for (i = 0; i < ogg->nstreams; i++)
489
if (ogg->streams[i].header < 0)
490
ogg->streams[i].codec = NULL;
492
//linear granulepos seek from end
495
//fill the extradata in the per codec callbacks
499
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
501
struct ogg *ogg = s->priv_data;
502
struct ogg_stream *os = ogg->streams + idx;
503
int64_t pts = AV_NOPTS_VALUE;
506
*dts = AV_NOPTS_VALUE;
508
if (os->lastpts != AV_NOPTS_VALUE) {
510
os->lastpts = AV_NOPTS_VALUE;
512
if (os->lastdts != AV_NOPTS_VALUE) {
515
os->lastdts = AV_NOPTS_VALUE;
518
if (os->granule != -1LL) {
519
if (os->codec && os->codec->granule_is_start)
520
pts = ogg_gptopts(s, idx, os->granule, dts);
522
os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
529
static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
532
struct ogg_stream *os;
535
int64_t fpos, pts, dts;
540
if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
542
}while (idx < 0 || !s->streams[idx]);
545
os = ogg->streams + idx;
547
// pflags might not be set until after this
548
pts = ogg_calc_pts(s, idx, &dts);
550
if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
552
os->keyframe_seek = 0;
555
if (av_new_packet (pkt, psize) < 0)
557
pkt->stream_index = idx;
558
memcpy (pkt->data, os->buf + pstart, psize);
562
pkt->flags = os->pflags;
563
pkt->duration = os->pduration;
569
static int ogg_read_close(AVFormatContext *s)
571
struct ogg *ogg = s->priv_data;
574
for (i = 0; i < ogg->nstreams; i++){
575
av_free (ogg->streams[i].buf);
576
av_free (ogg->streams[i].private);
578
av_free (ogg->streams);
582
static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
583
int64_t *pos_arg, int64_t pos_limit)
585
struct ogg *ogg = s->priv_data;
586
AVIOContext *bc = s->pb;
587
int64_t pts = AV_NOPTS_VALUE;
589
avio_seek(bc, *pos_arg, SEEK_SET);
592
while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
593
if (i == stream_index) {
594
struct ogg_stream *os = ogg->streams + stream_index;
595
pts = ogg_calc_pts(s, i, NULL);
596
if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
597
pts = AV_NOPTS_VALUE;
599
if (pts != AV_NOPTS_VALUE)
606
static int ogg_read_seek(AVFormatContext *s, int stream_index,
607
int64_t timestamp, int flags)
609
struct ogg *ogg = s->priv_data;
610
struct ogg_stream *os = ogg->streams + stream_index;
613
// Try seeking to a keyframe first. If this fails (very possible),
614
// av_seek_frame will fall back to ignoring keyframes
615
if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
616
&& !(flags & AVSEEK_FLAG_ANY))
617
os->keyframe_seek = 1;
619
ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
620
os = ogg->streams + stream_index;
622
os->keyframe_seek = 0;
626
static int ogg_probe(AVProbeData *p)
628
if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
629
return AVPROBE_SCORE_MAX;
633
AVInputFormat ff_ogg_demuxer = {
635
.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
636
.priv_data_size = sizeof(struct ogg),
637
.read_probe = ogg_probe,
638
.read_header = ogg_read_header,
639
.read_packet = ogg_read_packet,
640
.read_close = ogg_read_close,
641
.read_seek = ogg_read_seek,
642
.read_timestamp = ogg_read_timestamp,
644
.flags = AVFMT_GENERIC_INDEX,