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