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