FFmpeg
oggenc.c
Go to the documentation of this file.
1 /*
2  * Ogg muxer
3  * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at free dot fr>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config_components.h"
23 
24 #include <stdint.h>
25 
26 #include "libavutil/crc.h"
27 #include "libavutil/mathematics.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/random_seed.h"
31 #include "libavcodec/xiph.h"
32 #include "libavcodec/bytestream.h"
33 #include "libavcodec/flac.h"
34 #include "avformat.h"
35 #include "avio_internal.h"
36 #include "internal.h"
37 #include "mux.h"
38 #include "version.h"
39 #include "vorbiscomment.h"
40 
41 #define MAX_PAGE_SIZE 65025
42 
43 typedef struct OGGPage {
44  int64_t start_granule;
45  int64_t granule;
47  uint8_t flags;
48  uint8_t segments_count;
49  uint8_t segments[255];
50  uint8_t data[MAX_PAGE_SIZE];
51  uint16_t size;
52 } OGGPage;
53 
54 typedef struct OGGStreamContext {
55  unsigned page_counter;
56  uint8_t *header[3];
57  int header_len[3];
58  /** for theora granule */
59  int kfgshift;
60  int64_t last_kf_pts;
61  int vrev;
62  /* for VP8 granule */
63  int isvp8;
64  int eos;
65  unsigned page_count; ///< number of page buffered
66  OGGPage page; ///< current page
67  unsigned serial_num; ///< serial number
68  int64_t last_granule; ///< last packet granule
70 
71 typedef struct OGGPageList {
73  struct OGGPageList *next;
74 } OGGPageList;
75 
76 typedef struct OGGContext {
77  const AVClass *class;
79  int pref_size; ///< preferred page size (0 => fill all segments)
80  int64_t pref_duration; ///< preferred page duration (0 => fill all segments)
82 } OGGContext;
83 
84 #define OFFSET(x) offsetof(OGGContext, x)
85 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
86 
87 static const AVOption options[] = {
88  { "serial_offset", "serial number offset",
89  OFFSET(serial_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, PARAM },
90  { "oggpagesize", "Set preferred Ogg page size.",
91  OFFSET(pref_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, MAX_PAGE_SIZE, PARAM},
92  { "pagesize", "preferred page size in bytes (deprecated)",
93  OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM },
94  { "page_duration", "preferred page duration, in microseconds",
95  OFFSET(pref_duration), AV_OPT_TYPE_INT64, { .i64 = 1000000 }, 0, INT64_MAX, PARAM },
96  { NULL },
97 };
98 
99 static const AVClass ogg_muxer_class = {
100  .class_name = "Ogg (audio/video/Speex/Opus) muxer",
101  .item_name = av_default_item_name,
102  .option = options,
103  .version = LIBAVUTIL_VERSION_INT,
104 };
105 
106 static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
107 {
108  OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data;
109  uint8_t buf[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr = buf, *crc_pos;
110  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE);
111  uint32_t crc;
112 
113  bytestream_put_le32(&ptr, MKTAG('O', 'g', 'g', 'S'));
114  bytestream_put_byte(&ptr, 0);
115  bytestream_put_byte(&ptr, page->flags | extra_flags);
116  bytestream_put_le64(&ptr, page->granule);
117  bytestream_put_le32(&ptr, oggstream->serial_num);
118  bytestream_put_le32(&ptr, oggstream->page_counter++);
119  crc_pos = ptr;
120  bytestream_put_le32(&ptr, 0);
121  bytestream_put_byte(&ptr, page->segments_count);
122  bytestream_put_buffer(&ptr, page->segments, page->segments_count);
123 
124  crc = av_crc(crc_table, 0, buf, ptr - buf);
125  crc = av_crc(crc_table, crc, page->data, page->size);
126  bytestream_put_be32(&crc_pos, crc);
127 
128  avio_write(s->pb, buf, ptr - buf);
129  avio_write(s->pb, page->data, page->size);
131  oggstream->page_count--;
132 }
133 
134 static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
135 {
136  return (oggstream->kfgshift && !(granule & ((1<<oggstream->kfgshift)-1))) ||
137  (oggstream->isvp8 && !((granule >> 3) & 0x07ffffff));
138 }
139 
140 static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
141 {
142  if (oggstream->kfgshift)
143  return (granule>>oggstream->kfgshift) +
144  (granule & ((1<<oggstream->kfgshift)-1));
145  else if (oggstream->isvp8)
146  return granule >> 32;
147  else
148  return granule;
149 }
150 
152 {
153  AVStream *st2 = s->streams[next->stream_index];
154  AVStream *st = s->streams[page->stream_index];
155  int64_t next_granule, cur_granule;
156 
157  if (next->granule == -1 || page->granule == -1)
158  return 0;
159 
160  next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next->granule),
161  st2->time_base, AV_TIME_BASE_Q);
162  cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page->granule),
163  st ->time_base, AV_TIME_BASE_Q);
164  return next_granule > cur_granule;
165 }
166 
167 static int ogg_reset_cur_page(OGGStreamContext *oggstream)
168 {
169  oggstream->page.granule = -1;
170  oggstream->page.flags = 0;
171  oggstream->page.segments_count = 0;
172  oggstream->page.size = 0;
173  return 0;
174 }
175 
177 {
178  OGGContext *ogg = s->priv_data;
179  OGGPageList **p = &ogg->page_list;
180  OGGPageList *l = av_mallocz(sizeof(*l));
181 
182  if (!l)
183  return AVERROR(ENOMEM);
184  l->page = oggstream->page;
185 
186  oggstream->page.start_granule = ogg_granule_to_timestamp(oggstream, oggstream->page.granule);
187  oggstream->page_count++;
188  ogg_reset_cur_page(oggstream);
189 
190  while (*p) {
191  if (ogg_compare_granule(s, &(*p)->page, &l->page))
192  break;
193  p = &(*p)->next;
194  }
195  l->next = *p;
196  *p = l;
197 
198  return 0;
199 }
200 
202  const uint8_t *data, unsigned size, int64_t granule,
203  int header)
204 {
205  OGGStreamContext *oggstream = st->priv_data;
206  OGGContext *ogg = s->priv_data;
207  int total_segments = size / 255 + 1;
208  const uint8_t *p = data;
209  int i, segments, len, flush = 0;
210 
211  // Handles VFR by flushing page because this frame needs to have a timestamp
212  // For theora and VP8, keyframes also need to have a timestamp to correctly mark
213  // them as such, otherwise seeking will not work correctly at the very
214  // least with old libogg versions.
215  // Do not try to flush header packets though, that will create broken files.
217  (ogg_granule_to_timestamp(oggstream, granule) >
218  ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
219  ogg_key_granule(oggstream, granule))) {
220  if (oggstream->page.granule != -1)
221  ogg_buffer_page(s, oggstream);
222  flush = 1;
223  }
224 
225  // avoid a continued page
226  if (!header && oggstream->page.size > 0 &&
227  MAX_PAGE_SIZE - oggstream->page.size < size) {
228  ogg_buffer_page(s, oggstream);
229  }
230 
231  for (i = 0; i < total_segments; ) {
232  OGGPage *page = &oggstream->page;
233 
234  segments = FFMIN(total_segments - i, 255 - page->segments_count);
235 
236  if (i && !page->segments_count)
237  page->flags |= 1; // continued packet
238 
239  memset(page->segments+page->segments_count, 255, segments - 1);
240  page->segments_count += segments - 1;
241 
242  len = FFMIN(size, segments*255);
243  page->segments[page->segments_count++] = len - (segments-1)*255;
244  memcpy(page->data+page->size, p, len);
245  p += len;
246  size -= len;
247  i += segments;
248  page->size += len;
249 
250  if (i == total_segments)
251  page->granule = granule;
252 
253  {
254  AVStream *st = s->streams[page->stream_index];
255 
256  int64_t start = av_rescale_q(page->start_granule, st->time_base,
258  int64_t next = av_rescale_q(ogg_granule_to_timestamp(oggstream, page->granule),
260 
261  if (page->segments_count == 255) {
262  ogg_buffer_page(s, oggstream);
263  } else if (!header) {
264  if ((ogg->pref_size > 0 && page->size >= ogg->pref_size) ||
265  (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
266  ogg_buffer_page(s, oggstream);
267  }
268  }
269  }
270  }
271 
272  if (flush && oggstream->page.granule != -1)
273  ogg_buffer_page(s, oggstream);
274 
275  return 0;
276 }
277 
278 static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
279  int *header_len, AVDictionary **m, int framing_bit,
280  AVChapter **chapters, unsigned int nb_chapters)
281 {
282  const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
283  FFIOContext pb;
284  int64_t size;
285  uint8_t *p;
286 
288 
289  size = offset + ff_vorbiscomment_length(*m, vendor, chapters, nb_chapters) + framing_bit;
290  if (size > INT_MAX)
291  return NULL;
292  p = av_mallocz(size);
293  if (!p)
294  return NULL;
295 
297  ff_vorbiscomment_write(&pb.pub, *m, vendor, chapters, nb_chapters);
298  if (framing_bit)
299  avio_w8(&pb.pub, 1);
300 
301  *header_len = size;
302  return p;
303 }
304 
306  OGGStreamContext *oggstream, int bitexact,
307  AVDictionary **m)
308 {
309  uint8_t *p;
310 
312  return AVERROR(EINVAL);
313 
314  // first packet: STREAMINFO
315  oggstream->header_len[0] = 51;
316  oggstream->header[0] = av_mallocz(51); // per ogg flac specs
317  p = oggstream->header[0];
318  if (!p)
319  return AVERROR(ENOMEM);
320  bytestream_put_byte(&p, 0x7F);
321  bytestream_put_buffer(&p, "FLAC", 4);
322  bytestream_put_byte(&p, 1); // major version
323  bytestream_put_byte(&p, 0); // minor version
324  bytestream_put_be16(&p, 1); // headers packets without this one
325  bytestream_put_buffer(&p, "fLaC", 4);
326  bytestream_put_byte(&p, 0x00); // streaminfo
327  bytestream_put_be24(&p, 34);
329 
330  // second packet: VorbisComment
331  p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
332  if (!p)
333  return AVERROR(ENOMEM);
334  oggstream->header[1] = p;
335  bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment
336  bytestream_put_be24(&p, oggstream->header_len[1] - 4);
337 
338  return 0;
339 }
340 
341 #define SPEEX_HEADER_SIZE 80
342 
344  OGGStreamContext *oggstream, int bitexact,
345  AVDictionary **m)
346 {
347  uint8_t *p;
348 
350  return AVERROR_INVALIDDATA;
351 
352  // first packet: Speex header
354  if (!p)
355  return AVERROR(ENOMEM);
356  oggstream->header[0] = p;
357  oggstream->header_len[0] = SPEEX_HEADER_SIZE;
359  AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0
360 
361  // second packet: VorbisComment
362  p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
363  if (!p)
364  return AVERROR(ENOMEM);
365  oggstream->header[1] = p;
366 
367  return 0;
368 }
369 
370 #define OPUS_HEADER_SIZE 19
371 
373  OGGStreamContext *oggstream, int bitexact,
374  AVDictionary **m, AVChapter **chapters,
375  unsigned int nb_chapters)
376 {
377  uint8_t *p;
378 
379  if (par->extradata_size < OPUS_HEADER_SIZE)
380  return AVERROR_INVALIDDATA;
381 
382  /* first packet: Opus header */
383  p = av_mallocz(par->extradata_size);
384  if (!p)
385  return AVERROR(ENOMEM);
386  oggstream->header[0] = p;
387  oggstream->header_len[0] = par->extradata_size;
389 
390  /* second packet: VorbisComment */
391  p = ogg_write_vorbiscomment(8, bitexact, &oggstream->header_len[1], m, 0, chapters, nb_chapters);
392  if (!p)
393  return AVERROR(ENOMEM);
394  oggstream->header[1] = p;
395  bytestream_put_buffer(&p, "OpusTags", 8);
396 
397  return 0;
398 }
399 
400 #define VP8_HEADER_SIZE 26
401 
403  OGGStreamContext *oggstream, int bitexact)
404 {
405  AVCodecParameters *par = st->codecpar;
406  uint8_t *p;
407 
408  /* first packet: VP8 header */
410  if (!p)
411  return AVERROR(ENOMEM);
412  oggstream->header[0] = p;
413  oggstream->header_len[0] = VP8_HEADER_SIZE;
414  bytestream_put_byte(&p, 0x4f); // HDRID
415  bytestream_put_buffer(&p, "VP80", 4); // Identifier
416  bytestream_put_byte(&p, 1); // HDRTYP
417  bytestream_put_byte(&p, 1); // VMAJ
418  bytestream_put_byte(&p, 0); // VMIN
419  bytestream_put_be16(&p, par->width);
420  bytestream_put_be16(&p, par->height);
421  bytestream_put_be24(&p, par->sample_aspect_ratio.num);
422  bytestream_put_be24(&p, par->sample_aspect_ratio.den);
423  if (st->r_frame_rate.num > 0 && st->r_frame_rate.den > 0) {
424  // OggVP8 requires pts to increase by 1 per visible frame, so use the least common
425  // multiple framerate if available.
426  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
427  st->time_base.num, st->time_base.den,
428  st->r_frame_rate.den, st->r_frame_rate.num);
430  }
431  bytestream_put_be32(&p, st->time_base.den);
432  bytestream_put_be32(&p, st->time_base.num);
433 
434  /* optional second packet: VorbisComment */
435  if (av_dict_count(st->metadata)) {
436  p = ogg_write_vorbiscomment(7, bitexact, &oggstream->header_len[1], &st->metadata, 0, NULL, 0);
437  if (!p)
438  return AVERROR(ENOMEM);
439  oggstream->header[1] = p;
440  bytestream_put_byte(&p, 0x4f); // HDRID
441  bytestream_put_buffer(&p, "VP80", 4); // Identifier
442  bytestream_put_byte(&p, 2); // HDRTYP
443  bytestream_put_byte(&p, 0x20);
444  }
445 
446  oggstream->isvp8 = 1;
447 
448  return 0;
449 }
450 
452 {
453  OGGContext *ogg = s->priv_data;
454  OGGPageList *next, *p;
455 
456  if (!ogg->page_list)
457  return;
458 
459  for (p = ogg->page_list; p; ) {
460  OGGStreamContext *oggstream =
461  s->streams[p->page.stream_index]->priv_data;
462  if (oggstream->page_count < 2 && !flush)
463  break;
464  ogg_write_page(s, &p->page,
465  flush == 1 && oggstream->page_count == 1 ? 4 : 0); // eos
466  next = p->next;
467  av_freep(&p);
468  p = next;
469  }
470  ogg->page_list = p;
471 }
472 
474 {
475  OGGContext *ogg = s->priv_data;
476  OGGStreamContext *oggstream = NULL;
477  int i, j;
478 
479  if (ogg->pref_size)
480  av_log(s, AV_LOG_WARNING, "The pagesize option is deprecated\n");
481 
482  for (i = 0; i < s->nb_streams; i++) {
483  AVStream *st = s->streams[i];
484  unsigned serial_num = i + ogg->serial_offset;
485 
486  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
487  if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
488  /* Opus requires a fixed 48kHz clock */
489  avpriv_set_pts_info(st, 64, 1, 48000);
490  else
491  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
492  }
493 
494  if (st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
500  av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
501  return AVERROR(EINVAL);
502  }
503 
504  if ((!st->codecpar->extradata || !st->codecpar->extradata_size) &&
506  av_log(s, AV_LOG_ERROR, "No extradata present\n");
507  return AVERROR_INVALIDDATA;
508  }
509  oggstream = av_mallocz(sizeof(*oggstream));
510  if (!oggstream)
511  return AVERROR(ENOMEM);
512 
513  oggstream->page.stream_index = i;
514 
515  if (!(s->flags & AVFMT_FLAG_BITEXACT))
516  do {
517  serial_num = av_get_random_seed();
518  for (j = 0; j < i; j++) {
519  OGGStreamContext *sc = s->streams[j]->priv_data;
520  if (serial_num == sc->serial_num)
521  break;
522  }
523  } while (j < i);
524  oggstream->serial_num = serial_num;
525 
526  av_dict_copy(&st->metadata, s->metadata, AV_DICT_DONT_OVERWRITE);
527 
528  st->priv_data = oggstream;
529  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) {
530  int err = ogg_build_flac_headers(st->codecpar, oggstream,
531  s->flags & AVFMT_FLAG_BITEXACT,
532  &st->metadata);
533  if (err) {
534  av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
535  return err;
536  }
537  } else if (st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
538  int err = ogg_build_speex_headers(st->codecpar, oggstream,
539  s->flags & AVFMT_FLAG_BITEXACT,
540  &st->metadata);
541  if (err) {
542  av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
543  return err;
544  }
545  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
546  int err = ogg_build_opus_headers(st->codecpar, oggstream,
547  s->flags & AVFMT_FLAG_BITEXACT,
548  &st->metadata, s->chapters, s->nb_chapters);
549  if (err) {
550  av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
551  return err;
552  }
553  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
554  int err = ogg_build_vp8_headers(s, st, oggstream,
555  s->flags & AVFMT_FLAG_BITEXACT);
556  if (err) {
557  av_log(s, AV_LOG_ERROR, "Error writing VP8 headers\n");
558  return err;
559  }
560  } else {
561  uint8_t *p;
562  const char *cstr = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? "vorbis" : "theora";
563  int header_type = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 3 : 0x81;
564  int framing_bit = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 1 : 0;
565 
567  st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 30 : 42,
568  (const uint8_t**)oggstream->header, oggstream->header_len) < 0) {
569  av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
570  oggstream->header[1] = NULL;
571  return AVERROR_INVALIDDATA;
572  }
573 
575  &oggstream->header_len[1], &st->metadata,
576  framing_bit, NULL, 0);
577  oggstream->header[1] = p;
578  if (!p)
579  return AVERROR(ENOMEM);
580 
581  bytestream_put_byte(&p, header_type);
582  bytestream_put_buffer(&p, cstr, 6);
583 
584  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
585  int den = AV_RB32(oggstream->header[0] + 22), num = AV_RB32(oggstream->header[0] + 26);
586  /* Make sure to use time base stored in the Theora stream header to write
587  correct timestamps */
588  if (st->time_base.num != num || st->time_base.den != den) {
589  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
590  st->time_base.num, st->time_base.den, num, den);
591  avpriv_set_pts_info(st, 64, num, den);
592  }
593  /** KFGSHIFT is the width of the less significant section of the granule position
594  The less significant section is the frame count since the last keyframe */
595  oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5);
596  oggstream->vrev = oggstream->header[0][9];
597  av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n",
598  oggstream->kfgshift, oggstream->vrev);
599  }
600  }
601  }
602 
603  return 0;
604 }
605 
607 {
608  OGGStreamContext *oggstream = NULL;
609  int i, j;
610 
611  for (j = 0; j < s->nb_streams; j++) {
612  oggstream = s->streams[j]->priv_data;
613  ogg_buffer_data(s, s->streams[j], oggstream->header[0],
614  oggstream->header_len[0], 0, 1);
615  oggstream->page.flags |= 2; // bos
616  ogg_buffer_page(s, oggstream);
617  }
618  for (j = 0; j < s->nb_streams; j++) {
619  AVStream *st = s->streams[j];
620  oggstream = st->priv_data;
621  for (i = 1; i < 3; i++) {
622  if (oggstream->header_len[i])
623  ogg_buffer_data(s, st, oggstream->header[i],
624  oggstream->header_len[i], 0, 1);
625  }
626  ogg_buffer_page(s, oggstream);
627  }
628 
629  oggstream->page.start_granule = AV_NOPTS_VALUE;
630 
631  ogg_write_pages(s, 2);
632 
633  return 0;
634 }
635 
637 {
638  AVStream *st = s->streams[pkt->stream_index];
639  OGGStreamContext *oggstream = st->priv_data;
640  int ret;
641  int64_t granule;
642 
643  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
644  int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration;
645  int pframe_count;
646  if (pkt->flags & AV_PKT_FLAG_KEY)
647  oggstream->last_kf_pts = pts;
648  pframe_count = pts - oggstream->last_kf_pts;
649  // prevent frame count from overflow if key frame flag is not set
650  if (pframe_count >= (1<<oggstream->kfgshift)) {
651  oggstream->last_kf_pts += pframe_count;
652  pframe_count = 0;
653  }
654  granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
655  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
656  granule = pkt->pts + pkt->duration +
658  (AVRational){ 1, st->codecpar->sample_rate },
659  st->time_base);
660  else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
661  int64_t pts, invcnt, dist;
662  int visible;
663 
664  visible = (pkt->data[0] >> 4) & 1;
665  pts = pkt->pts + pkt->duration;
666  invcnt = (oggstream->last_granule >> 30) & 3;
667  invcnt = visible ? 3 : (invcnt == 3 ? 0 : invcnt + 1);
668  dist = (pkt->flags & AV_PKT_FLAG_KEY) ? 0 : ((oggstream->last_granule >> 3) & 0x07ffffff) + 1;
669 
670  granule = (pts << 32) | (invcnt << 30) | (dist << 3);
671  } else
672  granule = pkt->pts + pkt->duration;
673 
674  if (oggstream->page.start_granule == AV_NOPTS_VALUE)
675  oggstream->page.start_granule = pkt->pts;
676 
677  ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
678  if (ret < 0)
679  return ret;
680 
681  ogg_write_pages(s, 0);
682 
683  oggstream->last_granule = granule;
684 
685  return 0;
686 }
687 
689 {
690  int i;
691 
692  if (pkt)
693  return pkt->size ? ogg_write_packet_internal(s, pkt) : 0;
694 
695  for (i = 0; i < s->nb_streams; i++) {
696  OGGStreamContext *oggstream = s->streams[i]->priv_data;
697  if (oggstream->page.segments_count)
698  ogg_buffer_page(s, oggstream);
699  }
700 
701  ogg_write_pages(s, 2);
702  return 1;
703 }
704 
706 {
707  int i;
708 
709  /* flush current page if needed */
710  for (i = 0; i < s->nb_streams; i++) {
711  OGGStreamContext *oggstream = s->streams[i]->priv_data;
712 
713  if (oggstream->page.size > 0)
714  ogg_buffer_page(s, oggstream);
715  }
716 
717  ogg_write_pages(s, 1);
718 
719  return 0;
720 }
721 
723 {
724  OGGContext *ogg = s->priv_data;
725  OGGPageList *p = ogg->page_list;
726  int i;
727 
728  for (i = 0; i < s->nb_streams; i++) {
729  AVStream *st = s->streams[i];
730  OGGStreamContext *oggstream = st->priv_data;
731  if (!oggstream)
732  continue;
733  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
737  av_freep(&oggstream->header[0]);
738  }
739  av_freep(&oggstream->header[1]);
740  }
741 
742  while (p) {
743  OGGPageList *next = p->next;
744  av_free(p);
745  p = next;
746  }
747  ogg->page_list = NULL;
748 }
749 
750 #if CONFIG_OGG_MUXER
752  .p.name = "ogg",
753  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
754  .p.mime_type = "application/ogg",
755  .p.extensions = "ogg"
756 #if !CONFIG_OGV_MUXER
757  ",ogv"
758 #endif
759 #if !CONFIG_SPX_MUXER
760  ",spx"
761 #endif
762 #if !CONFIG_OPUS_MUXER
763  ",opus"
764 #endif
765  ,
766  .priv_data_size = sizeof(OGGContext),
767  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
769  .p.video_codec = AV_CODEC_ID_THEORA,
770  .init = ogg_init,
771  .write_header = ogg_write_header,
772  .write_packet = ogg_write_packet,
773  .write_trailer = ogg_write_trailer,
774  .deinit = ogg_free,
776  .p.flags = AVFMT_TS_NEGATIVE | AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
777 #else
779 #endif
780  .p.priv_class = &ogg_muxer_class,
781  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
782 };
783 #endif
784 
785 #if CONFIG_OGA_MUXER
787  .p.name = "oga",
788  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Audio"),
789  .p.mime_type = "audio/ogg",
790  .p.extensions = "oga",
791  .priv_data_size = sizeof(OGGContext),
792  .p.audio_codec = AV_CODEC_ID_FLAC,
793  .init = ogg_init,
794  .write_header = ogg_write_header,
795  .write_packet = ogg_write_packet,
796  .write_trailer = ogg_write_trailer,
797  .deinit = ogg_free,
799  .p.flags = AVFMT_TS_NEGATIVE | AVFMT_ALLOW_FLUSH,
800 #else
801  .p.flags = AVFMT_TS_NEGATIVE,
802 #endif
803  .p.priv_class = &ogg_muxer_class,
804  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
805 };
806 #endif
807 
808 #if CONFIG_OGV_MUXER
810  .p.name = "ogv",
811  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Video"),
812  .p.mime_type = "video/ogg",
813  .p.extensions = "ogv",
814  .priv_data_size = sizeof(OGGContext),
815  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
817  .p.video_codec = CONFIG_LIBTHEORA_ENCODER ?
819  .init = ogg_init,
820  .write_header = ogg_write_header,
821  .write_packet = ogg_write_packet,
822  .write_trailer = ogg_write_trailer,
823  .deinit = ogg_free,
825  .p.flags = AVFMT_TS_NEGATIVE | AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
826 #else
828 #endif
829  .p.priv_class = &ogg_muxer_class,
830  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
831 };
832 #endif
833 
834 #if CONFIG_SPX_MUXER
836  .p.name = "spx",
837  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Speex"),
838  .p.mime_type = "audio/ogg",
839  .p.extensions = "spx",
840  .priv_data_size = sizeof(OGGContext),
841  .p.audio_codec = AV_CODEC_ID_SPEEX,
842  .init = ogg_init,
843  .write_header = ogg_write_header,
844  .write_packet = ogg_write_packet,
845  .write_trailer = ogg_write_trailer,
846  .deinit = ogg_free,
848  .p.flags = AVFMT_TS_NEGATIVE | AVFMT_ALLOW_FLUSH,
849 #else
850  .p.flags = AVFMT_TS_NEGATIVE,
851 #endif
852  .p.priv_class = &ogg_muxer_class,
853  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
854 };
855 #endif
856 
857 #if CONFIG_OPUS_MUXER
859  .p.name = "opus",
860  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Opus"),
861  .p.mime_type = "audio/ogg",
862  .p.extensions = "opus",
863  .priv_data_size = sizeof(OGGContext),
864  .p.audio_codec = AV_CODEC_ID_OPUS,
865  .init = ogg_init,
866  .write_header = ogg_write_header,
867  .write_packet = ogg_write_packet,
868  .write_trailer = ogg_write_trailer,
869  .deinit = ogg_free,
871  .p.flags = AVFMT_TS_NEGATIVE | AVFMT_ALLOW_FLUSH,
872 #else
873  .p.flags = AVFMT_TS_NEGATIVE,
874 #endif
875  .p.priv_class = &ogg_muxer_class,
876  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
877 };
878 #endif
VP8_HEADER_SIZE
#define VP8_HEADER_SIZE
Definition: oggenc.c:400
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
OGGContext::pref_duration
int64_t pref_duration
preferred page duration (0 => fill all segments)
Definition: oggenc.c:80
AVOutputFormat::name
const char * name
Definition: avformat.h:510
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
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:424
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
AVCRC
uint32_t AVCRC
Definition: crc.h:46
AVStream::priv_data
void * priv_data
Definition: avformat.h:768
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:39
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
ogg_compare_granule
static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page)
Definition: oggenc.c:151
ff_metadata_conv
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
AVPacket::data
uint8_t * data
Definition: packet.h:524
vorbiscomment.h
OGGPageList
Definition: oggenc.c:71
AVOption
AVOption.
Definition: opt.h:357
data
const char data[16]
Definition: mxf.c:148
ogg_write_vorbiscomment
static uint8_t * ogg_write_vorbiscomment(int64_t offset, int bitexact, int *header_len, AVDictionary **m, int framing_bit, AVChapter **chapters, unsigned int nb_chapters)
Definition: oggenc.c:278
OGGStreamContext::last_granule
int64_t last_granule
last packet granule
Definition: oggenc.c:68
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:542
mathematics.h
AVDictionary
Definition: dict.c:34
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:452
ff_ogg_muxer
const FFOutputFormat ff_ogg_muxer
ogg_muxer_class
static const AVClass ogg_muxer_class
Definition: oggenc.c:99
ogg
Definition: oggdec.h:101
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
OGGPageList::next
struct OGGPageList * next
Definition: oggenc.c:73
OGGStreamContext::page_count
unsigned page_count
number of page buffered
Definition: oggenc.c:65
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:167
xiph.h
OGGPageList::page
OGGPage page
Definition: oggenc.c:72
crc.h
avio_write_marker
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
Definition: aviobuf.c:461
OGGStreamContext::page
OGGPage page
current page
Definition: oggenc.c:66
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:853
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:475
OFFSET
#define OFFSET(x)
Definition: oggenc.c:84
ff_vorbiscomment_write
int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m, const char *vendor_string, AVChapter **chapters, unsigned int nb_chapters)
Write a VorbisComment into an AVIOContext.
Definition: vorbiscomment.c:65
AVChapter
Definition: avformat.h:1214
ogg_write_header
static int ogg_write_header(AVFormatContext *s)
Definition: oggenc.c:606
pts
static int64_t pts
Definition: transcode_aac.c:644
AVRational::num
int num
Numerator.
Definition: rational.h:59
OGGStreamContext::eos
int eos
Definition: oggenc.c:64
OGGStreamContext::page_counter
unsigned page_counter
Definition: oggenc.c:55
ogg_write_packet_internal
static int ogg_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
Definition: oggenc.c:636
ogg_write_pages
static void ogg_write_pages(AVFormatContext *s, int flush)
Definition: oggenc.c:451
SPEEX_HEADER_SIZE
#define SPEEX_HEADER_SIZE
Definition: oggenc.c:341
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
OGGStreamContext::isvp8
int isvp8
Definition: oggenc.c:63
ogg_init
static int ogg_init(AVFormatContext *s)
Definition: oggenc.c:473
ogg_build_vp8_headers
static int ogg_build_vp8_headers(AVFormatContext *s, AVStream *st, OGGStreamContext *oggstream, int bitexact)
Definition: oggenc.c:402
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_spx_muxer
const FFOutputFormat ff_spx_muxer
AVCodecParameters::sample_aspect_ratio
AVRational sample_aspect_ratio
Video only.
Definition: codec_par.h:144
ogg_buffer_data
static int ogg_buffer_data(AVFormatContext *s, AVStream *st, const uint8_t *data, unsigned size, int64_t granule, int header)
Definition: oggenc.c:201
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
OGGStreamContext::last_kf_pts
int64_t last_kf_pts
Definition: oggenc.c:60
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:246
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_vorbiscomment_metadata_conv
const AVMetadataConv ff_vorbiscomment_metadata_conv[]
VorbisComment metadata conversion mapping.
Definition: vorbiscomment.c:33
OGGPage::granule
int64_t granule
Definition: oggenc.c:45
ogg_free
static void ogg_free(AVFormatContext *s)
Definition: oggenc.c:722
ogg_buffer_page
static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
Definition: oggenc.c:176
OGGStreamContext
Definition: oggenc.c:54
ff_opus_muxer
const FFOutputFormat ff_opus_muxer
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
OGGContext::serial_offset
int serial_offset
Definition: oggenc.c:81
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:782
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:823
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
FFOutputFormat
Definition: mux.h:61
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:179
options
static const AVOption options[]
Definition: oggenc.c:87
OGGStreamContext::header
uint8_t * header[3]
Definition: oggenc.c:56
ff_vorbiscomment_length
int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string, AVChapter **chapters, unsigned int nb_chapters)
Calculate the length in bytes of a VorbisComment.
Definition: vorbiscomment.c:41
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
OGGContext::pref_size
int pref_size
preferred page size (0 => fill all segments)
Definition: oggenc.c:79
MAX_PAGE_SIZE
#define MAX_PAGE_SIZE
Definition: oggenc.c:41
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
OGGPage::segments
uint8_t segments[255]
Definition: oggenc.c:49
AVPacket::size
int size
Definition: packet.h:525
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
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:29
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
PARAM
#define PARAM
Definition: oggenc.c:85
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:500
header
static const uint8_t header[24]
Definition: sdr2.c:68
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
OGGPage::stream_index
int stream_index
Definition: oggenc.c:46
av_crc_get_table
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:374
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
OGGPage::data
uint8_t data[MAX_PAGE_SIZE]
Definition: oggenc.c:50
ff_ogv_muxer
const FFOutputFormat ff_ogv_muxer
ogg_build_opus_headers
static int ogg_build_opus_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m, AVChapter **chapters, unsigned int nb_chapters)
Definition: oggenc.c:372
bytestream_put_buffer
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:372
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
avio_internal.h
OGGPage::segments_count
uint8_t segments_count
Definition: oggenc.c:48
ogg_build_flac_headers
static int ogg_build_flac_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
Definition: oggenc.c:305
AV_CODEC_ID_THEORA
@ AV_CODEC_ID_THEORA
Definition: codec_id.h:82
AVCodecParameters::height
int height
Definition: codec_par.h:135
OGGPage::start_granule
int64_t start_granule
Definition: oggenc.c:44
else
else
Definition: snow.txt:125
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
ogg_write_trailer
static int ogg_write_trailer(AVFormatContext *s)
Definition: oggenc.c:705
len
int len
Definition: vorbis_enc_data.h:426
AV_CRC_32_IEEE
@ AV_CRC_32_IEEE
Definition: crc.h:52
FF_API_ALLOW_FLUSH
#define FF_API_ALLOW_FLUSH
Definition: version_major.h:46
ff_oga_muxer
const FFOutputFormat ff_oga_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:494
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:491
version.h
ret
ret
Definition: filter_design.txt:187
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1423
AVStream
Stream structure.
Definition: avformat.h:743
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
OGGContext
Definition: oggenc.c:76
OGGPage
Definition: oggenc.c:43
ogg_write_page
static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
Definition: oggenc.c:106
avformat.h
ffio_init_write_context
void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for writing.
Definition: aviobuf.c:104
OGGStreamContext::serial_num
unsigned serial_num
serial number
Definition: oggenc.c:67
random_seed.h
ogg_granule_to_timestamp
static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
Definition: oggenc.c:140
av_crc
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition: crc.c:392
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:245
ogg_build_speex_headers
static int ogg_build_speex_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
Definition: oggenc.c:343
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:909
OGGPage::size
uint16_t size
Definition: oggenc.c:51
OGGPage::flags
uint8_t flags
Definition: oggenc.c:47
OGGContext::page_list
OGGPageList * page_list
Definition: oggenc.c:78
OGGStreamContext::vrev
int vrev
Definition: oggenc.c:61
AVPacket::stream_index
int stream_index
Definition: packet.h:526
avpriv_split_xiph_headers
int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size, int first_header_size, const uint8_t *header_start[3], int header_len[3])
Split a single extradata buffer into the three headers that most Xiph codecs use.
Definition: xiph.c:26
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:501
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:237
OGGStreamContext::kfgshift
int kfgshift
for theora granule
Definition: oggenc.c:59
bytestream.h
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
OGGStreamContext::header_len
int header_len[3]
Definition: oggenc.c:57
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
OPUS_HEADER_SIZE
#define OPUS_HEADER_SIZE
Definition: oggenc.c:370
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:445
ogg_write_packet
static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggenc.c:688
flac.h
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AVIO_DATA_MARKER_FLUSH_POINT
@ AVIO_DATA_MARKER_FLUSH_POINT
A point in the output bytestream where the underlying AVIOContext might flush the buffer depending on...
Definition: avio.h:145
mux.h
ogg_key_granule
static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
Definition: oggenc.c:134
ogg_reset_cur_page
static int ogg_reset_cur_page(OGGStreamContext *oggstream)
Definition: oggenc.c:167