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