FFmpeg
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 "avio_internal.h"
35 #include "oggdec.h"
36 #include "avformat.h"
37 #include "internal.h"
38 #include "vorbiscomment.h"
39 
40 #define MAX_PAGE_SIZE 65307
41 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
42 
43 static const struct ogg_codec * const ogg_codecs[] = {
52  &ff_vp8_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
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;
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 
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 
158 {
159  struct ogg *ogg = s->priv_data;
160  int i;
161  int64_t start_pos = avio_tell(s->pb);
162 
163  for (i = 0; i < ogg->nstreams; i++) {
164  struct ogg_stream *os = ogg->streams + i;
165  os->bufpos = 0;
166  os->pstart = 0;
167  os->psize = 0;
168  os->granule = -1;
169  os->lastpts = AV_NOPTS_VALUE;
170  os->lastdts = AV_NOPTS_VALUE;
171  os->sync_pos = -1;
172  os->page_pos = 0;
173  os->nsegs = 0;
174  os->segp = 0;
175  os->incomplete = 0;
176  os->got_data = 0;
177  if (start_pos <= s->internal->data_offset) {
178  os->lastpts = 0;
179  }
180  os->start_trimming = 0;
181  os->end_trimming = 0;
182  av_freep(&os->new_metadata);
183  os->new_metadata_size = 0;
184  }
185 
186  ogg->page_pos = -1;
187  ogg->curidx = -1;
188 
189  return 0;
190 }
191 
192 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
193 {
194  int i;
195 
196  for (i = 0; ogg_codecs[i]; i++)
197  if (size >= ogg_codecs[i]->magicsize &&
198  !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
199  return ogg_codecs[i];
200 
201  return NULL;
202 }
203 
204 /**
205  * Replace the current stream with a new one. This is a typical webradio
206  * situation where a new audio stream spawn (identified with a new serial) and
207  * must replace the previous one (track switch).
208  */
209 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, int page_size,
210  int probing)
211 {
212  struct ogg *ogg = s->priv_data;
213  struct ogg_stream *os;
214  const struct ogg_codec *codec;
215  int i = 0;
216 
217  if (ogg->nstreams != 1) {
218  avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
219  return AVERROR_PATCHWELCOME;
220  }
221 
222  /* Check for codecs */
223  codec = ogg_find_codec(magic, page_size);
224  if (!codec && !probing) {
225  av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
226  return AVERROR_INVALIDDATA;
227  }
228 
229  os = &ogg->streams[0];
230  if (os->codec != codec)
231  return AVERROR(EINVAL);
232 
233  os->serial = serial;
234  os->codec = codec;
235  os->serial = serial;
236  os->lastpts = 0;
237  os->lastdts = 0;
238  os->start_trimming = 0;
239  os->end_trimming = 0;
240 
241  /* Chained files have extradata as a new packet */
242  if (codec == &ff_opus_codec)
243  os->header = -1;
244 
245  return i;
246 }
247 
248 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
249 {
250  struct ogg *ogg = s->priv_data;
251  int idx = ogg->nstreams;
252  AVStream *st;
253  struct ogg_stream *os;
254  size_t size;
255 
256  if (ogg->state) {
257  av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
258  "in between Ogg context save/restore operations.\n");
259  return AVERROR_BUG;
260  }
261 
262  /* Allocate and init a new Ogg Stream */
263  if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
264  !(os = av_realloc(ogg->streams, size)))
265  return AVERROR(ENOMEM);
266  ogg->streams = os;
267  os = ogg->streams + idx;
268  memset(os, 0, sizeof(*os));
269  os->serial = serial;
272  os->header = -1;
274  if (!os->buf)
275  return AVERROR(ENOMEM);
276 
277  /* Create the associated AVStream */
278  st = avformat_new_stream(s, NULL);
279  if (!st) {
280  av_freep(&os->buf);
281  return AVERROR(ENOMEM);
282  }
283  st->id = idx;
284  avpriv_set_pts_info(st, 64, 1, 1000000);
285 
286  ogg->nstreams++;
287  return idx;
288 }
289 
290 static int data_packets_seen(const struct ogg *ogg)
291 {
292  int i;
293 
294  for (i = 0; i < ogg->nstreams; i++)
295  if (ogg->streams[i].got_data)
296  return 1;
297  return 0;
298 }
299 
300 static int buf_realloc(struct ogg_stream *os, int size)
301 {
302  /* Even if invalid guarantee there's enough memory to read the page */
303  if (os->bufsize - os->bufpos < size) {
305  if (!nb)
306  return AVERROR(ENOMEM);
307  os->buf = nb;
308  os->bufsize *= 2;
309  }
310 
311  return 0;
312 }
313 
314 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
315 {
316  AVIOContext *bc = s->pb;
317  struct ogg *ogg = s->priv_data;
318  struct ogg_stream *os;
319  int ret, i = 0;
320  int flags, nsegs;
321  uint64_t gp;
322  uint32_t serial;
323  uint32_t crc, crc_tmp;
324  int size = 0, idx;
325  int64_t version, page_pos;
326  int64_t start_pos;
327  uint8_t sync[4];
328  uint8_t segments[255];
329  uint8_t *readout_buf;
330  int sp = 0;
331 
332  ret = avio_read(bc, sync, 4);
333  if (ret < 4)
334  return ret < 0 ? ret : AVERROR_EOF;
335 
336  do {
337  int c;
338 
339  if (sync[sp & 3] == 'O' &&
340  sync[(sp + 1) & 3] == 'g' &&
341  sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
342  break;
343 
344  if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
345  memset(sync, 0, 4);
346  avio_seek(bc, ogg->page_pos+4, SEEK_SET);
347  ogg->page_pos = -1;
348  }
349 
350  c = avio_r8(bc);
351 
352  if (avio_feof(bc))
353  return AVERROR_EOF;
354 
355  sync[sp++ & 3] = c;
356  } while (i++ < MAX_PAGE_SIZE);
357 
358  if (i >= MAX_PAGE_SIZE) {
359  av_log(s, AV_LOG_INFO, "cannot find sync word\n");
360  return AVERROR_INVALIDDATA;
361  }
362 
363  /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
364  ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
365 
366  /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
368  start_pos = avio_tell(bc);
369 
370  version = avio_r8(bc);
371  flags = avio_r8(bc);
372  gp = avio_rl64(bc);
373  serial = avio_rl32(bc);
374  avio_skip(bc, 4); /* seq */
375 
376  crc_tmp = ffio_get_checksum(bc);
377  crc = avio_rb32(bc);
378  crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
380 
381  nsegs = avio_r8(bc);
382  page_pos = avio_tell(bc) - 27;
383 
384  ret = avio_read(bc, segments, nsegs);
385  if (ret < nsegs)
386  return ret < 0 ? ret : AVERROR_EOF;
387 
388  for (i = 0; i < nsegs; i++)
389  size += segments[i];
390 
391  idx = ogg_find_stream(ogg, serial);
392  if (idx >= 0) {
393  os = ogg->streams + idx;
394 
395  ret = buf_realloc(os, size);
396  if (ret < 0)
397  return ret;
398 
399  readout_buf = os->buf + os->bufpos;
400  } else {
401  readout_buf = av_malloc(size);
402  }
403 
404  ret = avio_read(bc, readout_buf, size);
405  if (ret < size) {
406  if (idx < 0)
407  av_free(readout_buf);
408  return ret < 0 ? ret : AVERROR_EOF;
409  }
410 
411  if (crc ^ ffio_get_checksum(bc)) {
412  av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
413  if (idx < 0)
414  av_free(readout_buf);
415  avio_seek(bc, start_pos, SEEK_SET);
416  *sid = -1;
417  return 0;
418  }
419 
420  /* Since we're almost sure its a valid packet, checking the version after
421  * the checksum lets the demuxer be more tolerant */
422  if (version) {
423  av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
424  if (idx < 0)
425  av_free(readout_buf);
426  avio_seek(bc, start_pos, SEEK_SET);
427  *sid = -1;
428  return 0;
429  }
430 
431  /* CRC is correct so we can be 99% sure there's an actual change here */
432  if (idx < 0) {
433  if (data_packets_seen(ogg))
434  idx = ogg_replace_stream(s, serial, readout_buf, size, probing);
435  else
436  idx = ogg_new_stream(s, serial);
437 
438  if (idx < 0) {
439  av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
440  av_free(readout_buf);
441  return idx;
442  }
443 
444  os = ogg->streams + idx;
445 
446  ret = buf_realloc(os, size);
447  if (ret < 0) {
448  av_free(readout_buf);
449  return ret;
450  }
451 
452  memcpy(os->buf + os->bufpos, readout_buf, size);
453  av_free(readout_buf);
454  }
455 
456  ogg->page_pos = page_pos;
457  os->page_pos = page_pos;
458  os->nsegs = nsegs;
459  os->segp = 0;
460  os->got_data = !(flags & OGG_FLAG_BOS);
461  os->bufpos += size;
462  os->granule = gp;
463  os->flags = flags;
464  memcpy(os->segments, segments, nsegs);
465  memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
466 
467  if (flags & OGG_FLAG_CONT || os->incomplete) {
468  if (!os->psize) {
469  // If this is the very first segment we started
470  // playback in the middle of a continuation packet.
471  // Discard it since we missed the start of it.
472  while (os->segp < os->nsegs) {
473  int seg = os->segments[os->segp++];
474  os->pstart += seg;
475  if (seg < 255)
476  break;
477  }
478  os->sync_pos = os->page_pos;
479  }
480  } else {
481  os->psize = 0;
482  os->sync_pos = os->page_pos;
483  }
484 
485  /* This function is always called with sid != NULL */
486  *sid = idx;
487 
488  return 0;
489 }
490 
491 /**
492  * @brief find the next Ogg packet
493  * @param *sid is set to the stream for the packet or -1 if there is
494  * no matching stream, in that case assume all other return
495  * values to be uninitialized.
496  * @return negative value on error or EOF.
497  */
498 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
499  int64_t *fpos)
500 {
501  struct ogg *ogg = s->priv_data;
502  int idx, i, ret;
503  struct ogg_stream *os;
504  int complete = 0;
505  int segp = 0, psize = 0;
506 
507  av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
508  if (sid)
509  *sid = -1;
510 
511  do {
512  idx = ogg->curidx;
513 
514  while (idx < 0) {
515  ret = ogg_read_page(s, &idx, 0);
516  if (ret < 0)
517  return ret;
518  }
519 
520  os = ogg->streams + idx;
521 
522  av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
523  idx, os->pstart, os->psize, os->segp, os->nsegs);
524 
525  if (!os->codec) {
526  if (os->header < 0) {
527  os->codec = ogg_find_codec(os->buf, os->bufpos);
528  if (!os->codec) {
529  av_log(s, AV_LOG_WARNING, "Codec not found\n");
530  os->header = 0;
531  return 0;
532  }
533  } else {
534  return 0;
535  }
536  }
537 
538  segp = os->segp;
539  psize = os->psize;
540 
541  while (os->segp < os->nsegs) {
542  int ss = os->segments[os->segp++];
543  os->psize += ss;
544  if (ss < 255) {
545  complete = 1;
546  break;
547  }
548  }
549 
550  if (!complete && os->segp == os->nsegs) {
551  ogg->curidx = -1;
552  // Do not set incomplete for empty packets.
553  // Together with the code in ogg_read_page
554  // that discards all continuation of empty packets
555  // we would get an infinite loop.
556  os->incomplete = !!os->psize;
557  }
558  } while (!complete);
559 
560 
561  if (os->granule == -1)
563  "Page at %"PRId64" is missing granule\n",
564  os->page_pos);
565 
566  ogg->curidx = idx;
567  os->incomplete = 0;
568 
569  if (os->header) {
570  if ((ret = os->codec->header(s, idx)) < 0) {
571  av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
572  return ret;
573  }
574  os->header = ret;
575  if (!os->header) {
576  os->segp = segp;
577  os->psize = psize;
578 
579  // We have reached the first non-header packet in this stream.
580  // Unfortunately more header packets may still follow for others,
581  // but if we continue with header parsing we may lose data packets.
582  ogg->headers = 1;
583 
584  // Update the header state for all streams and
585  // compute the data_offset.
586  if (!s->internal->data_offset)
587  s->internal->data_offset = os->sync_pos;
588 
589  for (i = 0; i < ogg->nstreams; i++) {
590  struct ogg_stream *cur_os = ogg->streams + i;
591 
592  // if we have a partial non-header packet, its start is
593  // obviously at or after the data start
594  if (cur_os->incomplete)
595  s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
596  }
597  } else {
598  os->nb_header++;
599  os->pstart += os->psize;
600  os->psize = 0;
601  }
602  } else {
603  os->pflags = 0;
604  os->pduration = 0;
605  if (os->codec && os->codec->packet) {
606  if ((ret = os->codec->packet(s, idx)) < 0) {
607  av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
608  return ret;
609  }
610  }
611  if (sid)
612  *sid = idx;
613  if (dstart)
614  *dstart = os->pstart;
615  if (dsize)
616  *dsize = os->psize;
617  if (fpos)
618  *fpos = os->sync_pos;
619  os->pstart += os->psize;
620  os->psize = 0;
621  if(os->pstart == os->bufpos)
622  os->bufpos = os->pstart = 0;
623  os->sync_pos = os->page_pos;
624  }
625 
626  // determine whether there are more complete packets in this page
627  // if not, the page's granule will apply to this packet
628  os->page_end = 1;
629  for (i = os->segp; i < os->nsegs; i++)
630  if (os->segments[i] < 255) {
631  os->page_end = 0;
632  break;
633  }
634 
635  if (os->segp == os->nsegs)
636  ogg->curidx = -1;
637 
638  return 0;
639 }
640 
642 {
643  struct ogg *ogg = s->priv_data;
644  int i, ret;
645  int64_t size, end;
646  int streams_left=0;
647 
648  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
649  return 0;
650 
651 // already set
652  if (s->duration != AV_NOPTS_VALUE)
653  return 0;
654 
655  size = avio_size(s->pb);
656  if (size < 0)
657  return 0;
658  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
659 
660  ret = ogg_save(s);
661  if (ret < 0)
662  return ret;
663  avio_seek(s->pb, end, SEEK_SET);
664  ogg->page_pos = -1;
665 
666  while (!ogg_read_page(s, &i, 1)) {
667  if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
668  ogg->streams[i].codec) {
669  s->streams[i]->duration =
671  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
672  s->streams[i]->duration -= s->streams[i]->start_time;
673  streams_left-= (ogg->streams[i].got_start==-1);
674  ogg->streams[i].got_start= 1;
675  } else if(!ogg->streams[i].got_start) {
676  ogg->streams[i].got_start= -1;
677  streams_left++;
678  }
679  }
680  }
681 
682  ogg_restore(s);
683 
684  ret = ogg_save(s);
685  if (ret < 0)
686  return ret;
687 
688  avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
689  ogg_reset(s);
690  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
691  int64_t pts;
692  if (i < 0) continue;
693  pts = ogg_calc_pts(s, i, NULL);
694  if (s->streams[i]->duration == AV_NOPTS_VALUE)
695  continue;
696  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
697  s->streams[i]->duration -= pts;
698  ogg->streams[i].got_start= 1;
699  streams_left--;
700  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
701  ogg->streams[i].got_start= 1;
702  streams_left--;
703  }
704  }
705  ogg_restore (s);
706 
707  return 0;
708 }
709 
711 {
712  struct ogg *ogg = s->priv_data;
713  int i;
714 
715  for (i = 0; i < ogg->nstreams; i++) {
716  free_stream(s, i);
717  }
718 
719  ogg->nstreams = 0;
720 
721  av_freep(&ogg->streams);
722  return 0;
723 }
724 
726 {
727  struct ogg *ogg = s->priv_data;
728  int ret, i;
729 
730  ogg->curidx = -1;
731 
732  //linear headers seek from start
733  do {
734  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
735  if (ret < 0) {
736  ogg_read_close(s);
737  return ret;
738  }
739  } while (!ogg->headers);
740  av_log(s, AV_LOG_TRACE, "found headers\n");
741 
742  for (i = 0; i < ogg->nstreams; i++) {
743  struct ogg_stream *os = ogg->streams + i;
744 
745  if (ogg->streams[i].header < 0) {
746  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
747  ogg->streams[i].codec = NULL;
749  } else if (os->codec && os->nb_header < os->codec->nb_header) {
751  "Headers mismatch for stream %d: "
752  "expected %d received %d.\n",
753  i, os->codec->nb_header, os->nb_header);
754  if (s->error_recognition & AV_EF_EXPLODE) {
755  ogg_read_close(s);
756  return AVERROR_INVALIDDATA;
757  }
758  }
760  os->lastpts = s->streams[i]->start_time =
761  ogg_gptopts(s, i, os->start_granule, NULL);
762  }
763 
764  //linear granulepos seek from end
765  ret = ogg_get_length(s);
766  if (ret < 0) {
767  ogg_read_close(s);
768  return ret;
769  }
770 
771  return 0;
772 }
773 
774 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
775 {
776  struct ogg *ogg = s->priv_data;
777  struct ogg_stream *os = ogg->streams + idx;
778  int64_t pts = AV_NOPTS_VALUE;
779 
780  if (dts)
781  *dts = AV_NOPTS_VALUE;
782 
783  if (os->lastpts != AV_NOPTS_VALUE) {
784  pts = os->lastpts;
785  os->lastpts = AV_NOPTS_VALUE;
786  }
787  if (os->lastdts != AV_NOPTS_VALUE) {
788  if (dts)
789  *dts = os->lastdts;
790  os->lastdts = AV_NOPTS_VALUE;
791  }
792  if (os->page_end) {
793  if (os->granule != -1LL) {
794  if (os->codec && os->codec->granule_is_start)
795  pts = ogg_gptopts(s, idx, os->granule, dts);
796  else
797  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
798  os->granule = -1LL;
799  }
800  }
801  return pts;
802 }
803 
804 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
805 {
806  struct ogg *ogg = s->priv_data;
807  struct ogg_stream *os = ogg->streams + idx;
808  int invalid = 0;
809  if (psize) {
810  switch (s->streams[idx]->codecpar->codec_id) {
811  case AV_CODEC_ID_THEORA:
812  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
813  break;
814  case AV_CODEC_ID_VP8:
815  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
816  }
817  if (invalid) {
818  os->pflags ^= AV_PKT_FLAG_KEY;
819  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
820  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
821  }
822  }
823 }
824 
826 {
827  struct ogg *ogg;
828  struct ogg_stream *os;
829  int idx, ret;
830  int pstart, psize;
831  int64_t fpos, pts, dts;
832 
833  if (s->io_repositioned) {
834  ogg_reset(s);
835  s->io_repositioned = 0;
836  }
837 
838  //Get an ogg packet
839 retry:
840  do {
841  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
842  if (ret < 0)
843  return ret;
844  } while (idx < 0 || !s->streams[idx]);
845 
846  ogg = s->priv_data;
847  os = ogg->streams + idx;
848 
849  // pflags might not be set until after this
850  pts = ogg_calc_pts(s, idx, &dts);
852 
853  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
854  goto retry;
855  os->keyframe_seek = 0;
856 
857  //Alloc a pkt
859  if (ret < 0)
860  return ret;
861  pkt->stream_index = idx;
862  memcpy(pkt->data, os->buf + pstart, psize);
863 
864  pkt->pts = pts;
865  pkt->dts = dts;
866  pkt->flags = os->pflags;
867  pkt->duration = os->pduration;
868  pkt->pos = fpos;
869 
870  if (os->start_trimming || os->end_trimming) {
871  uint8_t *side_data = av_packet_new_side_data(pkt,
873  10);
874  if(!side_data)
875  return AVERROR(ENOMEM);
876  AV_WL32(side_data + 0, os->start_trimming);
877  AV_WL32(side_data + 4, os->end_trimming);
878  os->start_trimming = 0;
879  os->end_trimming = 0;
880  }
881 
882  if (os->new_metadata) {
885  if (ret < 0)
886  return ret;
887 
888  os->new_metadata = NULL;
889  os->new_metadata_size = 0;
890  }
891 
892  return psize;
893 }
894 
895 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
896  int64_t *pos_arg, int64_t pos_limit)
897 {
898  struct ogg *ogg = s->priv_data;
899  AVIOContext *bc = s->pb;
900  int64_t pts = AV_NOPTS_VALUE;
901  int64_t keypos = -1;
902  int i;
903  int pstart, psize;
904  avio_seek(bc, *pos_arg, SEEK_SET);
905  ogg_reset(s);
906 
907  while ( avio_tell(bc) <= pos_limit
908  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
909  if (i == stream_index) {
910  struct ogg_stream *os = ogg->streams + stream_index;
911  // Do not trust the last timestamps of an ogm video
912  if ( (os->flags & OGG_FLAG_EOS)
913  && !(os->flags & OGG_FLAG_BOS)
914  && os->codec == &ff_ogm_video_codec)
915  continue;
916  pts = ogg_calc_pts(s, i, NULL);
918  if (os->pflags & AV_PKT_FLAG_KEY) {
919  keypos = *pos_arg;
920  } else if (os->keyframe_seek) {
921  // if we had a previous keyframe but no pts for it,
922  // return that keyframe with this pts value.
923  if (keypos >= 0)
924  *pos_arg = keypos;
925  else
927  }
928  }
929  if (pts != AV_NOPTS_VALUE)
930  break;
931  }
932  ogg_reset(s);
933  return pts;
934 }
935 
936 static int ogg_read_seek(AVFormatContext *s, int stream_index,
937  int64_t timestamp, int flags)
938 {
939  struct ogg *ogg = s->priv_data;
940  struct ogg_stream *os = ogg->streams + stream_index;
941  int ret;
942 
943  av_assert0(stream_index < ogg->nstreams);
944  // Ensure everything is reset even when seeking via
945  // the generated index.
946  ogg_reset(s);
947 
948  // Try seeking to a keyframe first. If this fails (very possible),
949  // av_seek_frame will fall back to ignoring keyframes
950  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
951  && !(flags & AVSEEK_FLAG_ANY))
952  os->keyframe_seek = 1;
953 
954  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
955  ogg_reset(s);
956  os = ogg->streams + stream_index;
957  if (ret < 0)
958  os->keyframe_seek = 0;
959  return ret;
960 }
961 
962 static int ogg_probe(const AVProbeData *p)
963 {
964  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
965  return AVPROBE_SCORE_MAX;
966  return 0;
967 }
968 
970  .name = "ogg",
971  .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
972  .priv_data_size = sizeof(struct ogg),
974  .read_header = ogg_read_header,
975  .read_packet = ogg_read_packet,
976  .read_close = ogg_read_close,
977  .read_seek = ogg_read_seek,
978  .read_timestamp = ogg_read_timestamp,
979  .extensions = "ogg",
981 };
ff_old_flac_codec
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:135
ff_ogm_text_codec
const struct ogg_codec ff_ogm_text_codec
Definition: oggparseogm.c:212
ff_ogg_demuxer
AVInputFormat ff_ogg_demuxer
Definition: oggdec.c:969
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
ogg_stream::segp
int segp
Definition: oggdec.h:79
ogg_stream::new_metadata_size
buffer_size_t new_metadata_size
Definition: oggdec.h:90
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4509
ogg_stream::lastpts
int64_t lastpts
Definition: oggdec.h:72
ff_ogm_audio_codec
const struct ogg_codec ff_ogm_audio_codec
Definition: oggparseogm.c:203
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
ogg_codec::magicsize
uint8_t magicsize
Definition: oggdec.h:33
ogg_validate_keyframe
static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
Definition: oggdec.c:804
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
ogg_stream::bufpos
unsigned int bufpos
Definition: oggdec.h:64
ff_vp8_codec
const struct ogg_codec ff_vp8_codec
Definition: oggparsevp8.c:139
ogg_stream::got_start
int got_start
Definition: oggdec.h:84
ff_old_dirac_codec
const struct ogg_codec ff_old_dirac_codec
Definition: oggparsedirac.c:125
AVPacket::data
uint8_t * data
Definition: packet.h:369
vorbiscomment.h
ogg_stream::granule
uint64_t granule
Definition: oggdec.h:70
ogg_stream::start_trimming
int start_trimming
set the number of packets to drop from the start
Definition: oggdec.h:87
ogg_read_header
static int ogg_read_header(AVFormatContext *s)
Definition: oggdec.c:725
ogg_new_stream
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
Definition: oggdec.c:248
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:387
ogg_stream::nb_header
int nb_header
set to the number of parsed headers
Definition: oggdec.h:86
ogg_stream::buf
uint8_t * buf
Definition: oggdec.h:62
ogg_stream::nsegs
int nsegs
Definition: oggdec.h:79
ogg_reset
static int ogg_reset(AVFormatContext *s)
Definition: oggdec.c:157
AVFMT_NOBINSEARCH
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:468
ogg
Definition: oggdec.h:102
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:342
ost
static AVStream * ost
Definition: vaapi_transcode.c:45
ff_vorbis_codec
const struct ogg_codec ff_vorbis_codec
Definition: oggparsevorbis.c:503
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
ffio_get_checksum
unsigned long ffio_get_checksum(AVIOContext *s)
Definition: aviobuf.c:604
ff_flac_codec
const struct ogg_codec ff_flac_codec
Definition: oggparseflac.c:128
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
ff_seek_frame_binary
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:2145
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:453
ogg_codec::packet
int(* packet)(AVFormatContext *, int)
Definition: oggdec.h:42
DECODER_BUFFER_SIZE
#define DECODER_BUFFER_SIZE
Definition: oggdec.c:41
ogg_gptopts
static uint64_t ogg_gptopts(AVFormatContext *s, int i, uint64_t gp, int64_t *dts)
Definition: oggdec.h:152
ogg_stream::serial
uint32_t serial
Definition: oggdec.h:69
av_packet_add_side_data
FF_ENABLE_DEPRECATION_WARNINGS int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: avpacket.c:309
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2417
ogg_stream::lastdts
int64_t lastdts
Definition: oggdec.h:73
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:463
ogg::headers
int headers
Definition: oggdec.h:105
pts
static int64_t pts
Definition: transcode_aac.c:652
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
ogg_packet
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition: oggdec.c:498
free_stream
static void free_stream(AVFormatContext *s, int i)
Definition: oggdec.c:66
avassert.h
ogg_stream::pstart
unsigned int pstart
Definition: oggdec.h:65
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:781
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:220
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
AVInputFormat
Definition: avformat.h:640
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:99
OGG_NOGRANULE_VALUE
#define OGG_NOGRANULE_VALUE
Definition: oggdec.h:115
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:645
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:443
ogg_stream::got_data
int got_data
1 if the stream got some data (non-initial packets), 0 otherwise
Definition: oggdec.h:85
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
av_size_mult
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:675
ogg_stream::page_end
int page_end
current packet is the last one completed in the page
Definition: oggdec.h:82
ogg::curidx
int curidx
Definition: oggdec.h:106
ogg_stream::new_metadata
uint8_t * new_metadata
Definition: oggdec.h:89
ogg_stream::page_pos
int64_t page_pos
file offset of the current page
Definition: oggdec.h:75
AVFormatContext
Format I/O context.
Definition: avformat.h:1232
ogg_codec::header
int(* header)(AVFormatContext *, int)
Attempt to process a packet as a header.
Definition: oggdec.h:41
internal.h
NULL
#define NULL
Definition: coverity.c:32
ogg_replace_stream
static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, int page_size, int probing)
Replace the current stream with a new one.
Definition: oggdec.c:209
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
read_probe
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
ff_ogm_old_codec
const struct ogg_codec ff_ogm_old_codec
Definition: oggparseogm.c:221
ogg_stream::flags
int flags
Definition: oggdec.h:76
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
ogg_read_seek
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: oggdec.c:936
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:1656
ogg::page_pos
int64_t page_pos
file offset of the current page
Definition: oggdec.h:107
ogg::streams
struct ogg_stream * streams
Definition: oggdec.h:103
ogg_save
static int ogg_save(AVFormatContext *s)
Definition: oggdec.c:82
ogg_get_length
static int ogg_get_length(AVFormatContext *s)
Definition: oggdec.c:641
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:750
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
buf_realloc
static int buf_realloc(struct ogg_stream *os, int size)
Definition: oggdec.c:300
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
ogg_read_close
static int ogg_read_close(AVFormatContext *s)
Definition: oggdec.c:710
gp
#define gp
Definition: regdef.h:62
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
sp
#define sp
Definition: regdef.h:63
avpriv_set_pts_info
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:4945
ogg_stream::private
void * private
Definition: oggdec.h:91
ogg_stream::keyframe_seek
int keyframe_seek
Definition: oggdec.h:83
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
data_packets_seen
static int data_packets_seen(const struct ogg *ogg)
Definition: oggdec.c:290
ffio_init_checksum
void ffio_init_checksum(AVIOContext *s, unsigned long(*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum)
Definition: aviobuf.c:612
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:368
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:624
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:206
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:998
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
ogg::state
struct ogg_state * state
Definition: oggdec.h:108
version
version
Definition: libkvazaar.c:326
AV_PKT_DATA_METADATA_UPDATE
@ AV_PKT_DATA_METADATA_UPDATE
A list of zero terminated key/value strings.
Definition: packet.h:209
ff_crc04C11DB7_update
unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition: aviobuf.c:586
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:134
MAX_PAGE_SIZE
#define MAX_PAGE_SIZE
Definition: oggdec.c:40
ogg_stream::pflags
unsigned int pflags
Definition: oggdec.h:67
ogg::nstreams
int nstreams
Definition: oggdec.h:104
i
int i
Definition: input.c:407
ogg_stream::sync_pos
int64_t sync_pos
file offset of the first page needed to reconstruct the current packet
Definition: oggdec.h:74
ogg_stream::incomplete
int incomplete
whether we're expecting a continuation in the next page
Definition: oggdec.h:81
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:362
ogg_stream
Definition: oggdec.h:61
avio_internal.h
AV_CODEC_ID_THEORA
@ AV_CODEC_ID_THEORA
Definition: codec_id.h:79
ff_ogm_video_codec
const struct ogg_codec ff_ogm_video_codec
Definition: oggparseogm.c:194
OGG_FLAG_CONT
#define OGG_FLAG_CONT
Definition: oggdec.h:111
ff_skeleton_codec
const struct ogg_codec ff_skeleton_codec
Definition: oggparseskeleton.c:96
uint8_t
uint8_t
Definition: audio_convert.c:194
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommmends skipping the specified number of samples.
Definition: packet.h:156
ogg_codecs
static const struct ogg_codec *const ogg_codecs[]
Definition: oggdec.c:43
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, buffer_size_t size)
Definition: avpacket.c:343
ogg_stream::header
int header
Definition: oggdec.h:78
ogg_read_timestamp
static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit)
Definition: oggdec.c:895
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:880
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:873
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
avformat.h
ogg_find_codec
static const struct ogg_codec * ogg_find_codec(uint8_t *buf, int size)
Definition: oggdec.c:192
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:215
ogg_find_stream
static int ogg_find_stream(struct ogg *ogg, int serial)
Definition: oggdec.h:140
ogg_codec::cleanup
void(* cleanup)(AVFormatContext *s, int idx)
Definition: oggdec.h:58
oggdec.h
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
ogg_restore
static int ogg_restore(AVFormatContext *s)
Definition: oggdec.c:118
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:633
ogg_stream::start_granule
uint64_t start_granule
Definition: oggdec.h:71
ogg_read_packet
static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggdec.c:825
AVPacket::stream_index
int stream_index
Definition: packet.h:371
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:337
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ogg_codec::nb_header
int nb_header
Number of expected headers.
Definition: oggdec.h:57
ogg_stream::segments
uint8_t segments[255]
Definition: oggdec.h:80
AVFMT_TS_DISCONT
#define AVFMT_TS_DISCONT
Format allows timestamp discontinuities.
Definition: avformat.h:464
OGG_FLAG_EOS
#define OGG_FLAG_EOS
Definition: oggdec.h:113
ogg_state
Definition: oggdec.h:94
ogg_calc_pts
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
Definition: oggdec.c:774
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
ff_celt_codec
const struct ogg_codec ff_celt_codec
Definition: oggparsecelt.c:92
ogg_probe
static int ogg_probe(const AVProbeData *p)
Definition: oggdec.c:962
AVPacket
This structure stores compressed data.
Definition: packet.h:346
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
ogg_stream::psize
unsigned int psize
Definition: oggdec.h:66
OGG_FLAG_BOS
#define OGG_FLAG_BOS
Definition: oggdec.h:112
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:389
avio_rl64
uint64_t avio_rl64(AVIOContext *s)
Definition: aviobuf.c:758
ogg_codec
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition: oggdec.h:31
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:189
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ogg_read_page
static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
Definition: oggdec.c:314
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
ogg_codec::magic
const int8_t * magic
Definition: oggdec.h:32
ogg_stream::end_trimming
int end_trimming
set the number of packets to drop from the end
Definition: oggdec.h:88
ff_dirac_codec
const struct ogg_codec ff_dirac_codec
Definition: oggparsedirac.c:116
ff_speex_codec
const struct ogg_codec ff_speex_codec
Definition: oggparsespeex.c:148
ogg_codec::granule_is_start
int granule_is_start
1 if granule is the start time of the associated packet.
Definition: oggdec.h:53
ogg_stream::pduration
unsigned int pduration
Definition: oggdec.h:68
ff_theora_codec
const struct ogg_codec ff_theora_codec
Definition: oggparsetheora.c:211
ogg_stream::codec
const struct ogg_codec * codec
Definition: oggdec.h:77
ff_opus_codec
const struct ogg_codec ff_opus_codec
Definition: oggparseopus.c:181
ogg_stream::bufsize
unsigned int bufsize
Definition: oggdec.h:63
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:364