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  if (os->header) {
576  if ((ret = os->codec->header(s, idx)) < 0) {
577  av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
578  return ret;
579  }
580  os->header = ret;
581  if (!os->header) {
582  os->segp = segp;
583  os->psize = psize;
584 
585  // We have reached the first non-header packet in this stream.
586  // Unfortunately more header packets may still follow for others,
587  // but if we continue with header parsing we may lose data packets.
588  ogg->headers = 1;
589 
590  // Update the header state for all streams and
591  // compute the data_offset.
592  if (!si->data_offset)
593  si->data_offset = os->sync_pos;
594 
595  for (i = 0; i < ogg->nstreams; i++) {
596  struct ogg_stream *cur_os = ogg->streams + i;
597 
598  // if we have a partial non-header packet, its start is
599  // obviously at or after the data start
600  if (cur_os->incomplete)
601  si->data_offset = FFMIN(si->data_offset, cur_os->sync_pos);
602  }
603  } else {
604  os->nb_header++;
605  os->pstart += os->psize;
606  os->psize = 0;
607  }
608  } else {
609  os->pflags = 0;
610  os->pduration = 0;
611 
612  ret = 0;
613  if (os->codec && os->codec->packet) {
614  if ((ret = os->codec->packet(s, idx)) < 0) {
615  av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
616  return ret;
617  }
618  }
619 
620  if (!ret) {
621  if (sid)
622  *sid = idx;
623  if (dstart)
624  *dstart = os->pstart;
625  if (dsize)
626  *dsize = os->psize;
627  if (fpos)
628  *fpos = os->sync_pos;
629  }
630 
631  os->pstart += os->psize;
632  os->psize = 0;
633  if(os->pstart == os->bufpos)
634  os->bufpos = os->pstart = 0;
635  os->sync_pos = os->page_pos;
636  }
637 
638  // determine whether there are more complete packets in this page
639  // if not, the page's granule will apply to this packet
640  os->page_end = 1;
641  for (i = os->segp; i < os->nsegs; i++)
642  if (os->segments[i] < 255) {
643  os->page_end = 0;
644  break;
645  }
646 
647  if (os->segp == os->nsegs)
648  ogg->curidx = -1;
649 
650  return 0;
651 }
652 
654 {
655  struct ogg *ogg = s->priv_data;
656  int i, ret;
657  int64_t size, end;
658  int streams_left=0;
659 
660  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
661  return 0;
662 
663 // already set
664  if (s->duration != AV_NOPTS_VALUE)
665  return 0;
666 
667  size = avio_size(s->pb);
668  if (size < 0)
669  return 0;
670  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
671 
672  ret = ogg_save(s);
673  if (ret < 0)
674  return ret;
675  avio_seek(s->pb, end, SEEK_SET);
676  ogg->page_pos = -1;
677 
678  while (!ogg_read_page(s, &i, 1)) {
679  if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
680  ogg->streams[i].codec) {
681  s->streams[i]->duration =
683  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
684  s->streams[i]->duration -= s->streams[i]->start_time;
685  streams_left-= (ogg->streams[i].got_start==-1);
686  ogg->streams[i].got_start= 1;
687  } else if(!ogg->streams[i].got_start) {
688  ogg->streams[i].got_start= -1;
689  streams_left++;
690  }
691  }
692  }
693 
694  ogg_restore(s);
695 
696  ret = ogg_save(s);
697  if (ret < 0)
698  return ret;
699 
700  avio_seek (s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
701  ogg_reset(s);
702  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
703  int64_t pts;
704  if (i < 0) continue;
705  pts = ogg_calc_pts(s, i, NULL);
706  if (s->streams[i]->duration == AV_NOPTS_VALUE)
707  continue;
708  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
709  s->streams[i]->duration -= pts;
710  ogg->streams[i].got_start= 1;
711  streams_left--;
712  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
713  ogg->streams[i].got_start= 1;
714  streams_left--;
715  }
716  }
717  ogg_restore (s);
718 
719  return 0;
720 }
721 
723 {
724  struct ogg *ogg = s->priv_data;
725  int i;
726 
727  for (i = 0; i < ogg->nstreams; i++) {
728  free_stream(s, i);
729  }
730 
731  ogg->nstreams = 0;
732 
733  av_freep(&ogg->streams);
734  return 0;
735 }
736 
738 {
739  struct ogg *ogg = s->priv_data;
740  int ret, i;
741 
742  ogg->curidx = -1;
743 
744  //linear headers seek from start
745  do {
746  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
747  if (ret < 0)
748  return ret;
749  } while (!ogg->headers);
750  av_log(s, AV_LOG_TRACE, "found headers\n");
751 
752  for (i = 0; i < ogg->nstreams; i++) {
753  struct ogg_stream *os = ogg->streams + i;
754 
755  if (ogg->streams[i].header < 0) {
756  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
757  ogg->streams[i].codec = NULL;
759  } else if (os->codec && os->nb_header < os->codec->nb_header) {
761  "Headers mismatch for stream %d: "
762  "expected %d received %d.\n",
763  i, os->codec->nb_header, os->nb_header);
764  if (s->error_recognition & AV_EF_EXPLODE)
765  return AVERROR_INVALIDDATA;
766  }
768  os->lastpts = s->streams[i]->start_time =
769  ogg_gptopts(s, i, os->start_granule, NULL);
770  }
771 
772  //linear granulepos seek from end
773  ret = ogg_get_length(s);
774  if (ret < 0)
775  return ret;
776 
777  return 0;
778 }
779 
781 {
782  struct ogg *ogg = s->priv_data;
783  struct ogg_stream *os = ogg->streams + idx;
785 
786  if (dts)
787  *dts = AV_NOPTS_VALUE;
788 
789  if (os->lastpts != AV_NOPTS_VALUE) {
790  pts = os->lastpts;
791  os->lastpts = AV_NOPTS_VALUE;
792  }
793  if (os->lastdts != AV_NOPTS_VALUE) {
794  if (dts)
795  *dts = os->lastdts;
796  os->lastdts = AV_NOPTS_VALUE;
797  }
798  if (os->page_end) {
799  if (os->granule != -1LL) {
800  if (os->codec && os->codec->granule_is_start)
801  pts = ogg_gptopts(s, idx, os->granule, dts);
802  else
803  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
804  os->granule = -1LL;
805  }
806  }
807  return pts;
808 }
809 
810 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
811 {
812  struct ogg *ogg = s->priv_data;
813  struct ogg_stream *os = ogg->streams + idx;
814  int invalid = 0;
815  if (psize) {
816  switch (s->streams[idx]->codecpar->codec_id) {
817  case AV_CODEC_ID_THEORA:
818  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
819  break;
820  case AV_CODEC_ID_VP8:
821  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
822  }
823  if (invalid) {
824  os->pflags ^= AV_PKT_FLAG_KEY;
825  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
826  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
827  }
828  }
829 }
830 
832 {
833  struct ogg *ogg;
834  struct ogg_stream *os;
835  int idx, ret;
836  int pstart, psize;
837  int64_t fpos, pts, dts;
838 
839  if (s->io_repositioned) {
840  ogg_reset(s);
841  s->io_repositioned = 0;
842  }
843 
844  //Get an ogg packet
845 retry:
846  do {
847  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
848  if (ret < 0)
849  return ret;
850  } while (idx < 0 || !s->streams[idx]);
851 
852  ogg = s->priv_data;
853  os = ogg->streams + idx;
854 
855  // pflags might not be set until after this
856  pts = ogg_calc_pts(s, idx, &dts);
858 
859  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
860  goto retry;
861  os->keyframe_seek = 0;
862 
863  //Alloc a pkt
865  if (ret < 0)
866  return ret;
867  pkt->stream_index = idx;
868  memcpy(pkt->data, os->buf + pstart, psize);
869 
870  pkt->pts = pts;
871  pkt->dts = dts;
872  pkt->flags = os->pflags;
873  pkt->duration = os->pduration;
874  pkt->pos = fpos;
875 
876  if (os->start_trimming || os->end_trimming) {
877  uint8_t *side_data = av_packet_new_side_data(pkt,
879  10);
880  if(!side_data)
881  return AVERROR(ENOMEM);
882  AV_WL32(side_data + 0, os->start_trimming);
883  AV_WL32(side_data + 4, os->end_trimming);
884  os->start_trimming = 0;
885  os->end_trimming = 0;
886  }
887 
888  if (os->replace) {
889  os->replace = 0;
890  pkt->dts = pkt->pts = AV_NOPTS_VALUE;
891  }
892 
893  if (os->new_metadata) {
896  if (ret < 0)
897  return ret;
898 
899  os->new_metadata = NULL;
900  os->new_metadata_size = 0;
901  }
902 
903  if (os->new_extradata) {
906  if (ret < 0)
907  return ret;
908 
909  os->new_extradata = NULL;
910  os->new_extradata_size = 0;
911  }
912 
913  return psize;
914 }
915 
916 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
917  int64_t *pos_arg, int64_t pos_limit)
918 {
919  struct ogg *ogg = s->priv_data;
920  AVIOContext *bc = s->pb;
922  int64_t keypos = -1;
923  int i;
924  int pstart, psize;
925  avio_seek(bc, *pos_arg, SEEK_SET);
926  ogg_reset(s);
927 
928  while ( avio_tell(bc) <= pos_limit
929  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
930  if (i == stream_index) {
931  struct ogg_stream *os = ogg->streams + stream_index;
932  // Do not trust the last timestamps of an ogm video
933  if ( (os->flags & OGG_FLAG_EOS)
934  && !(os->flags & OGG_FLAG_BOS)
935  && os->codec == &ff_ogm_video_codec)
936  continue;
937  pts = ogg_calc_pts(s, i, NULL);
939  if (os->pflags & AV_PKT_FLAG_KEY) {
940  keypos = *pos_arg;
941  } else if (os->keyframe_seek) {
942  // if we had a previous keyframe but no pts for it,
943  // return that keyframe with this pts value.
944  if (keypos >= 0)
945  *pos_arg = keypos;
946  else
948  }
949  }
950  if (pts != AV_NOPTS_VALUE)
951  break;
952  }
953  ogg_reset(s);
954  return pts;
955 }
956 
957 static int ogg_read_seek(AVFormatContext *s, int stream_index,
958  int64_t timestamp, int flags)
959 {
960  struct ogg *ogg = s->priv_data;
961  struct ogg_stream *os = ogg->streams + stream_index;
962  int ret;
963 
964  av_assert0(stream_index < ogg->nstreams);
965  // Ensure everything is reset even when seeking via
966  // the generated index.
967  ogg_reset(s);
968 
969  // Try seeking to a keyframe first. If this fails (very possible),
970  // av_seek_frame will fall back to ignoring keyframes
971  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
972  && !(flags & AVSEEK_FLAG_ANY))
973  os->keyframe_seek = 1;
974 
975  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
976  ogg_reset(s);
977  os = ogg->streams + stream_index;
978  if (ret < 0)
979  os->keyframe_seek = 0;
980  return ret;
981 }
982 
983 static int ogg_probe(const AVProbeData *p)
984 {
985  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
986  return AVPROBE_SCORE_MAX;
987  return 0;
988 }
989 
991  .p.name = "ogg",
992  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
993  .p.extensions = "ogg",
995  .priv_data_size = sizeof(struct ogg),
996  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
997  .read_probe = ogg_probe,
998  .read_header = ogg_read_header,
999  .read_packet = ogg_read_packet,
1000  .read_close = ogg_read_close,
1001  .read_seek = ogg_read_seek,
1002  .read_timestamp = ogg_read_timestamp,
1003 };
ff_old_flac_codec
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:167
flags
const SwsFlags flags[]
Definition: swscale.c:72
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:810
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:90
ff_old_dirac_codec
const struct ogg_codec ff_old_dirac_codec
Definition: oggparsedirac.c:126
AVPacket::data
uint8_t * data
Definition: packet.h:595
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:93
ogg_read_header
static int ogg_read_header(AVFormatContext *s)
Definition: oggdec.c:737
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:613
ogg_stream::nb_header
int nb_header
set to the number of parsed headers
Definition: oggdec.h:92
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:485
ogg
Definition: oggdec.h:111
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:623
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:99
ff_ogg_demuxer
const FFInputFormat ff_ogg_demuxer
Definition: oggdec.c:990
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:464
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:900
ogg_gptopts
static uint64_t ogg_gptopts(AVFormatContext *s, int i, uint64_t gp, int64_t *dts)
Definition: oggdec.h:190
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:2545
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:480
ogg::headers
int headers
Definition: oggdec.h:114
pts
static int64_t pts
Definition: transcode_aac.c:644
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
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:124
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:551
ogg_stream::got_data
int got_data
1 if the stream got some data (non-initial packets), 0 otherwise
Definition: oggdec.h:91
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:88
FFFormatContext::data_offset
int64_t data_offset
offset of the first packet
Definition: internal.h:89
ogg::curidx
int curidx
Definition: oggdec.h:115
ogg_stream::new_metadata
uint8_t * new_metadata
Definition: oggdec.h:96
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:1284
ogg_stream::replace
int replace
Definition: oggdec.h:95
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:452
ogg_read_seek
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: oggdec.c:957
ogg::page_pos
int64_t page_pos
file offset of the current page
Definition: oggdec.h:116
ogg::streams
struct ogg_stream * streams
Definition: oggdec.h:112
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:653
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:94
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:722
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:100
ogg_stream::keyframe_seek
int keyframe_seek
Definition: oggdec.h:89
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.
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:594
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:601
ogg::state
struct ogg_state * state
Definition: oggdec.h:117
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:113
ogg_stream::sync_pos
int64_t sync_pos
file offset of the first page needed to reconstruct the current packet
Definition: oggdec.h:80
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
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:588
ogg_stream
Definition: oggdec.h:67
avio_internal.h
AV_CODEC_ID_THEORA
@ AV_CODEC_ID_THEORA
Definition: codec_id.h:82
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:120
ff_skeleton_codec
const struct ogg_codec ff_skeleton_codec
Definition: oggparseskeleton.c:96
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:916
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:759
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:747
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:178
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:831
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:597
ogg_stream::new_metadata_size
size_t new_metadata_size
Definition: oggdec.h:97
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
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:481
mem.h
OGG_FLAG_EOS
#define OGG_FLAG_EOS
Definition: oggdec.h:122
ogg_state
Definition: oggdec.h:103
ogg_calc_pts
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
Definition: oggdec.c:780
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
ogg_probe
static int ogg_probe(const AVProbeData *p)
Definition: oggdec.c:983
AVPacket
This structure stores compressed data.
Definition: packet.h:572
ogg_stream::new_extradata
uint8_t * new_extradata
Definition: oggdec.h:98
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:121
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:615
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:192
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:94
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