FFmpeg  2.8.15
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
oggdec.c
Go to the documentation of this file.
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[] = {
51  &ff_vp8_codec,
58  NULL
59 };
60 
61 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
62 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
63 static int ogg_restore(AVFormatContext *s, int discard);
64 
65 //FIXME We could avoid some structure duplication
67 {
68  struct ogg *ogg = s->priv_data;
69  struct ogg_state *ost =
70  av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
71  int i;
72  int ret = 0;
73 
74  if (!ost)
75  return AVERROR(ENOMEM);
76 
77  ost->pos = avio_tell(s->pb);
78  ost->curidx = ogg->curidx;
79  ost->next = ogg->state;
80  ost->nstreams = ogg->nstreams;
81  memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
82 
83  for (i = 0; i < ogg->nstreams; i++) {
84  struct ogg_stream *os = ogg->streams + i;
86  if (os->buf)
87  memcpy(os->buf, ost->streams[i].buf, os->bufpos);
88  else
89  ret = AVERROR(ENOMEM);
90  os->new_metadata = NULL;
91  os->new_metadata_size = 0;
92  }
93 
94  ogg->state = ost;
95 
96  if (ret < 0)
97  ogg_restore(s, 0);
98 
99  return ret;
100 }
101 
102 static int ogg_restore(AVFormatContext *s, int discard)
103 {
104  struct ogg *ogg = s->priv_data;
105  AVIOContext *bc = s->pb;
106  struct ogg_state *ost = ogg->state;
107  int i, err;
108 
109  if (!ost)
110  return 0;
111 
112  ogg->state = ost->next;
113 
114  if (!discard) {
115 
116  for (i = 0; i < ogg->nstreams; i++)
117  av_freep(&ogg->streams[i].buf);
118 
119  avio_seek(bc, ost->pos, SEEK_SET);
120  ogg->page_pos = -1;
121  ogg->curidx = ost->curidx;
122  ogg->nstreams = ost->nstreams;
123  if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
124  sizeof(*ogg->streams))) < 0) {
125  ogg->nstreams = 0;
126  return err;
127  } else
128  memcpy(ogg->streams, ost->streams,
129  ost->nstreams * sizeof(*ogg->streams));
130  }
131 
132  av_free(ost);
133 
134  return 0;
135 }
136 
138 {
139  struct ogg *ogg = s->priv_data;
140  int i;
141  int64_t start_pos = avio_tell(s->pb);
142 
143  for (i = 0; i < ogg->nstreams; i++) {
144  struct ogg_stream *os = ogg->streams + i;
145  os->bufpos = 0;
146  os->pstart = 0;
147  os->psize = 0;
148  os->granule = -1;
149  os->lastpts = AV_NOPTS_VALUE;
150  os->lastdts = AV_NOPTS_VALUE;
151  os->sync_pos = -1;
152  os->page_pos = 0;
153  os->nsegs = 0;
154  os->segp = 0;
155  os->incomplete = 0;
156  os->got_data = 0;
157  if (start_pos <= s->internal->data_offset) {
158  os->lastpts = 0;
159  }
160  os->end_trimming = 0;
161  av_freep(&os->new_metadata);
162  os->new_metadata_size = 0;
163  }
164 
165  ogg->page_pos = -1;
166  ogg->curidx = -1;
167 
168  return 0;
169 }
170 
171 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
172 {
173  int i;
174 
175  for (i = 0; ogg_codecs[i]; i++)
176  if (size >= ogg_codecs[i]->magicsize &&
177  !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
178  return ogg_codecs[i];
179 
180  return NULL;
181 }
182 
183 /**
184  * Replace the current stream with a new one. This is a typical webradio
185  * situation where a new audio stream spawn (identified with a new serial) and
186  * must replace the previous one (track switch).
187  */
188 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
189 {
190  struct ogg *ogg = s->priv_data;
191  struct ogg_stream *os;
192  const struct ogg_codec *codec;
193  int i = 0;
194 
195  if (s->pb->seekable) {
196  uint8_t magic[8];
197  int64_t pos = avio_tell(s->pb);
198  avio_skip(s->pb, nsegs);
199  avio_read(s->pb, magic, sizeof(magic));
200  avio_seek(s->pb, pos, SEEK_SET);
201  codec = ogg_find_codec(magic, sizeof(magic));
202  if (!codec) {
203  av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
204  return AVERROR_INVALIDDATA;
205  }
206  for (i = 0; i < ogg->nstreams; i++) {
207  if (ogg->streams[i].codec == codec)
208  break;
209  }
210  if (i >= ogg->nstreams)
211  return ogg_new_stream(s, serial);
212  } else if (ogg->nstreams != 1) {
213  avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
214  return AVERROR_PATCHWELCOME;
215  }
216 
217  os = &ogg->streams[i];
218 
219  os->serial = serial;
220  return i;
221 
222 #if 0
223  buf = os->buf;
224  bufsize = os->bufsize;
225  codec = os->codec;
226 
227  if (!ogg->state || ogg->state->streams[i].private != os->private)
228  av_freep(&ogg->streams[i].private);
229 
230  /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
231  * also re-use the ogg_stream allocated buffer */
232  memset(os, 0, sizeof(*os));
233  os->serial = serial;
234  os->bufsize = bufsize;
235  os->buf = buf;
236  os->header = -1;
237  os->codec = codec;
238 
239  return i;
240 #endif
241 }
242 
243 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
244 {
245  struct ogg *ogg = s->priv_data;
246  int idx = ogg->nstreams;
247  AVStream *st;
248  struct ogg_stream *os;
249  size_t size;
250 
251  if (ogg->state) {
252  av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
253  "in between Ogg context save/restore operations.\n");
254  return AVERROR_BUG;
255  }
256 
257  /* Allocate and init a new Ogg Stream */
258  if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
259  !(os = av_realloc(ogg->streams, size)))
260  return AVERROR(ENOMEM);
261  ogg->streams = os;
262  os = ogg->streams + idx;
263  memset(os, 0, sizeof(*os));
264  os->serial = serial;
267  os->header = -1;
269  if (!os->buf)
270  return AVERROR(ENOMEM);
271 
272  /* Create the associated AVStream */
273  st = avformat_new_stream(s, NULL);
274  if (!st) {
275  av_freep(&os->buf);
276  return AVERROR(ENOMEM);
277  }
278  st->id = idx;
279  avpriv_set_pts_info(st, 64, 1, 1000000);
280 
281  ogg->nstreams++;
282  return idx;
283 }
284 
285 static int ogg_new_buf(struct ogg *ogg, int idx)
286 {
287  struct ogg_stream *os = ogg->streams + idx;
289  int size = os->bufpos - os->pstart;
290 
291  if (!nb)
292  return AVERROR(ENOMEM);
293 
294  if (os->buf) {
295  memcpy(nb, os->buf + os->pstart, size);
296  av_free(os->buf);
297  }
298 
299  os->buf = nb;
300  os->bufpos = size;
301  os->pstart = 0;
302 
303  return 0;
304 }
305 
306 static int data_packets_seen(const struct ogg *ogg)
307 {
308  int i;
309 
310  for (i = 0; i < ogg->nstreams; i++)
311  if (ogg->streams[i].got_data)
312  return 1;
313  return 0;
314 }
315 
316 static int ogg_read_page(AVFormatContext *s, int *sid)
317 {
318  AVIOContext *bc = s->pb;
319  struct ogg *ogg = s->priv_data;
320  struct ogg_stream *os;
321  int ret, i = 0;
322  int flags, nsegs;
323  uint64_t gp;
324  uint32_t serial;
325  int size, idx;
326  uint8_t sync[4];
327  int sp = 0;
328 
329  ret = avio_read(bc, sync, 4);
330  if (ret < 4)
331  return ret < 0 ? ret : AVERROR_EOF;
332 
333  do {
334  int c;
335 
336  if (sync[sp & 3] == 'O' &&
337  sync[(sp + 1) & 3] == 'g' &&
338  sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
339  break;
340 
341  if(!i && bc->seekable && ogg->page_pos > 0) {
342  memset(sync, 0, 4);
343  avio_seek(bc, ogg->page_pos+4, SEEK_SET);
344  ogg->page_pos = -1;
345  }
346 
347  c = avio_r8(bc);
348 
349  if (avio_feof(bc))
350  return AVERROR_EOF;
351 
352  sync[sp++ & 3] = c;
353  } while (i++ < MAX_PAGE_SIZE);
354 
355  if (i >= MAX_PAGE_SIZE) {
356  av_log(s, AV_LOG_INFO, "cannot find sync word\n");
357  return AVERROR_INVALIDDATA;
358  }
359 
360  if (avio_r8(bc) != 0) { /* version */
361  av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
362  return AVERROR_INVALIDDATA;
363  }
364 
365  flags = avio_r8(bc);
366  gp = avio_rl64(bc);
367  serial = avio_rl32(bc);
368  avio_skip(bc, 8); /* seq, crc */
369  nsegs = avio_r8(bc);
370 
371  idx = ogg_find_stream(ogg, serial);
372  if (idx < 0) {
373  if (data_packets_seen(ogg))
374  idx = ogg_replace_stream(s, serial, nsegs);
375  else
376  idx = ogg_new_stream(s, serial);
377 
378  if (idx < 0) {
379  av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
380  return idx;
381  }
382  }
383 
384  os = ogg->streams + idx;
385  ogg->page_pos =
386  os->page_pos = avio_tell(bc) - 27;
387 
388  if (os->psize > 0) {
389  ret = ogg_new_buf(ogg, idx);
390  if (ret < 0)
391  return ret;
392  }
393 
394  ret = avio_read(bc, os->segments, nsegs);
395  if (ret < nsegs)
396  return ret < 0 ? ret : AVERROR_EOF;
397 
398  os->nsegs = nsegs;
399  os->segp = 0;
400 
401  size = 0;
402  for (i = 0; i < nsegs; i++)
403  size += os->segments[i];
404 
405  if (!(flags & OGG_FLAG_BOS))
406  os->got_data = 1;
407 
408  if (flags & OGG_FLAG_CONT || os->incomplete) {
409  if (!os->psize) {
410  // If this is the very first segment we started
411  // playback in the middle of a continuation packet.
412  // Discard it since we missed the start of it.
413  while (os->segp < os->nsegs) {
414  int seg = os->segments[os->segp++];
415  os->pstart += seg;
416  if (seg < 255)
417  break;
418  }
419  os->sync_pos = os->page_pos;
420  }
421  } else {
422  os->psize = 0;
423  os->sync_pos = os->page_pos;
424  }
425 
426  if (os->bufsize - os->bufpos < size) {
428  if (!nb)
429  return AVERROR(ENOMEM);
430  memcpy(nb, os->buf, os->bufpos);
431  av_free(os->buf);
432  os->buf = nb;
433  }
434 
435  ret = avio_read(bc, os->buf + os->bufpos, size);
436  if (ret < size)
437  return ret < 0 ? ret : AVERROR_EOF;
438 
439  os->bufpos += size;
440  os->granule = gp;
441  os->flags = flags;
442 
443  memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
444  if (sid)
445  *sid = idx;
446 
447  return 0;
448 }
449 
450 /**
451  * @brief find the next Ogg packet
452  * @param *sid is set to the stream for the packet or -1 if there is
453  * no matching stream, in that case assume all other return
454  * values to be uninitialized.
455  * @return negative value on error or EOF.
456  */
457 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
458  int64_t *fpos)
459 {
460  struct ogg *ogg = s->priv_data;
461  int idx, i, ret;
462  struct ogg_stream *os;
463  int complete = 0;
464  int segp = 0, psize = 0;
465 
466  av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
467  if (sid)
468  *sid = -1;
469 
470  do {
471  idx = ogg->curidx;
472 
473  while (idx < 0) {
474  ret = ogg_read_page(s, &idx);
475  if (ret < 0)
476  return ret;
477  }
478 
479  os = ogg->streams + idx;
480 
481  av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
482  idx, os->pstart, os->psize, os->segp, os->nsegs);
483 
484  if (!os->codec) {
485  if (os->header < 0) {
486  os->codec = ogg_find_codec(os->buf, os->bufpos);
487  if (!os->codec) {
488  av_log(s, AV_LOG_WARNING, "Codec not found\n");
489  os->header = 0;
490  return 0;
491  }
492  } else {
493  return 0;
494  }
495  }
496 
497  segp = os->segp;
498  psize = os->psize;
499 
500  while (os->segp < os->nsegs) {
501  int ss = os->segments[os->segp++];
502  os->psize += ss;
503  if (ss < 255) {
504  complete = 1;
505  break;
506  }
507  }
508 
509  if (!complete && os->segp == os->nsegs) {
510  ogg->curidx = -1;
511  // Do not set incomplete for empty packets.
512  // Together with the code in ogg_read_page
513  // that discards all continuation of empty packets
514  // we would get an infinite loop.
515  os->incomplete = !!os->psize;
516  }
517  } while (!complete);
518 
519 
520  if (os->granule == -1)
522  "Page at %"PRId64" is missing granule\n",
523  os->page_pos);
524 
525  ogg->curidx = idx;
526  os->incomplete = 0;
527 
528  if (os->header) {
529  os->header = os->codec->header(s, idx);
530  if (!os->header) {
531  os->segp = segp;
532  os->psize = psize;
533 
534  // We have reached the first non-header packet in this stream.
535  // Unfortunately more header packets may still follow for others,
536  // but if we continue with header parsing we may lose data packets.
537  ogg->headers = 1;
538 
539  // Update the header state for all streams and
540  // compute the data_offset.
541  if (!s->internal->data_offset)
542  s->internal->data_offset = os->sync_pos;
543 
544  for (i = 0; i < ogg->nstreams; i++) {
545  struct ogg_stream *cur_os = ogg->streams + i;
546 
547  // if we have a partial non-header packet, its start is
548  // obviously at or after the data start
549  if (cur_os->incomplete)
551  }
552  } else {
553  os->nb_header++;
554  os->pstart += os->psize;
555  os->psize = 0;
556  }
557  } else {
558  os->pflags = 0;
559  os->pduration = 0;
560  if (os->codec && os->codec->packet)
561  os->codec->packet(s, idx);
562  if (sid)
563  *sid = idx;
564  if (dstart)
565  *dstart = os->pstart;
566  if (dsize)
567  *dsize = os->psize;
568  if (fpos)
569  *fpos = os->sync_pos;
570  os->pstart += os->psize;
571  os->psize = 0;
572  if(os->pstart == os->bufpos)
573  os->bufpos = os->pstart = 0;
574  os->sync_pos = os->page_pos;
575  }
576 
577  // determine whether there are more complete packets in this page
578  // if not, the page's granule will apply to this packet
579  os->page_end = 1;
580  for (i = os->segp; i < os->nsegs; i++)
581  if (os->segments[i] < 255) {
582  os->page_end = 0;
583  break;
584  }
585 
586  if (os->segp == os->nsegs)
587  ogg->curidx = -1;
588 
589  return 0;
590 }
591 
593 {
594  struct ogg *ogg = s->priv_data;
595  int i, ret;
596  int64_t size, end;
597  int streams_left=0;
598 
599  if (!s->pb->seekable)
600  return 0;
601 
602 // already set
603  if (s->duration != AV_NOPTS_VALUE)
604  return 0;
605 
606  size = avio_size(s->pb);
607  if (size < 0)
608  return 0;
609  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
610 
611  ret = ogg_save(s);
612  if (ret < 0)
613  return ret;
614  avio_seek(s->pb, end, SEEK_SET);
615  ogg->page_pos = -1;
616 
617  while (!ogg_read_page(s, &i)) {
618  if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
619  ogg->streams[i].codec) {
620  s->streams[i]->duration =
621  ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
622  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
623  s->streams[i]->duration -= s->streams[i]->start_time;
624  streams_left-= (ogg->streams[i].got_start==-1);
625  ogg->streams[i].got_start= 1;
626  } else if(!ogg->streams[i].got_start) {
627  ogg->streams[i].got_start= -1;
628  streams_left++;
629  }
630  }
631  }
632 
633  ogg_restore(s, 0);
634 
635  ret = ogg_save(s);
636  if (ret < 0)
637  return ret;
638 
639  avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
640  ogg_reset(s);
641  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
642  int64_t pts;
643  if (i < 0) continue;
644  pts = ogg_calc_pts(s, i, NULL);
645  if (s->streams[i]->duration == AV_NOPTS_VALUE)
646  continue;
647  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
648  s->streams[i]->duration -= pts;
649  ogg->streams[i].got_start= 1;
650  streams_left--;
651  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
652  ogg->streams[i].got_start= 1;
653  streams_left--;
654  }
655  }
656  ogg_restore (s, 0);
657 
658  return 0;
659 }
660 
662 {
663  struct ogg *ogg = s->priv_data;
664  int i;
665 
666  for (i = 0; i < ogg->nstreams; i++) {
667  av_freep(&ogg->streams[i].buf);
668  if (ogg->streams[i].codec &&
669  ogg->streams[i].codec->cleanup) {
670  ogg->streams[i].codec->cleanup(s, i);
671  }
672  av_freep(&ogg->streams[i].private);
673  av_freep(&ogg->streams[i].new_metadata);
674  }
675 
676  ogg->nstreams = 0;
677 
678  av_freep(&ogg->streams);
679  return 0;
680 }
681 
683 {
684  struct ogg *ogg = s->priv_data;
685  int ret, i;
686 
687  ogg->curidx = -1;
688 
689  //linear headers seek from start
690  do {
691  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
692  if (ret < 0) {
693  ogg_read_close(s);
694  return ret;
695  }
696  } while (!ogg->headers);
697  av_log(s, AV_LOG_TRACE, "found headers\n");
698 
699  for (i = 0; i < ogg->nstreams; i++) {
700  struct ogg_stream *os = ogg->streams + i;
701 
702  if (ogg->streams[i].header < 0) {
703  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
704  ogg->streams[i].codec = NULL;
705  av_freep(&ogg->streams[i].private);
706  } else if (os->codec && os->nb_header < os->codec->nb_header) {
708  "Headers mismatch for stream %d: "
709  "expected %d received %d.\n",
710  i, os->codec->nb_header, os->nb_header);
711  if (s->error_recognition & AV_EF_EXPLODE) {
712  ogg_read_close(s);
713  return AVERROR_INVALIDDATA;
714  }
715  }
717  os->lastpts = s->streams[i]->start_time =
718  ogg_gptopts(s, i, os->start_granule, NULL);
719  }
720 
721  //linear granulepos seek from end
722  ret = ogg_get_length(s);
723  if (ret < 0) {
724  ogg_read_close(s);
725  return ret;
726  }
727 
728  return 0;
729 }
730 
731 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
732 {
733  struct ogg *ogg = s->priv_data;
734  struct ogg_stream *os = ogg->streams + idx;
735  int64_t pts = AV_NOPTS_VALUE;
736 
737  if (dts)
738  *dts = AV_NOPTS_VALUE;
739 
740  if (os->lastpts != AV_NOPTS_VALUE) {
741  pts = os->lastpts;
742  os->lastpts = AV_NOPTS_VALUE;
743  }
744  if (os->lastdts != AV_NOPTS_VALUE) {
745  if (dts)
746  *dts = os->lastdts;
747  os->lastdts = AV_NOPTS_VALUE;
748  }
749  if (os->page_end) {
750  if (os->granule != -1LL) {
751  if (os->codec && os->codec->granule_is_start)
752  pts = ogg_gptopts(s, idx, os->granule, dts);
753  else
754  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
755  os->granule = -1LL;
756  }
757  }
758  return pts;
759 }
760 
761 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
762 {
763  struct ogg *ogg = s->priv_data;
764  struct ogg_stream *os = ogg->streams + idx;
765  int invalid = 0;
766  if (psize) {
767  switch (s->streams[idx]->codec->codec_id) {
768  case AV_CODEC_ID_THEORA:
769  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
770  break;
771  case AV_CODEC_ID_VP8:
772  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
773  }
774  if (invalid) {
775  os->pflags ^= AV_PKT_FLAG_KEY;
776  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
777  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
778  }
779  }
780 }
781 
783 {
784  struct ogg *ogg;
785  struct ogg_stream *os;
786  int idx, ret;
787  int pstart, psize;
788  int64_t fpos, pts, dts;
789 
790  if (s->io_repositioned) {
791  ogg_reset(s);
792  s->io_repositioned = 0;
793  }
794 
795  //Get an ogg packet
796 retry:
797  do {
798  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
799  if (ret < 0)
800  return ret;
801  } while (idx < 0 || !s->streams[idx]);
802 
803  ogg = s->priv_data;
804  os = ogg->streams + idx;
805 
806  // pflags might not be set until after this
807  pts = ogg_calc_pts(s, idx, &dts);
808  ogg_validate_keyframe(s, idx, pstart, psize);
809 
810  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
811  goto retry;
812  os->keyframe_seek = 0;
813 
814  //Alloc a pkt
815  ret = av_new_packet(pkt, psize);
816  if (ret < 0)
817  return ret;
818  pkt->stream_index = idx;
819  memcpy(pkt->data, os->buf + pstart, psize);
820 
821  pkt->pts = pts;
822  pkt->dts = dts;
823  pkt->flags = os->pflags;
824  pkt->duration = os->pduration;
825  pkt->pos = fpos;
826 
827  if (os->end_trimming) {
828  uint8_t *side_data = av_packet_new_side_data(pkt,
830  10);
831  if(!side_data)
832  goto fail;
833  AV_WL32(side_data + 4, os->end_trimming);
834  os->end_trimming = 0;
835  }
836 
837  if (os->new_metadata) {
838  uint8_t *side_data = av_packet_new_side_data(pkt,
840  os->new_metadata_size);
841  if(!side_data)
842  goto fail;
843 
844  memcpy(side_data, os->new_metadata, os->new_metadata_size);
845  av_freep(&os->new_metadata);
846  os->new_metadata_size = 0;
847  }
848 
849  return psize;
850 fail:
851  av_free_packet(pkt);
852  return AVERROR(ENOMEM);
853 }
854 
855 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
856  int64_t *pos_arg, int64_t pos_limit)
857 {
858  struct ogg *ogg = s->priv_data;
859  AVIOContext *bc = s->pb;
860  int64_t pts = AV_NOPTS_VALUE;
861  int64_t keypos = -1;
862  int i;
863  int pstart, psize;
864  avio_seek(bc, *pos_arg, SEEK_SET);
865  ogg_reset(s);
866 
867  while ( avio_tell(bc) <= pos_limit
868  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
869  if (i == stream_index) {
870  struct ogg_stream *os = ogg->streams + stream_index;
871  // Do not trust the last timestamps of a ogm video
872  if ( (os->flags & OGG_FLAG_EOS)
873  && !(os->flags & OGG_FLAG_BOS)
874  && os->codec == &ff_ogm_video_codec)
875  continue;
876  pts = ogg_calc_pts(s, i, NULL);
877  ogg_validate_keyframe(s, i, pstart, psize);
878  if (os->pflags & AV_PKT_FLAG_KEY) {
879  keypos = *pos_arg;
880  } else if (os->keyframe_seek) {
881  // if we had a previous keyframe but no pts for it,
882  // return that keyframe with this pts value.
883  if (keypos >= 0)
884  *pos_arg = keypos;
885  else
886  pts = AV_NOPTS_VALUE;
887  }
888  }
889  if (pts != AV_NOPTS_VALUE)
890  break;
891  }
892  ogg_reset(s);
893  return pts;
894 }
895 
896 static int ogg_read_seek(AVFormatContext *s, int stream_index,
897  int64_t timestamp, int flags)
898 {
899  struct ogg *ogg = s->priv_data;
900  struct ogg_stream *os = ogg->streams + stream_index;
901  int ret;
902 
903  av_assert0(stream_index < ogg->nstreams);
904  // Ensure everything is reset even when seeking via
905  // the generated index.
906  ogg_reset(s);
907 
908  // Try seeking to a keyframe first. If this fails (very possible),
909  // av_seek_frame will fall back to ignoring keyframes
910  if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
911  && !(flags & AVSEEK_FLAG_ANY))
912  os->keyframe_seek = 1;
913 
914  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
915  ogg_reset(s);
916  os = ogg->streams + stream_index;
917  if (ret < 0)
918  os->keyframe_seek = 0;
919  return ret;
920 }
921 
922 static int ogg_probe(AVProbeData *p)
923 {
924  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
925  return AVPROBE_SCORE_MAX;
926  return 0;
927 }
928 
930  .name = "ogg",
931  .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
932  .priv_data_size = sizeof(struct ogg),
933  .read_probe = ogg_probe,
934  .read_header = ogg_read_header,
935  .read_packet = ogg_read_packet,
936  .read_close = ogg_read_close,
937  .read_seek = ogg_read_seek,
938  .read_timestamp = ogg_read_timestamp,
939  .extensions = "ogg",
941 };
int headers
Definition: oggdec.h:104
int header
Definition: oggdec.h:78
int granule_is_start
1 if granule is the start time of the associated packet.
Definition: oggdec.h:53
#define NULL
Definition: coverity.c:32
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:490
const char * s
Definition: avisynth_c.h:631
Bytestream IO Context.
Definition: avio.h:111
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:284
A list of zero terminated key/value strings.
Definition: avcodec.h:1367
int nstreams
Definition: oggdec.h:103
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:284
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition: oggdec.h:31
static const struct ogg_codec * ogg_find_codec(uint8_t *buf, int size)
Definition: oggdec.c:171
unsigned int bufsize
Definition: oggdec.h:63
unsigned int pflags
Definition: oggdec.h:67
const struct ogg_codec ff_celt_codec
Definition: oggparsecelt.c:90
#define DECODER_BUFFER_SIZE
Definition: oggdec.c:40
int nb_header
set to the number of parsed headers
Definition: oggdec.h:86
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t pos
byte position in stream, -1 if unknown
Definition: avcodec.h:1458
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4093
static int ogg_new_buf(struct ogg *ogg, int idx)
Definition: oggdec.c:285
#define OGG_NOGRANULE_VALUE
Definition: oggdec.h:114
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2298
const struct ogg_codec * codec
Definition: oggdec.h:77
int64_t data_offset
offset of the first packet
Definition: internal.h:80
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:204
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1710
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:279
void(* cleanup)(AVFormatContext *s, int idx)
Definition: oggdec.h:58
int flags
Definition: oggdec.h:76
#define OGG_FLAG_CONT
Definition: oggdec.h:110
static AVPacket pkt
static int ogg_get_length(AVFormatContext *s)
Definition: oggdec.c:592
static int ogg_probe(AVProbeData *p)
Definition: oggdec.c:922
static const struct ogg_codec *const ogg_codecs[]
Definition: oggdec.c:42
int64_t lastpts
Definition: oggdec.h:72
static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggdec.c:782
const struct ogg_codec ff_ogm_old_codec
Definition: oggparseogm.c:212
Format I/O context.
Definition: avformat.h:1285
unsigned int psize
Definition: oggdec.h:66
static int ogg_restore(AVFormatContext *s, int discard)
Definition: oggdec.c:102
int64_t sync_pos
file offset of the first page needed to reconstruct the current packet
Definition: oggdec.h:74
uint64_t pos
Definition: oggdec.h:94
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
#define av_malloc(s)
const struct ogg_codec ff_ogm_video_codec
Definition: oggparseogm.c:185
static int data_packets_seen(const struct ogg *ogg)
Definition: oggdec.c:306
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int id
Format-specific stream ID.
Definition: avformat.h:861
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:3756
int64_t page_pos
file offset of the current page
Definition: oggdec.h:75
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1353
struct ogg_state * state
Definition: oggdec.h:107
uint8_t * data
Definition: avcodec.h:1433
int nstreams
Definition: oggdec.h:97
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define sp
Definition: regdef.h:63
int end_trimming
set the number of packets to drop from the end
Definition: oggdec.h:87
ptrdiff_t size
Definition: opengl_enc.c:101
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:390
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: oggdec.c:896
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1451
#define av_log(a,...)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:542
const struct ogg_codec ff_skeleton_codec
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1479
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:84
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVFMT_TS_DISCONT
Format allows timestamp discontinuities.
Definition: avformat.h:486
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:2911
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:663
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:178
static int ogg_read_close(AVFormatContext *s)
Definition: oggdec.c:661
#define MAX_PAGE_SIZE
Definition: oggdec.c:39
#define OGG_FLAG_EOS
Definition: oggdec.h:112
simple assert() macros that are a bit more flexible than ISO C assert().
const struct ogg_codec ff_opus_codec
Definition: oggparseopus.c:179
uint8_t segments[255]
Definition: oggdec.h:80
#define fail()
Definition: checkasm.h:57
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1439
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:533
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:873
int incomplete
whether we're expecting a continuation in the next page
Definition: oggdec.h:81
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:462
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:160
uint32_t serial
Definition: oggdec.h:69
#define FFMIN(a, b)
Definition: common.h:92
unsigned int new_metadata_size
Definition: oggdec.h:89
uint64_t granule
Definition: oggdec.h:70
static int ogg_read_page(AVFormatContext *s, int *sid)
Definition: oggdec.c:316
unsigned int pstart
Definition: oggdec.h:65
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
Definition: oggdec.c:731
static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
Replace the current stream with a new one.
Definition: oggdec.c:188
static int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition: mem.h:337
uint64_t start_granule
Definition: oggdec.h:71
int(* packet)(AVFormatContext *, int)
Definition: oggdec.h:42
struct ogg_stream * streams
Definition: oggdec.h:102
int segp
Definition: oggdec.h:79
const struct ogg_codec ff_vorbis_codec
#define OGG_FLAG_BOS
Definition: oggdec.h:111
const struct ogg_codec ff_vp8_codec
Definition: oggparsevp8.c:139
int page_end
current packet is the last one completed in the page
Definition: oggdec.h:82
AVInputFormat ff_ogg_demuxer
Definition: oggdec.c:929
const struct ogg_codec ff_ogm_audio_codec
Definition: oggparseogm.c:194
Stream structure.
Definition: avformat.h:854
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
const struct ogg_codec ff_theora_codec
static int ogg_find_stream(struct ogg *ogg, int serial)
Definition: oggdec.h:139
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
enum AVMediaType codec_type
Definition: avcodec.h:1520
unsigned int pduration
Definition: oggdec.h:68
int got_start
Definition: oggdec.h:84
int nsegs
Definition: oggdec.h:79
enum AVCodecID codec_id
Definition: avcodec.h:1529
AVIOContext * pb
I/O context.
Definition: avformat.h:1327
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition: oggdec.c:457
const struct ogg_codec ff_flac_codec
Definition: oggparseflac.c:111
const struct ogg_codec ff_old_dirac_codec
int io_repositioned
IO repositioned flag.
Definition: avformat.h:1718
void * buf
Definition: avisynth_c.h:553
void * private
Definition: oggdec.h:90
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:485
struct ogg_state * next
Definition: oggdec.h:96
uint8_t * new_metadata
Definition: oggdec.h:88
static int ogg_read_header(AVFormatContext *s)
Definition: oggdec.c:682
int nb_header
Number of expected headers.
Definition: oggdec.h:57
Recommmends skipping the specified number of samples.
Definition: avcodec.h:1314
static int ogg_reset(AVFormatContext *s)
Definition: oggdec.c:137
int64_t lastdts
Definition: oggdec.h:73
This structure contains the data a format has to probe a file.
Definition: avformat.h:460
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:118
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static int64_t pts
Global timestamp for the audio frames.
static int flags
Definition: cpu.c:47
int curidx
Definition: oggdec.h:95
const int8_t * magic
Definition: oggdec.h:32
const struct ogg_codec ff_dirac_codec
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:913
uint8_t * buf
Definition: oggdec.h:62
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:472
const struct ogg_codec ff_speex_codec
Main libavformat public API header.
if(ret< 0)
Definition: vf_mcdeint.c:280
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:145
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
Definition: avformat.h:906
static double c[64]
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition: avformat.h:1524
int got_data
1 if the stream got some data (non-initial packets), 0 otherwise
Definition: oggdec.h:85
const struct ogg_codec ff_ogm_text_codec
Definition: oggparseogm.c:203
int keyframe_seek
Definition: oggdec.h:83
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:636
#define av_free(p)
Definition: oggdec.h:101
static int ogg_save(AVFormatContext *s)
Definition: oggdec.c:66
int64_t page_pos
file offset of the current page
Definition: oggdec.h:106
void * priv_data
Format private data.
Definition: avformat.h:1313
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
Definition: oggdec.c:243
static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
Definition: oggdec.c:761
uint8_t magicsize
Definition: oggdec.h:33
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1432
static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit)
Definition: oggdec.c:855
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1380
#define av_freep(p)
#define gp
Definition: regdef.h:62
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:640
int curidx
Definition: oggdec.h:105
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:303
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:303
int stream_index
Definition: avcodec.h:1435
struct ogg_stream streams[1]
Definition: oggdec.h:98
This structure stores compressed data.
Definition: avcodec.h:1410
uint64_t avio_rl64(AVIOContext *s)
Definition: aviobuf.c:671
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
int(* header)(AVFormatContext *, int)
Attempt to process a packet as a header.
Definition: oggdec.h:41
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1426
unsigned int bufpos
Definition: oggdec.h:64
static uint64_t ogg_gptopts(AVFormatContext *s, int i, uint64_t gp, int64_t *dts)
Definition: oggdec.h:151
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:240
int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
Perform a binary search using av_index_search_timestamp() and AVInputFormat.read_timestamp().
Definition: utils.c:1862
#define AV_WL32(p, v)
Definition: intreadwrite.h:426