]> git.sesse.net Git - ffmpeg/blob - libavformat/oggdec.c
7dd48af66ce73d90249ad304f0fdaf5cf65dd10b
[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     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 #include <stdio.h>
32 #include "libavutil/avassert.h"
33 #include "libavutil/intreadwrite.h"
34 #include "avio_internal.h"
35 #include "oggdec.h"
36 #include "avformat.h"
37 #include "internal.h"
38 #include "vorbiscomment.h"
39
40 #define MAX_PAGE_SIZE 65307
41 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
42
43 static const struct ogg_codec * const ogg_codecs[] = {
44     &ff_skeleton_codec,
45     &ff_daala_codec,
46     &ff_dirac_codec,
47     &ff_speex_codec,
48     &ff_vorbis_codec,
49     &ff_theora_codec,
50     &ff_flac_codec,
51     &ff_celt_codec,
52     &ff_opus_codec,
53     &ff_vp8_codec,
54     &ff_old_dirac_codec,
55     &ff_old_flac_codec,
56     &ff_ogm_video_codec,
57     &ff_ogm_audio_codec,
58     &ff_ogm_text_codec,
59     &ff_ogm_old_codec,
60     NULL
61 };
62
63 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
64 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
65 static int ogg_restore(AVFormatContext *s);
66
67 static void free_stream(AVFormatContext *s, int i)
68 {
69     struct ogg *ogg = s->priv_data;
70     struct ogg_stream *stream = &ogg->streams[i];
71
72     av_freep(&stream->buf);
73     if (stream->codec &&
74         stream->codec->cleanup) {
75         stream->codec->cleanup(s, i);
76     }
77
78     av_freep(&stream->private);
79     av_freep(&stream->new_metadata);
80 }
81
82 //FIXME We could avoid some structure duplication
83 static int ogg_save(AVFormatContext *s)
84 {
85     struct ogg *ogg = s->priv_data;
86     struct ogg_state *ost =
87         av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
88     int i;
89     int ret = 0;
90
91     if (!ost)
92         return AVERROR(ENOMEM);
93
94     ost->pos      = avio_tell(s->pb);
95     ost->curidx   = ogg->curidx;
96     ost->next     = ogg->state;
97     ost->nstreams = ogg->nstreams;
98     memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
99
100     for (i = 0; i < ogg->nstreams; i++) {
101         struct ogg_stream *os = ogg->streams + i;
102         os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
103         if (os->buf)
104             memcpy(os->buf, ost->streams[i].buf, os->bufpos);
105         else
106             ret = AVERROR(ENOMEM);
107         os->new_metadata      = NULL;
108         os->new_metadata_size = 0;
109     }
110
111     ogg->state = ost;
112
113     if (ret < 0)
114         ogg_restore(s);
115
116     return ret;
117 }
118
119 static int ogg_restore(AVFormatContext *s)
120 {
121     struct ogg *ogg = s->priv_data;
122     AVIOContext *bc = s->pb;
123     struct ogg_state *ost = ogg->state;
124     int i, err;
125
126     if (!ost)
127         return 0;
128
129     ogg->state = ost->next;
130
131         for (i = 0; i < ogg->nstreams; i++) {
132             struct ogg_stream *stream = &ogg->streams[i];
133             av_freep(&stream->buf);
134             av_freep(&stream->new_metadata);
135
136             if (i >= ost->nstreams || !ost->streams[i].private) {
137                 free_stream(s, i);
138             }
139         }
140
141         avio_seek(bc, ost->pos, SEEK_SET);
142         ogg->page_pos = -1;
143         ogg->curidx   = ost->curidx;
144         ogg->nstreams = ost->nstreams;
145         if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
146                                      sizeof(*ogg->streams))) < 0) {
147             ogg->nstreams = 0;
148             return err;
149         } else
150             memcpy(ogg->streams, ost->streams,
151                    ost->nstreams * sizeof(*ogg->streams));
152
153     av_free(ost);
154
155     return 0;
156 }
157
158 static int ogg_reset(AVFormatContext *s)
159 {
160     struct ogg *ogg = s->priv_data;
161     int i;
162     int64_t start_pos = avio_tell(s->pb);
163
164     for (i = 0; i < ogg->nstreams; i++) {
165         struct ogg_stream *os = ogg->streams + i;
166         os->bufpos     = 0;
167         os->pstart     = 0;
168         os->psize      = 0;
169         os->granule    = -1;
170         os->lastpts    = AV_NOPTS_VALUE;
171         os->lastdts    = AV_NOPTS_VALUE;
172         os->sync_pos   = -1;
173         os->page_pos   = 0;
174         os->nsegs      = 0;
175         os->segp       = 0;
176         os->incomplete = 0;
177         os->got_data = 0;
178         if (start_pos <= s->internal->data_offset) {
179             os->lastpts = 0;
180         }
181         os->start_trimming = 0;
182         os->end_trimming = 0;
183         av_freep(&os->new_metadata);
184         os->new_metadata_size = 0;
185     }
186
187     ogg->page_pos = -1;
188     ogg->curidx = -1;
189
190     return 0;
191 }
192
193 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
194 {
195     int i;
196
197     for (i = 0; ogg_codecs[i]; i++)
198         if (size >= ogg_codecs[i]->magicsize &&
199             !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
200             return ogg_codecs[i];
201
202     return NULL;
203 }
204
205 /**
206  * Replace the current stream with a new one. This is a typical webradio
207  * situation where a new audio stream spawn (identified with a new serial) and
208  * must replace the previous one (track switch).
209  */
210 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic,
211                               int probing)
212 {
213     struct ogg *ogg = s->priv_data;
214     struct ogg_stream *os;
215     const struct ogg_codec *codec;
216     int i = 0;
217
218     if (ogg->nstreams != 1) {
219         avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
220         return AVERROR_PATCHWELCOME;
221     }
222
223     /* Check for codecs */
224     codec = ogg_find_codec(magic, 8);
225     if (!codec && !probing) {
226         av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
227         return AVERROR_INVALIDDATA;
228     }
229
230     /* We only have a single stream anyway, so if there's a new stream with
231      * a different codec just replace it */
232     os = &ogg->streams[0];
233     os->serial  = serial;
234     os->codec   = codec;
235     os->serial  = serial;
236     os->lastpts = 0;
237     os->lastdts = 0;
238     os->start_trimming = 0;
239     os->end_trimming = 0;
240
241     /* Chained files have extradata as a new packet */
242     if (codec == &ff_opus_codec)
243         os->header = -1;
244
245     return i;
246 }
247
248 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
249 {
250     struct ogg *ogg = s->priv_data;
251     int idx         = ogg->nstreams;
252     AVStream *st;
253     struct ogg_stream *os;
254     size_t size;
255
256     if (ogg->state) {
257         av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
258                "in between Ogg context save/restore operations.\n");
259         return AVERROR_BUG;
260     }
261
262     /* Allocate and init a new Ogg Stream */
263     if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
264         !(os = av_realloc(ogg->streams, size)))
265         return AVERROR(ENOMEM);
266     ogg->streams = os;
267     os           = ogg->streams + idx;
268     memset(os, 0, sizeof(*os));
269     os->serial        = serial;
270     os->bufsize       = DECODER_BUFFER_SIZE;
271     os->buf           = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
272     os->header        = -1;
273     os->start_granule = OGG_NOGRANULE_VALUE;
274     if (!os->buf)
275         return AVERROR(ENOMEM);
276
277     /* Create the associated AVStream */
278     st = avformat_new_stream(s, NULL);
279     if (!st) {
280         av_freep(&os->buf);
281         return AVERROR(ENOMEM);
282     }
283     st->id = idx;
284     avpriv_set_pts_info(st, 64, 1, 1000000);
285
286     ogg->nstreams++;
287     return idx;
288 }
289
290 static int data_packets_seen(const struct ogg *ogg)
291 {
292     int i;
293
294     for (i = 0; i < ogg->nstreams; i++)
295         if (ogg->streams[i].got_data)
296             return 1;
297     return 0;
298 }
299
300 static int buf_realloc(struct ogg_stream *os, int size)
301 {
302     /* Even if invalid guarantee there's enough memory to read the page */
303     if (os->bufsize - os->bufpos < size) {
304         uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
305         if (!nb)
306             return AVERROR(ENOMEM);
307         os->buf = nb;
308         os->bufsize *= 2;
309     }
310
311     return 0;
312 }
313
314 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
315 {
316     AVIOContext *bc = s->pb;
317     struct ogg *ogg = s->priv_data;
318     struct ogg_stream *os;
319     int ret, i = 0;
320     int flags, nsegs;
321     uint64_t gp;
322     uint32_t serial;
323     uint32_t crc, crc_tmp;
324     int size = 0, idx;
325     int64_t version, page_pos;
326     int64_t start_pos;
327     uint8_t sync[4];
328     uint8_t segments[255];
329     uint8_t *readout_buf;
330     int sp = 0;
331
332     ret = avio_read(bc, sync, 4);
333     if (ret < 4)
334         return ret < 0 ? ret : AVERROR_EOF;
335
336     do {
337         int c;
338
339         if (sync[sp & 3] == 'O' &&
340             sync[(sp + 1) & 3] == 'g' &&
341             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
342             break;
343
344         if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
345             memset(sync, 0, 4);
346             avio_seek(bc, ogg->page_pos+4, SEEK_SET);
347             ogg->page_pos = -1;
348         }
349
350         c = avio_r8(bc);
351
352         if (avio_feof(bc))
353             return AVERROR_EOF;
354
355         sync[sp++ & 3] = c;
356     } while (i++ < MAX_PAGE_SIZE);
357
358     if (i >= MAX_PAGE_SIZE) {
359         av_log(s, AV_LOG_INFO, "cannot find sync word\n");
360         return AVERROR_INVALIDDATA;
361     }
362
363     /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
364     ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
365
366     /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
367     ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
368     start_pos = avio_tell(bc);
369
370     version = avio_r8(bc);
371     flags   = avio_r8(bc);
372     gp      = avio_rl64(bc);
373     serial  = avio_rl32(bc);
374     avio_skip(bc, 4); /* seq */
375
376     crc_tmp = ffio_get_checksum(bc);
377     crc     = avio_rb32(bc);
378     crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
379     ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
380
381     nsegs    = avio_r8(bc);
382     page_pos = avio_tell(bc) - 27;
383
384     ret = avio_read(bc, segments, nsegs);
385     if (ret < nsegs)
386         return ret < 0 ? ret : AVERROR_EOF;
387
388     for (i = 0; i < nsegs; i++)
389         size += segments[i];
390
391     idx = ogg_find_stream(ogg, serial);
392     if (idx >= 0) {
393         os = ogg->streams + idx;
394
395         ret = buf_realloc(os, size);
396         if (ret < 0)
397             return ret;
398
399         readout_buf = os->buf + os->bufpos;
400     } else {
401         readout_buf = av_malloc(size);
402     }
403
404     ret = avio_read(bc, readout_buf, size);
405     if (ret < size) {
406         if (idx < 0)
407             av_free(readout_buf);
408         return ret < 0 ? ret : AVERROR_EOF;
409     }
410
411     if (crc ^ ffio_get_checksum(bc)) {
412         av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
413         if (idx < 0)
414             av_free(readout_buf);
415         avio_seek(bc, start_pos, SEEK_SET);
416         return 0;
417     }
418
419     /* Since we're almost sure its a valid packet, checking the version after
420      * the checksum lets the demuxer be more tolerant */
421     if (version) {
422         av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
423         if (idx < 0)
424             av_free(readout_buf);
425         avio_seek(bc, start_pos, SEEK_SET);
426         return 0;
427     }
428
429     /* CRC is correct so we can be 99% sure there's an actual change here */
430     if (idx < 0) {
431         if (data_packets_seen(ogg))
432             idx = ogg_replace_stream(s, serial, readout_buf, probing);
433         else
434             idx = ogg_new_stream(s, serial);
435
436         if (idx < 0) {
437             av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
438             av_free(readout_buf);
439             return idx;
440         }
441
442         os = ogg->streams + idx;
443
444         ret = buf_realloc(os, size);
445         if (ret < 0) {
446             av_free(readout_buf);
447             return ret;
448         }
449
450         memcpy(os->buf + os->bufpos, readout_buf, size);
451         av_free(readout_buf);
452     }
453
454     ogg->page_pos = page_pos;
455     os->page_pos  = page_pos;
456     os->nsegs     = nsegs;
457     os->segp      = 0;
458     os->got_data  = !(flags & OGG_FLAG_BOS);
459     os->bufpos   += size;
460     os->granule   = gp;
461     os->flags     = flags;
462     memcpy(os->segments, segments, nsegs);
463     memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
464
465     if (flags & OGG_FLAG_CONT || os->incomplete) {
466         if (!os->psize) {
467             // If this is the very first segment we started
468             // playback in the middle of a continuation packet.
469             // Discard it since we missed the start of it.
470             while (os->segp < os->nsegs) {
471                 int seg = os->segments[os->segp++];
472                 os->pstart += seg;
473                 if (seg < 255)
474                     break;
475             }
476             os->sync_pos = os->page_pos;
477         }
478     } else {
479         os->psize    = 0;
480         os->sync_pos = os->page_pos;
481     }
482
483     /* This function is always called with sid != NULL */
484     *sid = idx;
485
486     return 0;
487 }
488
489 /**
490  * @brief find the next Ogg packet
491  * @param *sid is set to the stream for the packet or -1 if there is
492  *             no matching stream, in that case assume all other return
493  *             values to be uninitialized.
494  * @return negative value on error or EOF.
495  */
496 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
497                       int64_t *fpos)
498 {
499     struct ogg *ogg = s->priv_data;
500     int idx, i, ret;
501     struct ogg_stream *os;
502     int complete = 0;
503     int segp     = 0, psize = 0;
504
505     av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
506     if (sid)
507         *sid = -1;
508
509     do {
510         idx = ogg->curidx;
511
512         while (idx < 0) {
513             ret = ogg_read_page(s, &idx, 0);
514             if (ret < 0)
515                 return ret;
516         }
517
518         os = ogg->streams + idx;
519
520         av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
521                 idx, os->pstart, os->psize, os->segp, os->nsegs);
522
523         if (!os->codec) {
524             if (os->header < 0) {
525                 os->codec = ogg_find_codec(os->buf, os->bufpos);
526                 if (!os->codec) {
527                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
528                     os->header = 0;
529                     return 0;
530                 }
531             } else {
532                 return 0;
533             }
534         }
535
536         segp  = os->segp;
537         psize = os->psize;
538
539         while (os->segp < os->nsegs) {
540             int ss = os->segments[os->segp++];
541             os->psize += ss;
542             if (ss < 255) {
543                 complete = 1;
544                 break;
545             }
546         }
547
548         if (!complete && os->segp == os->nsegs) {
549             ogg->curidx    = -1;
550             // Do not set incomplete for empty packets.
551             // Together with the code in ogg_read_page
552             // that discards all continuation of empty packets
553             // we would get an infinite loop.
554             os->incomplete = !!os->psize;
555         }
556     } while (!complete);
557
558
559     if (os->granule == -1)
560         av_log(s, AV_LOG_WARNING,
561                "Page at %"PRId64" is missing granule\n",
562                os->page_pos);
563
564     ogg->curidx    = idx;
565     os->incomplete = 0;
566
567     if (os->header) {
568         if ((ret = os->codec->header(s, idx)) < 0) {
569             av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
570             return ret;
571         }
572         os->header = ret;
573         if (!os->header) {
574             os->segp  = segp;
575             os->psize = psize;
576
577             // We have reached the first non-header packet in this stream.
578             // Unfortunately more header packets may still follow for others,
579             // but if we continue with header parsing we may lose data packets.
580             ogg->headers = 1;
581
582             // Update the header state for all streams and
583             // compute the data_offset.
584             if (!s->internal->data_offset)
585                 s->internal->data_offset = os->sync_pos;
586
587             for (i = 0; i < ogg->nstreams; i++) {
588                 struct ogg_stream *cur_os = ogg->streams + i;
589
590                 // if we have a partial non-header packet, its start is
591                 // obviously at or after the data start
592                 if (cur_os->incomplete)
593                     s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
594             }
595         } else {
596             os->nb_header++;
597             os->pstart += os->psize;
598             os->psize   = 0;
599         }
600     } else {
601         os->pflags    = 0;
602         os->pduration = 0;
603         if (os->codec && os->codec->packet) {
604             if ((ret = os->codec->packet(s, idx)) < 0) {
605                 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
606                 return ret;
607             }
608         }
609         if (sid)
610             *sid = idx;
611         if (dstart)
612             *dstart = os->pstart;
613         if (dsize)
614             *dsize = os->psize;
615         if (fpos)
616             *fpos = os->sync_pos;
617         os->pstart  += os->psize;
618         os->psize    = 0;
619         if(os->pstart == os->bufpos)
620             os->bufpos = os->pstart = 0;
621         os->sync_pos = os->page_pos;
622     }
623
624     // determine whether there are more complete packets in this page
625     // if not, the page's granule will apply to this packet
626     os->page_end = 1;
627     for (i = os->segp; i < os->nsegs; i++)
628         if (os->segments[i] < 255) {
629             os->page_end = 0;
630             break;
631         }
632
633     if (os->segp == os->nsegs)
634         ogg->curidx = -1;
635
636     return 0;
637 }
638
639 static int ogg_get_length(AVFormatContext *s)
640 {
641     struct ogg *ogg = s->priv_data;
642     int i, ret;
643     int64_t size, end;
644     int streams_left=0;
645
646     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
647         return 0;
648
649 // already set
650     if (s->duration != AV_NOPTS_VALUE)
651         return 0;
652
653     size = avio_size(s->pb);
654     if (size < 0)
655         return 0;
656     end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
657
658     ret = ogg_save(s);
659     if (ret < 0)
660         return ret;
661     avio_seek(s->pb, end, SEEK_SET);
662     ogg->page_pos = -1;
663
664     while (!ogg_read_page(s, &i, 1)) {
665         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
666             ogg->streams[i].codec) {
667             s->streams[i]->duration =
668                 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
669             if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
670                 s->streams[i]->duration -= s->streams[i]->start_time;
671                 streams_left-= (ogg->streams[i].got_start==-1);
672                 ogg->streams[i].got_start= 1;
673             } else if(!ogg->streams[i].got_start) {
674                 ogg->streams[i].got_start= -1;
675                 streams_left++;
676             }
677         }
678     }
679
680     ogg_restore(s);
681
682     ret = ogg_save(s);
683     if (ret < 0)
684         return ret;
685
686     avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
687     ogg_reset(s);
688     while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
689         int64_t pts;
690         if (i < 0) continue;
691         pts = ogg_calc_pts(s, i, NULL);
692         if (s->streams[i]->duration == AV_NOPTS_VALUE)
693             continue;
694         if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
695             s->streams[i]->duration -= pts;
696             ogg->streams[i].got_start= 1;
697             streams_left--;
698         }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
699             ogg->streams[i].got_start= 1;
700             streams_left--;
701         }
702     }
703     ogg_restore (s);
704
705     return 0;
706 }
707
708 static int ogg_read_close(AVFormatContext *s)
709 {
710     struct ogg *ogg = s->priv_data;
711     int i;
712
713     for (i = 0; i < ogg->nstreams; i++) {
714         free_stream(s, i);
715     }
716
717     ogg->nstreams = 0;
718
719     av_freep(&ogg->streams);
720     return 0;
721 }
722
723 static int ogg_read_header(AVFormatContext *s)
724 {
725     struct ogg *ogg = s->priv_data;
726     int ret, i;
727
728     ogg->curidx = -1;
729
730     //linear headers seek from start
731     do {
732         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
733         if (ret < 0) {
734             ogg_read_close(s);
735             return ret;
736         }
737     } while (!ogg->headers);
738     av_log(s, AV_LOG_TRACE, "found headers\n");
739
740     for (i = 0; i < ogg->nstreams; i++) {
741         struct ogg_stream *os = ogg->streams + i;
742
743         if (ogg->streams[i].header < 0) {
744             av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
745             ogg->streams[i].codec = NULL;
746             av_freep(&ogg->streams[i].private);
747         } else if (os->codec && os->nb_header < os->codec->nb_header) {
748             av_log(s, AV_LOG_WARNING,
749                    "Headers mismatch for stream %d: "
750                    "expected %d received %d.\n",
751                    i, os->codec->nb_header, os->nb_header);
752             if (s->error_recognition & AV_EF_EXPLODE) {
753                 ogg_read_close(s);
754                 return AVERROR_INVALIDDATA;
755             }
756         }
757         if (os->start_granule != OGG_NOGRANULE_VALUE)
758             os->lastpts = s->streams[i]->start_time =
759                 ogg_gptopts(s, i, os->start_granule, NULL);
760     }
761
762     //linear granulepos seek from end
763     ret = ogg_get_length(s);
764     if (ret < 0) {
765         ogg_read_close(s);
766         return ret;
767     }
768
769     return 0;
770 }
771
772 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
773 {
774     struct ogg *ogg       = s->priv_data;
775     struct ogg_stream *os = ogg->streams + idx;
776     int64_t pts           = AV_NOPTS_VALUE;
777
778     if (dts)
779         *dts = AV_NOPTS_VALUE;
780
781     if (os->lastpts != AV_NOPTS_VALUE) {
782         pts         = os->lastpts;
783         os->lastpts = AV_NOPTS_VALUE;
784     }
785     if (os->lastdts != AV_NOPTS_VALUE) {
786         if (dts)
787             *dts = os->lastdts;
788         os->lastdts = AV_NOPTS_VALUE;
789     }
790     if (os->page_end) {
791         if (os->granule != -1LL) {
792             if (os->codec && os->codec->granule_is_start)
793                 pts = ogg_gptopts(s, idx, os->granule, dts);
794             else
795                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
796             os->granule = -1LL;
797         }
798     }
799     return pts;
800 }
801
802 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
803 {
804     struct ogg *ogg = s->priv_data;
805     struct ogg_stream *os = ogg->streams + idx;
806     int invalid = 0;
807     if (psize) {
808         switch (s->streams[idx]->codecpar->codec_id) {
809         case AV_CODEC_ID_THEORA:
810             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
811         break;
812         case AV_CODEC_ID_VP8:
813             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
814         }
815         if (invalid) {
816             os->pflags ^= AV_PKT_FLAG_KEY;
817             av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
818                    (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
819         }
820     }
821 }
822
823 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
824 {
825     struct ogg *ogg;
826     struct ogg_stream *os;
827     int idx, ret;
828     int pstart, psize;
829     int64_t fpos, pts, dts;
830
831     if (s->io_repositioned) {
832         ogg_reset(s);
833         s->io_repositioned = 0;
834     }
835
836     //Get an ogg packet
837 retry:
838     do {
839         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
840         if (ret < 0)
841             return ret;
842     } while (idx < 0 || !s->streams[idx]);
843
844     ogg = s->priv_data;
845     os  = ogg->streams + idx;
846
847     // pflags might not be set until after this
848     pts = ogg_calc_pts(s, idx, &dts);
849     ogg_validate_keyframe(s, idx, pstart, psize);
850
851     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
852         goto retry;
853     os->keyframe_seek = 0;
854
855     //Alloc a pkt
856     ret = av_new_packet(pkt, psize);
857     if (ret < 0)
858         return ret;
859     pkt->stream_index = idx;
860     memcpy(pkt->data, os->buf + pstart, psize);
861
862     pkt->pts      = pts;
863     pkt->dts      = dts;
864     pkt->flags    = os->pflags;
865     pkt->duration = os->pduration;
866     pkt->pos      = fpos;
867
868     if (os->start_trimming || os->end_trimming) {
869         uint8_t *side_data = av_packet_new_side_data(pkt,
870                                                      AV_PKT_DATA_SKIP_SAMPLES,
871                                                      10);
872         if(!side_data)
873             return AVERROR(ENOMEM);
874          AV_WL32(side_data + 0, os->start_trimming);
875         AV_WL32(side_data + 4, os->end_trimming);
876         os->start_trimming = 0;
877         os->end_trimming = 0;
878     }
879
880     if (os->new_metadata) {
881         uint8_t *side_data = av_packet_new_side_data(pkt,
882                                                      AV_PKT_DATA_METADATA_UPDATE,
883                                                      os->new_metadata_size);
884         if(!side_data)
885             return AVERROR(ENOMEM);
886
887         memcpy(side_data, os->new_metadata, os->new_metadata_size);
888         av_freep(&os->new_metadata);
889         os->new_metadata_size = 0;
890     }
891
892     return psize;
893 }
894
895 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
896                                   int64_t *pos_arg, int64_t pos_limit)
897 {
898     struct ogg *ogg = s->priv_data;
899     AVIOContext *bc = s->pb;
900     int64_t pts     = AV_NOPTS_VALUE;
901     int64_t keypos  = -1;
902     int i;
903     int pstart, psize;
904     avio_seek(bc, *pos_arg, SEEK_SET);
905     ogg_reset(s);
906
907     while (   avio_tell(bc) <= pos_limit
908            && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
909         if (i == stream_index) {
910             struct ogg_stream *os = ogg->streams + stream_index;
911             // Do not trust the last timestamps of an ogm video
912             if (    (os->flags & OGG_FLAG_EOS)
913                 && !(os->flags & OGG_FLAG_BOS)
914                 && os->codec == &ff_ogm_video_codec)
915                 continue;
916             pts = ogg_calc_pts(s, i, NULL);
917             ogg_validate_keyframe(s, i, pstart, psize);
918             if (os->pflags & AV_PKT_FLAG_KEY) {
919                 keypos = *pos_arg;
920             } else if (os->keyframe_seek) {
921                 // if we had a previous keyframe but no pts for it,
922                 // return that keyframe with this pts value.
923                 if (keypos >= 0)
924                     *pos_arg = keypos;
925                 else
926                     pts = AV_NOPTS_VALUE;
927             }
928         }
929         if (pts != AV_NOPTS_VALUE)
930             break;
931     }
932     ogg_reset(s);
933     return pts;
934 }
935
936 static int ogg_read_seek(AVFormatContext *s, int stream_index,
937                          int64_t timestamp, int flags)
938 {
939     struct ogg *ogg       = s->priv_data;
940     struct ogg_stream *os = ogg->streams + stream_index;
941     int ret;
942
943     av_assert0(stream_index < ogg->nstreams);
944     // Ensure everything is reset even when seeking via
945     // the generated index.
946     ogg_reset(s);
947
948     // Try seeking to a keyframe first. If this fails (very possible),
949     // av_seek_frame will fall back to ignoring keyframes
950     if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
951         && !(flags & AVSEEK_FLAG_ANY))
952         os->keyframe_seek = 1;
953
954     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
955     ogg_reset(s);
956     os  = ogg->streams + stream_index;
957     if (ret < 0)
958         os->keyframe_seek = 0;
959     return ret;
960 }
961
962 static int ogg_probe(const AVProbeData *p)
963 {
964     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
965         return AVPROBE_SCORE_MAX;
966     return 0;
967 }
968
969 AVInputFormat ff_ogg_demuxer = {
970     .name           = "ogg",
971     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
972     .priv_data_size = sizeof(struct ogg),
973     .read_probe     = ogg_probe,
974     .read_header    = ogg_read_header,
975     .read_packet    = ogg_read_packet,
976     .read_close     = ogg_read_close,
977     .read_seek      = ogg_read_seek,
978     .read_timestamp = ogg_read_timestamp,
979     .extensions     = "ogg",
980     .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
981 };