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