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