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  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->flags = 0;
241  os->start_trimming = 0;
242  os->end_trimming = 0;
243  os->replace = 1;
244 
245  return i;
246 }
247 
248 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
249 {
250  struct ogg *ogg = s->priv_data;
251  int idx = ogg->nstreams;
252  AVStream *st;
253  struct ogg_stream *os;
254 
255  if (ogg->state) {
256  av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
257  "in between Ogg context save/restore operations.\n");
258  return AVERROR_BUG;
259  }
260 
261  /* Allocate and init a new Ogg Stream */
262  if (!(os = av_realloc_array(ogg->streams, ogg->nstreams + 1,
263  sizeof(*ogg->streams))))
264  return AVERROR(ENOMEM);
265  ogg->streams = os;
266  os = ogg->streams + idx;
267  memset(os, 0, sizeof(*os));
268  os->serial = serial;
271  os->header = -1;
273  if (!os->buf)
274  return AVERROR(ENOMEM);
275 
276  /* Create the associated AVStream */
277  st = avformat_new_stream(s, NULL);
278  if (!st) {
279  av_freep(&os->buf);
280  return AVERROR(ENOMEM);
281  }
282  st->id = idx;
283  avpriv_set_pts_info(st, 64, 1, 1000000);
284 
285  ogg->nstreams++;
286  return idx;
287 }
288 
289 static int data_packets_seen(const struct ogg *ogg)
290 {
291  int i;
292 
293  for (i = 0; i < ogg->nstreams; i++)
294  if (ogg->streams[i].got_data)
295  return 1;
296  return 0;
297 }
298 
299 static int buf_realloc(struct ogg_stream *os, int size)
300 {
301  /* Even if invalid guarantee there's enough memory to read the page */
302  if (os->bufsize - os->bufpos < size) {
303  uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
304  if (!nb)
305  return AVERROR(ENOMEM);
306  os->buf = nb;
307  os->bufsize *= 2;
308  }
309 
310  return 0;
311 }
312 
313 static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
314 {
315  AVIOContext *bc = s->pb;
316  struct ogg *ogg = s->priv_data;
317  struct ogg_stream *os;
318  int ret, i = 0;
319  int flags, nsegs;
320  uint64_t gp;
321  uint32_t serial;
322  uint32_t crc, crc_tmp;
323  int size = 0, idx;
325  int64_t start_pos;
326  uint8_t sync[4];
327  uint8_t segments[255];
328  uint8_t *readout_buf;
329  int sp = 0;
330 
331  ret = avio_read(bc, sync, 4);
332  if (ret < 4)
333  return ret < 0 ? ret : AVERROR_EOF;
334 
335  do {
336  int c;
337 
338  if (sync[sp & 3] == 'O' &&
339  sync[(sp + 1) & 3] == 'g' &&
340  sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
341  break;
342 
343  if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
344  memset(sync, 0, 4);
345  avio_seek(bc, ogg->page_pos+4, SEEK_SET);
346  ogg->page_pos = -1;
347  }
348 
349  c = avio_r8(bc);
350 
351  if (avio_feof(bc))
352  return AVERROR_EOF;
353 
354  sync[sp++ & 3] = c;
355  } while (i++ < MAX_PAGE_SIZE);
356 
357  if (i >= MAX_PAGE_SIZE) {
358  av_log(s, AV_LOG_INFO, "cannot find sync word\n");
359  return AVERROR_INVALIDDATA;
360  }
361 
362  /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
363  ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
364 
365  /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
367  if (ret < 0)
368  return ret;
369  start_pos = avio_tell(bc);
370 
371  version = avio_r8(bc);
372  flags = avio_r8(bc);
373  gp = avio_rl64(bc);
374  serial = avio_rl32(bc);
375  avio_rl32(bc); /* seq */
376 
377  crc_tmp = ffio_get_checksum(bc);
378  crc = avio_rb32(bc);
379  crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
381 
382  nsegs = avio_r8(bc);
383  page_pos = avio_tell(bc) - 27;
384 
385  ret = avio_read(bc, segments, nsegs);
386  if (ret < nsegs)
387  return ret < 0 ? ret : AVERROR_EOF;
388 
389  for (i = 0; i < nsegs; i++)
390  size += segments[i];
391 
392  idx = ogg_find_stream(ogg, serial);
393  if (idx >= 0) {
394  os = ogg->streams + idx;
395 
396  ret = buf_realloc(os, size);
397  if (ret < 0)
398  return ret;
399 
400  readout_buf = os->buf + os->bufpos;
401  } else {
402  readout_buf = av_malloc(size);
403  }
404 
405  ret = avio_read(bc, readout_buf, size);
406  if (ret < size) {
407  if (idx < 0)
408  av_free(readout_buf);
409  return ret < 0 ? ret : AVERROR_EOF;
410  }
411 
412  if (crc ^ ffio_get_checksum(bc)) {
413  av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
414  if (idx < 0)
415  av_free(readout_buf);
416  avio_seek(bc, start_pos, SEEK_SET);
417  *sid = -1;
418  return 0;
419  }
420 
421  /* Since we're almost sure its a valid packet, checking the version after
422  * the checksum lets the demuxer be more tolerant */
423  if (version) {
424  av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
425  if (idx < 0)
426  av_free(readout_buf);
427  avio_seek(bc, start_pos, SEEK_SET);
428  *sid = -1;
429  return 0;
430  }
431 
432  /* CRC is correct so we can be 99% sure there's an actual change here */
433  if (idx < 0) {
434  if (data_packets_seen(ogg))
435  idx = ogg_replace_stream(s, serial, readout_buf, size, probing);
436  else
437  idx = ogg_new_stream(s, serial);
438 
439  if (idx < 0) {
440  av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
441  av_free(readout_buf);
442  return idx;
443  }
444 
445  os = ogg->streams + idx;
446 
447  ret = buf_realloc(os, size);
448  if (ret < 0) {
449  av_free(readout_buf);
450  return ret;
451  }
452 
453  memcpy(os->buf + os->bufpos, readout_buf, size);
454  av_free(readout_buf);
455  }
456 
457  ogg->page_pos = page_pos;
458  os->page_pos = page_pos;
459  os->nsegs = nsegs;
460  os->segp = 0;
461  os->got_data = !(flags & OGG_FLAG_BOS);
462  os->bufpos += size;
463  os->granule = gp;
464  os->flags = flags;
465  memcpy(os->segments, segments, nsegs);
466  memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
467 
468  if (flags & OGG_FLAG_CONT || os->incomplete) {
469  if (!os->psize) {
470  // If this is the very first segment we started
471  // playback in the middle of a continuation packet.
472  // Discard it since we missed the start of it.
473  while (os->segp < os->nsegs) {
474  int seg = os->segments[os->segp++];
475  os->pstart += seg;
476  if (seg < 255)
477  break;
478  }
479  os->sync_pos = os->page_pos;
480  }
481  } else {
482  os->psize = 0;
483  os->sync_pos = os->page_pos;
484  }
485 
486  /* This function is always called with sid != NULL */
487  *sid = idx;
488 
489  return 0;
490 }
491 
492 /**
493  * @brief find the next Ogg packet
494  * @param *sid is set to the stream for the packet or -1 if there is
495  * no matching stream, in that case assume all other return
496  * values to be uninitialized.
497  * @return negative value on error or EOF.
498  */
499 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
500  int64_t *fpos)
501 {
502  FFFormatContext *const si = ffformatcontext(s);
503  struct ogg *ogg = s->priv_data;
504  int idx, i, ret;
505  struct ogg_stream *os;
506  int complete = 0;
507  int segp = 0, psize = 0;
508 
509  av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
510  if (sid)
511  *sid = -1;
512 
513  do {
514  idx = ogg->curidx;
515 
516  while (idx < 0) {
517  ret = ogg_read_page(s, &idx, 0);
518  if (ret < 0)
519  return ret;
520  }
521 
522  os = ogg->streams + idx;
523 
524  av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
525  idx, os->pstart, os->psize, os->segp, os->nsegs);
526 
527  if (!os->codec) {
528  if (os->header < 0) {
529  os->codec = ogg_find_codec(os->buf, os->bufpos);
530  if (!os->codec) {
531  av_log(s, AV_LOG_WARNING, "Codec not found\n");
532  os->header = 0;
533  return 0;
534  }
535  } else {
536  return 0;
537  }
538  }
539 
540  segp = os->segp;
541  psize = os->psize;
542 
543  while (os->segp < os->nsegs) {
544  int ss = os->segments[os->segp++];
545  os->psize += ss;
546  if (ss < 255) {
547  complete = 1;
548  break;
549  }
550  }
551 
552  if (!complete && os->segp == os->nsegs) {
553  ogg->curidx = -1;
554  // Do not set incomplete for empty packets.
555  // Together with the code in ogg_read_page
556  // that discards all continuation of empty packets
557  // we would get an infinite loop.
558  os->incomplete = !!os->psize;
559  }
560  } while (!complete);
561 
562 
563  if (os->granule == -1)
565  "Page at %"PRId64" is missing granule\n",
566  os->page_pos);
567 
568  ogg->curidx = idx;
569  os->incomplete = 0;
570 
571  if (os->header) {
572  if ((ret = os->codec->header(s, idx)) < 0) {
573  av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
574  return ret;
575  }
576  os->header = ret;
577  if (!os->header) {
578  os->segp = segp;
579  os->psize = psize;
580 
581  // We have reached the first non-header packet in this stream.
582  // Unfortunately more header packets may still follow for others,
583  // but if we continue with header parsing we may lose data packets.
584  ogg->headers = 1;
585 
586  // Update the header state for all streams and
587  // compute the data_offset.
588  if (!si->data_offset)
589  si->data_offset = os->sync_pos;
590 
591  for (i = 0; i < ogg->nstreams; i++) {
592  struct ogg_stream *cur_os = ogg->streams + i;
593 
594  // if we have a partial non-header packet, its start is
595  // obviously at or after the data start
596  if (cur_os->incomplete)
597  si->data_offset = FFMIN(si->data_offset, cur_os->sync_pos);
598  }
599  } else {
600  os->nb_header++;
601  os->pstart += os->psize;
602  os->psize = 0;
603  }
604  } else {
605  os->pflags = 0;
606  os->pduration = 0;
607 
608  ret = 0;
609  if (os->codec && os->codec->packet) {
610  if ((ret = os->codec->packet(s, idx)) < 0) {
611  av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
612  return ret;
613  }
614  }
615 
616  if (!ret) {
617  if (sid)
618  *sid = idx;
619  if (dstart)
620  *dstart = os->pstart;
621  if (dsize)
622  *dsize = os->psize;
623  if (fpos)
624  *fpos = os->sync_pos;
625  }
626 
627  os->pstart += os->psize;
628  os->psize = 0;
629  if(os->pstart == os->bufpos)
630  os->bufpos = os->pstart = 0;
631  os->sync_pos = os->page_pos;
632  }
633 
634  // determine whether there are more complete packets in this page
635  // if not, the page's granule will apply to this packet
636  os->page_end = 1;
637  for (i = os->segp; i < os->nsegs; i++)
638  if (os->segments[i] < 255) {
639  os->page_end = 0;
640  break;
641  }
642 
643  if (os->segp == os->nsegs)
644  ogg->curidx = -1;
645 
646  return 0;
647 }
648 
650 {
651  struct ogg *ogg = s->priv_data;
652  int i, ret;
653  int64_t size, end;
654  int streams_left=0;
655 
656  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
657  return 0;
658 
659 // already set
660  if (s->duration != AV_NOPTS_VALUE)
661  return 0;
662 
663  size = avio_size(s->pb);
664  if (size < 0)
665  return 0;
666  end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
667 
668  ret = ogg_save(s);
669  if (ret < 0)
670  return ret;
671  avio_seek(s->pb, end, SEEK_SET);
672  ogg->page_pos = -1;
673 
674  while (!ogg_read_page(s, &i, 1)) {
675  if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
676  ogg->streams[i].codec) {
677  s->streams[i]->duration =
679  if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
680  s->streams[i]->duration -= s->streams[i]->start_time;
681  streams_left-= (ogg->streams[i].got_start==-1);
682  ogg->streams[i].got_start= 1;
683  } else if(!ogg->streams[i].got_start) {
684  ogg->streams[i].got_start= -1;
685  streams_left++;
686  }
687  }
688  }
689 
690  ogg_restore(s);
691 
692  ret = ogg_save(s);
693  if (ret < 0)
694  return ret;
695 
696  avio_seek (s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
697  ogg_reset(s);
698  while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
699  int64_t pts;
700  if (i < 0) continue;
701  pts = ogg_calc_pts(s, i, NULL);
702  if (s->streams[i]->duration == AV_NOPTS_VALUE)
703  continue;
704  if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
705  s->streams[i]->duration -= pts;
706  ogg->streams[i].got_start= 1;
707  streams_left--;
708  }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
709  ogg->streams[i].got_start= 1;
710  streams_left--;
711  }
712  }
713  ogg_restore (s);
714 
715  return 0;
716 }
717 
719 {
720  struct ogg *ogg = s->priv_data;
721  int i;
722 
723  for (i = 0; i < ogg->nstreams; i++) {
724  free_stream(s, i);
725  }
726 
727  ogg->nstreams = 0;
728 
729  av_freep(&ogg->streams);
730  return 0;
731 }
732 
734 {
735  struct ogg *ogg = s->priv_data;
736  int ret, i;
737 
738  ogg->curidx = -1;
739 
740  //linear headers seek from start
741  do {
742  ret = ogg_packet(s, NULL, NULL, NULL, NULL);
743  if (ret < 0)
744  return ret;
745  } while (!ogg->headers);
746  av_log(s, AV_LOG_TRACE, "found headers\n");
747 
748  for (i = 0; i < ogg->nstreams; i++) {
749  struct ogg_stream *os = ogg->streams + i;
750 
751  if (ogg->streams[i].header < 0) {
752  av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
753  ogg->streams[i].codec = NULL;
755  } else if (os->codec && os->nb_header < os->codec->nb_header) {
757  "Headers mismatch for stream %d: "
758  "expected %d received %d.\n",
759  i, os->codec->nb_header, os->nb_header);
760  if (s->error_recognition & AV_EF_EXPLODE)
761  return AVERROR_INVALIDDATA;
762  }
764  os->lastpts = s->streams[i]->start_time =
765  ogg_gptopts(s, i, os->start_granule, NULL);
766  }
767 
768  //linear granulepos seek from end
769  ret = ogg_get_length(s);
770  if (ret < 0)
771  return ret;
772 
773  return 0;
774 }
775 
777 {
778  struct ogg *ogg = s->priv_data;
779  struct ogg_stream *os = ogg->streams + idx;
781 
782  if (dts)
783  *dts = AV_NOPTS_VALUE;
784 
785  if (os->lastpts != AV_NOPTS_VALUE) {
786  pts = os->lastpts;
787  os->lastpts = AV_NOPTS_VALUE;
788  }
789  if (os->lastdts != AV_NOPTS_VALUE) {
790  if (dts)
791  *dts = os->lastdts;
792  os->lastdts = AV_NOPTS_VALUE;
793  }
794  if (os->page_end) {
795  if (os->granule != -1LL) {
796  if (os->codec && os->codec->granule_is_start)
797  pts = ogg_gptopts(s, idx, os->granule, dts);
798  else
799  os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
800  os->granule = -1LL;
801  }
802  }
803  return pts;
804 }
805 
806 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
807 {
808  struct ogg *ogg = s->priv_data;
809  struct ogg_stream *os = ogg->streams + idx;
810  int invalid = 0;
811  if (psize) {
812  switch (s->streams[idx]->codecpar->codec_id) {
813  case AV_CODEC_ID_THEORA:
814  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
815  break;
816  case AV_CODEC_ID_VP8:
817  invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
818  }
819  if (invalid) {
820  os->pflags ^= AV_PKT_FLAG_KEY;
821  av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
822  (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
823  }
824  }
825 }
826 
828 {
829  struct ogg *ogg;
830  struct ogg_stream *os;
831  int idx, ret;
832  int pstart, psize;
833  int64_t fpos, pts, dts;
834 
835  if (s->io_repositioned) {
836  ogg_reset(s);
837  s->io_repositioned = 0;
838  }
839 
840  //Get an ogg packet
841 retry:
842  do {
843  ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
844  if (ret < 0)
845  return ret;
846  } while (idx < 0 || !s->streams[idx]);
847 
848  ogg = s->priv_data;
849  os = ogg->streams + idx;
850 
851  // pflags might not be set until after this
852  pts = ogg_calc_pts(s, idx, &dts);
854 
855  if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
856  goto retry;
857  os->keyframe_seek = 0;
858 
859  //Alloc a pkt
861  if (ret < 0)
862  return ret;
863  pkt->stream_index = idx;
864  memcpy(pkt->data, os->buf + pstart, psize);
865 
866  pkt->pts = pts;
867  pkt->dts = dts;
868  pkt->flags = os->pflags;
869  pkt->duration = os->pduration;
870  pkt->pos = fpos;
871 
872  if (os->start_trimming || os->end_trimming) {
873  uint8_t *side_data = av_packet_new_side_data(pkt,
875  10);
876  if(!side_data)
877  return AVERROR(ENOMEM);
878  AV_WL32(side_data + 0, os->start_trimming);
879  AV_WL32(side_data + 4, os->end_trimming);
880  os->start_trimming = 0;
881  os->end_trimming = 0;
882  }
883 
884  if (os->replace) {
885  os->replace = 0;
886  pkt->dts = pkt->pts = AV_NOPTS_VALUE;
887  }
888 
889  if (os->new_metadata) {
892  if (ret < 0)
893  return ret;
894 
895  os->new_metadata = NULL;
896  os->new_metadata_size = 0;
897  }
898 
899  if (os->new_extradata) {
902  if (ret < 0)
903  return ret;
904 
905  os->new_extradata = NULL;
906  os->new_extradata_size = 0;
907  }
908 
909  return psize;
910 }
911 
912 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
913  int64_t *pos_arg, int64_t pos_limit)
914 {
915  struct ogg *ogg = s->priv_data;
916  AVIOContext *bc = s->pb;
918  int64_t keypos = -1;
919  int i;
920  int pstart, psize;
921  avio_seek(bc, *pos_arg, SEEK_SET);
922  ogg_reset(s);
923 
924  while ( avio_tell(bc) <= pos_limit
925  && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
926  if (i == stream_index) {
927  struct ogg_stream *os = ogg->streams + stream_index;
928  // Do not trust the last timestamps of an ogm video
929  if ( (os->flags & OGG_FLAG_EOS)
930  && !(os->flags & OGG_FLAG_BOS)
931  && os->codec == &ff_ogm_video_codec)
932  continue;
933  pts = ogg_calc_pts(s, i, NULL);
935  if (os->pflags & AV_PKT_FLAG_KEY) {
936  keypos = *pos_arg;
937  } else if (os->keyframe_seek) {
938  // if we had a previous keyframe but no pts for it,
939  // return that keyframe with this pts value.
940  if (keypos >= 0)
941  *pos_arg = keypos;
942  else
944  }
945  }
946  if (pts != AV_NOPTS_VALUE)
947  break;
948  }
949  ogg_reset(s);
950  return pts;
951 }
952 
953 static int ogg_read_seek(AVFormatContext *s, int stream_index,
954  int64_t timestamp, int flags)
955 {
956  struct ogg *ogg = s->priv_data;
957  struct ogg_stream *os = ogg->streams + stream_index;
958  int ret;
959 
960  av_assert0(stream_index < ogg->nstreams);
961  // Ensure everything is reset even when seeking via
962  // the generated index.
963  ogg_reset(s);
964 
965  // Try seeking to a keyframe first. If this fails (very possible),
966  // av_seek_frame will fall back to ignoring keyframes
967  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
968  && !(flags & AVSEEK_FLAG_ANY))
969  os->keyframe_seek = 1;
970 
971  ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
972  ogg_reset(s);
973  os = ogg->streams + stream_index;
974  if (ret < 0)
975  os->keyframe_seek = 0;
976  return ret;
977 }
978 
979 static int ogg_probe(const AVProbeData *p)
980 {
981  if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
982  return AVPROBE_SCORE_MAX;
983  return 0;
984 }
985 
987  .p.name = "ogg",
988  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
989  .p.extensions = "ogg",
991  .priv_data_size = sizeof(struct ogg),
992  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
993  .read_probe = ogg_probe,
994  .read_header = ogg_read_header,
995  .read_packet = ogg_read_packet,
996  .read_close = ogg_read_close,
997  .read_seek = ogg_read_seek,
998  .read_timestamp = ogg_read_timestamp,
999 };
ff_old_flac_codec
const struct ogg_codec ff_old_flac_codec
Definition: oggparseflac.c:167
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:806
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:588
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:733
ogg_new_stream
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
Definition: oggdec.c:248
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:606
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: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:613
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:643
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:986
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:191
ogg_stream::serial
uint32_t serial
Definition: oggdec.h:75
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h: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: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:499
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:764
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: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:549
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:115
ogg_stream::new_metadata
uint8_t * new_metadata
Definition: oggdec.h:96
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_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: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:953
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:84
ogg_get_length
static int ogg_get_length(AVFormatContext *s)
Definition: oggdec.c:649
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:299
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:718
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:289
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:51
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:587
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:594
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
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:581
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
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:912
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:236
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:179
ogg_codec::cleanup
void(* cleanup)(AVFormatContext *s, int idx)
Definition: oggdec.h:64
oggdec.h
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
ogg_restore
static int ogg_restore(AVFormatContext *s)
Definition: oggdec.c:120
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:827
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:590
ogg_stream::new_metadata_size
size_t new_metadata_size
Definition: oggdec.h:97
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: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:776
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:979
AVPacket
This structure stores compressed data.
Definition: packet.h:565
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:608
FFInputFormat
Definition: demux.h:47
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:313
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: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