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