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