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