Merge remote-tracking branch 'qatar/master'
[ffmpeg.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         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                 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
244                     av_freep(&ogg->streams[n].private);
245             }
246             ogg->curidx   = -1;
247             ogg->nstreams = 0;
248             idx = ogg_new_stream(s, serial, 0);
249         } else {
250             idx = ogg_new_stream(s, serial, 1);
251         }
252         if (idx < 0)
253             return idx;
254     }
255
256     os = ogg->streams + idx;
257     os->page_pos = avio_tell(bc) - 27;
258
259     if(os->psize > 0)
260         ogg_new_buf(ogg, idx);
261
262     ret = avio_read(bc, os->segments, nsegs);
263     if (ret < nsegs)
264         return ret < 0 ? ret : AVERROR_EOF;
265
266     os->nsegs = nsegs;
267     os->segp = 0;
268
269     size = 0;
270     for (i = 0; i < nsegs; i++)
271         size += os->segments[i];
272
273     if (flags & OGG_FLAG_CONT || os->incomplete){
274         if (!os->psize){
275             while (os->segp < os->nsegs){
276                 int seg = os->segments[os->segp++];
277                 os->pstart += seg;
278                 if (seg < 255)
279                     break;
280             }
281             os->sync_pos = os->page_pos;
282         }
283     }else{
284         os->psize = 0;
285         os->sync_pos = os->page_pos;
286     }
287
288     if (os->bufsize - os->bufpos < size){
289         uint8_t *nb = av_malloc (os->bufsize *= 2);
290         memcpy (nb, os->buf, os->bufpos);
291         av_free (os->buf);
292         os->buf = nb;
293     }
294
295     ret = avio_read(bc, os->buf + os->bufpos, size);
296     if (ret < size)
297         return ret < 0 ? ret : AVERROR_EOF;
298
299     os->bufpos += size;
300     os->granule = gp;
301     os->flags = flags;
302
303     if (str)
304         *str = idx;
305
306     return 0;
307 }
308
309 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
310                       int64_t *fpos)
311 {
312     struct ogg *ogg = s->priv_data;
313     int idx, i, ret;
314     struct ogg_stream *os;
315     int complete = 0;
316     int segp = 0, psize = 0;
317
318     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
319
320     do{
321         idx = ogg->curidx;
322
323         while (idx < 0){
324             ret = ogg_read_page(s, &idx);
325             if (ret < 0)
326                 return ret;
327         }
328
329         os = ogg->streams + idx;
330
331         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
332                 idx, os->pstart, os->psize, os->segp, os->nsegs);
333
334         if (!os->codec){
335             if (os->header < 0){
336                 os->codec = ogg_find_codec (os->buf, os->bufpos);
337                 if (!os->codec){
338                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
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
366     if (os->granule == -1)
367         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
368
369     ogg->curidx = idx;
370     os->incomplete = 0;
371
372     if (os->header) {
373         os->header = os->codec->header (s, idx);
374         if (!os->header){
375             os->segp = segp;
376             os->psize = psize;
377
378             // We have reached the first non-header packet in this stream.
379             // Unfortunately more header packets may still follow for others,
380             // but if we continue with header parsing we may lose data packets.
381             ogg->headers = 1;
382
383             // Update the header state for all streams and
384             // compute the data_offset.
385             if (!s->data_offset)
386                 s->data_offset = os->sync_pos;
387             for (i = 0; i < ogg->nstreams; i++) {
388                 struct ogg_stream *cur_os = ogg->streams + i;
389
390                 // if we have a partial non-header packet, its start is
391                 // obviously at or after the data start
392                 if (cur_os->incomplete)
393                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
394             }
395         }else{
396             os->pstart += os->psize;
397             os->psize = 0;
398         }
399     } else {
400         os->pflags = 0;
401         os->pduration = 0;
402         if (os->codec && os->codec->packet)
403             os->codec->packet (s, idx);
404         if (str)
405             *str = idx;
406         if (dstart)
407             *dstart = os->pstart;
408         if (dsize)
409             *dsize = os->psize;
410         if (fpos)
411             *fpos = os->sync_pos;
412         os->pstart += os->psize;
413         os->psize = 0;
414         if(os->pstart == os->bufpos)
415             os->bufpos = os->pstart = 0;
416         os->sync_pos = os->page_pos;
417     }
418
419     // determine whether there are more complete packets in this page
420     // if not, the page's granule will apply to this packet
421     os->page_end = 1;
422     for (i = os->segp; i < os->nsegs; i++)
423         if (os->segments[i] < 255) {
424             os->page_end = 0;
425             break;
426         }
427
428     if (os->segp == os->nsegs)
429         ogg->curidx = -1;
430
431     return 0;
432 }
433
434 static int ogg_get_headers(AVFormatContext *s)
435 {
436     struct ogg *ogg = s->priv_data;
437     int ret;
438
439     do{
440         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
441         if (ret < 0)
442             return ret;
443     }while (!ogg->headers);
444
445     av_dlog(s, "found headers\n");
446
447     return 0;
448 }
449
450 static int ogg_get_length(AVFormatContext *s)
451 {
452     struct ogg *ogg = s->priv_data;
453     int i;
454     int64_t size, end;
455
456     if(!s->pb->seekable)
457         return 0;
458
459 // already set
460     if (s->duration != AV_NOPTS_VALUE)
461         return 0;
462
463     size = avio_size(s->pb);
464     if(size < 0)
465         return 0;
466     end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
467
468     ogg_save (s);
469     avio_seek (s->pb, end, SEEK_SET);
470
471     while (!ogg_read_page (s, &i)){
472         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
473             ogg->streams[i].codec) {
474             s->streams[i]->duration =
475                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
476             if (s->streams[i]->start_time != AV_NOPTS_VALUE)
477                 s->streams[i]->duration -= s->streams[i]->start_time;
478         }
479     }
480
481     ogg_restore (s, 0);
482
483     ogg_save (s);
484     avio_seek (s->pb, 0, SEEK_SET);
485     while (!ogg_read_page (s, &i)){
486         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
487             ogg->streams[i].codec) {
488             s->streams[i]->duration -=
489                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
490             break;
491         }
492     }
493     ogg_restore (s, 0);
494
495     return 0;
496 }
497
498 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
499 {
500     struct ogg *ogg = s->priv_data;
501     int ret, i;
502     ogg->curidx = -1;
503     //linear headers seek from start
504     ret = ogg_get_headers(s);
505     if (ret < 0)
506         return ret;
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, ret;
554     int pstart, psize;
555     int64_t fpos, pts, dts;
556
557     //Get an ogg packet
558 retry:
559     do{
560         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
561         if (ret < 0)
562             return ret;
563     }while (idx < 0 || !s->streams[idx]);
564
565     ogg = s->priv_data;
566     os = ogg->streams + idx;
567
568     // pflags might not be set until after this
569     pts = ogg_calc_pts(s, idx, &dts);
570
571     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
572         goto retry;
573     os->keyframe_seek = 0;
574
575     //Alloc a pkt
576     ret = av_new_packet(pkt, psize);
577     if (ret < 0)
578         return ret;
579     pkt->stream_index = idx;
580     memcpy (pkt->data, os->buf + pstart, psize);
581
582     pkt->pts = pts;
583     pkt->dts = dts;
584     pkt->flags = os->pflags;
585     pkt->duration = os->pduration;
586     pkt->pos = fpos;
587
588     return psize;
589 }
590
591 static int ogg_read_close(AVFormatContext *s)
592 {
593     struct ogg *ogg = s->priv_data;
594     int i;
595
596     for (i = 0; i < ogg->nstreams; i++){
597         av_free (ogg->streams[i].buf);
598         av_free (ogg->streams[i].private);
599     }
600     av_free (ogg->streams);
601     return 0;
602 }
603
604 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
605                                   int64_t *pos_arg, int64_t pos_limit)
606 {
607     struct ogg *ogg = s->priv_data;
608     AVIOContext *bc = s->pb;
609     int64_t pts = AV_NOPTS_VALUE;
610     int i = -1;
611     avio_seek(bc, *pos_arg, SEEK_SET);
612     ogg_reset(ogg);
613
614     while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
615         if (i == stream_index) {
616             struct ogg_stream *os = ogg->streams + stream_index;
617             pts = ogg_calc_pts(s, i, NULL);
618             if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
619                 pts = AV_NOPTS_VALUE;
620         }
621         if (pts != AV_NOPTS_VALUE)
622             break;
623     }
624     ogg_reset(ogg);
625     return pts;
626 }
627
628 static int ogg_read_seek(AVFormatContext *s, int stream_index,
629                          int64_t timestamp, int flags)
630 {
631     struct ogg *ogg = s->priv_data;
632     struct ogg_stream *os = ogg->streams + stream_index;
633     int ret;
634
635     // Try seeking to a keyframe first. If this fails (very possible),
636     // av_seek_frame will fall back to ignoring keyframes
637     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
638         && !(flags & AVSEEK_FLAG_ANY))
639         os->keyframe_seek = 1;
640
641     ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
642     os = ogg->streams + stream_index;
643     if (ret < 0)
644         os->keyframe_seek = 0;
645     return ret;
646 }
647
648 static int ogg_probe(AVProbeData *p)
649 {
650     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
651         return AVPROBE_SCORE_MAX;
652     return 0;
653 }
654
655 AVInputFormat ff_ogg_demuxer = {
656     .name           = "ogg",
657     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
658     .priv_data_size = sizeof(struct ogg),
659     .read_probe     = ogg_probe,
660     .read_header    = ogg_read_header,
661     .read_packet    = ogg_read_packet,
662     .read_close     = ogg_read_close,
663     .read_seek      = ogg_read_seek,
664     .read_timestamp = ogg_read_timestamp,
665     .extensions     = "ogg",
666     .flags          = AVFMT_GENERIC_INDEX,
667 };