]> 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     uint32_t seq;
201     uint32_t crc;
202     int size, idx;
203     uint8_t sync[4];
204     int sp = 0;
205
206     ret = avio_read (bc, sync, 4);
207     if (ret < 4)
208         return ret < 0 ? ret : AVERROR_EOF;
209
210     do{
211         int c;
212
213         if (sync[sp & 3] == 'O' &&
214             sync[(sp + 1) & 3] == 'g' &&
215             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
216             break;
217
218         c = avio_r8(bc);
219         if (url_feof(bc))
220             return AVERROR_EOF;
221         sync[sp++ & 3] = c;
222     }while (i++ < MAX_PAGE_SIZE);
223
224     if (i >= MAX_PAGE_SIZE){
225         av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
226         return AVERROR_INVALIDDATA;
227     }
228
229     if (avio_r8(bc) != 0)      /* version */
230         return AVERROR_INVALIDDATA;
231
232     flags = avio_r8(bc);
233     gp = avio_rl64 (bc);
234     serial = avio_rl32 (bc);
235     seq = avio_rl32 (bc);
236     crc = avio_rl32 (bc);
237     nsegs = avio_r8(bc);
238
239     idx = ogg_find_stream (ogg, serial);
240     if (idx < 0){
241         if (ogg->headers) {
242             int n;
243
244             for (n = 0; n < ogg->nstreams; n++) {
245                 av_freep(&ogg->streams[n].buf);
246                 av_freep(&ogg->streams[n].private);
247             }
248             ogg->curidx   = -1;
249             ogg->nstreams = 0;
250             idx = ogg_new_stream(s, serial, 0);
251         } else {
252             idx = ogg_new_stream(s, serial, 1);
253         }
254         if (idx < 0)
255             return idx;
256     }
257
258     os = ogg->streams + idx;
259     os->page_pos = avio_tell(bc) - 27;
260
261     if(os->psize > 0)
262         ogg_new_buf(ogg, idx);
263
264     ret = avio_read (bc, os->segments, nsegs);
265     if (ret < nsegs)
266         return ret < 0 ? ret : AVERROR_EOF;
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     ret = avio_read (bc, os->buf + os->bufpos, size);
298     if (ret < size)
299         return ret < 0 ? ret : AVERROR_EOF;
300
301     os->bufpos += size;
302     os->granule = gp;
303     os->flags = flags;
304
305     if (str)
306         *str = idx;
307
308     return 0;
309 }
310
311 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
312                       int64_t *fpos)
313 {
314     struct ogg *ogg = s->priv_data;
315     int idx, i, ret;
316     struct ogg_stream *os;
317     int complete = 0;
318     int segp = 0, psize = 0;
319
320     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
321
322     do{
323         idx = ogg->curidx;
324
325         while (idx < 0){
326             ret = ogg_read_page (s, &idx);
327             if (ret < 0)
328                 return ret;
329         }
330
331         os = ogg->streams + idx;
332
333         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
334                 idx, os->pstart, os->psize, os->segp, os->nsegs);
335
336         if (!os->codec){
337             if (os->header < 0){
338                 os->codec = ogg_find_codec (os->buf, os->bufpos);
339                 if (!os->codec){
340                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
341                     os->header = 0;
342                     return 0;
343                 }
344             }else{
345                 return 0;
346             }
347         }
348
349         segp = os->segp;
350         psize = os->psize;
351
352         while (os->segp < os->nsegs){
353             int ss = os->segments[os->segp++];
354             os->psize += ss;
355             if (ss < 255){
356                 complete = 1;
357                 break;
358             }
359         }
360
361         if (!complete && os->segp == os->nsegs){
362             ogg->curidx = -1;
363             os->incomplete = 1;
364         }
365     }while (!complete);
366
367     av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
368            idx, os->psize, os->pstart);
369
370     if (os->granule == -1)
371         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
372
373     ogg->curidx = idx;
374     os->incomplete = 0;
375
376     if (os->header) {
377         os->header = os->codec->header (s, idx);
378         if (!os->header){
379             os->segp = segp;
380             os->psize = psize;
381
382             // We have reached the first non-header packet in this stream.
383             // Unfortunately more header packets may still follow for others,
384             // but if we continue with header parsing we may lose data packets.
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
394                 // if we have a partial non-header packet, its start is
395                 // obviously at or after the data start
396                 if (cur_os->incomplete)
397                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
398             }
399         }else{
400             os->pstart += os->psize;
401             os->psize = 0;
402         }
403     } else {
404         os->pflags = 0;
405         os->pduration = 0;
406         if (os->codec && os->codec->packet)
407             os->codec->packet (s, idx);
408         if (str)
409             *str = idx;
410         if (dstart)
411             *dstart = os->pstart;
412         if (dsize)
413             *dsize = os->psize;
414         if (fpos)
415             *fpos = os->sync_pos;
416         os->pstart += os->psize;
417         os->psize = 0;
418         os->sync_pos = os->page_pos;
419     }
420
421     // determine whether there are more complete packets in this page
422     // if not, the page's granule will apply to this packet
423     os->page_end = 1;
424     for (i = os->segp; i < os->nsegs; i++)
425         if (os->segments[i] < 255) {
426             os->page_end = 0;
427             break;
428         }
429
430     if (os->segp == os->nsegs)
431         ogg->curidx = -1;
432
433     return 0;
434 }
435
436 static int ogg_get_headers(AVFormatContext *s)
437 {
438     struct ogg *ogg = s->priv_data;
439     int ret;
440
441     do{
442         ret = ogg_packet (s, NULL, NULL, NULL, NULL);
443         if (ret < 0)
444             return ret;
445     }while (!ogg->headers);
446
447     av_dlog(s, "found headers\n");
448
449     return 0;
450 }
451
452 static int ogg_get_length(AVFormatContext *s)
453 {
454     struct ogg *ogg = s->priv_data;
455     int i;
456     int64_t size, end;
457
458     if(!s->pb->seekable)
459         return 0;
460
461 // already set
462     if (s->duration != AV_NOPTS_VALUE)
463         return 0;
464
465     size = avio_size(s->pb);
466     if(size < 0)
467         return 0;
468     end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
469
470     ogg_save (s);
471     avio_seek (s->pb, end, SEEK_SET);
472
473     while (!ogg_read_page (s, &i)){
474         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
475             ogg->streams[i].codec) {
476             s->streams[i]->duration =
477                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
478             if (s->streams[i]->start_time != AV_NOPTS_VALUE)
479                 s->streams[i]->duration -= s->streams[i]->start_time;
480         }
481     }
482
483     ogg_restore (s, 0);
484
485     ogg_save (s);
486     avio_seek (s->pb, 0, SEEK_SET);
487     while (!ogg_read_page (s, &i)){
488         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
489             ogg->streams[i].codec) {
490             s->streams[i]->duration -=
491                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
492             break;
493         }
494     }
495     ogg_restore (s, 0);
496
497     return 0;
498 }
499
500 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
501 {
502     struct ogg *ogg = s->priv_data;
503     int ret, i;
504     ogg->curidx = -1;
505     //linear headers seek from start
506     ret = ogg_get_headers (s);
507     if (ret < 0){
508         return ret;
509     }
510
511     for (i = 0; i < ogg->nstreams; i++)
512         if (ogg->streams[i].header < 0)
513             ogg->streams[i].codec = NULL;
514
515     //linear granulepos seek from end
516     ogg_get_length (s);
517
518     //fill the extradata in the per codec callbacks
519     return 0;
520 }
521
522 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
523 {
524     struct ogg *ogg = s->priv_data;
525     struct ogg_stream *os = ogg->streams + idx;
526     int64_t pts = AV_NOPTS_VALUE;
527
528     if (dts)
529         *dts = AV_NOPTS_VALUE;
530
531     if (os->lastpts != AV_NOPTS_VALUE) {
532         pts = os->lastpts;
533         os->lastpts = AV_NOPTS_VALUE;
534     }
535     if (os->lastdts != AV_NOPTS_VALUE) {
536         if (dts)
537             *dts = os->lastdts;
538         os->lastdts = AV_NOPTS_VALUE;
539     }
540     if (os->page_end) {
541         if (os->granule != -1LL) {
542             if (os->codec && os->codec->granule_is_start)
543                 pts = ogg_gptopts(s, idx, os->granule, dts);
544             else
545                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
546             os->granule = -1LL;
547         }
548     }
549     return pts;
550 }
551
552 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
553 {
554     struct ogg *ogg;
555     struct ogg_stream *os;
556     int idx = -1;
557     int pstart, psize;
558     int64_t fpos, pts, dts;
559
560     //Get an ogg packet
561 retry:
562     do{
563         if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
564             return AVERROR(EIO);
565     }while (idx < 0 || !s->streams[idx]);
566
567     ogg = s->priv_data;
568     os = ogg->streams + idx;
569
570     // pflags might not be set until after this
571     pts = ogg_calc_pts(s, idx, &dts);
572
573     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
574         goto retry;
575     os->keyframe_seek = 0;
576
577     //Alloc a pkt
578     if (av_new_packet (pkt, psize) < 0)
579         return AVERROR(EIO);
580     pkt->stream_index = idx;
581     memcpy (pkt->data, os->buf + pstart, psize);
582
583     pkt->pts = pts;
584     pkt->dts = dts;
585     pkt->flags = os->pflags;
586     pkt->duration = os->pduration;
587     pkt->pos = fpos;
588
589     return psize;
590 }
591
592 static int ogg_read_close(AVFormatContext *s)
593 {
594     struct ogg *ogg = s->priv_data;
595     int i;
596
597     for (i = 0; i < ogg->nstreams; i++){
598         av_free (ogg->streams[i].buf);
599         av_free (ogg->streams[i].private);
600     }
601     av_free (ogg->streams);
602     return 0;
603 }
604
605 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
606                                   int64_t *pos_arg, int64_t pos_limit)
607 {
608     struct ogg *ogg = s->priv_data;
609     struct ogg_stream *os = ogg->streams + stream_index;
610     AVIOContext *bc = s->pb;
611     int64_t pts = AV_NOPTS_VALUE;
612     int i;
613     avio_seek(bc, *pos_arg, SEEK_SET);
614     ogg_reset(ogg);
615
616     while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
617         if (i == stream_index) {
618             pts = ogg_calc_pts(s, i, NULL);
619             if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
620                 pts = AV_NOPTS_VALUE;
621         }
622         if (pts != AV_NOPTS_VALUE)
623             break;
624     }
625     ogg_reset(ogg);
626     return pts;
627 }
628
629 static int ogg_read_seek(AVFormatContext *s, int stream_index,
630                          int64_t timestamp, int flags)
631 {
632     struct ogg *ogg = s->priv_data;
633     struct ogg_stream *os = ogg->streams + stream_index;
634     int ret;
635
636     // Try seeking to a keyframe first. If this fails (very possible),
637     // av_seek_frame will fall back to ignoring keyframes
638     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
639         && !(flags & AVSEEK_FLAG_ANY))
640         os->keyframe_seek = 1;
641
642     ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
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 };