ogg: propagate return values and return more meaningful error values
[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_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 ogg_save(AVFormatContext *s)
59 {
60     struct ogg *ogg = s->priv_data;
61     struct ogg_state *ost =
62         av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
63     int i;
64     ost->pos = avio_tell (s->pb);
65     ost->curidx = ogg->curidx;
66     ost->next = ogg->state;
67     ost->nstreams = ogg->nstreams;
68     memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
69
70     for (i = 0; i < ogg->nstreams; i++){
71         struct ogg_stream *os = ogg->streams + i;
72         os->buf = av_malloc (os->bufsize);
73         memset (os->buf, 0, os->bufsize);
74         memcpy (os->buf, ost->streams[i].buf, os->bufpos);
75     }
76
77     ogg->state = ost;
78
79     return 0;
80 }
81
82 static int ogg_restore(AVFormatContext *s, int discard)
83 {
84     struct ogg *ogg = s->priv_data;
85     AVIOContext *bc = s->pb;
86     struct ogg_state *ost = ogg->state;
87     int i;
88
89     if (!ost)
90         return 0;
91
92     ogg->state = ost->next;
93
94     if (!discard){
95         for (i = 0; i < ogg->nstreams; i++)
96             av_free (ogg->streams[i].buf);
97
98         avio_seek (bc, ost->pos, SEEK_SET);
99         ogg->curidx = ost->curidx;
100         ogg->nstreams = ost->nstreams;
101         memcpy(ogg->streams, ost->streams,
102                ost->nstreams * sizeof(*ogg->streams));
103     }
104
105     av_free (ost);
106
107     return 0;
108 }
109
110 static int ogg_reset(struct ogg *ogg)
111 {
112     int i;
113
114     for (i = 0; i < ogg->nstreams; i++){
115         struct ogg_stream *os = ogg->streams + i;
116         os->bufpos = 0;
117         os->pstart = 0;
118         os->psize = 0;
119         os->granule = -1;
120         os->lastpts = AV_NOPTS_VALUE;
121         os->lastdts = AV_NOPTS_VALUE;
122         os->sync_pos = -1;
123         os->page_pos = 0;
124         os->nsegs = 0;
125         os->segp = 0;
126         os->incomplete = 0;
127     }
128
129     ogg->curidx = -1;
130
131     return 0;
132 }
133
134 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
135 {
136     int i;
137
138     for (i = 0; ogg_codecs[i]; i++)
139         if (size >= ogg_codecs[i]->magicsize &&
140             !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
141             return ogg_codecs[i];
142
143     return NULL;
144 }
145
146 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
147 {
148
149     struct ogg *ogg = s->priv_data;
150     int idx = ogg->nstreams++;
151     AVStream *st;
152     struct ogg_stream *os;
153
154     ogg->streams = av_realloc (ogg->streams,
155                                ogg->nstreams * sizeof (*ogg->streams));
156     memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
157     os = ogg->streams + idx;
158     os->serial = serial;
159     os->bufsize = DECODER_BUFFER_SIZE;
160     os->buf = av_malloc(os->bufsize);
161     os->header = -1;
162
163     if (new_avstream) {
164         st = av_new_stream(s, idx);
165         if (!st)
166             return AVERROR(ENOMEM);
167
168         av_set_pts_info(st, 64, 1, 1000000);
169     }
170
171     return idx;
172 }
173
174 static int ogg_new_buf(struct ogg *ogg, int idx)
175 {
176     struct ogg_stream *os = ogg->streams + idx;
177     uint8_t *nb = av_malloc(os->bufsize);
178     int size = os->bufpos - os->pstart;
179     if(os->buf){
180         memcpy(nb, os->buf + os->pstart, size);
181         av_free(os->buf);
182     }
183     os->buf = nb;
184     os->bufpos = size;
185     os->pstart = 0;
186
187     return 0;
188 }
189
190 static int ogg_read_page(AVFormatContext *s, int *str)
191 {
192     AVIOContext *bc = s->pb;
193     struct ogg *ogg = s->priv_data;
194     struct ogg_stream *os;
195     int ret, i = 0;
196     int flags, nsegs;
197     uint64_t gp;
198     uint32_t serial;
199     int size, idx;
200     uint8_t sync[4];
201     int sp = 0;
202
203     ret = avio_read(bc, sync, 4);
204     if (ret < 4)
205         return ret < 0 ? ret : AVERROR_EOF;
206
207     do{
208         int c;
209
210         if (sync[sp & 3] == 'O' &&
211             sync[(sp + 1) & 3] == 'g' &&
212             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
213             break;
214
215         c = avio_r8(bc);
216         if (bc->eof_reached)
217             return AVERROR_EOF;
218         sync[sp++ & 3] = c;
219     }while (i++ < MAX_PAGE_SIZE);
220
221     if (i >= MAX_PAGE_SIZE){
222         av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
223         return AVERROR_INVALIDDATA;
224     }
225
226     if (avio_r8(bc) != 0)      /* version */
227         return AVERROR_INVALIDDATA;
228
229     flags = avio_r8(bc);
230     gp = avio_rl64 (bc);
231     serial = avio_rl32 (bc);
232     avio_skip(bc, 8); /* seq, crc */
233     nsegs = avio_r8(bc);
234
235     idx = ogg_find_stream (ogg, serial);
236     if (idx < 0){
237         if (ogg->headers) {
238             int n;
239
240             for (n = 0; n < ogg->nstreams; n++) {
241                 av_freep(&ogg->streams[n].buf);
242                 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
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     av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
365             idx, os->psize, os->pstart);
366
367     if (os->granule == -1)
368         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
369
370     ogg->curidx = idx;
371     os->incomplete = 0;
372
373     if (os->header) {
374         os->header = os->codec->header (s, idx);
375         if (!os->header){
376             os->segp = segp;
377             os->psize = psize;
378
379             // We have reached the first non-header packet in this stream.
380             // Unfortunately more header packets may still follow for others,
381             // but if we continue with header parsing we may lose data packets.
382             ogg->headers = 1;
383
384             // Update the header state for all streams and
385             // compute the data_offset.
386             if (!s->data_offset)
387                 s->data_offset = os->sync_pos;
388             for (i = 0; i < ogg->nstreams; i++) {
389                 struct ogg_stream *cur_os = ogg->streams + i;
390
391                 // if we have a partial non-header packet, its start is
392                 // obviously at or after the data start
393                 if (cur_os->incomplete)
394                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
395             }
396         }else{
397             os->pstart += os->psize;
398             os->psize = 0;
399         }
400     } else {
401         os->pflags = 0;
402         os->pduration = 0;
403         if (os->codec && os->codec->packet)
404             os->codec->packet (s, idx);
405         if (str)
406             *str = idx;
407         if (dstart)
408             *dstart = os->pstart;
409         if (dsize)
410             *dsize = os->psize;
411         if (fpos)
412             *fpos = os->sync_pos;
413         os->pstart += os->psize;
414         os->psize = 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     return 0;
483 }
484
485 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
486 {
487     struct ogg *ogg = s->priv_data;
488     int ret, i;
489     ogg->curidx = -1;
490     //linear headers seek from start
491     ret = ogg_get_headers(s);
492     if (ret < 0)
493         return ret;
494
495     for (i = 0; i < ogg->nstreams; i++)
496         if (ogg->streams[i].header < 0)
497             ogg->streams[i].codec = NULL;
498
499     //linear granulepos seek from end
500     ogg_get_length (s);
501
502     //fill the extradata in the per codec callbacks
503     return 0;
504 }
505
506 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
507 {
508     struct ogg *ogg = s->priv_data;
509     struct ogg_stream *os = ogg->streams + idx;
510     int64_t pts = AV_NOPTS_VALUE;
511
512     if (dts)
513         *dts = AV_NOPTS_VALUE;
514
515     if (os->lastpts != AV_NOPTS_VALUE) {
516         pts = os->lastpts;
517         os->lastpts = AV_NOPTS_VALUE;
518     }
519     if (os->lastdts != AV_NOPTS_VALUE) {
520         if (dts)
521             *dts = os->lastdts;
522         os->lastdts = AV_NOPTS_VALUE;
523     }
524     if (os->page_end) {
525         if (os->granule != -1LL) {
526             if (os->codec && os->codec->granule_is_start)
527                 pts = ogg_gptopts(s, idx, os->granule, dts);
528             else
529                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
530             os->granule = -1LL;
531         }
532     }
533     return pts;
534 }
535
536 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
537 {
538     struct ogg *ogg;
539     struct ogg_stream *os;
540     int idx = -1, ret;
541     int pstart, psize;
542     int64_t fpos, pts, dts;
543
544     //Get an ogg packet
545 retry:
546     do{
547         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
548         if (ret < 0)
549             return ret;
550     }while (idx < 0 || !s->streams[idx]);
551
552     ogg = s->priv_data;
553     os = ogg->streams + idx;
554
555     // pflags might not be set until after this
556     pts = ogg_calc_pts(s, idx, &dts);
557
558     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
559         goto retry;
560     os->keyframe_seek = 0;
561
562     //Alloc a pkt
563     ret = av_new_packet(pkt, psize);
564     if (ret < 0)
565         return ret;
566     pkt->stream_index = idx;
567     memcpy (pkt->data, os->buf + pstart, psize);
568
569     pkt->pts = pts;
570     pkt->dts = dts;
571     pkt->flags = os->pflags;
572     pkt->duration = os->pduration;
573     pkt->pos = fpos;
574
575     return psize;
576 }
577
578 static int ogg_read_close(AVFormatContext *s)
579 {
580     struct ogg *ogg = s->priv_data;
581     int i;
582
583     for (i = 0; i < ogg->nstreams; i++){
584         av_free (ogg->streams[i].buf);
585         av_free (ogg->streams[i].private);
586     }
587     av_free (ogg->streams);
588     return 0;
589 }
590
591 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
592                                   int64_t *pos_arg, int64_t pos_limit)
593 {
594     struct ogg *ogg = s->priv_data;
595     struct ogg_stream *os = ogg->streams + stream_index;
596     AVIOContext *bc = s->pb;
597     int64_t pts = AV_NOPTS_VALUE;
598     int i;
599     avio_seek(bc, *pos_arg, SEEK_SET);
600     ogg_reset(ogg);
601
602     while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
603         if (i == stream_index) {
604             pts = ogg_calc_pts(s, i, NULL);
605             if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
606                 pts = AV_NOPTS_VALUE;
607         }
608         if (pts != AV_NOPTS_VALUE)
609             break;
610     }
611     ogg_reset(ogg);
612     return pts;
613 }
614
615 static int ogg_read_seek(AVFormatContext *s, int stream_index,
616                          int64_t timestamp, int flags)
617 {
618     struct ogg *ogg = s->priv_data;
619     struct ogg_stream *os = ogg->streams + stream_index;
620     int ret;
621
622     // Try seeking to a keyframe first. If this fails (very possible),
623     // av_seek_frame will fall back to ignoring keyframes
624     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
625         && !(flags & AVSEEK_FLAG_ANY))
626         os->keyframe_seek = 1;
627
628     ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
629     if (ret < 0)
630         os->keyframe_seek = 0;
631     return ret;
632 }
633
634 static int ogg_probe(AVProbeData *p)
635 {
636     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
637         return AVPROBE_SCORE_MAX;
638     return 0;
639 }
640
641 AVInputFormat ff_ogg_demuxer = {
642     .name           = "ogg",
643     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
644     .priv_data_size = sizeof(struct ogg),
645     .read_probe     = ogg_probe,
646     .read_header    = ogg_read_header,
647     .read_packet    = ogg_read_packet,
648     .read_close     = ogg_read_close,
649     .read_seek      = ogg_read_seek,
650     .read_timestamp = ogg_read_timestamp,
651     .extensions     = "ogg",
652     .flags          = AVFMT_GENERIC_INDEX,
653 };