avformat: Use av_reallocp_array() where suitable
[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     Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
9
10     Permission is hereby granted, free of charge, to any person
11     obtaining a copy of this software and associated documentation
12     files (the "Software"), to deal in the Software without
13     restriction, including without limitation the rights to use, copy,
14     modify, merge, publish, distribute, sublicense, and/or sell copies
15     of the Software, and to permit persons to whom the Software is
16     furnished to do so, subject to the following conditions:
17
18     The above copyright notice and this permission notice shall be
19     included in all copies or substantial portions of the Software.
20
21     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28     DEALINGS IN THE SOFTWARE.
29  */
30
31
32 #include <stdio.h>
33 #include "oggdec.h"
34 #include "avformat.h"
35 #include "internal.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_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
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, err;
88
89     if (!ost)
90         return 0;
91
92     ogg->state = ost->next;
93
94     if (!discard) {
95
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         if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
103                                      sizeof(*ogg->streams))) < 0) {
104             ogg->nstreams = 0;
105             return err;
106         } else
107             memcpy(ogg->streams, ost->streams,
108                    ost->nstreams * sizeof(*ogg->streams));
109     }
110
111     av_free(ost);
112
113     return 0;
114 }
115
116 static int ogg_reset(struct ogg *ogg)
117 {
118     int i;
119
120     for (i = 0; i < ogg->nstreams; i++) {
121         struct ogg_stream *os = ogg->streams + i;
122         os->bufpos     = 0;
123         os->pstart     = 0;
124         os->psize      = 0;
125         os->granule    = -1;
126         os->lastpts    = AV_NOPTS_VALUE;
127         os->lastdts    = AV_NOPTS_VALUE;
128         os->sync_pos   = -1;
129         os->page_pos   = 0;
130         os->nsegs      = 0;
131         os->segp       = 0;
132         os->incomplete = 0;
133     }
134
135     ogg->curidx = -1;
136
137     return 0;
138 }
139
140 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
141 {
142     int i;
143
144     for (i = 0; ogg_codecs[i]; i++)
145         if (size >= ogg_codecs[i]->magicsize &&
146             !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
147             return ogg_codecs[i];
148
149     return NULL;
150 }
151
152 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
153 {
154     struct ogg *ogg = s->priv_data;
155     int idx         = ogg->nstreams++;
156     AVStream *st;
157     struct ogg_stream *os;
158
159     os = av_realloc(ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
160
161     if (!os)
162         return AVERROR(ENOMEM);
163
164     ogg->streams = os;
165
166     memset(ogg->streams + idx, 0, sizeof(*ogg->streams));
167
168     os                = ogg->streams + idx;
169     os->serial        = serial;
170     os->bufsize       = DECODER_BUFFER_SIZE;
171     os->buf           = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
172     os->header        = -1;
173     os->start_granule = OGG_NOGRANULE_VALUE;
174
175     if (new_avstream) {
176         st = avformat_new_stream(s, NULL);
177         if (!st)
178             return AVERROR(ENOMEM);
179
180         st->id = idx;
181         avpriv_set_pts_info(st, 64, 1, 1000000);
182     }
183
184     return idx;
185 }
186
187 static int ogg_new_buf(struct ogg *ogg, int idx)
188 {
189     struct ogg_stream *os = ogg->streams + idx;
190     uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
191     int size = os->bufpos - os->pstart;
192
193     if (os->buf) {
194         memcpy(nb, os->buf + os->pstart, size);
195         av_free(os->buf);
196     }
197
198     os->buf    = nb;
199     os->bufpos = size;
200     os->pstart = 0;
201
202     return 0;
203 }
204
205 static int ogg_read_page(AVFormatContext *s, int *str)
206 {
207     AVIOContext *bc = s->pb;
208     struct ogg *ogg = s->priv_data;
209     struct ogg_stream *os;
210     int ret, i = 0;
211     int flags, nsegs;
212     uint64_t gp;
213     uint32_t serial;
214     int size, idx;
215     uint8_t sync[4];
216     int sp = 0;
217
218     ret = avio_read(bc, sync, 4);
219     if (ret < 4)
220         return ret < 0 ? ret : AVERROR_EOF;
221
222     do {
223         int c;
224
225         if (sync[sp & 3] == 'O' &&
226             sync[(sp + 1) & 3] == 'g' &&
227             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
228             break;
229
230         c = avio_r8(bc);
231
232         if (bc->eof_reached)
233             return AVERROR_EOF;
234
235         sync[sp++ & 3] = c;
236     } while (i++ < MAX_PAGE_SIZE);
237
238     if (i >= MAX_PAGE_SIZE) {
239         av_log(s, AV_LOG_INFO, "cannot find sync word\n");
240         return AVERROR_INVALIDDATA;
241     }
242
243     if (avio_r8(bc) != 0)      /* version */
244         return AVERROR_INVALIDDATA;
245
246     flags  = avio_r8(bc);
247     gp     = avio_rl64(bc);
248     serial = avio_rl32(bc);
249     avio_skip(bc, 8); /* seq, crc */
250     nsegs  = avio_r8(bc);
251
252     idx = ogg_find_stream(ogg, serial);
253     if (idx < 0) {
254         if (ogg->headers) {
255             int n;
256
257             for (n = 0; n < ogg->nstreams; n++) {
258                 av_freep(&ogg->streams[n].buf);
259                 if (!ogg->state ||
260                     ogg->state->streams[n].private != ogg->streams[n].private)
261                     av_freep(&ogg->streams[n].private);
262             }
263
264             ogg->curidx   = -1;
265             ogg->nstreams = 0;
266
267             idx = ogg_new_stream(s, serial, 0);
268         } else {
269             idx = ogg_new_stream(s, serial, 1);
270         }
271         if (idx < 0)
272             return idx;
273     }
274
275     os = ogg->streams + idx;
276     os->page_pos = avio_tell(bc) - 27;
277
278     if (os->psize > 0)
279         ogg_new_buf(ogg, idx);
280
281     ret = avio_read(bc, os->segments, nsegs);
282     if (ret < nsegs)
283         return ret < 0 ? ret : AVERROR_EOF;
284
285     os->nsegs = nsegs;
286     os->segp  = 0;
287
288     size = 0;
289     for (i = 0; i < nsegs; i++)
290         size += os->segments[i];
291
292     if (flags & OGG_FLAG_CONT || os->incomplete) {
293         if (!os->psize) {
294             while (os->segp < os->nsegs) {
295                 int seg = os->segments[os->segp++];
296                 os->pstart += seg;
297                 if (seg < 255)
298                     break;
299             }
300             os->sync_pos = os->page_pos;
301         }
302     } else {
303         os->psize    = 0;
304         os->sync_pos = os->page_pos;
305     }
306
307     if (os->bufsize - os->bufpos < size) {
308         uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
309         if (!nb)
310             return AVERROR(ENOMEM);
311         memcpy(nb, os->buf, os->bufpos);
312         av_free(os->buf);
313         os->buf = nb;
314     }
315
316     ret = avio_read(bc, os->buf + os->bufpos, size);
317     if (ret < size)
318         return ret < 0 ? ret : AVERROR_EOF;
319
320     os->bufpos += size;
321     os->granule = gp;
322     os->flags   = flags;
323
324     memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
325     if (str)
326         *str = idx;
327
328     return 0;
329 }
330
331 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
332                       int64_t *fpos)
333 {
334     struct ogg *ogg = s->priv_data;
335     int idx, i, ret;
336     struct ogg_stream *os;
337     int complete = 0;
338     int segp     = 0, psize = 0;
339
340     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
341
342     do {
343         idx = ogg->curidx;
344
345         while (idx < 0) {
346             ret = ogg_read_page(s, &idx);
347             if (ret < 0)
348                 return ret;
349         }
350
351         os = ogg->streams + idx;
352
353         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
354                 idx, os->pstart, os->psize, os->segp, os->nsegs);
355
356         if (!os->codec) {
357             if (os->header < 0) {
358                 os->codec = ogg_find_codec(os->buf, os->bufpos);
359                 if (!os->codec) {
360                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
361                     os->header = 0;
362                     return 0;
363                 }
364             } else {
365                 return 0;
366             }
367         }
368
369         segp  = os->segp;
370         psize = os->psize;
371
372         while (os->segp < os->nsegs) {
373             int ss = os->segments[os->segp++];
374             os->psize += ss;
375             if (ss < 255) {
376                 complete = 1;
377                 break;
378             }
379         }
380
381         if (!complete && os->segp == os->nsegs) {
382             ogg->curidx    = -1;
383             // Do not set incomplete for empty packets.
384             // Together with the code in ogg_read_page
385             // that discards all continuation of empty packets
386             // we would get an infinite loop.
387             os->incomplete = !!os->psize;
388         }
389     } while (!complete);
390
391     av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
392             idx, os->psize, os->pstart);
393
394     if (os->granule == -1)
395         av_log(s, AV_LOG_WARNING,
396                "Page at %"PRId64" is missing granule\n",
397                os->page_pos);
398
399     ogg->curidx    = idx;
400     os->incomplete = 0;
401
402     if (os->header) {
403         os->header = os->codec->header(s, idx);
404         if (!os->header) {
405             os->segp  = segp;
406             os->psize = psize;
407
408             // We have reached the first non-header packet in this stream.
409             // Unfortunately more header packets may still follow for others,
410             // but if we continue with header parsing we may lose data packets.
411             ogg->headers = 1;
412
413             // Update the header state for all streams and
414             // compute the data_offset.
415             if (!s->data_offset)
416                 s->data_offset = os->sync_pos;
417
418             for (i = 0; i < ogg->nstreams; i++) {
419                 struct ogg_stream *cur_os = ogg->streams + i;
420
421                 // if we have a partial non-header packet, its start is
422                 // obviously at or after the data start
423                 if (cur_os->incomplete)
424                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
425             }
426         } else {
427             os->nb_header++;
428             os->pstart += os->psize;
429             os->psize   = 0;
430         }
431     } else {
432         os->pflags    = 0;
433         os->pduration = 0;
434         if (os->codec && os->codec->packet)
435             os->codec->packet(s, idx);
436         if (str)
437             *str = idx;
438         if (dstart)
439             *dstart = os->pstart;
440         if (dsize)
441             *dsize = os->psize;
442         if (fpos)
443             *fpos = os->sync_pos;
444         os->pstart  += os->psize;
445         os->psize    = 0;
446         os->sync_pos = os->page_pos;
447     }
448
449     // determine whether there are more complete packets in this page
450     // if not, the page's granule will apply to this packet
451     os->page_end = 1;
452     for (i = os->segp; i < os->nsegs; i++)
453         if (os->segments[i] < 255) {
454             os->page_end = 0;
455             break;
456         }
457
458     if (os->segp == os->nsegs)
459         ogg->curidx = -1;
460
461     return 0;
462 }
463
464 static int ogg_get_headers(AVFormatContext *s)
465 {
466     struct ogg *ogg = s->priv_data;
467     int ret, i;
468
469     do {
470         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
471         if (ret < 0)
472             return ret;
473     } while (!ogg->headers);
474
475     for (i = 0; i < ogg->nstreams; i++) {
476         struct ogg_stream *os = ogg->streams + i;
477
478         if (os->codec && os->codec->nb_header &&
479             os->nb_header < os->codec->nb_header) {
480             av_log(s, AV_LOG_ERROR,
481                    "Headers mismatch for stream %d: "
482                    "expected %d received %d.\n",
483                    i, os->codec->nb_header, os->nb_header);
484             if (s->error_recognition & AV_EF_EXPLODE)
485                 return AVERROR_INVALIDDATA;
486         }
487         if (os->start_granule != OGG_NOGRANULE_VALUE)
488             os->lastpts = s->streams[i]->start_time =
489                 ogg_gptopts(s, i, os->start_granule, NULL);
490     }
491     av_dlog(s, "found headers\n");
492
493     return 0;
494 }
495
496 static int ogg_get_length(AVFormatContext *s)
497 {
498     struct ogg *ogg = s->priv_data;
499     int i;
500     int64_t size, end;
501
502     if (!s->pb->seekable)
503         return 0;
504
505 // already set
506     if (s->duration != AV_NOPTS_VALUE)
507         return 0;
508
509     size = avio_size(s->pb);
510     if (size < 0)
511         return 0;
512     end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
513
514     ogg_save(s);
515     avio_seek(s->pb, end, SEEK_SET);
516
517     while (!ogg_read_page(s, &i)) {
518         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
519             ogg->streams[i].codec) {
520             s->streams[i]->duration =
521                 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
522             if (s->streams[i]->start_time != AV_NOPTS_VALUE)
523                 s->streams[i]->duration -= s->streams[i]->start_time;
524         }
525     }
526
527     ogg_restore(s, 0);
528
529     return 0;
530 }
531
532 static int ogg_read_close(AVFormatContext *s)
533 {
534     struct ogg *ogg = s->priv_data;
535     int i;
536
537     for (i = 0; i < ogg->nstreams; i++) {
538         av_free(ogg->streams[i].buf);
539         if (ogg->streams[i].codec &&
540             ogg->streams[i].codec->cleanup) {
541             ogg->streams[i].codec->cleanup(s, i);
542         }
543         av_free(ogg->streams[i].private);
544     }
545     av_free(ogg->streams);
546     return 0;
547 }
548
549 static int ogg_read_header(AVFormatContext *s)
550 {
551     struct ogg *ogg = s->priv_data;
552     int ret, i;
553     ogg->curidx = -1;
554     //linear headers seek from start
555     ret = ogg_get_headers(s);
556     if (ret < 0) {
557         ogg_read_close(s);
558         return ret;
559     }
560
561     for (i = 0; i < ogg->nstreams; i++)
562         if (ogg->streams[i].header < 0)
563             ogg->streams[i].codec = NULL;
564
565     //linear granulepos seek from end
566     ogg_get_length(s);
567
568     //fill the extradata in the per codec callbacks
569     return 0;
570 }
571
572 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
573 {
574     struct ogg *ogg       = s->priv_data;
575     struct ogg_stream *os = ogg->streams + idx;
576     int64_t pts           = AV_NOPTS_VALUE;
577
578     if (dts)
579         *dts = AV_NOPTS_VALUE;
580
581     if (os->lastpts != AV_NOPTS_VALUE) {
582         pts         = os->lastpts;
583         os->lastpts = AV_NOPTS_VALUE;
584     }
585     if (os->lastdts != AV_NOPTS_VALUE) {
586         if (dts)
587             *dts = os->lastdts;
588         os->lastdts = AV_NOPTS_VALUE;
589     }
590     if (os->page_end) {
591         if (os->granule != -1LL) {
592             if (os->codec && os->codec->granule_is_start)
593                 pts = ogg_gptopts(s, idx, os->granule, dts);
594             else
595                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
596             os->granule = -1LL;
597         }
598     }
599     return pts;
600 }
601
602 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
603 {
604     struct ogg *ogg;
605     struct ogg_stream *os;
606     int idx = -1, ret;
607     int pstart, psize;
608     int64_t fpos, pts, dts;
609
610     //Get an ogg packet
611 retry:
612     do {
613         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
614         if (ret < 0)
615             return ret;
616     } while (idx < 0 || !s->streams[idx]);
617
618     ogg = s->priv_data;
619     os  = ogg->streams + idx;
620
621     // pflags might not be set until after this
622     pts = ogg_calc_pts(s, idx, &dts);
623
624     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
625         goto retry;
626     os->keyframe_seek = 0;
627
628     //Alloc a pkt
629     ret = av_new_packet(pkt, psize);
630     if (ret < 0)
631         return ret;
632     pkt->stream_index = idx;
633     memcpy(pkt->data, os->buf + pstart, psize);
634
635     pkt->pts      = pts;
636     pkt->dts      = dts;
637     pkt->flags    = os->pflags;
638     pkt->duration = os->pduration;
639     pkt->pos      = fpos;
640
641     return psize;
642 }
643
644 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
645                                   int64_t *pos_arg, int64_t pos_limit)
646 {
647     struct ogg *ogg = s->priv_data;
648     AVIOContext *bc = s->pb;
649     int64_t pts     = AV_NOPTS_VALUE;
650     int i           = -1;
651     avio_seek(bc, *pos_arg, SEEK_SET);
652     ogg_reset(ogg);
653
654     while (avio_tell(bc) < pos_limit &&
655            !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
656         if (i == stream_index) {
657             struct ogg_stream *os = ogg->streams + stream_index;
658             pts = ogg_calc_pts(s, i, NULL);
659             if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
660                 pts = AV_NOPTS_VALUE;
661         }
662         if (pts != AV_NOPTS_VALUE)
663             break;
664     }
665     ogg_reset(ogg);
666     return pts;
667 }
668
669 static int ogg_read_seek(AVFormatContext *s, int stream_index,
670                          int64_t timestamp, int flags)
671 {
672     struct ogg *ogg       = s->priv_data;
673     struct ogg_stream *os = ogg->streams + stream_index;
674     int ret;
675
676     // Try seeking to a keyframe first. If this fails (very possible),
677     // av_seek_frame will fall back to ignoring keyframes
678     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
679         && !(flags & AVSEEK_FLAG_ANY))
680         os->keyframe_seek = 1;
681
682     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
683     os  = ogg->streams + stream_index;
684     if (ret < 0)
685         os->keyframe_seek = 0;
686     return ret;
687 }
688
689 static int ogg_probe(AVProbeData *p)
690 {
691     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
692         return AVPROBE_SCORE_MAX;
693     return 0;
694 }
695
696 AVInputFormat ff_ogg_demuxer = {
697     .name           = "ogg",
698     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
699     .priv_data_size = sizeof(struct ogg),
700     .read_probe     = ogg_probe,
701     .read_header    = ogg_read_header,
702     .read_packet    = ogg_read_packet,
703     .read_close     = ogg_read_close,
704     .read_seek      = ogg_read_seek,
705     .read_timestamp = ogg_read_timestamp,
706     .extensions     = "ogg",
707     .flags          = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,
708 };