1fa8b09d13928c4ac284f10501b446c76e5ddb83
[libav.git] / libavformat / oggdec.c
1 /*
2 * Ogg bitstream support
3 * Luca Barbato <lu_zero@gentoo.org>
4 * Based on tcvp implementation
5 *
6 */
7
8 /**
9 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
10
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:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
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.
30 **/
31
32
33 #include <stdio.h>
34 #include "oggdec.h"
35 #include "avformat.h"
36 #include "vorbiscomment.h"
37
38 #define MAX_PAGE_SIZE 65307
39 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
40
41 static const struct ogg_codec * const ogg_codecs[] = {
42 &ff_skeleton_codec,
43 &ff_dirac_codec,
44 &ff_speex_codec,
45 &ff_vorbis_codec,
46 &ff_theora_codec,
47 &ff_flac_codec,
48 &ff_celt_codec,
49 &ff_old_dirac_codec,
50 &ff_old_flac_codec,
51 &ff_ogm_video_codec,
52 &ff_ogm_audio_codec,
53 &ff_ogm_text_codec,
54 &ff_ogm_old_codec,
55 NULL
56 };
57
58 //FIXME We could avoid some structure duplication
59 static int ogg_save(AVFormatContext *s)
60 {
61 struct ogg *ogg = s->priv_data;
62 struct ogg_state *ost =
63 av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
64 int i;
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));
70
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);
76 }
77
78 ogg->state = ost;
79
80 return 0;
81 }
82
83 static int ogg_restore(AVFormatContext *s, int discard)
84 {
85 struct ogg *ogg = s->priv_data;
86 AVIOContext *bc = s->pb;
87 struct ogg_state *ost = ogg->state;
88 int i;
89
90 if (!ost)
91 return 0;
92
93 ogg->state = ost->next;
94
95 if (!discard){
96 struct ogg_stream *old_streams = ogg->streams;
97
98 for (i = 0; i < ogg->nstreams; i++)
99 av_free (ogg->streams[i].buf);
100
101 avio_seek (bc, ost->pos, SEEK_SET);
102 ogg->curidx = ost->curidx;
103 ogg->nstreams = ost->nstreams;
104 ogg->streams = av_realloc (ogg->streams,
105 ogg->nstreams * sizeof (*ogg->streams));
106
107 if (ogg->streams) {
108 memcpy(ogg->streams, ost->streams,
109 ost->nstreams * sizeof(*ogg->streams));
110 } else {
111 av_free(old_streams);
112 ogg->nstreams = 0;
113 }
114 }
115
116 av_free (ost);
117
118 return 0;
119 }
120
121 static int ogg_reset(struct ogg *ogg)
122 {
123 int i;
124
125 for (i = 0; i < ogg->nstreams; i++){
126 struct ogg_stream *os = ogg->streams + i;
127 os->bufpos = 0;
128 os->pstart = 0;
129 os->psize = 0;
130 os->granule = -1;
131 os->lastpts = AV_NOPTS_VALUE;
132 os->lastdts = AV_NOPTS_VALUE;
133 os->sync_pos = -1;
134 os->page_pos = 0;
135 os->nsegs = 0;
136 os->segp = 0;
137 os->incomplete = 0;
138 }
139
140 ogg->curidx = -1;
141
142 return 0;
143 }
144
145 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
146 {
147 int i;
148
149 for (i = 0; ogg_codecs[i]; i++)
150 if (size >= ogg_codecs[i]->magicsize &&
151 !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
152 return ogg_codecs[i];
153
154 return NULL;
155 }
156
157 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
158 {
159
160 struct ogg *ogg = s->priv_data;
161 int idx = ogg->nstreams++;
162 AVStream *st;
163 struct ogg_stream *os;
164
165 ogg->streams = av_realloc (ogg->streams,
166 ogg->nstreams * sizeof (*ogg->streams));
167 memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
168 os = ogg->streams + idx;
169 os->serial = serial;
170 os->bufsize = DECODER_BUFFER_SIZE;
171 os->buf = av_malloc(os->bufsize);
172 os->header = -1;
173
174 if (new_avstream) {
175 st = av_new_stream(s, idx);
176 if (!st)
177 return AVERROR(ENOMEM);
178
179 av_set_pts_info(st, 64, 1, 1000000);
180 }
181
182 return idx;
183 }
184
185 static int ogg_new_buf(struct ogg *ogg, int idx)
186 {
187 struct ogg_stream *os = ogg->streams + idx;
188 uint8_t *nb = av_malloc(os->bufsize);
189 int size = os->bufpos - os->pstart;
190 if(os->buf){
191 memcpy(nb, os->buf + os->pstart, size);
192 av_free(os->buf);
193 }
194 os->buf = nb;
195 os->bufpos = size;
196 os->pstart = 0;
197
198 return 0;
199 }
200
201 static int ogg_read_page(AVFormatContext *s, int *str)
202 {
203 AVIOContext *bc = s->pb;
204 struct ogg *ogg = s->priv_data;
205 struct ogg_stream *os;
206 int ret, i = 0;
207 int flags, nsegs;
208 uint64_t gp;
209 uint32_t serial;
210 int size, idx;
211 uint8_t sync[4];
212 int sp = 0;
213
214 ret = avio_read(bc, sync, 4);
215 if (ret < 4)
216 return ret < 0 ? ret : AVERROR_EOF;
217
218 do{
219 int c;
220
221 if (sync[sp & 3] == 'O' &&
222 sync[(sp + 1) & 3] == 'g' &&
223 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
224 break;
225
226 c = avio_r8(bc);
227 if (bc->eof_reached)
228 return AVERROR_EOF;
229 sync[sp++ & 3] = c;
230 }while (i++ < MAX_PAGE_SIZE);
231
232 if (i >= MAX_PAGE_SIZE){
233 av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
234 return AVERROR_INVALIDDATA;
235 }
236
237 if (avio_r8(bc) != 0) /* version */
238 return AVERROR_INVALIDDATA;
239
240 flags = avio_r8(bc);
241 gp = avio_rl64 (bc);
242 serial = avio_rl32 (bc);
243 avio_skip(bc, 8); /* seq, crc */
244 nsegs = avio_r8(bc);
245
246 idx = ogg_find_stream (ogg, serial);
247 if (idx < 0){
248 if (ogg->headers) {
249 int n;
250
251 for (n = 0; n < ogg->nstreams; n++) {
252 av_freep(&ogg->streams[n].buf);
253 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
254 av_freep(&ogg->streams[n].private);
255 }
256 ogg->curidx = -1;
257 ogg->nstreams = 0;
258 idx = ogg_new_stream(s, serial, 0);
259 } else {
260 idx = ogg_new_stream(s, serial, 1);
261 }
262 if (idx < 0)
263 return idx;
264 }
265
266 os = ogg->streams + idx;
267 os->page_pos = avio_tell(bc) - 27;
268
269 if(os->psize > 0)
270 ogg_new_buf(ogg, idx);
271
272 ret = avio_read(bc, os->segments, nsegs);
273 if (ret < nsegs)
274 return ret < 0 ? ret : AVERROR_EOF;
275
276 os->nsegs = nsegs;
277 os->segp = 0;
278
279 size = 0;
280 for (i = 0; i < nsegs; i++)
281 size += os->segments[i];
282
283 if (flags & OGG_FLAG_CONT || os->incomplete){
284 if (!os->psize){
285 while (os->segp < os->nsegs){
286 int seg = os->segments[os->segp++];
287 os->pstart += seg;
288 if (seg < 255)
289 break;
290 }
291 os->sync_pos = os->page_pos;
292 }
293 }else{
294 os->psize = 0;
295 os->sync_pos = os->page_pos;
296 }
297
298 if (os->bufsize - os->bufpos < size){
299 uint8_t *nb = av_malloc (os->bufsize *= 2);
300 memcpy (nb, os->buf, os->bufpos);
301 av_free (os->buf);
302 os->buf = nb;
303 }
304
305 ret = avio_read(bc, os->buf + os->bufpos, size);
306 if (ret < size)
307 return ret < 0 ? ret : AVERROR_EOF;
308
309 os->bufpos += size;
310 os->granule = gp;
311 os->flags = flags;
312
313 if (str)
314 *str = idx;
315
316 return 0;
317 }
318
319 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
320 int64_t *fpos)
321 {
322 struct ogg *ogg = s->priv_data;
323 int idx, i, ret;
324 struct ogg_stream *os;
325 int complete = 0;
326 int segp = 0, psize = 0;
327
328 av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
329
330 do{
331 idx = ogg->curidx;
332
333 while (idx < 0){
334 ret = ogg_read_page(s, &idx);
335 if (ret < 0)
336 return ret;
337 }
338
339 os = ogg->streams + idx;
340
341 av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
342 idx, os->pstart, os->psize, os->segp, os->nsegs);
343
344 if (!os->codec){
345 if (os->header < 0){
346 os->codec = ogg_find_codec (os->buf, os->bufpos);
347 if (!os->codec){
348 av_log(s, AV_LOG_WARNING, "Codec not found\n");
349 os->header = 0;
350 return 0;
351 }
352 }else{
353 return 0;
354 }
355 }
356
357 segp = os->segp;
358 psize = os->psize;
359
360 while (os->segp < os->nsegs){
361 int ss = os->segments[os->segp++];
362 os->psize += ss;
363 if (ss < 255){
364 complete = 1;
365 break;
366 }
367 }
368
369 if (!complete && os->segp == os->nsegs){
370 ogg->curidx = -1;
371 os->incomplete = 1;
372 }
373 }while (!complete);
374
375 av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
376 idx, os->psize, os->pstart);
377
378 if (os->granule == -1)
379 av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
380
381 ogg->curidx = idx;
382 os->incomplete = 0;
383
384 if (os->header) {
385 os->header = os->codec->header (s, idx);
386 if (!os->header){
387 os->segp = segp;
388 os->psize = psize;
389
390 // We have reached the first non-header packet in this stream.
391 // Unfortunately more header packets may still follow for others,
392 // but if we continue with header parsing we may lose data packets.
393 ogg->headers = 1;
394
395 // Update the header state for all streams and
396 // compute the data_offset.
397 if (!s->data_offset)
398 s->data_offset = os->sync_pos;
399 for (i = 0; i < ogg->nstreams; i++) {
400 struct ogg_stream *cur_os = ogg->streams + i;
401
402 // if we have a partial non-header packet, its start is
403 // obviously at or after the data start
404 if (cur_os->incomplete)
405 s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
406 }
407 }else{
408 os->pstart += os->psize;
409 os->psize = 0;
410 }
411 } else {
412 os->pflags = 0;
413 os->pduration = 0;
414 if (os->codec && os->codec->packet)
415 os->codec->packet (s, idx);
416 if (str)
417 *str = idx;
418 if (dstart)
419 *dstart = os->pstart;
420 if (dsize)
421 *dsize = os->psize;
422 if (fpos)
423 *fpos = os->sync_pos;
424 os->pstart += os->psize;
425 os->psize = 0;
426 os->sync_pos = os->page_pos;
427 }
428
429 // determine whether there are more complete packets in this page
430 // if not, the page's granule will apply to this packet
431 os->page_end = 1;
432 for (i = os->segp; i < os->nsegs; i++)
433 if (os->segments[i] < 255) {
434 os->page_end = 0;
435 break;
436 }
437
438 if (os->segp == os->nsegs)
439 ogg->curidx = -1;
440
441 return 0;
442 }
443
444 static int ogg_get_headers(AVFormatContext *s)
445 {
446 struct ogg *ogg = s->priv_data;
447 int ret;
448
449 do{
450 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
451 if (ret < 0)
452 return ret;
453 }while (!ogg->headers);
454
455 av_dlog(s, "found headers\n");
456
457 return 0;
458 }
459
460 static int ogg_get_length(AVFormatContext *s)
461 {
462 struct ogg *ogg = s->priv_data;
463 int i;
464 int64_t size, end;
465
466 if(!s->pb->seekable)
467 return 0;
468
469 // already set
470 if (s->duration != AV_NOPTS_VALUE)
471 return 0;
472
473 size = avio_size(s->pb);
474 if(size < 0)
475 return 0;
476 end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
477
478 ogg_save (s);
479 avio_seek (s->pb, end, SEEK_SET);
480
481 while (!ogg_read_page (s, &i)){
482 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
483 ogg->streams[i].codec) {
484 s->streams[i]->duration =
485 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
486 if (s->streams[i]->start_time != AV_NOPTS_VALUE)
487 s->streams[i]->duration -= s->streams[i]->start_time;
488 }
489 }
490
491 ogg_restore (s, 0);
492
493 return 0;
494 }
495
496 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
497 {
498 struct ogg *ogg = s->priv_data;
499 int ret, i;
500 ogg->curidx = -1;
501 //linear headers seek from start
502 ret = ogg_get_headers(s);
503 if (ret < 0)
504 return ret;
505
506 for (i = 0; i < ogg->nstreams; i++)
507 if (ogg->streams[i].header < 0)
508 ogg->streams[i].codec = NULL;
509
510 //linear granulepos seek from end
511 ogg_get_length (s);
512
513 //fill the extradata in the per codec callbacks
514 return 0;
515 }
516
517 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
518 {
519 struct ogg *ogg = s->priv_data;
520 struct ogg_stream *os = ogg->streams + idx;
521 int64_t pts = AV_NOPTS_VALUE;
522
523 if (dts)
524 *dts = AV_NOPTS_VALUE;
525
526 if (os->lastpts != AV_NOPTS_VALUE) {
527 pts = os->lastpts;
528 os->lastpts = AV_NOPTS_VALUE;
529 }
530 if (os->lastdts != AV_NOPTS_VALUE) {
531 if (dts)
532 *dts = os->lastdts;
533 os->lastdts = AV_NOPTS_VALUE;
534 }
535 if (os->page_end) {
536 if (os->granule != -1LL) {
537 if (os->codec && os->codec->granule_is_start)
538 pts = ogg_gptopts(s, idx, os->granule, dts);
539 else
540 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
541 os->granule = -1LL;
542 }
543 }
544 return pts;
545 }
546
547 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
548 {
549 struct ogg *ogg;
550 struct ogg_stream *os;
551 int idx = -1, ret;
552 int pstart, psize;
553 int64_t fpos, pts, dts;
554
555 //Get an ogg packet
556 retry:
557 do{
558 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
559 if (ret < 0)
560 return ret;
561 }while (idx < 0 || !s->streams[idx]);
562
563 ogg = s->priv_data;
564 os = ogg->streams + idx;
565
566 // pflags might not be set until after this
567 pts = ogg_calc_pts(s, idx, &dts);
568
569 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
570 goto retry;
571 os->keyframe_seek = 0;
572
573 //Alloc a pkt
574 ret = av_new_packet(pkt, psize);
575 if (ret < 0)
576 return ret;
577 pkt->stream_index = idx;
578 memcpy (pkt->data, os->buf + pstart, psize);
579
580 pkt->pts = pts;
581 pkt->dts = dts;
582 pkt->flags = os->pflags;
583 pkt->duration = os->pduration;
584 pkt->pos = fpos;
585
586 return psize;
587 }
588
589 static int ogg_read_close(AVFormatContext *s)
590 {
591 struct ogg *ogg = s->priv_data;
592 int i;
593
594 for (i = 0; i < ogg->nstreams; i++){
595 av_free (ogg->streams[i].buf);
596 av_free (ogg->streams[i].private);
597 }
598 av_free (ogg->streams);
599 return 0;
600 }
601
602 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
603 int64_t *pos_arg, int64_t pos_limit)
604 {
605 struct ogg *ogg = s->priv_data;
606 AVIOContext *bc = s->pb;
607 int64_t pts = AV_NOPTS_VALUE;
608 int i = -1;
609 avio_seek(bc, *pos_arg, SEEK_SET);
610 ogg_reset(ogg);
611
612 while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
613 if (i == stream_index) {
614 struct ogg_stream *os = ogg->streams + stream_index;
615 pts = ogg_calc_pts(s, i, NULL);
616 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
617 pts = AV_NOPTS_VALUE;
618 }
619 if (pts != AV_NOPTS_VALUE)
620 break;
621 }
622 ogg_reset(ogg);
623 return pts;
624 }
625
626 static int ogg_read_seek(AVFormatContext *s, int stream_index,
627 int64_t timestamp, int flags)
628 {
629 struct ogg *ogg = s->priv_data;
630 struct ogg_stream *os = ogg->streams + stream_index;
631 int ret;
632
633 // Try seeking to a keyframe first. If this fails (very possible),
634 // av_seek_frame will fall back to ignoring keyframes
635 if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
636 && !(flags & AVSEEK_FLAG_ANY))
637 os->keyframe_seek = 1;
638
639 ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
640 os = ogg->streams + stream_index;
641 if (ret < 0)
642 os->keyframe_seek = 0;
643 return ret;
644 }
645
646 static int ogg_probe(AVProbeData *p)
647 {
648 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
649 return AVPROBE_SCORE_MAX;
650 return 0;
651 }
652
653 AVInputFormat ff_ogg_demuxer = {
654 .name = "ogg",
655 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
656 .priv_data_size = sizeof(struct ogg),
657 .read_probe = ogg_probe,
658 .read_header = ogg_read_header,
659 .read_packet = ogg_read_packet,
660 .read_close = ogg_read_close,
661 .read_seek = ogg_read_seek,
662 .read_timestamp = ogg_read_timestamp,
663 .extensions = "ogg",
664 .flags = AVFMT_GENERIC_INDEX,
665 };