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