]> git.sesse.net Git - ffmpeg/blob - libavformat/oggdec.c
aac_latm: reconfigure decoder on audio specific config changes
[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 "internal.h"
37 #include "vorbiscomment.h"
38
39 #define MAX_PAGE_SIZE 65307
40 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
41
42 static const struct ogg_codec * const ogg_codecs[] = {
43     &ff_skeleton_codec,
44     &ff_dirac_codec,
45     &ff_speex_codec,
46     &ff_vorbis_codec,
47     &ff_theora_codec,
48     &ff_flac_codec,
49     &ff_celt_codec,
50     &ff_old_dirac_codec,
51     &ff_old_flac_codec,
52     &ff_ogm_video_codec,
53     &ff_ogm_audio_codec,
54     &ff_ogm_text_codec,
55     &ff_ogm_old_codec,
56     NULL
57 };
58
59 //FIXME We could avoid some structure duplication
60 static int ogg_save(AVFormatContext *s)
61 {
62     struct ogg *ogg = s->priv_data;
63     struct ogg_state *ost =
64         av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
65     int i;
66     ost->pos = avio_tell (s->pb);
67     ost->curidx = ogg->curidx;
68     ost->next = ogg->state;
69     ost->nstreams = ogg->nstreams;
70     memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
71
72     for (i = 0; i < ogg->nstreams; i++){
73         struct ogg_stream *os = ogg->streams + i;
74         os->buf = av_malloc (os->bufsize);
75         memset (os->buf, 0, os->bufsize);
76         memcpy (os->buf, ost->streams[i].buf, os->bufpos);
77     }
78
79     ogg->state = ost;
80
81     return 0;
82 }
83
84 static int 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         struct ogg_stream *old_streams = ogg->streams;
98
99         for (i = 0; i < ogg->nstreams; i++)
100             av_free (ogg->streams[i].buf);
101
102         avio_seek (bc, ost->pos, SEEK_SET);
103         ogg->curidx = ost->curidx;
104         ogg->nstreams = ost->nstreams;
105         ogg->streams = av_realloc (ogg->streams,
106                                    ogg->nstreams * sizeof (*ogg->streams));
107
108         if (ogg->streams) {
109             memcpy(ogg->streams, ost->streams,
110                    ost->nstreams * sizeof(*ogg->streams));
111         } else {
112             av_free(old_streams);
113             ogg->nstreams = 0;
114         }
115     }
116
117     av_free (ost);
118
119     return 0;
120 }
121
122 static int ogg_reset(struct ogg *ogg)
123 {
124     int i;
125
126     for (i = 0; i < ogg->nstreams; i++){
127         struct ogg_stream *os = ogg->streams + i;
128         os->bufpos = 0;
129         os->pstart = 0;
130         os->psize = 0;
131         os->granule = -1;
132         os->lastpts = AV_NOPTS_VALUE;
133         os->lastdts = AV_NOPTS_VALUE;
134         os->sync_pos = -1;
135         os->page_pos = 0;
136         os->nsegs = 0;
137         os->segp = 0;
138         os->incomplete = 0;
139     }
140
141     ogg->curidx = -1;
142
143     return 0;
144 }
145
146 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
147 {
148     int i;
149
150     for (i = 0; ogg_codecs[i]; i++)
151         if (size >= ogg_codecs[i]->magicsize &&
152             !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
153             return ogg_codecs[i];
154
155     return NULL;
156 }
157
158 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
159 {
160
161     struct ogg *ogg = s->priv_data;
162     int idx = ogg->nstreams++;
163     AVStream *st;
164     struct ogg_stream *os;
165
166     ogg->streams = av_realloc (ogg->streams,
167                                ogg->nstreams * sizeof (*ogg->streams));
168     memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
169     os = ogg->streams + idx;
170     os->serial = serial;
171     os->bufsize = DECODER_BUFFER_SIZE;
172     os->buf = av_malloc(os->bufsize);
173     os->header = -1;
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);
191     int size = os->bufpos - os->pstart;
192     if(os->buf){
193         memcpy(nb, os->buf + os->pstart, size);
194         av_free(os->buf);
195     }
196     os->buf = nb;
197     os->bufpos = size;
198     os->pstart = 0;
199
200     return 0;
201 }
202
203 static int ogg_read_page(AVFormatContext *s, int *str)
204 {
205     AVIOContext *bc = s->pb;
206     struct ogg *ogg = s->priv_data;
207     struct ogg_stream *os;
208     int ret, i = 0;
209     int flags, nsegs;
210     uint64_t gp;
211     uint32_t serial;
212     int size, idx;
213     uint8_t sync[4];
214     int sp = 0;
215
216     ret = avio_read(bc, sync, 4);
217     if (ret < 4)
218         return ret < 0 ? ret : AVERROR_EOF;
219
220     do{
221         int c;
222
223         if (sync[sp & 3] == 'O' &&
224             sync[(sp + 1) & 3] == 'g' &&
225             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
226             break;
227
228         c = avio_r8(bc);
229         if (bc->eof_reached)
230             return AVERROR_EOF;
231         sync[sp++ & 3] = c;
232     }while (i++ < MAX_PAGE_SIZE);
233
234     if (i >= MAX_PAGE_SIZE){
235         av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
236         return AVERROR_INVALIDDATA;
237     }
238
239     if (avio_r8(bc) != 0)      /* version */
240         return AVERROR_INVALIDDATA;
241
242     flags = avio_r8(bc);
243     gp = avio_rl64 (bc);
244     serial = avio_rl32 (bc);
245     avio_skip(bc, 8); /* seq, crc */
246     nsegs = avio_r8(bc);
247
248     idx = ogg_find_stream (ogg, serial);
249     if (idx < 0){
250         if (ogg->headers) {
251             int n;
252
253             for (n = 0; n < ogg->nstreams; n++) {
254                 av_freep(&ogg->streams[n].buf);
255                 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
256                     av_freep(&ogg->streams[n].private);
257             }
258             ogg->curidx   = -1;
259             ogg->nstreams = 0;
260             idx = ogg_new_stream(s, serial, 0);
261         } else {
262             idx = ogg_new_stream(s, serial, 1);
263         }
264         if (idx < 0)
265             return idx;
266     }
267
268     os = ogg->streams + idx;
269     os->page_pos = avio_tell(bc) - 27;
270
271     if(os->psize > 0)
272         ogg_new_buf(ogg, idx);
273
274     ret = avio_read(bc, os->segments, nsegs);
275     if (ret < nsegs)
276         return ret < 0 ? ret : AVERROR_EOF;
277
278     os->nsegs = nsegs;
279     os->segp = 0;
280
281     size = 0;
282     for (i = 0; i < nsegs; i++)
283         size += os->segments[i];
284
285     if (flags & OGG_FLAG_CONT || os->incomplete){
286         if (!os->psize){
287             while (os->segp < os->nsegs){
288                 int seg = os->segments[os->segp++];
289                 os->pstart += seg;
290                 if (seg < 255)
291                     break;
292             }
293             os->sync_pos = os->page_pos;
294         }
295     }else{
296         os->psize = 0;
297         os->sync_pos = os->page_pos;
298     }
299
300     if (os->bufsize - os->bufpos < size){
301         uint8_t *nb = av_malloc (os->bufsize *= 2);
302         memcpy (nb, os->buf, os->bufpos);
303         av_free (os->buf);
304         os->buf = nb;
305     }
306
307     ret = avio_read(bc, os->buf + os->bufpos, size);
308     if (ret < size)
309         return ret < 0 ? ret : AVERROR_EOF;
310
311     os->bufpos += size;
312     os->granule = gp;
313     os->flags = flags;
314
315     if (str)
316         *str = idx;
317
318     return 0;
319 }
320
321 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
322                       int64_t *fpos)
323 {
324     struct ogg *ogg = s->priv_data;
325     int idx, i, ret;
326     struct ogg_stream *os;
327     int complete = 0;
328     int segp = 0, psize = 0;
329
330     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
331
332     do{
333         idx = ogg->curidx;
334
335         while (idx < 0){
336             ret = ogg_read_page(s, &idx);
337             if (ret < 0)
338                 return ret;
339         }
340
341         os = ogg->streams + idx;
342
343         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
344                 idx, os->pstart, os->psize, os->segp, os->nsegs);
345
346         if (!os->codec){
347             if (os->header < 0){
348                 os->codec = ogg_find_codec (os->buf, os->bufpos);
349                 if (!os->codec){
350                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
351                     os->header = 0;
352                     return 0;
353                 }
354             }else{
355                 return 0;
356             }
357         }
358
359         segp = os->segp;
360         psize = os->psize;
361
362         while (os->segp < os->nsegs){
363             int ss = os->segments[os->segp++];
364             os->psize += ss;
365             if (ss < 255){
366                 complete = 1;
367                 break;
368             }
369         }
370
371         if (!complete && os->segp == os->nsegs){
372             ogg->curidx = -1;
373             os->incomplete = 1;
374         }
375     }while (!complete);
376
377     av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
378             idx, os->psize, os->pstart);
379
380     if (os->granule == -1)
381         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
382
383     ogg->curidx = idx;
384     os->incomplete = 0;
385
386     if (os->header) {
387         os->header = os->codec->header (s, idx);
388         if (!os->header){
389             os->segp = segp;
390             os->psize = psize;
391
392             // We have reached the first non-header packet in this stream.
393             // Unfortunately more header packets may still follow for others,
394             // but if we continue with header parsing we may lose data packets.
395             ogg->headers = 1;
396
397             // Update the header state for all streams and
398             // compute the data_offset.
399             if (!s->data_offset)
400                 s->data_offset = os->sync_pos;
401             for (i = 0; i < ogg->nstreams; i++) {
402                 struct ogg_stream *cur_os = ogg->streams + i;
403
404                 // if we have a partial non-header packet, its start is
405                 // obviously at or after the data start
406                 if (cur_os->incomplete)
407                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
408             }
409         }else{
410             os->pstart += os->psize;
411             os->psize = 0;
412         }
413     } else {
414         os->pflags = 0;
415         os->pduration = 0;
416         if (os->codec && os->codec->packet)
417             os->codec->packet (s, idx);
418         if (str)
419             *str = idx;
420         if (dstart)
421             *dstart = os->pstart;
422         if (dsize)
423             *dsize = os->psize;
424         if (fpos)
425             *fpos = os->sync_pos;
426         os->pstart += os->psize;
427         os->psize = 0;
428         os->sync_pos = os->page_pos;
429     }
430
431     // determine whether there are more complete packets in this page
432     // if not, the page's granule will apply to this packet
433     os->page_end = 1;
434     for (i = os->segp; i < os->nsegs; i++)
435         if (os->segments[i] < 255) {
436             os->page_end = 0;
437             break;
438         }
439
440     if (os->segp == os->nsegs)
441         ogg->curidx = -1;
442
443     return 0;
444 }
445
446 static int ogg_get_headers(AVFormatContext *s)
447 {
448     struct ogg *ogg = s->priv_data;
449     int ret;
450
451     do{
452         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
453         if (ret < 0)
454             return ret;
455     }while (!ogg->headers);
456
457     av_dlog(s, "found headers\n");
458
459     return 0;
460 }
461
462 static int ogg_get_length(AVFormatContext *s)
463 {
464     struct ogg *ogg = s->priv_data;
465     int i;
466     int64_t size, end;
467
468     if(!s->pb->seekable)
469         return 0;
470
471 // already set
472     if (s->duration != AV_NOPTS_VALUE)
473         return 0;
474
475     size = avio_size(s->pb);
476     if(size < 0)
477         return 0;
478     end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
479
480     ogg_save (s);
481     avio_seek (s->pb, end, SEEK_SET);
482
483     while (!ogg_read_page (s, &i)){
484         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
485             ogg->streams[i].codec) {
486             s->streams[i]->duration =
487                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
488             if (s->streams[i]->start_time != AV_NOPTS_VALUE)
489                 s->streams[i]->duration -= s->streams[i]->start_time;
490         }
491     }
492
493     ogg_restore (s, 0);
494
495     return 0;
496 }
497
498 static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
499 {
500     struct ogg *ogg = s->priv_data;
501     int ret, i;
502     ogg->curidx = -1;
503     //linear headers seek from start
504     ret = ogg_get_headers(s);
505     if (ret < 0)
506         return ret;
507
508     for (i = 0; i < ogg->nstreams; i++)
509         if (ogg->streams[i].header < 0)
510             ogg->streams[i].codec = NULL;
511
512     //linear granulepos seek from end
513     ogg_get_length (s);
514
515     //fill the extradata in the per codec callbacks
516     return 0;
517 }
518
519 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
520 {
521     struct ogg *ogg = s->priv_data;
522     struct ogg_stream *os = ogg->streams + idx;
523     int64_t pts = AV_NOPTS_VALUE;
524
525     if (dts)
526         *dts = AV_NOPTS_VALUE;
527
528     if (os->lastpts != AV_NOPTS_VALUE) {
529         pts = os->lastpts;
530         os->lastpts = AV_NOPTS_VALUE;
531     }
532     if (os->lastdts != AV_NOPTS_VALUE) {
533         if (dts)
534             *dts = os->lastdts;
535         os->lastdts = AV_NOPTS_VALUE;
536     }
537     if (os->page_end) {
538         if (os->granule != -1LL) {
539             if (os->codec && os->codec->granule_is_start)
540                 pts = ogg_gptopts(s, idx, os->granule, dts);
541             else
542                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
543             os->granule = -1LL;
544         }
545     }
546     return pts;
547 }
548
549 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
550 {
551     struct ogg *ogg;
552     struct ogg_stream *os;
553     int idx = -1, ret;
554     int pstart, psize;
555     int64_t fpos, pts, dts;
556
557     //Get an ogg packet
558 retry:
559     do{
560         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
561         if (ret < 0)
562             return ret;
563     }while (idx < 0 || !s->streams[idx]);
564
565     ogg = s->priv_data;
566     os = ogg->streams + idx;
567
568     // pflags might not be set until after this
569     pts = ogg_calc_pts(s, idx, &dts);
570
571     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
572         goto retry;
573     os->keyframe_seek = 0;
574
575     //Alloc a pkt
576     ret = av_new_packet(pkt, psize);
577     if (ret < 0)
578         return ret;
579     pkt->stream_index = idx;
580     memcpy (pkt->data, os->buf + pstart, psize);
581
582     pkt->pts = pts;
583     pkt->dts = dts;
584     pkt->flags = os->pflags;
585     pkt->duration = os->pduration;
586     pkt->pos = fpos;
587
588     return psize;
589 }
590
591 static int ogg_read_close(AVFormatContext *s)
592 {
593     struct ogg *ogg = s->priv_data;
594     int i;
595
596     for (i = 0; i < ogg->nstreams; i++){
597         av_free (ogg->streams[i].buf);
598         av_free (ogg->streams[i].private);
599     }
600     av_free (ogg->streams);
601     return 0;
602 }
603
604 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
605                                   int64_t *pos_arg, int64_t pos_limit)
606 {
607     struct ogg *ogg = s->priv_data;
608     AVIOContext *bc = s->pb;
609     int64_t pts = AV_NOPTS_VALUE;
610     int i = -1;
611     avio_seek(bc, *pos_arg, SEEK_SET);
612     ogg_reset(ogg);
613
614     while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
615         if (i == stream_index) {
616             struct ogg_stream *os = ogg->streams + stream_index;
617             pts = ogg_calc_pts(s, i, NULL);
618             if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
619                 pts = AV_NOPTS_VALUE;
620         }
621         if (pts != AV_NOPTS_VALUE)
622             break;
623     }
624     ogg_reset(ogg);
625     return pts;
626 }
627
628 static int ogg_read_seek(AVFormatContext *s, int stream_index,
629                          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 = ff_seek_frame_binary(s, stream_index, timestamp, flags);
642     os = ogg->streams + stream_index;
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 };