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