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