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[] = {
53  &ff_vp8_codec,
60  NULL
61 };
62 
63 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
64 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
65 static int ogg_restore(AVFormatContext *s);
66 
67 static void free_stream(AVFormatContext *s, int i)
68 {
69  struct ogg *ogg = s->priv_data;
70  struct ogg_stream *stream = &ogg->streams[i];
71 
72  av_freep(&stream->buf);
73  if (stream->codec &&
74  stream->codec->cleanup) {
75  stream->codec->cleanup(s, i);
76  }
77 
78  av_freep(&stream->private);
79  av_freep(&stream->new_metadata);
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  }
110 
111  ogg->state = ost;
112 
113  if (ret < 0)
114  ogg_restore(s);
115 
116  return ret;
117 }
118 
120 {
121  struct ogg *ogg = s->priv_data;
122  AVIOContext *bc = s->pb;
123  struct ogg_state *ost = ogg->state;
124  int i, err;
125 
126  if (!ost)
127  return 0;
128 
129  ogg->state = ost->next;
130 
131  for (i = 0; i < ogg->nstreams; i++) {
132  struct ogg_stream *stream = &ogg->streams[i];
133  av_freep(&stream->buf);
134  av_freep(&stream->new_metadata);
135 
136  if (i >= ost->nstreams || !ost->streams[i].private) {
137  free_stream(s, i);
138  }
139  }
140 
141  avio_seek(bc, ost->pos, SEEK_SET);
142  ogg->page_pos = -1;
143  ogg->curidx = ost->curidx;
144  ogg->nstreams = ost->nstreams;
145  if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
146  sizeof(*ogg->streams))) < 0) {
147  ogg->nstreams = 0;
148  return err;
149  } else
150  memcpy(ogg->streams, ost->streams,
151  ost->nstreams * sizeof(*ogg->streams));
152 
153  av_free(ost);
154 
155  return 0;
156 }
157 
159 {
160  struct ogg *ogg = s->priv_data;
161  int i;
162  int64_t start_pos = avio_tell(s->pb);
163 
164  for (i = 0; i < ogg->nstreams; i++) {
165  struct ogg_stream *os = ogg->streams + i;
166  os->bufpos = 0;
167  os->pstart = 0;
168  os->psize = 0;
169  os->granule = -1;
170  os->lastpts = AV_NOPTS_VALUE;
171  os->lastdts = AV_NOPTS_VALUE;
172  os->sync_pos = -1;
173  os->page_pos = 0;
174  os->nsegs = 0;
175  os->segp = 0;
176  os->incomplete = 0;
177  os->got_data = 0;
178  if (start_pos <= ffformatcontext(s)->data_offset) {
179  os->lastpts = 0;
180  }
181  os->start_trimming = 0;
182  os->end_trimming = 0;
183  av_freep(&os->new_metadata);
184  os->new_metadata_size = 0;
185  }
186 
187  ogg->page_pos = -1;
188  ogg->curidx = -1;
189 
190  return 0;
191 }
192 
193 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
194 {
195  int i;
196 
197  for (i = 0; ogg_codecs[i]; i++)
198  if (size >= ogg_codecs[i]->magicsize &&
199  !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
200  return ogg_codecs[i];
201 
202  return NULL;
203 }
204 
205 /**
206  * Replace the current stream with a new one. This is a typical webradio
207  * situation where a new audio stream spawn (identified with a new serial) and
208  * must replace the previous one (track switch).
209  */
210 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, int page_size,
211  int probing)
212 {
213  struct ogg *ogg = s->priv_data;
214  struct ogg_stream *os;
215  const struct ogg_codec *codec;
216  int i = 0;
217 
218  if (ogg->nstreams != 1) {
219  avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
220  return AVERROR_PATCHWELCOME;
221  }
222 
223  /* Check for codecs */
224  codec = ogg_find_codec(magic, page_size);
225  if (!codec && !probing) {
226  av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
227  return AVERROR_INVALIDDATA;
228  }
229 
230  os = &ogg->streams[0];
231  if (os->codec != codec)
232  return AVERROR(EINVAL);
233 
234  os->serial = serial;
235  os->codec = codec;
236  os->serial = serial;
237  os->lastpts = 0;
238  os->lastdts = 0;
239  os->start_trimming = 0;
240  os->end_trimming = 0;
241 
242  /* Chained files have extradata as a new packet */
243  if (codec == &ff_opus_codec)
244  os->header = -1;
245 
246  return i;
247 }
248 
249 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
250 {
251  struct ogg *ogg = s->priv_data;
252  int idx = ogg->nstreams;
253  AVStream *st;
254  struct ogg_stream *os;
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 (!(os = av_realloc_array(ogg->streams, ogg->nstreams + 1,
264  sizeof(*ogg->streams))))
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) {
304  uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_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  if (ret < 0)
369  return ret;
370  start_pos = avio_tell(bc);
371 
372  version = avio_r8(bc);
373  flags = avio_r8(bc);
374  gp = avio_rl64(bc);
375  serial = avio_rl32(bc);
376  avio_skip(bc, 4); /* seq */
377 
378  crc_tmp = ffio_get_checksum(bc);
379  crc = avio_rb32(bc);
380  crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
382 
383  nsegs = avio_r8(bc);
384  page_pos = avio_tell(bc) - 27;
385 
386  ret = avio_read(bc, segments, nsegs);
387  if (ret < nsegs)
388  return ret < 0 ? ret : AVERROR_EOF;
389 
390  for (i = 0; i < nsegs; i++)
391  size += segments[i];
392 
393  idx = ogg_find_stream(ogg, serial);
394  if (idx >= 0) {
395  os = ogg->streams + idx;
396 
397  ret = buf_realloc(os, size);
398  if (ret < 0)
399  return ret;
400 
401  readout_buf = os->buf + os->bufpos;
402  } else {
403  readout_buf = av_malloc(size);
404  }
405 
406  ret = avio_read(bc, readout_buf, size);
407  if (ret < size) {
408  if (idx < 0)
409  av_free(readout_buf);
410  return ret < 0 ? ret : AVERROR_EOF;
411  }
412 
413  if (crc ^ ffio_get_checksum(bc)) {
414  av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
415  if (idx < 0)
416  av_free(readout_buf);
417  avio_seek(bc, start_pos, SEEK_SET);
418  *sid = -1;
419  return 0;
420  }
421 
422  /* Since we're almost sure its a valid packet, checking the version after
423  * the checksum lets the demuxer be more tolerant */
424  if (version) {
425  av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
426  if (idx < 0)
427  av_free(readout_buf);
428  avio_seek(bc, start_pos, SEEK_SET);
429  *sid = -1;
430  return 0;
431  }
432 
433  /* CRC is correct so we can be 99% sure there's an actual change here */
434  if (idx < 0) {
435  if (data_packets_seen(ogg))
436  idx = ogg_replace_stream(s, serial, readout_buf, size, probing);
437  else
438  idx = ogg_new_stream(s, serial);
439 
440  if (idx < 0) {
441  av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
442  av_free(readout_buf);
443  return idx;
444  }
445 
446  os = ogg->streams + idx;
447 
448  ret = buf_realloc(os, size);
449  if (ret < 0) {
450  av_free(readout_buf);
451  return ret;
452  }
453 
454  memcpy(os->buf + os->bufpos, readout_buf, size);
455  av_free(readout_buf);
456  }
457 
458  ogg->page_pos = page_pos;
459  os->page_pos = page_pos;
460  os->nsegs = nsegs;
461  os->segp = 0;
462  os->got_data = !(flags & OGG_FLAG_BOS);
463  os->bufpos += size;
464  os->granule = gp;
465  os->flags = flags;
466  memcpy(os->segments, segments, nsegs);
467  memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
468 
469  if (flags & OGG_FLAG_CONT || os->incomplete) {
470  if (!os->psize) {
471  // If this is the very first segment we started
472  // playback in the middle of a continuation packet.
473  // Discard it since we missed the start of it.
474  while (os->segp < os->nsegs) {
475  int seg = os->segments[os->segp++];
476  os->pstart += seg;
477  if (seg < 255)
478  break;
479  }
480  os->sync_pos = os->page_pos;
481  }
482  } else {
483  os->psize = 0;
484  os->sync_pos = os->page_pos;
485  }
486 
487  /* This function is always called with sid != NULL */
488  *sid = idx;
489 
490  return 0;
491 }
492 
493 /**
494  * @brief find the next Ogg packet
495  * @param *sid is set to the stream for the packet or -1 if there is
496  * no matching stream, in that case assume all other return
497  * values to be uninitialized.
498  * @return negative value on error or EOF.
499  */
500 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
501  int64_t *fpos)
502 {
503  FFFormatContext *const si = ffformatcontext(s);
504  struct ogg *ogg = s->priv_data;
505  int idx, i, ret;
506  struct ogg_stream *os;
507  int complete = 0;
508  int segp = 0, psize = 0;
509 
510  av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
511  if (sid)
512  *sid = -1;
513 
514  do {
515  idx = ogg->curidx;
516 
517  while (idx < 0) {
518  ret = ogg_read_page(s, &idx, 0);
519  if (ret < 0)
520  return ret;
521  }
522 
523  os = ogg->streams + idx;
524 
525  av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
526  idx, os->pstart, os->psize, os->segp, os->nsegs);
527 
528  if (!os->codec) {
529  if (os->header < 0) {
530  os->codec = ogg_find_codec(os->buf, os->bufpos);
531  if (!os->codec) {
532  av_log(s, AV_LOG_WARNING, "Codec not found\n");
533  os->header = 0;
534  return 0;
535  }
536  } else {
537  return 0;
538  }
539  }
540 
541  segp = os->segp;
542  psize = os->psize;
543 
544  while (os->segp < os->nsegs) {
545  int ss = os->segments[os->segp++];
546  os->psize += ss;
547  if (ss < 255) {
548  complete = 1;
549  break;
550  }
551  }
552 
553  if (!complete && os->segp == os->nsegs) {
554  ogg->curidx = -1;
555  // Do not set incomplete for empty packets.
556  // Together with the code in ogg_read_page
557  // that discards all continuation of empty packets
558  // we would get an infinite loop.
559  os->incomplete = !!os->psize;
560  }
561  } while (!complete);
562 
563 
564  if (os->granule == -1)
566  "Page at %"PRId64" is missing granule\n",
567  os->page_pos);
568 
569  ogg->curidx = idx;
570  os->incomplete = 0;
571 
572  if (os->header) {
573  if ((ret = os->codec->header(s, idx)) < 0) {
574  av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
575  return ret;
576  }
577  os->header = ret;
578  if (!os->header) {
579  os->segp = segp;
580  os->psize = psize;
581 
582  // We have reached the first non-header packet in this stream.
583  // Unfortunately more header packets may still follow for others,
584  // but if we continue with header parsing we may lose data packets.
585  ogg->headers = 1;
586 
587  // Update the header state for all streams and
588  // compute the data_offset.
589  if (!si->data_offset)
590  si->data_offset = os->sync_pos;
591 
592  for (i = 0; i < ogg->nstreams; i++) {
593  struct ogg_stream *cur_os = ogg->streams + i;
594 
595  // if we have a partial non-header packet, its start is
596  // obviously at or after the data start
597  if (cur_os->incomplete)
598  si->data_offset = FFMIN(si->data_offset, cur_os->sync_pos);
599  }
600  } else {
601  os->nb_header++;
602  os->pstart += os->psize;
603  os->psize = 0;
604  }
605  } else {
606  os->pflags = 0;
607  os->pduration = 0;
608  if (os->codec && os->codec->packet) {
609  if ((ret = os->codec->packet(s, idx)) < 0) {
610  av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
611  return ret;
612  }
613  }
614  if (sid)
615  *sid = idx;
616  if (dstart)
617  *dstart = os->pstart;
618  if (dsize)
619  *dsize = os->psize;
620  if (fpos)
621  *fpos = os->sync_pos;
622  os->pstart += os->psize;
623  os->psize = 0;
624  if(os->pstart == os->bufpos)
625  os->bufpos = os->pstart = 0;
626  os->sync_pos = os->page_pos;
627  }
628 
629  // determine whether there are more complete packets in this page
630  // if not, the page's granule will apply to this packet
631  os->page_end = 1;
632  for (i = os->segp; i < os->nsegs; i++)
633  if (os->segments[i] < 255) {
634  os->page_end = 0;
635  break;
636  }
637 
638  if (os->segp == os->nsegs)
639  ogg->curidx = -1;
640 
641  return 0;
642 }
643 
645 {
646  struct ogg *ogg = s->priv_data;
647  int i, ret;
648  int64_t size, end;
649  int streams_left=0;
650 
651  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
652  return 0;
653 
654 // already set
655  if (s->duration != AV_NOPTS_VALUE)
656  return 0;
657 
658  size = avio_size(s->pb);
659  if (size < 0)
660  return 0;
661  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
662 
663  ret = ogg_save(s);
664  if (ret < 0)
665  return ret;
666  avio_seek(s->pb, end, SEEK_SET);
667  ogg->page_pos = -1;
668 
669  while (!ogg_read_page(s, &i, 1)) {
670  if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
671  ogg->streams[i].codec) {
672  s->streams[i]->duration =
674  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
675  s->streams[i]->duration -= s->streams[i]->start_time;
676  streams_left-= (ogg->streams[i].got_start==-1);
677  ogg->streams[i].got_start= 1;
678  } else if(!ogg->streams[i].got_start) {
679  ogg->streams[i].got_start= -1;
680  streams_left++;
681  }
682  }
683  }
684 
685  ogg_restore(s);
686 
687  ret = ogg_save(s);
688  if (ret < 0)
689  return ret;
690 
691  avio_seek (s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
692  ogg_reset(s);
693  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
694  int64_t pts;
695  if (i < 0) continue;
696  pts = ogg_calc_pts(s, i, NULL);
697  if (s->streams[i]->duration == AV_NOPTS_VALUE)
698  continue;
699  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
700  s->streams[i]->duration -= pts;
701  ogg->streams[i].got_start= 1;
702  streams_left--;
703  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
704  ogg->streams[i].got_start= 1;
705  streams_left--;
706  }
707  }
708  ogg_restore (s);
709 
710  return 0;
711 }
712 
714 {
715  struct ogg *ogg = s->priv_data;
716  int i;
717 
718  for (i = 0; i < ogg->nstreams; i++) {
719  free_stream(s, i);
720  }
721 
722  ogg->nstreams = 0;
723 
724  av_freep(&ogg->streams);
725  return 0;
726 }
727 
729 {
730  struct ogg *ogg = s->priv_data;
731  int ret, i;
732 
733  ogg->curidx = -1;
734 
735  //linear headers seek from start
736  do {
737  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
738  if (ret < 0)
739  return ret;
740  } while (!ogg->headers);
741  av_log(s, AV_LOG_TRACE, "found headers\n");
742 
743  for (i = 0; i < ogg->nstreams; i++) {
744  struct ogg_stream *os = ogg->streams + i;
745 
746  if (ogg->streams[i].header < 0) {
747  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
748  ogg->streams[i].codec = NULL;
750  } else if (os->codec && os->nb_header < os->codec->nb_header) {
752  "Headers mismatch for stream %d: "
753  "expected %d received %d.\n",
754  i, os->codec->nb_header, os->nb_header);
755  if (s->error_recognition & AV_EF_EXPLODE)
756  return AVERROR_INVALIDDATA;
757  }
759  os->lastpts = s->streams[i]->start_time =
760  ogg_gptopts(s, i, os->start_granule, NULL);
761  }
762 
763  //linear granulepos seek from end
764  ret = ogg_get_length(s);
765  if (ret < 0)
766  return ret;
767 
768  return 0;
769 }
770 
771 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
772 {
773  struct ogg *ogg = s->priv_data;
774  struct ogg_stream *os = ogg->streams + idx;
775  int64_t pts = AV_NOPTS_VALUE;
776 
777  if (dts)
778  *dts = AV_NOPTS_VALUE;
779 
780  if (os->lastpts != AV_NOPTS_VALUE) {
781  pts = os->lastpts;
782  os->lastpts = AV_NOPTS_VALUE;
783  }
784  if (os->lastdts != AV_NOPTS_VALUE) {
785  if (dts)
786  *dts = os->lastdts;
787  os->lastdts = AV_NOPTS_VALUE;
788  }
789  if (os->page_end) {
790  if (os->granule != -1LL) {
791  if (os->codec && os->codec->granule_is_start)
792  pts = ogg_gptopts(s, idx, os->granule, dts);
793  else
794  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
795  os->granule = -1LL;
796  }
797  }
798  return pts;
799 }
800 
801 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
802 {
803  struct ogg *ogg = s->priv_data;
804  struct ogg_stream *os = ogg->streams + idx;
805  int invalid = 0;
806  if (psize) {
807  switch (s->streams[idx]->codecpar->codec_id) {
808  case AV_CODEC_ID_THEORA:
809  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
810  break;
811  case AV_CODEC_ID_VP8:
812  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
813  }
814  if (invalid) {
815  os->pflags ^= AV_PKT_FLAG_KEY;
816  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
817  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
818  }
819  }
820 }
821 
823 {
824  struct ogg *ogg;
825  struct ogg_stream *os;
826  int idx, ret;
827  int pstart, psize;
828  int64_t fpos, pts, dts;
829 
830  if (s->io_repositioned) {
831  ogg_reset(s);
832  s->io_repositioned = 0;
833  }
834 
835  //Get an ogg packet
836 retry:
837  do {
838  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
839  if (ret < 0)
840  return ret;
841  } while (idx < 0 || !s->streams[idx]);
842 
843  ogg = s->priv_data;
844  os = ogg->streams + idx;
845 
846  // pflags might not be set until after this
847  pts = ogg_calc_pts(s, idx, &dts);
849 
850  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
851  goto retry;
852  os->keyframe_seek = 0;
853 
854  //Alloc a pkt
856  if (ret < 0)
857  return ret;
858  pkt->stream_index = idx;
859  memcpy(pkt->data, os->buf + pstart, psize);
860 
861  pkt->pts = pts;
862  pkt->dts = dts;
863  pkt->flags = os->pflags;
864  pkt->duration = os->pduration;
865  pkt->pos = fpos;
866 
867  if (os->start_trimming || os->end_trimming) {
868  uint8_t *side_data = av_packet_new_side_data(pkt,
870  10);
871  if(!side_data)
872  return AVERROR(ENOMEM);
873  AV_WL32(side_data + 0, os->start_trimming);
874  AV_WL32(side_data + 4, os->end_trimming);
875  os->start_trimming = 0;
876  os->end_trimming = 0;
877  }
878 
879  if (os->new_metadata) {
882  if (ret < 0)
883  return ret;
884 
885  os->new_metadata = NULL;
886  os->new_metadata_size = 0;
887  }
888 
889  return psize;
890 }
891 
892 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
893  int64_t *pos_arg, int64_t pos_limit)
894 {
895  struct ogg *ogg = s->priv_data;
896  AVIOContext *bc = s->pb;
897  int64_t pts = AV_NOPTS_VALUE;
898  int64_t keypos = -1;
899  int i;
900  int pstart, psize;
901  avio_seek(bc, *pos_arg, SEEK_SET);
902  ogg_reset(s);
903 
904  while ( avio_tell(bc) <= pos_limit
905  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
906  if (i == stream_index) {
907  struct ogg_stream *os = ogg->streams + stream_index;
908  // Do not trust the last timestamps of an ogm video
909  if ( (os->flags & OGG_FLAG_EOS)
910  && !(os->flags & OGG_FLAG_BOS)
911  && os->codec == &ff_ogm_video_codec)
912  continue;
913  pts = ogg_calc_pts(s, i, NULL);
915  if (os->pflags & AV_PKT_FLAG_KEY) {
916  keypos = *pos_arg;
917  } else if (os->keyframe_seek) {
918  // if we had a previous keyframe but no pts for it,
919  // return that keyframe with this pts value.
920  if (keypos >= 0)
921  *pos_arg = keypos;
922  else
924  }
925  }
926  if (pts != AV_NOPTS_VALUE)
927  break;
928  }
929  ogg_reset(s);
930  return pts;
931 }
932 
933 static int ogg_read_seek(AVFormatContext *s, int stream_index,
934  int64_t timestamp, int flags)
935 {
936  struct ogg *ogg = s->priv_data;
937  struct ogg_stream *os = ogg->streams + stream_index;
938  int ret;
939 
940  av_assert0(stream_index < ogg->nstreams);
941  // Ensure everything is reset even when seeking via
942  // the generated index.
943  ogg_reset(s);
944 
945  // Try seeking to a keyframe first. If this fails (very possible),
946  // av_seek_frame will fall back to ignoring keyframes
947  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
948  && !(flags & AVSEEK_FLAG_ANY))
949  os->keyframe_seek = 1;
950 
951  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
952  ogg_reset(s);
953  os = ogg->streams + stream_index;
954  if (ret < 0)
955  os->keyframe_seek = 0;
956  return ret;
957 }
958 
959 static int ogg_probe(const AVProbeData *p)
960 {
961  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
962  return AVPROBE_SCORE_MAX;
963  return 0;
964 }
965 
967  .p.name = "ogg",
968  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
969  .p.extensions = "ogg",
971  .priv_data_size = sizeof(struct ogg),
972  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
973  .read_probe = ogg_probe,
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 };
ff_old_flac_codec
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:136
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:186
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:289
ogg_stream::segp
int segp
Definition: oggdec.h:78
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:71
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:424
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:801
ffformatcontext
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition: internal.h:188
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ogg_stream::bufpos
unsigned int bufpos
Definition: oggdec.h:63
ff_vp8_codec
const struct ogg_codec ff_vp8_codec
Definition: oggparsevp8.c:139
ogg_stream::got_start
int got_start
Definition: oggdec.h:83
ff_old_dirac_codec
const struct ogg_codec ff_old_dirac_codec
Definition: oggparsedirac.c:126
AVPacket::data
uint8_t * data
Definition: packet.h:524
ogg_stream::granule
uint64_t granule
Definition: oggdec.h:69
ogg_stream::start_trimming
int start_trimming
set the number of packets to drop from the start
Definition: oggdec.h:86
ogg_read_header
static int ogg_read_header(AVFormatContext *s)
Definition: oggdec.c:728
ogg_new_stream
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
Definition: oggdec.c:249
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:542
ogg_stream::nb_header
int nb_header
set to the number of parsed headers
Definition: oggdec.h:85
ogg_stream::buf
uint8_t * buf
Definition: oggdec.h:61
ogg_stream::nsegs
int nsegs
Definition: oggdec.h:78
ogg_reset
static int ogg_reset(AVFormatContext *s)
Definition: oggdec.c:158
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:101
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
ost
static AVStream * ost
Definition: vaapi_transcode.c:42
ff_vorbis_codec
const struct ogg_codec ff_vorbis_codec
Definition: oggparsevorbis.c:511
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
ffio_get_checksum
unsigned long ffio_get_checksum(AVIOContext *s)
Definition: aviobuf.c:583
ff_flac_codec
const struct ogg_codec ff_flac_codec
Definition: oggparseflac.c:129
ff_ogg_demuxer
const FFInputFormat ff_ogg_demuxer
Definition: oggdec.c:966
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
ogg_codec::packet
int(* packet)(AVFormatContext *, int)
Definition: oggdec.h:41
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:853
ogg_gptopts
static uint64_t ogg_gptopts(AVFormatContext *s, int i, uint64_t gp, int64_t *dts)
Definition: oggdec.h:167
ogg_stream::serial
uint32_t serial
Definition: oggdec.h:68
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:2447
ogg_stream::lastdts
int64_t lastdts
Definition: oggdec.h:72
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:104
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:500
free_stream
static void free_stream(AVFormatContext *s, int i)
Definition: oggdec.c:67
avassert.h
ogg_stream::pstart
unsigned int pstart
Definition: oggdec.h:64
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:114
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:553
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
ogg_stream::got_data
int got_data
1 if the stream got some data (non-initial packets), 0 otherwise
Definition: oggdec.h:84
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ogg_stream::page_end
int page_end
current packet is the last one completed in the page
Definition: oggdec.h:81
FFFormatContext::data_offset
int64_t data_offset
offset of the first packet
Definition: internal.h:101
ogg::curidx
int curidx
Definition: oggdec.h:105
ogg_stream::new_metadata
uint8_t * new_metadata
Definition: oggdec.h:88
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:74
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
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:210
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:75
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
ogg_read_seek
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: oggdec.c:933
ogg::page_pos
int64_t page_pos
file offset of the current page
Definition: oggdec.h:106
ogg::streams
struct ogg_stream * streams
Definition: oggdec.h:102
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:644
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:730
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:300
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:713
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:122
sp
#define sp
Definition: regdef.h:63
ogg_stream::private
void * private
Definition: oggdec.h:90
ogg_stream::keyframe_seek
int keyframe_seek
Definition: oggdec.h:82
size
int size
Definition: twinvq_data.h:10344
AV_PKT_DATA_METADATA_UPDATE
@ AV_PKT_DATA_METADATA_UPDATE
A list of zero terminated key/value strings.
Definition: packet.h:210
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:591
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:523
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
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:1023
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
ogg::state
struct ogg_state * state
Definition: oggdec.h:107
version
version
Definition: libkvazaar.c:321
ff_crc04C11DB7_update
unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition: aviobuf.c:565
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
MAX_PAGE_SIZE
#define MAX_PAGE_SIZE
Definition: oggdec.c:41
ogg_stream::pflags
unsigned int pflags
Definition: oggdec.h:66
ogg::nstreams
int nstreams
Definition: oggdec.h:103
ogg_stream::sync_pos
int64_t sync_pos
file offset of the first page needed to reconstruct the current packet
Definition: oggdec.h:73
ogg_stream::incomplete
int incomplete
whether we're expecting a continuation in the next page
Definition: oggdec.h:80
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
ogg_stream
Definition: oggdec.h:60
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:110
ff_skeleton_codec
const struct ogg_codec ff_skeleton_codec
Definition: oggparseskeleton.c:96
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:256
demux.h
ogg_codecs
static const struct ogg_codec *const ogg_codecs[]
Definition: oggdec.c:44
ogg_stream::header
int header
Definition: oggdec.h:77
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:892
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:755
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
avformat.h
ogg_find_codec
static const struct ogg_codec * ogg_find_codec(uint8_t *buf, int size)
Definition: oggdec.c:193
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:155
ogg_codec::cleanup
void(* cleanup)(AVFormatContext *s, int idx)
Definition: oggdec.h:57
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:119
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
ogg_stream::start_granule
uint64_t start_granule
Definition: oggdec.h:70
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommmends skipping the specified number of samples.
Definition: packet.h:157
ogg_read_packet
static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggdec.c:822
AVPacket::stream_index
int stream_index
Definition: packet.h:526
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
ogg_stream::new_metadata_size
size_t new_metadata_size
Definition: oggdec.h:89
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ogg_codec::nb_header
int nb_header
Number of expected headers.
Definition: oggdec.h:56
ogg_stream::segments
uint8_t segments[255]
Definition: oggdec.h:79
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:112
ogg_state
Definition: oggdec.h:93
ogg_calc_pts
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
Definition: oggdec.c:771
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
ff_celt_codec
const struct ogg_codec ff_celt_codec
Definition: oggparsecelt.c:93
ogg_probe
static int ogg_probe(const AVProbeData *p)
Definition: oggdec.c:959
AVPacket
This structure stores compressed data.
Definition: packet.h:501
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
ogg_stream::psize
unsigned int psize
Definition: oggdec.h:65
OGG_FLAG_BOS
#define OGG_FLAG_BOS
Definition: oggdec.h:111
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:544
FFInputFormat
Definition: demux.h:37
avio_rl64
uint64_t avio_rl64(AVIOContext *s)
Definition: aviobuf.c:738
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
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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:314
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
ogg_stream::end_trimming
int end_trimming
set the number of packets to drop from the end
Definition: oggdec.h:87
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:52
ogg_stream::pduration
unsigned int pduration
Definition: oggdec.h:67
ff_theora_codec
const struct ogg_codec ff_theora_codec
Definition: oggparsetheora.c:211
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
ogg_stream::codec
const struct ogg_codec * codec
Definition: oggdec.h:76
ff_opus_codec
const struct ogg_codec ff_opus_codec
Definition: oggparseopus.c:182
ogg_stream::bufsize
unsigned int bufsize
Definition: oggdec.h:62
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346