]> git.sesse.net Git - ffmpeg/blob - libavformat/oggdec.c
oggdec: remove the oggparsedaala subdemuxer
[ffmpeg] / libavformat / oggdec.c
1 /*
2  * Ogg bitstream support
3  * Luca Barbato <lu_zero@gentoo.org>
4  * Based on tcvp implementation
5  */
6
7 /*
8     Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
9
10     Permission is hereby granted, free of charge, to any person
11     obtaining a copy of this software and associated documentation
12     files (the "Software"), to deal in the Software without
13     restriction, including without limitation the rights to use, copy,
14     modify, merge, publish, distribute, sublicense, and/or sell copies
15     of the Software, and to permit persons to whom the Software is
16     furnished to do so, subject to the following conditions:
17
18     The above copyright notice and this permission notice shall be
19     included in all copies or substantial portions of the Software.
20
21     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28     DEALINGS IN THE SOFTWARE.
29  */
30
31 #include <stdio.h>
32 #include "libavutil/avassert.h"
33 #include "libavutil/intreadwrite.h"
34 #include "avio_internal.h"
35 #include "oggdec.h"
36 #include "avformat.h"
37 #include "internal.h"
38 #include "vorbiscomment.h"
39
40 #define MAX_PAGE_SIZE 65307
41 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
42
43 static const struct ogg_codec * const ogg_codecs[] = {
44     &ff_skeleton_codec,
45     &ff_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->start_trimming = 0;
181         os->end_trimming = 0;
182         av_freep(&os->new_metadata);
183         os->new_metadata_size = 0;
184     }
185
186     ogg->page_pos = -1;
187     ogg->curidx = -1;
188
189     return 0;
190 }
191
192 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
193 {
194     int i;
195
196     for (i = 0; ogg_codecs[i]; i++)
197         if (size >= ogg_codecs[i]->magicsize &&
198             !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
199             return ogg_codecs[i];
200
201     return NULL;
202 }
203
204 /**
205  * Replace the current stream with a new one. This is a typical webradio
206  * situation where a new audio stream spawn (identified with a new serial) and
207  * must replace the previous one (track switch).
208  */
209 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic,
210                               int probing)
211 {
212     struct ogg *ogg = s->priv_data;
213     struct ogg_stream *os;
214     const struct ogg_codec *codec;
215     int i = 0;
216
217     if (ogg->nstreams != 1) {
218         avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
219         return AVERROR_PATCHWELCOME;
220     }
221
222     /* Check for codecs */
223     codec = ogg_find_codec(magic, 8);
224     if (!codec && !probing) {
225         av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
226         return AVERROR_INVALIDDATA;
227     }
228
229     /* We only have a single stream anyway, so if there's a new stream with
230      * a different codec just replace it */
231     os = &ogg->streams[0];
232     os->serial  = serial;
233     os->codec   = codec;
234     os->serial  = serial;
235     os->lastpts = 0;
236     os->lastdts = 0;
237     os->start_trimming = 0;
238     os->end_trimming = 0;
239
240     /* Chained files have extradata as a new packet */
241     if (codec == &ff_opus_codec)
242         os->header = -1;
243
244     return i;
245 }
246
247 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
248 {
249     struct ogg *ogg = s->priv_data;
250     int idx         = ogg->nstreams;
251     AVStream *st;
252     struct ogg_stream *os;
253     size_t size;
254
255     if (ogg->state) {
256         av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
257                "in between Ogg context save/restore operations.\n");
258         return AVERROR_BUG;
259     }
260
261     /* Allocate and init a new Ogg Stream */
262     if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
263         !(os = av_realloc(ogg->streams, size)))
264         return AVERROR(ENOMEM);
265     ogg->streams = os;
266     os           = ogg->streams + idx;
267     memset(os, 0, sizeof(*os));
268     os->serial        = serial;
269     os->bufsize       = DECODER_BUFFER_SIZE;
270     os->buf           = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
271     os->header        = -1;
272     os->start_granule = OGG_NOGRANULE_VALUE;
273     if (!os->buf)
274         return AVERROR(ENOMEM);
275
276     /* Create the associated AVStream */
277     st = avformat_new_stream(s, NULL);
278     if (!st) {
279         av_freep(&os->buf);
280         return AVERROR(ENOMEM);
281     }
282     st->id = idx;
283     avpriv_set_pts_info(st, 64, 1, 1000000);
284
285     ogg->nstreams++;
286     return idx;
287 }
288
289 static int data_packets_seen(const struct ogg *ogg)
290 {
291     int i;
292
293     for (i = 0; i < ogg->nstreams; i++)
294         if (ogg->streams[i].got_data)
295             return 1;
296     return 0;
297 }
298
299 static int buf_realloc(struct ogg_stream *os, int size)
300 {
301     /* Even if invalid guarantee there's enough memory to read the page */
302     if (os->bufsize - os->bufpos < size) {
303         uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
304         if (!nb)
305             return AVERROR(ENOMEM);
306         os->buf = nb;
307         os->bufsize *= 2;
308     }
309
310     return 0;
311 }
312
313 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
314 {
315     AVIOContext *bc = s->pb;
316     struct ogg *ogg = s->priv_data;
317     struct ogg_stream *os;
318     int ret, i = 0;
319     int flags, nsegs;
320     uint64_t gp;
321     uint32_t serial;
322     uint32_t crc, crc_tmp;
323     int size = 0, idx;
324     int64_t version, page_pos;
325     int64_t start_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     /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
363     ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
364
365     /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
366     ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
367     start_pos = avio_tell(bc);
368
369     version = avio_r8(bc);
370     flags   = avio_r8(bc);
371     gp      = avio_rl64(bc);
372     serial  = avio_rl32(bc);
373     avio_skip(bc, 4); /* seq */
374
375     crc_tmp = ffio_get_checksum(bc);
376     crc     = avio_rb32(bc);
377     crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
378     ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
379
380     nsegs    = avio_r8(bc);
381     page_pos = avio_tell(bc) - 27;
382
383     ret = avio_read(bc, segments, nsegs);
384     if (ret < nsegs)
385         return ret < 0 ? ret : AVERROR_EOF;
386
387     for (i = 0; i < nsegs; i++)
388         size += segments[i];
389
390     idx = ogg_find_stream(ogg, serial);
391     if (idx >= 0) {
392         os = ogg->streams + idx;
393
394         ret = buf_realloc(os, size);
395         if (ret < 0)
396             return ret;
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 (crc ^ ffio_get_checksum(bc)) {
411         av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
412         if (idx < 0)
413             av_free(readout_buf);
414         avio_seek(bc, start_pos, SEEK_SET);
415         return 0;
416     }
417
418     /* Since we're almost sure its a valid packet, checking the version after
419      * the checksum lets the demuxer be more tolerant */
420     if (version) {
421         av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
422         if (idx < 0)
423             av_free(readout_buf);
424         avio_seek(bc, start_pos, SEEK_SET);
425         return 0;
426     }
427
428     /* CRC is correct so we can be 99% sure there's an actual change here */
429     if (idx < 0) {
430         if (data_packets_seen(ogg))
431             idx = ogg_replace_stream(s, serial, readout_buf, probing);
432         else
433             idx = ogg_new_stream(s, serial);
434
435         if (idx < 0) {
436             av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
437             av_free(readout_buf);
438             return idx;
439         }
440
441         os = ogg->streams + idx;
442
443         ret = buf_realloc(os, size);
444         if (ret < 0) {
445             av_free(readout_buf);
446             return ret;
447         }
448
449         memcpy(os->buf + os->bufpos, readout_buf, size);
450         av_free(readout_buf);
451     }
452
453     ogg->page_pos = page_pos;
454     os->page_pos  = page_pos;
455     os->nsegs     = nsegs;
456     os->segp      = 0;
457     os->got_data  = !(flags & OGG_FLAG_BOS);
458     os->bufpos   += size;
459     os->granule   = gp;
460     os->flags     = flags;
461     memcpy(os->segments, segments, nsegs);
462     memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
463
464     if (flags & OGG_FLAG_CONT || os->incomplete) {
465         if (!os->psize) {
466             // If this is the very first segment we started
467             // playback in the middle of a continuation packet.
468             // Discard it since we missed the start of it.
469             while (os->segp < os->nsegs) {
470                 int seg = os->segments[os->segp++];
471                 os->pstart += seg;
472                 if (seg < 255)
473                     break;
474             }
475             os->sync_pos = os->page_pos;
476         }
477     } else {
478         os->psize    = 0;
479         os->sync_pos = os->page_pos;
480     }
481
482     /* This function is always called with sid != NULL */
483     *sid = idx;
484
485     return 0;
486 }
487
488 /**
489  * @brief find the next Ogg packet
490  * @param *sid is set to the stream for the packet or -1 if there is
491  *             no matching stream, in that case assume all other return
492  *             values to be uninitialized.
493  * @return negative value on error or EOF.
494  */
495 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
496                       int64_t *fpos)
497 {
498     struct ogg *ogg = s->priv_data;
499     int idx, i, ret;
500     struct ogg_stream *os;
501     int complete = 0;
502     int segp     = 0, psize = 0;
503
504     av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
505     if (sid)
506         *sid = -1;
507
508     do {
509         idx = ogg->curidx;
510
511         while (idx < 0) {
512             ret = ogg_read_page(s, &idx, 0);
513             if (ret < 0)
514                 return ret;
515         }
516
517         os = ogg->streams + idx;
518
519         av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
520                 idx, os->pstart, os->psize, os->segp, os->nsegs);
521
522         if (!os->codec) {
523             if (os->header < 0) {
524                 os->codec = ogg_find_codec(os->buf, os->bufpos);
525                 if (!os->codec) {
526                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
527                     os->header = 0;
528                     return 0;
529                 }
530             } else {
531                 return 0;
532             }
533         }
534
535         segp  = os->segp;
536         psize = os->psize;
537
538         while (os->segp < os->nsegs) {
539             int ss = os->segments[os->segp++];
540             os->psize += ss;
541             if (ss < 255) {
542                 complete = 1;
543                 break;
544             }
545         }
546
547         if (!complete && os->segp == os->nsegs) {
548             ogg->curidx    = -1;
549             // Do not set incomplete for empty packets.
550             // Together with the code in ogg_read_page
551             // that discards all continuation of empty packets
552             // we would get an infinite loop.
553             os->incomplete = !!os->psize;
554         }
555     } while (!complete);
556
557
558     if (os->granule == -1)
559         av_log(s, AV_LOG_WARNING,
560                "Page at %"PRId64" is missing granule\n",
561                os->page_pos);
562
563     ogg->curidx    = idx;
564     os->incomplete = 0;
565
566     if (os->header) {
567         if ((ret = os->codec->header(s, idx)) < 0) {
568             av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
569             return ret;
570         }
571         os->header = ret;
572         if (!os->header) {
573             os->segp  = segp;
574             os->psize = psize;
575
576             // We have reached the first non-header packet in this stream.
577             // Unfortunately more header packets may still follow for others,
578             // but if we continue with header parsing we may lose data packets.
579             ogg->headers = 1;
580
581             // Update the header state for all streams and
582             // compute the data_offset.
583             if (!s->internal->data_offset)
584                 s->internal->data_offset = os->sync_pos;
585
586             for (i = 0; i < ogg->nstreams; i++) {
587                 struct ogg_stream *cur_os = ogg->streams + i;
588
589                 // if we have a partial non-header packet, its start is
590                 // obviously at or after the data start
591                 if (cur_os->incomplete)
592                     s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
593             }
594         } else {
595             os->nb_header++;
596             os->pstart += os->psize;
597             os->psize   = 0;
598         }
599     } else {
600         os->pflags    = 0;
601         os->pduration = 0;
602         if (os->codec && os->codec->packet) {
603             if ((ret = os->codec->packet(s, idx)) < 0) {
604                 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
605                 return ret;
606             }
607         }
608         if (sid)
609             *sid = idx;
610         if (dstart)
611             *dstart = os->pstart;
612         if (dsize)
613             *dsize = os->psize;
614         if (fpos)
615             *fpos = os->sync_pos;
616         os->pstart  += os->psize;
617         os->psize    = 0;
618         if(os->pstart == os->bufpos)
619             os->bufpos = os->pstart = 0;
620         os->sync_pos = os->page_pos;
621     }
622
623     // determine whether there are more complete packets in this page
624     // if not, the page's granule will apply to this packet
625     os->page_end = 1;
626     for (i = os->segp; i < os->nsegs; i++)
627         if (os->segments[i] < 255) {
628             os->page_end = 0;
629             break;
630         }
631
632     if (os->segp == os->nsegs)
633         ogg->curidx = -1;
634
635     return 0;
636 }
637
638 static int ogg_get_length(AVFormatContext *s)
639 {
640     struct ogg *ogg = s->priv_data;
641     int i, ret;
642     int64_t size, end;
643     int streams_left=0;
644
645     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
646         return 0;
647
648 // already set
649     if (s->duration != AV_NOPTS_VALUE)
650         return 0;
651
652     size = avio_size(s->pb);
653     if (size < 0)
654         return 0;
655     end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
656
657     ret = ogg_save(s);
658     if (ret < 0)
659         return ret;
660     avio_seek(s->pb, end, SEEK_SET);
661     ogg->page_pos = -1;
662
663     while (!ogg_read_page(s, &i, 1)) {
664         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
665             ogg->streams[i].codec) {
666             s->streams[i]->duration =
667                 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
668             if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
669                 s->streams[i]->duration -= s->streams[i]->start_time;
670                 streams_left-= (ogg->streams[i].got_start==-1);
671                 ogg->streams[i].got_start= 1;
672             } else if(!ogg->streams[i].got_start) {
673                 ogg->streams[i].got_start= -1;
674                 streams_left++;
675             }
676         }
677     }
678
679     ogg_restore(s);
680
681     ret = ogg_save(s);
682     if (ret < 0)
683         return ret;
684
685     avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
686     ogg_reset(s);
687     while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
688         int64_t pts;
689         if (i < 0) continue;
690         pts = ogg_calc_pts(s, i, NULL);
691         if (s->streams[i]->duration == AV_NOPTS_VALUE)
692             continue;
693         if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
694             s->streams[i]->duration -= pts;
695             ogg->streams[i].got_start= 1;
696             streams_left--;
697         }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
698             ogg->streams[i].got_start= 1;
699             streams_left--;
700         }
701     }
702     ogg_restore (s);
703
704     return 0;
705 }
706
707 static int ogg_read_close(AVFormatContext *s)
708 {
709     struct ogg *ogg = s->priv_data;
710     int i;
711
712     for (i = 0; i < ogg->nstreams; i++) {
713         free_stream(s, i);
714     }
715
716     ogg->nstreams = 0;
717
718     av_freep(&ogg->streams);
719     return 0;
720 }
721
722 static int ogg_read_header(AVFormatContext *s)
723 {
724     struct ogg *ogg = s->priv_data;
725     int ret, i;
726
727     ogg->curidx = -1;
728
729     //linear headers seek from start
730     do {
731         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
732         if (ret < 0) {
733             ogg_read_close(s);
734             return ret;
735         }
736     } while (!ogg->headers);
737     av_log(s, AV_LOG_TRACE, "found headers\n");
738
739     for (i = 0; i < ogg->nstreams; i++) {
740         struct ogg_stream *os = ogg->streams + i;
741
742         if (ogg->streams[i].header < 0) {
743             av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
744             ogg->streams[i].codec = NULL;
745             av_freep(&ogg->streams[i].private);
746         } else if (os->codec && os->nb_header < os->codec->nb_header) {
747             av_log(s, AV_LOG_WARNING,
748                    "Headers mismatch for stream %d: "
749                    "expected %d received %d.\n",
750                    i, os->codec->nb_header, os->nb_header);
751             if (s->error_recognition & AV_EF_EXPLODE) {
752                 ogg_read_close(s);
753                 return AVERROR_INVALIDDATA;
754             }
755         }
756         if (os->start_granule != OGG_NOGRANULE_VALUE)
757             os->lastpts = s->streams[i]->start_time =
758                 ogg_gptopts(s, i, os->start_granule, NULL);
759     }
760
761     //linear granulepos seek from end
762     ret = ogg_get_length(s);
763     if (ret < 0) {
764         ogg_read_close(s);
765         return ret;
766     }
767
768     return 0;
769 }
770
771 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
772 {
773     struct ogg *ogg       = s->priv_data;
774     struct ogg_stream *os = ogg->streams + idx;
775     int64_t pts           = AV_NOPTS_VALUE;
776
777     if (dts)
778         *dts = AV_NOPTS_VALUE;
779
780     if (os->lastpts != AV_NOPTS_VALUE) {
781         pts         = os->lastpts;
782         os->lastpts = AV_NOPTS_VALUE;
783     }
784     if (os->lastdts != AV_NOPTS_VALUE) {
785         if (dts)
786             *dts = os->lastdts;
787         os->lastdts = AV_NOPTS_VALUE;
788     }
789     if (os->page_end) {
790         if (os->granule != -1LL) {
791             if (os->codec && os->codec->granule_is_start)
792                 pts = ogg_gptopts(s, idx, os->granule, dts);
793             else
794                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
795             os->granule = -1LL;
796         }
797     }
798     return pts;
799 }
800
801 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
802 {
803     struct ogg *ogg = s->priv_data;
804     struct ogg_stream *os = ogg->streams + idx;
805     int invalid = 0;
806     if (psize) {
807         switch (s->streams[idx]->codecpar->codec_id) {
808         case AV_CODEC_ID_THEORA:
809             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
810         break;
811         case AV_CODEC_ID_VP8:
812             invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
813         }
814         if (invalid) {
815             os->pflags ^= AV_PKT_FLAG_KEY;
816             av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
817                    (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
818         }
819     }
820 }
821
822 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
823 {
824     struct ogg *ogg;
825     struct ogg_stream *os;
826     int idx, ret;
827     int pstart, psize;
828     int64_t fpos, pts, dts;
829
830     if (s->io_repositioned) {
831         ogg_reset(s);
832         s->io_repositioned = 0;
833     }
834
835     //Get an ogg packet
836 retry:
837     do {
838         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
839         if (ret < 0)
840             return ret;
841     } while (idx < 0 || !s->streams[idx]);
842
843     ogg = s->priv_data;
844     os  = ogg->streams + idx;
845
846     // pflags might not be set until after this
847     pts = ogg_calc_pts(s, idx, &dts);
848     ogg_validate_keyframe(s, idx, pstart, psize);
849
850     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
851         goto retry;
852     os->keyframe_seek = 0;
853
854     //Alloc a pkt
855     ret = av_new_packet(pkt, psize);
856     if (ret < 0)
857         return ret;
858     pkt->stream_index = idx;
859     memcpy(pkt->data, os->buf + pstart, psize);
860
861     pkt->pts      = pts;
862     pkt->dts      = dts;
863     pkt->flags    = os->pflags;
864     pkt->duration = os->pduration;
865     pkt->pos      = fpos;
866
867     if (os->start_trimming || os->end_trimming) {
868         uint8_t *side_data = av_packet_new_side_data(pkt,
869                                                      AV_PKT_DATA_SKIP_SAMPLES,
870                                                      10);
871         if(!side_data)
872             return AVERROR(ENOMEM);
873          AV_WL32(side_data + 0, os->start_trimming);
874         AV_WL32(side_data + 4, os->end_trimming);
875         os->start_trimming = 0;
876         os->end_trimming = 0;
877     }
878
879     if (os->new_metadata) {
880         uint8_t *side_data = av_packet_new_side_data(pkt,
881                                                      AV_PKT_DATA_METADATA_UPDATE,
882                                                      os->new_metadata_size);
883         if(!side_data)
884             return AVERROR(ENOMEM);
885
886         memcpy(side_data, os->new_metadata, os->new_metadata_size);
887         av_freep(&os->new_metadata);
888         os->new_metadata_size = 0;
889     }
890
891     return psize;
892 }
893
894 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
895                                   int64_t *pos_arg, int64_t pos_limit)
896 {
897     struct ogg *ogg = s->priv_data;
898     AVIOContext *bc = s->pb;
899     int64_t pts     = AV_NOPTS_VALUE;
900     int64_t keypos  = -1;
901     int i;
902     int pstart, psize;
903     avio_seek(bc, *pos_arg, SEEK_SET);
904     ogg_reset(s);
905
906     while (   avio_tell(bc) <= pos_limit
907            && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
908         if (i == stream_index) {
909             struct ogg_stream *os = ogg->streams + stream_index;
910             // Do not trust the last timestamps of an ogm video
911             if (    (os->flags & OGG_FLAG_EOS)
912                 && !(os->flags & OGG_FLAG_BOS)
913                 && os->codec == &ff_ogm_video_codec)
914                 continue;
915             pts = ogg_calc_pts(s, i, NULL);
916             ogg_validate_keyframe(s, i, pstart, psize);
917             if (os->pflags & AV_PKT_FLAG_KEY) {
918                 keypos = *pos_arg;
919             } else if (os->keyframe_seek) {
920                 // if we had a previous keyframe but no pts for it,
921                 // return that keyframe with this pts value.
922                 if (keypos >= 0)
923                     *pos_arg = keypos;
924                 else
925                     pts = AV_NOPTS_VALUE;
926             }
927         }
928         if (pts != AV_NOPTS_VALUE)
929             break;
930     }
931     ogg_reset(s);
932     return pts;
933 }
934
935 static int ogg_read_seek(AVFormatContext *s, int stream_index,
936                          int64_t timestamp, int flags)
937 {
938     struct ogg *ogg       = s->priv_data;
939     struct ogg_stream *os = ogg->streams + stream_index;
940     int ret;
941
942     av_assert0(stream_index < ogg->nstreams);
943     // Ensure everything is reset even when seeking via
944     // the generated index.
945     ogg_reset(s);
946
947     // Try seeking to a keyframe first. If this fails (very possible),
948     // av_seek_frame will fall back to ignoring keyframes
949     if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
950         && !(flags & AVSEEK_FLAG_ANY))
951         os->keyframe_seek = 1;
952
953     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
954     ogg_reset(s);
955     os  = ogg->streams + stream_index;
956     if (ret < 0)
957         os->keyframe_seek = 0;
958     return ret;
959 }
960
961 static int ogg_probe(const AVProbeData *p)
962 {
963     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
964         return AVPROBE_SCORE_MAX;
965     return 0;
966 }
967
968 AVInputFormat ff_ogg_demuxer = {
969     .name           = "ogg",
970     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
971     .priv_data_size = sizeof(struct ogg),
972     .read_probe     = ogg_probe,
973     .read_header    = ogg_read_header,
974     .read_packet    = ogg_read_packet,
975     .read_close     = ogg_read_close,
976     .read_seek      = ogg_read_seek,
977     .read_timestamp = ogg_read_timestamp,
978     .extensions     = "ogg",
979     .flags          = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
980 };