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