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