FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
oggdec.c
Go to the documentation of this file.
1 /*
2  * Ogg bitstream support
3  * Luca Barbato <lu_zero@gentoo.org>
4  * Based on tcvp implementation
5  */
6 
7 /*
8  Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
9 
10  Permission is hereby granted, free of charge, to any person
11  obtaining a copy of this software and associated documentation
12  files (the "Software"), to deal in the Software without
13  restriction, including without limitation the rights to use, copy,
14  modify, merge, publish, distribute, sublicense, and/or sell copies
15  of the Software, and to permit persons to whom the Software is
16  furnished to do so, subject to the following conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  DEALINGS IN THE SOFTWARE.
29  */
30 
31 #include <stdio.h>
32 #include "libavutil/avassert.h"
33 #include "libavutil/intreadwrite.h"
34 #include "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  av_freep(&stream->new_extradata);
81 }
82 
83 //FIXME We could avoid some structure duplication
85 {
86  struct ogg *ogg = s->priv_data;
87  struct ogg_state *ost =
88  av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
89  int i;
90  int ret = 0;
91 
92  if (!ost)
93  return AVERROR(ENOMEM);
94 
95  ost->pos = avio_tell(s->pb);
96  ost->curidx = ogg->curidx;
97  ost->next = ogg->state;
98  ost->nstreams = ogg->nstreams;
99  memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
100 
101  for (i = 0; i < ogg->nstreams; i++) {
102  struct ogg_stream *os = ogg->streams + i;
104  if (os->buf)
105  memcpy(os->buf, ost->streams[i].buf, os->bufpos);
106  else
107  ret = AVERROR(ENOMEM);
108  os->new_metadata = NULL;
109  os->new_metadata_size = 0;
110  }
111 
112  ogg->state = ost;
113 
114  if (ret < 0)
115  ogg_restore(s);
116 
117  return ret;
118 }
119 
121 {
122  struct ogg *ogg = s->priv_data;
123  AVIOContext *bc = s->pb;
124  struct ogg_state *ost = ogg->state;
125  int i, err;
126 
127  if (!ost)
128  return 0;
129 
130  ogg->state = ost->next;
131 
132  for (i = 0; i < ogg->nstreams; i++) {
133  struct ogg_stream *stream = &ogg->streams[i];
134  av_freep(&stream->buf);
135  av_freep(&stream->new_metadata);
136 
137  if (i >= ost->nstreams || !ost->streams[i].private) {
138  free_stream(s, i);
139  }
140  }
141 
142  avio_seek(bc, ost->pos, SEEK_SET);
143  ogg->page_pos = -1;
144  ogg->curidx = ost->curidx;
145  ogg->nstreams = ost->nstreams;
146  if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
147  sizeof(*ogg->streams))) < 0) {
148  ogg->nstreams = 0;
149  return err;
150  } else
151  memcpy(ogg->streams, ost->streams,
152  ost->nstreams * sizeof(*ogg->streams));
153 
154  av_free(ost);
155 
156  return 0;
157 }
158 
160 {
161  struct ogg *ogg = s->priv_data;
162  int i;
163  int64_t start_pos = avio_tell(s->pb);
164 
165  for (i = 0; i < ogg->nstreams; i++) {
166  struct ogg_stream *os = ogg->streams + i;
167  os->bufpos = 0;
168  os->pstart = 0;
169  os->psize = 0;
170  os->granule = -1;
171  os->lastpts = AV_NOPTS_VALUE;
172  os->lastdts = AV_NOPTS_VALUE;
173  os->sync_pos = -1;
174  os->page_pos = 0;
175  os->nsegs = 0;
176  os->segp = 0;
177  os->incomplete = 0;
178  os->got_data = 0;
179  if (start_pos <= ffformatcontext(s)->data_offset) {
180  os->lastpts = 0;
181  }
182  os->start_trimming = 0;
183  os->end_trimming = 0;
184  av_freep(&os->new_metadata);
185  os->new_metadata_size = 0;
186  }
187 
188  ogg->page_pos = -1;
189  ogg->curidx = -1;
190 
191  return 0;
192 }
193 
194 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
195 {
196  int i;
197 
198  for (i = 0; ogg_codecs[i]; i++)
199  if (size >= ogg_codecs[i]->magicsize &&
200  !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
201  return ogg_codecs[i];
202 
203  return NULL;
204 }
205 
206 /**
207  * Replace the current stream with a new one. This is a typical webradio
208  * situation where a new audio stream spawn (identified with a new serial) and
209  * must replace the previous one (track switch).
210  */
211 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, int page_size,
212  int probing)
213 {
214  struct ogg *ogg = s->priv_data;
215  struct ogg_stream *os;
216  const struct ogg_codec *codec;
217  int i = 0;
218 
219  if (ogg->nstreams != 1) {
220  avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
221  return AVERROR_PATCHWELCOME;
222  }
223 
224  /* Check for codecs */
225  codec = ogg_find_codec(magic, page_size);
226  if (!codec && !probing) {
227  av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
228  return AVERROR_INVALIDDATA;
229  }
230 
231  os = &ogg->streams[0];
232  if (os->codec != codec)
233  return AVERROR(EINVAL);
234 
235  os->serial = serial;
236  os->codec = codec;
237  os->serial = serial;
238  os->lastpts = 0;
239  os->lastdts = 0;
240  os->start_trimming = 0;
241  os->end_trimming = 0;
242 
243  return i;
244 }
245 
246 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
247 {
248  struct ogg *ogg = s->priv_data;
249  int idx = ogg->nstreams;
250  AVStream *st;
251  struct ogg_stream *os;
252 
253  if (ogg->state) {
254  av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
255  "in between Ogg context save/restore operations.\n");
256  return AVERROR_BUG;
257  }
258 
259  /* Allocate and init a new Ogg Stream */
260  if (!(os = av_realloc_array(ogg->streams, ogg->nstreams + 1,
261  sizeof(*ogg->streams))))
262  return AVERROR(ENOMEM);
263  ogg->streams = os;
264  os = ogg->streams + idx;
265  memset(os, 0, sizeof(*os));
266  os->serial = serial;
269  os->header = -1;
271  if (!os->buf)
272  return AVERROR(ENOMEM);
273 
274  /* Create the associated AVStream */
275  st = avformat_new_stream(s, NULL);
276  if (!st) {
277  av_freep(&os->buf);
278  return AVERROR(ENOMEM);
279  }
280  st->id = idx;
281  avpriv_set_pts_info(st, 64, 1, 1000000);
282 
283  ogg->nstreams++;
284  return idx;
285 }
286 
287 static int data_packets_seen(const struct ogg *ogg)
288 {
289  int i;
290 
291  for (i = 0; i < ogg->nstreams; i++)
292  if (ogg->streams[i].got_data)
293  return 1;
294  return 0;
295 }
296 
297 static int buf_realloc(struct ogg_stream *os, int size)
298 {
299  /* Even if invalid guarantee there's enough memory to read the page */
300  if (os->bufsize - os->bufpos < size) {
301  uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
302  if (!nb)
303  return AVERROR(ENOMEM);
304  os->buf = nb;
305  os->bufsize *= 2;
306  }
307 
308  return 0;
309 }
310 
311 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
312 {
313  AVIOContext *bc = s->pb;
314  struct ogg *ogg = s->priv_data;
315  struct ogg_stream *os;
316  int ret, i = 0;
317  int flags, nsegs;
318  uint64_t gp;
319  uint32_t serial;
320  uint32_t crc, crc_tmp;
321  int size = 0, idx;
323  int64_t start_pos;
324  uint8_t sync[4];
325  uint8_t segments[255];
326  uint8_t *readout_buf;
327  int sp = 0;
328 
329  ret = avio_read(bc, sync, 4);
330  if (ret < 4)
331  return ret < 0 ? ret : AVERROR_EOF;
332 
333  do {
334  int c;
335 
336  if (sync[sp & 3] == 'O' &&
337  sync[(sp + 1) & 3] == 'g' &&
338  sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
339  break;
340 
341  if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
342  memset(sync, 0, 4);
343  avio_seek(bc, ogg->page_pos+4, SEEK_SET);
344  ogg->page_pos = -1;
345  }
346 
347  c = avio_r8(bc);
348 
349  if (avio_feof(bc))
350  return AVERROR_EOF;
351 
352  sync[sp++ & 3] = c;
353  } while (i++ < MAX_PAGE_SIZE);
354 
355  if (i >= MAX_PAGE_SIZE) {
356  av_log(s, AV_LOG_INFO, "cannot find sync word\n");
357  return AVERROR_INVALIDDATA;
358  }
359 
360  /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
361  ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
362 
363  /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
365  if (ret < 0)
366  return ret;
367  start_pos = avio_tell(bc);
368 
369  version = avio_r8(bc);
370  flags = avio_r8(bc);
371  gp = avio_rl64(bc);
372  serial = avio_rl32(bc);
373  avio_skip(bc, 4); /* seq */
374 
375  crc_tmp = ffio_get_checksum(bc);
376  crc = avio_rb32(bc);
377  crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
379 
380  nsegs = avio_r8(bc);
381  page_pos = avio_tell(bc) - 27;
382 
383  ret = avio_read(bc, segments, nsegs);
384  if (ret < nsegs)
385  return ret < 0 ? ret : AVERROR_EOF;
386 
387  for (i = 0; i < nsegs; i++)
388  size += segments[i];
389 
390  idx = ogg_find_stream(ogg, serial);
391  if (idx >= 0) {
392  os = ogg->streams + idx;
393 
394  ret = buf_realloc(os, size);
395  if (ret < 0)
396  return ret;
397 
398  readout_buf = os->buf + os->bufpos;
399  } else {
400  readout_buf = av_malloc(size);
401  }
402 
403  ret = avio_read(bc, readout_buf, size);
404  if (ret < size) {
405  if (idx < 0)
406  av_free(readout_buf);
407  return ret < 0 ? ret : AVERROR_EOF;
408  }
409 
410  if (crc ^ ffio_get_checksum(bc)) {
411  av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
412  if (idx < 0)
413  av_free(readout_buf);
414  avio_seek(bc, start_pos, SEEK_SET);
415  *sid = -1;
416  return 0;
417  }
418 
419  /* Since we're almost sure its a valid packet, checking the version after
420  * the checksum lets the demuxer be more tolerant */
421  if (version) {
422  av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
423  if (idx < 0)
424  av_free(readout_buf);
425  avio_seek(bc, start_pos, SEEK_SET);
426  *sid = -1;
427  return 0;
428  }
429 
430  /* CRC is correct so we can be 99% sure there's an actual change here */
431  if (idx < 0) {
432  if (data_packets_seen(ogg))
433  idx = ogg_replace_stream(s, serial, readout_buf, size, probing);
434  else
435  idx = ogg_new_stream(s, serial);
436 
437  if (idx < 0) {
438  av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
439  av_free(readout_buf);
440  return idx;
441  }
442 
443  os = ogg->streams + idx;
444 
445  ret = buf_realloc(os, size);
446  if (ret < 0) {
447  av_free(readout_buf);
448  return ret;
449  }
450 
451  memcpy(os->buf + os->bufpos, readout_buf, size);
452  av_free(readout_buf);
453  }
454 
455  ogg->page_pos = page_pos;
456  os->page_pos = page_pos;
457  os->nsegs = nsegs;
458  os->segp = 0;
459  os->got_data = !(flags & OGG_FLAG_BOS);
460  os->bufpos += size;
461  os->granule = gp;
462  os->flags = flags;
463  memcpy(os->segments, segments, nsegs);
464  memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
465 
466  if (flags & OGG_FLAG_CONT || os->incomplete) {
467  if (!os->psize) {
468  // If this is the very first segment we started
469  // playback in the middle of a continuation packet.
470  // Discard it since we missed the start of it.
471  while (os->segp < os->nsegs) {
472  int seg = os->segments[os->segp++];
473  os->pstart += seg;
474  if (seg < 255)
475  break;
476  }
477  os->sync_pos = os->page_pos;
478  }
479  } else {
480  os->psize = 0;
481  os->sync_pos = os->page_pos;
482  }
483 
484  /* This function is always called with sid != NULL */
485  *sid = idx;
486 
487  return 0;
488 }
489 
490 /**
491  * @brief find the next Ogg packet
492  * @param *sid is set to the stream for the packet or -1 if there is
493  * no matching stream, in that case assume all other return
494  * values to be uninitialized.
495  * @return negative value on error or EOF.
496  */
497 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
498  int64_t *fpos)
499 {
500  FFFormatContext *const si = ffformatcontext(s);
501  struct ogg *ogg = s->priv_data;
502  int idx, i, ret;
503  struct ogg_stream *os;
504  int complete = 0;
505  int segp = 0, psize = 0;
506 
507  av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
508  if (sid)
509  *sid = -1;
510 
511  do {
512  idx = ogg->curidx;
513 
514  while (idx < 0) {
515  ret = ogg_read_page(s, &idx, 0);
516  if (ret < 0)
517  return ret;
518  }
519 
520  os = ogg->streams + idx;
521 
522  av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
523  idx, os->pstart, os->psize, os->segp, os->nsegs);
524 
525  if (!os->codec) {
526  if (os->header < 0) {
527  os->codec = ogg_find_codec(os->buf, os->bufpos);
528  if (!os->codec) {
529  av_log(s, AV_LOG_WARNING, "Codec not found\n");
530  os->header = 0;
531  return 0;
532  }
533  } else {
534  return 0;
535  }
536  }
537 
538  segp = os->segp;
539  psize = os->psize;
540 
541  while (os->segp < os->nsegs) {
542  int ss = os->segments[os->segp++];
543  os->psize += ss;
544  if (ss < 255) {
545  complete = 1;
546  break;
547  }
548  }
549 
550  if (!complete && os->segp == os->nsegs) {
551  ogg->curidx = -1;
552  // Do not set incomplete for empty packets.
553  // Together with the code in ogg_read_page
554  // that discards all continuation of empty packets
555  // we would get an infinite loop.
556  os->incomplete = !!os->psize;
557  }
558  } while (!complete);
559 
560 
561  if (os->granule == -1)
563  "Page at %"PRId64" is missing granule\n",
564  os->page_pos);
565 
566  ogg->curidx = idx;
567  os->incomplete = 0;
568 
569  if (os->header) {
570  if ((ret = os->codec->header(s, idx)) < 0) {
571  av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
572  return ret;
573  }
574  os->header = ret;
575  if (!os->header) {
576  os->segp = segp;
577  os->psize = psize;
578 
579  // We have reached the first non-header packet in this stream.
580  // Unfortunately more header packets may still follow for others,
581  // but if we continue with header parsing we may lose data packets.
582  ogg->headers = 1;
583 
584  // Update the header state for all streams and
585  // compute the data_offset.
586  if (!si->data_offset)
587  si->data_offset = os->sync_pos;
588 
589  for (i = 0; i < ogg->nstreams; i++) {
590  struct ogg_stream *cur_os = ogg->streams + i;
591 
592  // if we have a partial non-header packet, its start is
593  // obviously at or after the data start
594  if (cur_os->incomplete)
595  si->data_offset = FFMIN(si->data_offset, cur_os->sync_pos);
596  }
597  } else {
598  os->nb_header++;
599  os->pstart += os->psize;
600  os->psize = 0;
601  }
602  } else {
603  os->pflags = 0;
604  os->pduration = 0;
605 
606  ret = 0;
607  if (os->codec && os->codec->packet) {
608  if ((ret = os->codec->packet(s, idx)) < 0) {
609  av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
610  return ret;
611  }
612  }
613 
614  if (!ret) {
615  if (sid)
616  *sid = idx;
617  if (dstart)
618  *dstart = os->pstart;
619  if (dsize)
620  *dsize = os->psize;
621  if (fpos)
622  *fpos = os->sync_pos;
623  }
624 
625  os->pstart += os->psize;
626  os->psize = 0;
627  if(os->pstart == os->bufpos)
628  os->bufpos = os->pstart = 0;
629  os->sync_pos = os->page_pos;
630  }
631 
632  // determine whether there are more complete packets in this page
633  // if not, the page's granule will apply to this packet
634  os->page_end = 1;
635  for (i = os->segp; i < os->nsegs; i++)
636  if (os->segments[i] < 255) {
637  os->page_end = 0;
638  break;
639  }
640 
641  if (os->segp == os->nsegs)
642  ogg->curidx = -1;
643 
644  return 0;
645 }
646 
648 {
649  struct ogg *ogg = s->priv_data;
650  int i, ret;
651  int64_t size, end;
652  int streams_left=0;
653 
654  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
655  return 0;
656 
657 // already set
658  if (s->duration != AV_NOPTS_VALUE)
659  return 0;
660 
661  size = avio_size(s->pb);
662  if (size < 0)
663  return 0;
664  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
665 
666  ret = ogg_save(s);
667  if (ret < 0)
668  return ret;
669  avio_seek(s->pb, end, SEEK_SET);
670  ogg->page_pos = -1;
671 
672  while (!ogg_read_page(s, &i, 1)) {
673  if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
674  ogg->streams[i].codec) {
675  s->streams[i]->duration =
677  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
678  s->streams[i]->duration -= s->streams[i]->start_time;
679  streams_left-= (ogg->streams[i].got_start==-1);
680  ogg->streams[i].got_start= 1;
681  } else if(!ogg->streams[i].got_start) {
682  ogg->streams[i].got_start= -1;
683  streams_left++;
684  }
685  }
686  }
687 
688  ogg_restore(s);
689 
690  ret = ogg_save(s);
691  if (ret < 0)
692  return ret;
693 
694  avio_seek (s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
695  ogg_reset(s);
696  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
697  int64_t pts;
698  if (i < 0) continue;
699  pts = ogg_calc_pts(s, i, NULL);
700  if (s->streams[i]->duration == AV_NOPTS_VALUE)
701  continue;
702  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
703  s->streams[i]->duration -= pts;
704  ogg->streams[i].got_start= 1;
705  streams_left--;
706  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
707  ogg->streams[i].got_start= 1;
708  streams_left--;
709  }
710  }
711  ogg_restore (s);
712 
713  return 0;
714 }
715 
717 {
718  struct ogg *ogg = s->priv_data;
719  int i;
720 
721  for (i = 0; i < ogg->nstreams; i++) {
722  free_stream(s, i);
723  }
724 
725  ogg->nstreams = 0;
726 
727  av_freep(&ogg->streams);
728  return 0;
729 }
730 
732 {
733  struct ogg *ogg = s->priv_data;
734  int ret, i;
735 
736  ogg->curidx = -1;
737 
738  //linear headers seek from start
739  do {
740  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
741  if (ret < 0)
742  return ret;
743  } while (!ogg->headers);
744  av_log(s, AV_LOG_TRACE, "found headers\n");
745 
746  for (i = 0; i < ogg->nstreams; i++) {
747  struct ogg_stream *os = ogg->streams + i;
748 
749  if (ogg->streams[i].header < 0) {
750  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
751  ogg->streams[i].codec = NULL;
753  } else if (os->codec && os->nb_header < os->codec->nb_header) {
755  "Headers mismatch for stream %d: "
756  "expected %d received %d.\n",
757  i, os->codec->nb_header, os->nb_header);
758  if (s->error_recognition & AV_EF_EXPLODE)
759  return AVERROR_INVALIDDATA;
760  }
762  os->lastpts = s->streams[i]->start_time =
763  ogg_gptopts(s, i, os->start_granule, NULL);
764  }
765 
766  //linear granulepos seek from end
767  ret = ogg_get_length(s);
768  if (ret < 0)
769  return ret;
770 
771  return 0;
772 }
773 
775 {
776  struct ogg *ogg = s->priv_data;
777  struct ogg_stream *os = ogg->streams + idx;
779 
780  if (dts)
781  *dts = AV_NOPTS_VALUE;
782 
783  if (os->lastpts != AV_NOPTS_VALUE) {
784  pts = os->lastpts;
785  os->lastpts = AV_NOPTS_VALUE;
786  }
787  if (os->lastdts != AV_NOPTS_VALUE) {
788  if (dts)
789  *dts = os->lastdts;
790  os->lastdts = AV_NOPTS_VALUE;
791  }
792  if (os->page_end) {
793  if (os->granule != -1LL) {
794  if (os->codec && os->codec->granule_is_start)
795  pts = ogg_gptopts(s, idx, os->granule, dts);
796  else
797  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
798  os->granule = -1LL;
799  }
800  }
801  return pts;
802 }
803 
804 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
805 {
806  struct ogg *ogg = s->priv_data;
807  struct ogg_stream *os = ogg->streams + idx;
808  int invalid = 0;
809  if (psize) {
810  switch (s->streams[idx]->codecpar->codec_id) {
811  case AV_CODEC_ID_THEORA:
812  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
813  break;
814  case AV_CODEC_ID_VP8:
815  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
816  }
817  if (invalid) {
818  os->pflags ^= AV_PKT_FLAG_KEY;
819  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
820  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
821  }
822  }
823 }
824 
826 {
827  struct ogg *ogg;
828  struct ogg_stream *os;
829  int idx, ret;
830  int pstart, psize;
831  int64_t fpos, pts, dts;
832 
833  if (s->io_repositioned) {
834  ogg_reset(s);
835  s->io_repositioned = 0;
836  }
837 
838  //Get an ogg packet
839 retry:
840  do {
841  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
842  if (ret < 0)
843  return ret;
844  } while (idx < 0 || !s->streams[idx]);
845 
846  ogg = s->priv_data;
847  os = ogg->streams + idx;
848 
849  // pflags might not be set until after this
850  pts = ogg_calc_pts(s, idx, &dts);
852 
853  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
854  goto retry;
855  os->keyframe_seek = 0;
856 
857  //Alloc a pkt
859  if (ret < 0)
860  return ret;
861  pkt->stream_index = idx;
862  memcpy(pkt->data, os->buf + pstart, psize);
863 
864  pkt->pts = pts;
865  pkt->dts = dts;
866  pkt->flags = os->pflags;
867  pkt->duration = os->pduration;
868  pkt->pos = fpos;
869 
870  if (os->start_trimming || os->end_trimming) {
871  uint8_t *side_data = av_packet_new_side_data(pkt,
873  10);
874  if(!side_data)
875  return AVERROR(ENOMEM);
876  AV_WL32(side_data + 0, os->start_trimming);
877  AV_WL32(side_data + 4, os->end_trimming);
878  os->start_trimming = 0;
879  os->end_trimming = 0;
880  }
881 
882  if (os->new_metadata) {
885  if (ret < 0)
886  return ret;
887 
888  os->new_metadata = NULL;
889  os->new_metadata_size = 0;
890  }
891 
892  if (os->new_extradata) {
895  if (ret < 0)
896  return ret;
897 
898  os->new_extradata = NULL;
899  os->new_extradata_size = 0;
900  }
901 
902  return psize;
903 }
904 
905 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
906  int64_t *pos_arg, int64_t pos_limit)
907 {
908  struct ogg *ogg = s->priv_data;
909  AVIOContext *bc = s->pb;
911  int64_t keypos = -1;
912  int i;
913  int pstart, psize;
914  avio_seek(bc, *pos_arg, SEEK_SET);
915  ogg_reset(s);
916 
917  while ( avio_tell(bc) <= pos_limit
918  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
919  if (i == stream_index) {
920  struct ogg_stream *os = ogg->streams + stream_index;
921  // Do not trust the last timestamps of an ogm video
922  if ( (os->flags & OGG_FLAG_EOS)
923  && !(os->flags & OGG_FLAG_BOS)
924  && os->codec == &ff_ogm_video_codec)
925  continue;
926  pts = ogg_calc_pts(s, i, NULL);
928  if (os->pflags & AV_PKT_FLAG_KEY) {
929  keypos = *pos_arg;
930  } else if (os->keyframe_seek) {
931  // if we had a previous keyframe but no pts for it,
932  // return that keyframe with this pts value.
933  if (keypos >= 0)
934  *pos_arg = keypos;
935  else
937  }
938  }
939  if (pts != AV_NOPTS_VALUE)
940  break;
941  }
942  ogg_reset(s);
943  return pts;
944 }
945 
946 static int ogg_read_seek(AVFormatContext *s, int stream_index,
947  int64_t timestamp, int flags)
948 {
949  struct ogg *ogg = s->priv_data;
950  struct ogg_stream *os = ogg->streams + stream_index;
951  int ret;
952 
953  av_assert0(stream_index < ogg->nstreams);
954  // Ensure everything is reset even when seeking via
955  // the generated index.
956  ogg_reset(s);
957 
958  // Try seeking to a keyframe first. If this fails (very possible),
959  // av_seek_frame will fall back to ignoring keyframes
960  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
961  && !(flags & AVSEEK_FLAG_ANY))
962  os->keyframe_seek = 1;
963 
964  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
965  ogg_reset(s);
966  os = ogg->streams + stream_index;
967  if (ret < 0)
968  os->keyframe_seek = 0;
969  return ret;
970 }
971 
972 static int ogg_probe(const AVProbeData *p)
973 {
974  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
975  return AVPROBE_SCORE_MAX;
976  return 0;
977 }
978 
980  .p.name = "ogg",
981  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
982  .p.extensions = "ogg",
984  .priv_data_size = sizeof(struct ogg),
985  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
986  .read_probe = ogg_probe,
987  .read_header = ogg_read_header,
988  .read_packet = ogg_read_packet,
989  .read_close = ogg_read_close,
990  .read_seek = ogg_read_seek,
991  .read_timestamp = ogg_read_timestamp,
992 };
ff_old_flac_codec
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:160
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:804
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:535
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:731
ogg_new_stream
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
Definition: oggdec.c:246
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:553
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:159
AVFMT_NOBINSEARCH
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:484
ogg
Definition: oggdec.h:110
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:527
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:590
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:152
ogg_stream::new_extradata_size
size_t new_extradata_size
Definition: oggdec.h:98
ff_ogg_demuxer
const FFInputFormat ff_ogg_demuxer
Definition: oggdec.c:979
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
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:777
ogg_gptopts
static uint64_t ogg_gptopts(AVFormatContext *s, int i, uint64_t gp, int64_t *dts)
Definition: oggdec.h:176
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:198
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2376
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:479
ogg::headers
int headers
Definition: oggdec.h:113
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:497
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:71
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:236
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: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:99
OGG_NOGRANULE_VALUE
#define OGG_NOGRANULE_VALUE
Definition: oggdec.h:123
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:549
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:91
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
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:114
ogg_stream::new_metadata
uint8_t * new_metadata
Definition: oggdec.h:95
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:1264
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:211
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:451
ogg_read_seek
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: oggdec.c:946
ogg::page_pos
int64_t page_pos
file offset of the current page
Definition: oggdec.h:115
ogg::streams
struct ogg_stream * streams
Definition: oggdec.h:111
ogg_save
static int ogg_save(AVFormatContext *s)
Definition: oggdec.c:84
ogg_get_length
static int ogg_get_length(AVFormatContext *s)
Definition: oggdec.c:647
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:297
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:716
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:99
ogg_stream::keyframe_seek
int keyframe_seek
Definition: oggdec.h:89
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:206
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:287
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:46
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:534
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:541
ogg::state
struct ogg_state * state
Definition: oggdec.h:116
version
version
Definition: libkvazaar.c:315
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:221
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:112
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
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:528
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:119
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: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:905
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
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:194
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:164
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:232
ogg_restore
static int ogg_restore(AVFormatContext *s)
Definition: oggdec.c:120
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:77
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommmends 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:825
AVPacket::stream_index
int stream_index
Definition: packet.h:537
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:96
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:480
mem.h
OGG_FLAG_EOS
#define OGG_FLAG_EOS
Definition: oggdec.h:121
ogg_state
Definition: oggdec.h:102
ogg_calc_pts
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
Definition: oggdec.c:774
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
ff_celt_codec
const struct ogg_codec ff_celt_codec
Definition: oggparsecelt.c:93
ogg_probe
static int ogg_probe(const AVProbeData *p)
Definition: oggdec.c:972
AVPacket
This structure stores compressed data.
Definition: packet.h:512
ogg_stream::new_extradata
uint8_t * new_extradata
Definition: oggdec.h:97
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:120
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:555
FFInputFormat
Definition: demux.h:42
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
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:311
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: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: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:83
ff_opus_codec
const struct ogg_codec ff_opus_codec
Definition: oggparseopus.c:215
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:346