]> git.sesse.net Git - ffmpeg/blob - libavformat/oggdec.c
oggdec: add support for proper demuxing of chained Opus files and streams
[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 ogg_read_page(AVFormatContext *s, int *sid, int probing)
301 {
302     AVIOContext *bc = s->pb;
303     struct ogg *ogg = s->priv_data;
304     struct ogg_stream *os;
305     int ret, i = 0;
306     int flags, nsegs;
307     uint64_t gp;
308     uint32_t serial;
309     uint32_t crc, crc_tmp;
310     int size = 0, idx;
311     int64_t version, page_pos;
312     int64_t start_pos;
313     uint8_t sync[4];
314     uint8_t segments[255];
315     uint8_t *readout_buf;
316     int sp = 0;
317
318     ret = avio_read(bc, sync, 4);
319     if (ret < 4)
320         return ret < 0 ? ret : AVERROR_EOF;
321
322     do {
323         int c;
324
325         if (sync[sp & 3] == 'O' &&
326             sync[(sp + 1) & 3] == 'g' &&
327             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
328             break;
329
330         if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
331             memset(sync, 0, 4);
332             avio_seek(bc, ogg->page_pos+4, SEEK_SET);
333             ogg->page_pos = -1;
334         }
335
336         c = avio_r8(bc);
337
338         if (avio_feof(bc))
339             return AVERROR_EOF;
340
341         sync[sp++ & 3] = c;
342     } while (i++ < MAX_PAGE_SIZE);
343
344     if (i >= MAX_PAGE_SIZE) {
345         av_log(s, AV_LOG_INFO, "cannot find sync word\n");
346         return AVERROR_INVALIDDATA;
347     }
348
349     /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
350     ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
351
352     /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
353     ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
354     start_pos = avio_tell(bc);
355
356     version = avio_r8(bc);
357     flags   = avio_r8(bc);
358     gp      = avio_rl64(bc);
359     serial  = avio_rl32(bc);
360     avio_skip(bc, 4); /* seq */
361
362     crc_tmp = ffio_get_checksum(bc);
363     crc     = avio_rb32(bc);
364     crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
365     ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
366
367     nsegs    = avio_r8(bc);
368     page_pos = avio_tell(bc) - 27;
369
370     ret = avio_read(bc, segments, nsegs);
371     if (ret < nsegs)
372         return ret < 0 ? ret : AVERROR_EOF;
373
374     for (i = 0; i < nsegs; i++)
375         size += segments[i];
376
377     idx = ogg_find_stream(ogg, serial);
378     if (idx >= 0) {
379         os = ogg->streams + idx;
380
381         /* Even if invalid guarantee there's enough memory to read the page */
382         if (os->bufsize - os->bufpos < size) {
383             uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
384             if (!nb)
385                 return AVERROR(ENOMEM);
386             os->buf = nb;
387             os->bufsize *= 2;
388         }
389
390         readout_buf = os->buf + os->bufpos;
391     } else {
392         readout_buf = av_malloc(size);
393     }
394
395     ret = avio_read(bc, readout_buf, size);
396     if (ret < size) {
397         if (idx < 0)
398             av_free(readout_buf);
399         return ret < 0 ? ret : AVERROR_EOF;
400     }
401
402     if (crc ^ ffio_get_checksum(bc)) {
403         av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
404         if (idx < 0)
405             av_free(readout_buf);
406         avio_seek(bc, start_pos, SEEK_SET);
407         return 0;
408     }
409
410     /* Since we're almost sure its a valid packet, checking the version after
411      * the checksum lets the demuxer be more tolerant */
412     if (version) {
413         av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
414         if (idx < 0)
415             av_free(readout_buf);
416         avio_seek(bc, start_pos, SEEK_SET);
417         return 0;
418     }
419
420     /* CRC is correct so we can be 99% sure there's an actual change here */
421     if (idx < 0) {
422         if (data_packets_seen(ogg))
423             idx = ogg_replace_stream(s, serial, readout_buf, probing);
424         else
425             idx = ogg_new_stream(s, serial);
426
427         if (idx < 0) {
428             av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
429             av_free(readout_buf);
430             return idx;
431         }
432
433         os = ogg->streams + idx;
434
435         memcpy(os->buf + os->bufpos, readout_buf, size);
436         av_free(readout_buf);
437     }
438
439     ogg->page_pos = page_pos;
440     os->page_pos  = page_pos;
441     os->nsegs     = nsegs;
442     os->segp      = 0;
443     os->got_data  = !(flags & OGG_FLAG_BOS);
444     os->bufpos   += size;
445     os->granule   = gp;
446     os->flags     = flags;
447     memcpy(os->segments, segments, nsegs);
448     memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
449
450     if (flags & OGG_FLAG_CONT || os->incomplete) {
451         if (!os->psize) {
452             // If this is the very first segment we started
453             // playback in the middle of a continuation packet.
454             // Discard it since we missed the start of it.
455             while (os->segp < os->nsegs) {
456                 int seg = os->segments[os->segp++];
457                 os->pstart += seg;
458                 if (seg < 255)
459                     break;
460             }
461             os->sync_pos = os->page_pos;
462         }
463     } else {
464         os->psize    = 0;
465         os->sync_pos = os->page_pos;
466     }
467
468     /* This function is always called with sid != NULL */
469     *sid = idx;
470
471     return 0;
472 }
473
474 /**
475  * @brief find the next Ogg packet
476  * @param *sid is set to the stream for the packet or -1 if there is
477  *             no matching stream, in that case assume all other return
478  *             values to be uninitialized.
479  * @return negative value on error or EOF.
480  */
481 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
482                       int64_t *fpos)
483 {
484     struct ogg *ogg = s->priv_data;
485     int idx, i, ret;
486     struct ogg_stream *os;
487     int complete = 0;
488     int segp     = 0, psize = 0;
489
490     av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
491     if (sid)
492         *sid = -1;
493
494     do {
495         idx = ogg->curidx;
496
497         while (idx < 0) {
498             ret = ogg_read_page(s, &idx, 0);
499             if (ret < 0)
500                 return ret;
501         }
502
503         os = ogg->streams + idx;
504
505         av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
506                 idx, os->pstart, os->psize, os->segp, os->nsegs);
507
508         if (!os->codec) {
509             if (os->header < 0) {
510                 os->codec = ogg_find_codec(os->buf, os->bufpos);
511                 if (!os->codec) {
512                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
513                     os->header = 0;
514                     return 0;
515                 }
516             } else {
517                 return 0;
518             }
519         }
520
521         segp  = os->segp;
522         psize = os->psize;
523
524         while (os->segp < os->nsegs) {
525             int ss = os->segments[os->segp++];
526             os->psize += ss;
527             if (ss < 255) {
528                 complete = 1;
529                 break;
530             }
531         }
532
533         if (!complete && os->segp == os->nsegs) {
534             ogg->curidx    = -1;
535             // Do not set incomplete for empty packets.
536             // Together with the code in ogg_read_page
537             // that discards all continuation of empty packets
538             // we would get an infinite loop.
539             os->incomplete = !!os->psize;
540         }
541     } while (!complete);
542
543
544     if (os->granule == -1)
545         av_log(s, AV_LOG_WARNING,
546                "Page at %"PRId64" is missing granule\n",
547                os->page_pos);
548
549     ogg->curidx    = idx;
550     os->incomplete = 0;
551
552     if (os->header) {
553         if ((ret = os->codec->header(s, idx)) < 0) {
554             av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
555             return ret;
556         }
557         os->header = ret;
558         if (!os->header) {
559             os->segp  = segp;
560             os->psize = psize;
561
562             // We have reached the first non-header packet in this stream.
563             // Unfortunately more header packets may still follow for others,
564             // but if we continue with header parsing we may lose data packets.
565             ogg->headers = 1;
566
567             // Update the header state for all streams and
568             // compute the data_offset.
569             if (!s->internal->data_offset)
570                 s->internal->data_offset = os->sync_pos;
571
572             for (i = 0; i < ogg->nstreams; i++) {
573                 struct ogg_stream *cur_os = ogg->streams + i;
574
575                 // if we have a partial non-header packet, its start is
576                 // obviously at or after the data start
577                 if (cur_os->incomplete)
578                     s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
579             }
580         } else {
581             os->nb_header++;
582             os->pstart += os->psize;
583             os->psize   = 0;
584         }
585     } else {
586         os->pflags    = 0;
587         os->pduration = 0;
588         if (os->codec && os->codec->packet) {
589             if ((ret = os->codec->packet(s, idx)) < 0) {
590                 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
591                 return ret;
592             }
593         }
594         if (sid)
595             *sid = idx;
596         if (dstart)
597             *dstart = os->pstart;
598         if (dsize)
599             *dsize = os->psize;
600         if (fpos)
601             *fpos = os->sync_pos;
602         os->pstart  += os->psize;
603         os->psize    = 0;
604         if(os->pstart == os->bufpos)
605             os->bufpos = os->pstart = 0;
606         os->sync_pos = os->page_pos;
607     }
608
609     // determine whether there are more complete packets in this page
610     // if not, the page's granule will apply to this packet
611     os->page_end = 1;
612     for (i = os->segp; i < os->nsegs; i++)
613         if (os->segments[i] < 255) {
614             os->page_end = 0;
615             break;
616         }
617
618     if (os->segp == os->nsegs)
619         ogg->curidx = -1;
620
621     return 0;
622 }
623
624 static int ogg_get_length(AVFormatContext *s)
625 {
626     struct ogg *ogg = s->priv_data;
627     int i, ret;
628     int64_t size, end;
629     int streams_left=0;
630
631     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
632         return 0;
633
634 // already set
635     if (s->duration != AV_NOPTS_VALUE)
636         return 0;
637
638     size = avio_size(s->pb);
639     if (size < 0)
640         return 0;
641     end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
642
643     ret = ogg_save(s);
644     if (ret < 0)
645         return ret;
646     avio_seek(s->pb, end, SEEK_SET);
647     ogg->page_pos = -1;
648
649     while (!ogg_read_page(s, &i, 1)) {
650         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
651             ogg->streams[i].codec) {
652             s->streams[i]->duration =
653                 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
654             if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
655                 s->streams[i]->duration -= s->streams[i]->start_time;
656                 streams_left-= (ogg->streams[i].got_start==-1);
657                 ogg->streams[i].got_start= 1;
658             } else if(!ogg->streams[i].got_start) {
659                 ogg->streams[i].got_start= -1;
660                 streams_left++;
661             }
662         }
663     }
664
665     ogg_restore(s);
666
667     ret = ogg_save(s);
668     if (ret < 0)
669         return ret;
670
671     avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
672     ogg_reset(s);
673     while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
674         int64_t pts;
675         if (i < 0) continue;
676         pts = ogg_calc_pts(s, i, NULL);
677         if (s->streams[i]->duration == AV_NOPTS_VALUE)
678             continue;
679         if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
680             s->streams[i]->duration -= pts;
681             ogg->streams[i].got_start= 1;
682             streams_left--;
683         }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
684             ogg->streams[i].got_start= 1;
685             streams_left--;
686         }
687     }
688     ogg_restore (s);
689
690     return 0;
691 }
692
693 static int ogg_read_close(AVFormatContext *s)
694 {
695     struct ogg *ogg = s->priv_data;
696     int i;
697
698     for (i = 0; i < ogg->nstreams; i++) {
699         free_stream(s, i);
700     }
701
702     ogg->nstreams = 0;
703
704     av_freep(&ogg->streams);
705     return 0;
706 }
707
708 static int ogg_read_header(AVFormatContext *s)
709 {
710     struct ogg *ogg = s->priv_data;
711     int ret, i;
712
713     ogg->curidx = -1;
714
715     //linear headers seek from start
716     do {
717         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
718         if (ret < 0) {
719             ogg_read_close(s);
720             return ret;
721         }
722     } while (!ogg->headers);
723     av_log(s, AV_LOG_TRACE, "found headers\n");
724
725     for (i = 0; i < ogg->nstreams; i++) {
726         struct ogg_stream *os = ogg->streams + i;
727
728         if (ogg->streams[i].header < 0) {
729             av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
730             ogg->streams[i].codec = NULL;
731             av_freep(&ogg->streams[i].private);
732         } else if (os->codec && os->nb_header < os->codec->nb_header) {
733             av_log(s, AV_LOG_WARNING,
734                    "Headers mismatch for stream %d: "
735                    "expected %d received %d.\n",
736                    i, os->codec->nb_header, os->nb_header);
737             if (s->error_recognition & AV_EF_EXPLODE) {
738                 ogg_read_close(s);
739                 return AVERROR_INVALIDDATA;
740             }
741         }
742         if (os->start_granule != OGG_NOGRANULE_VALUE)
743             os->lastpts = s->streams[i]->start_time =
744                 ogg_gptopts(s, i, os->start_granule, NULL);
745     }
746
747     //linear granulepos seek from end
748     ret = ogg_get_length(s);
749     if (ret < 0) {
750         ogg_read_close(s);
751         return ret;
752     }
753
754     return 0;
755 }
756
757 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
758 {
759     struct ogg *ogg       = s->priv_data;
760     struct ogg_stream *os = ogg->streams + idx;
761     int64_t pts           = AV_NOPTS_VALUE;
762
763     if (dts)
764         *dts = AV_NOPTS_VALUE;
765
766     if (os->lastpts != AV_NOPTS_VALUE) {
767         pts         = os->lastpts;
768         os->lastpts = AV_NOPTS_VALUE;
769     }
770     if (os->lastdts != AV_NOPTS_VALUE) {
771         if (dts)
772             *dts = os->lastdts;
773         os->lastdts = AV_NOPTS_VALUE;
774     }
775     if (os->page_end) {
776         if (os->granule != -1LL) {
777             if (os->codec && os->codec->granule_is_start)
778                 pts = ogg_gptopts(s, idx, os->granule, dts);
779             else
780                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
781             os->granule = -1LL;
782         }
783     }
784     return pts;
785 }
786
787 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
788 {
789     struct ogg *ogg = s->priv_data;
790     struct ogg_stream *os = ogg->streams + idx;
791     int invalid = 0;
792     if (psize) {
793         switch (s->streams[idx]->codecpar->codec_id) {
794         case AV_CODEC_ID_THEORA:
795             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
796         break;
797         case AV_CODEC_ID_VP8:
798             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
799         }
800         if (invalid) {
801             os->pflags ^= AV_PKT_FLAG_KEY;
802             av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
803                    (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
804         }
805     }
806 }
807
808 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
809 {
810     struct ogg *ogg;
811     struct ogg_stream *os;
812     int idx, ret;
813     int pstart, psize;
814     int64_t fpos, pts, dts;
815
816     if (s->io_repositioned) {
817         ogg_reset(s);
818         s->io_repositioned = 0;
819     }
820
821     //Get an ogg packet
822 retry:
823     do {
824         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
825         if (ret < 0)
826             return ret;
827     } while (idx < 0 || !s->streams[idx]);
828
829     ogg = s->priv_data;
830     os  = ogg->streams + idx;
831
832     // pflags might not be set until after this
833     pts = ogg_calc_pts(s, idx, &dts);
834     ogg_validate_keyframe(s, idx, pstart, psize);
835
836     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
837         goto retry;
838     os->keyframe_seek = 0;
839
840     //Alloc a pkt
841     ret = av_new_packet(pkt, psize);
842     if (ret < 0)
843         return ret;
844     pkt->stream_index = idx;
845     memcpy(pkt->data, os->buf + pstart, psize);
846
847     pkt->pts      = pts;
848     pkt->dts      = dts;
849     pkt->flags    = os->pflags;
850     pkt->duration = os->pduration;
851     pkt->pos      = fpos;
852
853     if (os->start_trimming || os->end_trimming) {
854         uint8_t *side_data = av_packet_new_side_data(pkt,
855                                                      AV_PKT_DATA_SKIP_SAMPLES,
856                                                      10);
857         if(!side_data)
858             return AVERROR(ENOMEM);
859          AV_WL32(side_data + 0, os->start_trimming);
860         AV_WL32(side_data + 4, os->end_trimming);
861         os->start_trimming = 0;
862         os->end_trimming = 0;
863     }
864
865     if (os->new_metadata) {
866         uint8_t *side_data = av_packet_new_side_data(pkt,
867                                                      AV_PKT_DATA_METADATA_UPDATE,
868                                                      os->new_metadata_size);
869         if(!side_data)
870             return AVERROR(ENOMEM);
871
872         memcpy(side_data, os->new_metadata, os->new_metadata_size);
873         av_freep(&os->new_metadata);
874         os->new_metadata_size = 0;
875     }
876
877     return psize;
878 }
879
880 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
881                                   int64_t *pos_arg, int64_t pos_limit)
882 {
883     struct ogg *ogg = s->priv_data;
884     AVIOContext *bc = s->pb;
885     int64_t pts     = AV_NOPTS_VALUE;
886     int64_t keypos  = -1;
887     int i;
888     int pstart, psize;
889     avio_seek(bc, *pos_arg, SEEK_SET);
890     ogg_reset(s);
891
892     while (   avio_tell(bc) <= pos_limit
893            && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
894         if (i == stream_index) {
895             struct ogg_stream *os = ogg->streams + stream_index;
896             // Do not trust the last timestamps of an ogm video
897             if (    (os->flags & OGG_FLAG_EOS)
898                 && !(os->flags & OGG_FLAG_BOS)
899                 && os->codec == &ff_ogm_video_codec)
900                 continue;
901             pts = ogg_calc_pts(s, i, NULL);
902             ogg_validate_keyframe(s, i, pstart, psize);
903             if (os->pflags & AV_PKT_FLAG_KEY) {
904                 keypos = *pos_arg;
905             } else if (os->keyframe_seek) {
906                 // if we had a previous keyframe but no pts for it,
907                 // return that keyframe with this pts value.
908                 if (keypos >= 0)
909                     *pos_arg = keypos;
910                 else
911                     pts = AV_NOPTS_VALUE;
912             }
913         }
914         if (pts != AV_NOPTS_VALUE)
915             break;
916     }
917     ogg_reset(s);
918     return pts;
919 }
920
921 static int ogg_read_seek(AVFormatContext *s, int stream_index,
922                          int64_t timestamp, int flags)
923 {
924     struct ogg *ogg       = s->priv_data;
925     struct ogg_stream *os = ogg->streams + stream_index;
926     int ret;
927
928     av_assert0(stream_index < ogg->nstreams);
929     // Ensure everything is reset even when seeking via
930     // the generated index.
931     ogg_reset(s);
932
933     // Try seeking to a keyframe first. If this fails (very possible),
934     // av_seek_frame will fall back to ignoring keyframes
935     if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
936         && !(flags & AVSEEK_FLAG_ANY))
937         os->keyframe_seek = 1;
938
939     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
940     ogg_reset(s);
941     os  = ogg->streams + stream_index;
942     if (ret < 0)
943         os->keyframe_seek = 0;
944     return ret;
945 }
946
947 static int ogg_probe(const AVProbeData *p)
948 {
949     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
950         return AVPROBE_SCORE_MAX;
951     return 0;
952 }
953
954 AVInputFormat ff_ogg_demuxer = {
955     .name           = "ogg",
956     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
957     .priv_data_size = sizeof(struct ogg),
958     .read_probe     = ogg_probe,
959     .read_header    = ogg_read_header,
960     .read_packet    = ogg_read_packet,
961     .read_close     = ogg_read_close,
962     .read_seek      = ogg_read_seek,
963     .read_timestamp = ogg_read_timestamp,
964     .extensions     = "ogg",
965     .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
966 };