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