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 {
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;
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 #if LIBAVFORMAT_VERSION_MAJOR < 63
80  int pref_size; ///< preferred page size (0 => fill all segments)
81 #endif
82  int64_t pref_duration; ///< preferred page duration (0 => fill all segments)
84 } OGGContext;
85 
86 #define OFFSET(x) offsetof(OGGContext, x)
87 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
88 
89 static const AVOption options[] = {
90  { "serial_offset", "serial number offset",
91  OFFSET(serial_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, PARAM },
92 #if LIBAVFORMAT_VERSION_MAJOR < 63
93  { "oggpagesize", "Set preferred Ogg page size.",
94  OFFSET(pref_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, MAX_PAGE_SIZE, PARAM | AV_OPT_FLAG_DEPRECATED },
95  { "pagesize", "preferred page size in bytes",
96  OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM | AV_OPT_FLAG_DEPRECATED },
97 #endif
98  { "page_duration", "preferred page duration, in microseconds",
99  OFFSET(pref_duration), AV_OPT_TYPE_INT64, { .i64 = 1000000 }, 0, INT64_MAX, PARAM },
100  { NULL },
101 };
102 
103 static const AVClass ogg_muxer_class = {
104  .class_name = "Ogg (audio/video/Speex/Opus) muxer",
105  .item_name = av_default_item_name,
106  .option = options,
107  .version = LIBAVUTIL_VERSION_INT,
108 };
109 
110 static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
111 {
112  OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data;
113  uint8_t buf[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr = buf, *crc_pos;
114  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE);
115  uint32_t crc;
116 
117  bytestream_put_le32(&ptr, MKTAG('O', 'g', 'g', 'S'));
118  bytestream_put_byte(&ptr, 0);
119  bytestream_put_byte(&ptr, page->flags | extra_flags);
120  bytestream_put_le64(&ptr, page->granule);
121  bytestream_put_le32(&ptr, oggstream->serial_num);
122  bytestream_put_le32(&ptr, oggstream->page_counter++);
123  crc_pos = ptr;
124  bytestream_put_le32(&ptr, 0);
125  bytestream_put_byte(&ptr, page->segments_count);
126  bytestream_put_buffer(&ptr, page->segments, page->segments_count);
127 
128  crc = av_crc(crc_table, 0, buf, ptr - buf);
129  crc = av_crc(crc_table, crc, page->data, page->size);
130  bytestream_put_be32(&crc_pos, crc);
131 
132  avio_write(s->pb, buf, ptr - buf);
133  avio_write(s->pb, page->data, page->size);
135  oggstream->page_count--;
136 }
137 
138 static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
139 {
140  return (oggstream->kfgshift && !(granule & ((1<<oggstream->kfgshift)-1))) ||
141  (oggstream->isvp8 && !((granule >> 3) & 0x07ffffff));
142 }
143 
145 {
146  if (oggstream->kfgshift)
147  return (granule>>oggstream->kfgshift) +
148  (granule & ((1<<oggstream->kfgshift)-1));
149  else if (oggstream->isvp8)
150  return granule >> 32;
151  else
152  return granule;
153 }
154 
156 {
157  AVStream *st2 = s->streams[next->stream_index];
158  AVStream *st = s->streams[page->stream_index];
159  int64_t next_granule, cur_granule;
160 
161  if (next->granule == -1 || page->granule == -1)
162  return 0;
163 
164  next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next->granule),
165  st2->time_base, AV_TIME_BASE_Q);
166  cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page->granule),
167  st ->time_base, AV_TIME_BASE_Q);
168  return next_granule > cur_granule;
169 }
170 
171 static int ogg_reset_cur_page(OGGStreamContext *oggstream)
172 {
173  oggstream->page.granule = -1;
174  oggstream->page.flags = 0;
175  oggstream->page.segments_count = 0;
176  oggstream->page.size = 0;
177  return 0;
178 }
179 
181 {
182  OGGContext *ogg = s->priv_data;
183  OGGPageList **p = &ogg->page_list;
184  OGGPageList *l = av_mallocz(sizeof(*l));
185 
186  if (!l)
187  return AVERROR(ENOMEM);
188  l->page = oggstream->page;
189 
190  oggstream->page.start_granule = ogg_granule_to_timestamp(oggstream, oggstream->page.granule);
191  oggstream->page_count++;
192  ogg_reset_cur_page(oggstream);
193 
194  while (*p) {
195  if (ogg_compare_granule(s, &(*p)->page, &l->page))
196  break;
197  p = &(*p)->next;
198  }
199  l->next = *p;
200  *p = l;
201 
202  return 0;
203 }
204 
206  const uint8_t *data, unsigned size, int64_t granule,
207  int header)
208 {
209  OGGStreamContext *oggstream = st->priv_data;
210  OGGContext *ogg = s->priv_data;
211  int total_segments = size / 255 + 1;
212  const uint8_t *p = data;
213  int i, segments, len, flush = 0;
214 
215  // Handles VFR by flushing page because this frame needs to have a timestamp
216  // For theora and VP8, keyframes also need to have a timestamp to correctly mark
217  // them as such, otherwise seeking will not work correctly at the very
218  // least with old libogg versions.
219  // Do not try to flush header packets though, that will create broken files.
221  (ogg_granule_to_timestamp(oggstream, granule) >
222  ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
223  ogg_key_granule(oggstream, granule))) {
224  if (oggstream->page.granule != -1)
225  ogg_buffer_page(s, oggstream);
226  flush = 1;
227  }
228 
229  // avoid a continued page
230  if (!header && oggstream->page.size > 0 &&
231  MAX_PAGE_SIZE - oggstream->page.size < size) {
232  ogg_buffer_page(s, oggstream);
233  }
234 
235  for (i = 0; i < total_segments; ) {
236  OGGPage *page = &oggstream->page;
237 
238  segments = FFMIN(total_segments - i, 255 - page->segments_count);
239 
240  if (i && !page->segments_count)
241  page->flags |= 1; // continued packet
242 
243  memset(page->segments+page->segments_count, 255, segments - 1);
244  page->segments_count += segments - 1;
245 
246  len = FFMIN(size, segments*255);
247  page->segments[page->segments_count++] = len - (segments-1)*255;
248  if (len)
249  memcpy(page->data+page->size, p, len);
250  p += len;
251  size -= len;
252  i += segments;
253  page->size += len;
254 
255  if (i == total_segments)
256  page->granule = granule;
257 
258  {
259  AVStream *st = s->streams[page->stream_index];
260 
261  int64_t start = av_rescale_q(page->start_granule, st->time_base,
263  int64_t next = av_rescale_q(ogg_granule_to_timestamp(oggstream, page->granule),
265 
266  if (page->segments_count == 255) {
267  ogg_buffer_page(s, oggstream);
268  } else if (!header) {
269 #if LIBAVFORMAT_VERSION_MAJOR < 63
270  if ((ogg->pref_size > 0 && page->size >= ogg->pref_size) ||
271  (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
272 #else
273  if (ogg->pref_duration > 0 && next - start >= ogg->pref_duration) {
274 #endif
275  ogg_buffer_page(s, oggstream);
276  }
277  }
278  }
279  }
280 
281  if (flush && oggstream->page.granule != -1)
282  ogg_buffer_page(s, oggstream);
283 
284  return 0;
285 }
286 
287 static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
288  int *header_len, AVDictionary **m, int framing_bit,
289  AVChapter **chapters, unsigned int nb_chapters)
290 {
291  const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
292  FFIOContext pb;
293  int64_t size;
294  uint8_t *p;
295 
297 
298  size = offset + ff_vorbiscomment_length(*m, vendor, chapters, nb_chapters) + framing_bit;
299  if (size > INT_MAX)
300  return NULL;
301  p = av_mallocz(size);
302  if (!p)
303  return NULL;
304 
306  ff_vorbiscomment_write(&pb.pub, *m, vendor, chapters, nb_chapters);
307  if (framing_bit)
308  avio_w8(&pb.pub, 1);
309 
310  *header_len = size;
311  return p;
312 }
313 
315  OGGStreamContext *oggstream, int bitexact,
316  AVDictionary **m)
317 {
318  uint8_t *p;
319 
321  return AVERROR(EINVAL);
322 
323  // first packet: STREAMINFO
324  oggstream->header_len[0] = 51;
325  oggstream->header[0] = av_mallocz(51); // per ogg flac specs
326  p = oggstream->header[0];
327  if (!p)
328  return AVERROR(ENOMEM);
329  bytestream_put_byte(&p, 0x7F);
330  bytestream_put_buffer(&p, "FLAC", 4);
331  bytestream_put_byte(&p, 1); // major version
332  bytestream_put_byte(&p, 0); // minor version
333  bytestream_put_be16(&p, 1); // headers packets without this one
334  bytestream_put_buffer(&p, "fLaC", 4);
335  bytestream_put_byte(&p, 0x00); // streaminfo
336  bytestream_put_be24(&p, 34);
338 
339  // second packet: VorbisComment
340  p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
341  if (!p)
342  return AVERROR(ENOMEM);
343  oggstream->header[1] = p;
344  bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment
345  bytestream_put_be24(&p, oggstream->header_len[1] - 4);
346 
347  return 0;
348 }
349 
350 #define SPEEX_HEADER_SIZE 80
351 
353  OGGStreamContext *oggstream, int bitexact,
354  AVDictionary **m)
355 {
356  uint8_t *p;
357 
359  return AVERROR_INVALIDDATA;
360 
361  // first packet: Speex header
363  if (!p)
364  return AVERROR(ENOMEM);
365  oggstream->header[0] = p;
366  oggstream->header_len[0] = SPEEX_HEADER_SIZE;
368  AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0
369 
370  // second packet: VorbisComment
371  p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
372  if (!p)
373  return AVERROR(ENOMEM);
374  oggstream->header[1] = p;
375 
376  return 0;
377 }
378 
379 #define OPUS_HEADER_SIZE 19
380 
382  OGGStreamContext *oggstream, int bitexact,
383  AVDictionary **m, AVChapter **chapters,
384  unsigned int nb_chapters)
385 {
386  uint8_t *p;
387 
388  if (par->extradata_size < OPUS_HEADER_SIZE)
389  return AVERROR_INVALIDDATA;
390 
391  /* first packet: Opus header */
392  p = av_mallocz(par->extradata_size);
393  if (!p)
394  return AVERROR(ENOMEM);
395  oggstream->header[0] = p;
396  oggstream->header_len[0] = par->extradata_size;
398 
399  /* second packet: VorbisComment */
400  p = ogg_write_vorbiscomment(8, bitexact, &oggstream->header_len[1], m, 0, chapters, nb_chapters);
401  if (!p)
402  return AVERROR(ENOMEM);
403  oggstream->header[1] = p;
404  bytestream_put_buffer(&p, "OpusTags", 8);
405 
406  return 0;
407 }
408 
409 #define VP8_HEADER_SIZE 26
410 
412  OGGStreamContext *oggstream, int bitexact)
413 {
414  AVCodecParameters *par = st->codecpar;
415  uint8_t *p;
416 
417  /* first packet: VP8 header */
419  if (!p)
420  return AVERROR(ENOMEM);
421  oggstream->header[0] = p;
422  oggstream->header_len[0] = VP8_HEADER_SIZE;
423  bytestream_put_byte(&p, 0x4f); // HDRID
424  bytestream_put_buffer(&p, "VP80", 4); // Identifier
425  bytestream_put_byte(&p, 1); // HDRTYP
426  bytestream_put_byte(&p, 1); // VMAJ
427  bytestream_put_byte(&p, 0); // VMIN
428  bytestream_put_be16(&p, par->width);
429  bytestream_put_be16(&p, par->height);
430  bytestream_put_be24(&p, par->sample_aspect_ratio.num);
431  bytestream_put_be24(&p, par->sample_aspect_ratio.den);
432  if (st->r_frame_rate.num > 0 && st->r_frame_rate.den > 0) {
433  // OggVP8 requires pts to increase by 1 per visible frame, so use the least common
434  // multiple framerate if available.
435  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
436  st->time_base.num, st->time_base.den,
437  st->r_frame_rate.den, st->r_frame_rate.num);
439  }
440  bytestream_put_be32(&p, st->time_base.den);
441  bytestream_put_be32(&p, st->time_base.num);
442 
443  /* optional second packet: VorbisComment */
444  if (av_dict_count(st->metadata)) {
445  p = ogg_write_vorbiscomment(7, bitexact, &oggstream->header_len[1], &st->metadata, 0, NULL, 0);
446  if (!p)
447  return AVERROR(ENOMEM);
448  oggstream->header[1] = p;
449  bytestream_put_byte(&p, 0x4f); // HDRID
450  bytestream_put_buffer(&p, "VP80", 4); // Identifier
451  bytestream_put_byte(&p, 2); // HDRTYP
452  bytestream_put_byte(&p, 0x20);
453  }
454 
455  oggstream->isvp8 = 1;
456 
457  return 0;
458 }
459 
461 {
462  OGGContext *ogg = s->priv_data;
463  OGGPageList *next, *p;
464 
465  if (!ogg->page_list)
466  return;
467 
468  for (p = ogg->page_list; p; ) {
469  OGGStreamContext *oggstream =
470  s->streams[p->page.stream_index]->priv_data;
471  if (oggstream->page_count < 2 && !flush)
472  break;
473  ogg_write_page(s, &p->page,
474  flush == 1 && oggstream->page_count == 1 ? 4 : 0); // eos
475  next = p->next;
476  av_freep(&p);
477  p = next;
478  }
479  ogg->page_list = p;
480 }
481 
483 {
484  OGGContext *ogg = s->priv_data;
485  OGGStreamContext *oggstream = NULL;
486  int i, j;
487 
488  for (i = 0; i < s->nb_streams; i++) {
489  AVStream *st = s->streams[i];
490  unsigned serial_num = i + ogg->serial_offset;
491 
492  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
493  if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
494  /* Opus requires a fixed 48kHz clock */
495  avpriv_set_pts_info(st, 64, 1, 48000);
496  else
497  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
498  }
499 
500  if (st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
506  av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
507  return AVERROR(EINVAL);
508  }
509 
510  if ((!st->codecpar->extradata || !st->codecpar->extradata_size) &&
512  av_log(s, AV_LOG_ERROR, "No extradata present\n");
513  return AVERROR_INVALIDDATA;
514  }
515  oggstream = av_mallocz(sizeof(*oggstream));
516  if (!oggstream)
517  return AVERROR(ENOMEM);
518 
519  oggstream->page.stream_index = i;
520 
521  if (!(s->flags & AVFMT_FLAG_BITEXACT))
522  do {
523  serial_num = av_get_random_seed();
524  for (j = 0; j < i; j++) {
525  OGGStreamContext *sc = s->streams[j]->priv_data;
526  if (serial_num == sc->serial_num)
527  break;
528  }
529  } while (j < i);
530  oggstream->serial_num = serial_num;
531 
532  av_dict_copy(&st->metadata, s->metadata, AV_DICT_DONT_OVERWRITE);
533 
534  st->priv_data = oggstream;
535  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) {
536  int err = ogg_build_flac_headers(st->codecpar, oggstream,
537  s->flags & AVFMT_FLAG_BITEXACT,
538  &st->metadata);
539  if (err) {
540  av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
541  return err;
542  }
543  } else if (st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
544  int err = ogg_build_speex_headers(st->codecpar, oggstream,
545  s->flags & AVFMT_FLAG_BITEXACT,
546  &st->metadata);
547  if (err) {
548  av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
549  return err;
550  }
551  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
552  int err = ogg_build_opus_headers(st->codecpar, oggstream,
553  s->flags & AVFMT_FLAG_BITEXACT,
554  &st->metadata, s->chapters, s->nb_chapters);
555  if (err) {
556  av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
557  return err;
558  }
559  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
560  int err = ogg_build_vp8_headers(s, st, oggstream,
561  s->flags & AVFMT_FLAG_BITEXACT);
562  if (err) {
563  av_log(s, AV_LOG_ERROR, "Error writing VP8 headers\n");
564  return err;
565  }
566  } else {
567  uint8_t *p;
568  const char *cstr = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? "vorbis" : "theora";
569  int header_type = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 3 : 0x81;
570  int framing_bit = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 1 : 0;
571 
573  st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 30 : 42,
574  (const uint8_t**)oggstream->header, oggstream->header_len) < 0) {
575  av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
576  oggstream->header[1] = NULL;
577  return AVERROR_INVALIDDATA;
578  }
579 
581  &oggstream->header_len[1], &st->metadata,
582  framing_bit, NULL, 0);
583  oggstream->header[1] = p;
584  if (!p)
585  return AVERROR(ENOMEM);
586 
587  bytestream_put_byte(&p, header_type);
588  bytestream_put_buffer(&p, cstr, 6);
589 
590  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
591  int den = AV_RB32(oggstream->header[0] + 22), num = AV_RB32(oggstream->header[0] + 26);
592  /* Make sure to use time base stored in the Theora stream header to write
593  correct timestamps */
594  if (st->time_base.num != num || st->time_base.den != den) {
595  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
596  st->time_base.num, st->time_base.den, num, den);
597  avpriv_set_pts_info(st, 64, num, den);
598  }
599  /** KFGSHIFT is the width of the less significant section of the granule position
600  The less significant section is the frame count since the last keyframe */
601  oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5);
602  oggstream->vrev = oggstream->header[0][9];
603  av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n",
604  oggstream->kfgshift, oggstream->vrev);
605  }
606  }
607  }
608 
609  return 0;
610 }
611 
613 {
614  OGGStreamContext *oggstream = NULL;
615  int i, j;
616 
617  for (j = 0; j < s->nb_streams; j++) {
618  oggstream = s->streams[j]->priv_data;
619  ogg_buffer_data(s, s->streams[j], oggstream->header[0],
620  oggstream->header_len[0], 0, 1);
621  oggstream->page.flags |= 2; // bos
622  ogg_buffer_page(s, oggstream);
623  }
624  for (j = 0; j < s->nb_streams; j++) {
625  AVStream *st = s->streams[j];
626  oggstream = st->priv_data;
627  for (i = 1; i < 3; i++) {
628  if (oggstream->header_len[i])
629  ogg_buffer_data(s, st, oggstream->header[i],
630  oggstream->header_len[i], 0, 1);
631  }
632  ogg_buffer_page(s, oggstream);
633  }
634 
635  oggstream->page.start_granule = AV_NOPTS_VALUE;
636 
637  ogg_write_pages(s, 2);
638 
639  return 0;
640 }
641 
643 {
644  AVStream *st = s->streams[pkt->stream_index];
645  OGGStreamContext *oggstream = st->priv_data;
646  int ret;
647  int64_t granule;
648 
649  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
650  int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration;
651  int pframe_count;
652  if (pkt->flags & AV_PKT_FLAG_KEY)
653  oggstream->last_kf_pts = pts;
654  pframe_count = pts - oggstream->last_kf_pts;
655  // prevent frame count from overflow if key frame flag is not set
656  if (pframe_count >= (1<<oggstream->kfgshift)) {
657  oggstream->last_kf_pts += pframe_count;
658  pframe_count = 0;
659  }
660  granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
661  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
662  granule = pkt->pts + pkt->duration +
664  (AVRational){ 1, st->codecpar->sample_rate },
665  st->time_base);
666  else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
667  int64_t pts, invcnt, dist;
668  int visible;
669 
670  visible = (pkt->data[0] >> 4) & 1;
671  pts = pkt->pts + pkt->duration;
672  invcnt = (oggstream->last_granule >> 30) & 3;
673  invcnt = visible ? 3 : (invcnt == 3 ? 0 : invcnt + 1);
674  dist = (pkt->flags & AV_PKT_FLAG_KEY) ? 0 : ((oggstream->last_granule >> 3) & 0x07ffffff) + 1;
675 
676  granule = (pts << 32) | (invcnt << 30) | (dist << 3);
677  } else
678  granule = pkt->pts + pkt->duration;
679 
680  if (oggstream->page.start_granule == AV_NOPTS_VALUE)
681  oggstream->page.start_granule = pkt->pts;
682 
683  ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
684  if (ret < 0)
685  return ret;
686 
687  ogg_write_pages(s, 0);
688 
689  oggstream->last_granule = granule;
690 
691  return 0;
692 }
693 
695 {
696  int i;
697 
698  if (pkt)
700 
701  for (i = 0; i < s->nb_streams; i++) {
702  OGGStreamContext *oggstream = s->streams[i]->priv_data;
703  if (oggstream->page.segments_count)
704  ogg_buffer_page(s, oggstream);
705  }
706 
707  ogg_write_pages(s, 2);
708  return 1;
709 }
710 
712 {
713  int i;
714 
715  /* flush current page if needed */
716  for (i = 0; i < s->nb_streams; i++) {
717  OGGStreamContext *oggstream = s->streams[i]->priv_data;
718 
719  if (oggstream->page.segments_count)
720  ogg_buffer_page(s, oggstream);
721  }
722 
723  ogg_write_pages(s, 1);
724 
725  return 0;
726 }
727 
729 {
730  OGGContext *ogg = s->priv_data;
731  OGGPageList *p = ogg->page_list;
732  int i;
733 
734  for (i = 0; i < s->nb_streams; i++) {
735  AVStream *st = s->streams[i];
736  OGGStreamContext *oggstream = st->priv_data;
737  if (!oggstream)
738  continue;
739  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
743  av_freep(&oggstream->header[0]);
744  }
745  av_freep(&oggstream->header[1]);
746  }
747 
748  while (p) {
749  OGGPageList *next = p->next;
750  av_free(p);
751  p = next;
752  }
753  ogg->page_list = NULL;
754 }
755 
756 #if CONFIG_OGG_MUXER
758  .p.name = "ogg",
759  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
760  .p.mime_type = "application/ogg",
761  .p.extensions = "ogg"
762 #if !CONFIG_OGV_MUXER
763  ",ogv"
764 #endif
765 #if !CONFIG_SPX_MUXER
766  ",spx"
767 #endif
768 #if !CONFIG_OPUS_MUXER
769  ",opus"
770 #endif
771  ,
772  .priv_data_size = sizeof(OGGContext),
773  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
775  .p.video_codec = AV_CODEC_ID_THEORA,
776  .init = ogg_init,
777  .write_header = ogg_write_header,
778  .write_packet = ogg_write_packet,
779  .write_trailer = ogg_write_trailer,
780  .deinit = ogg_free,
782  .p.priv_class = &ogg_muxer_class,
783  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
784 };
785 #endif
786 
787 #if CONFIG_OGA_MUXER
789  .p.name = "oga",
790  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Audio"),
791  .p.mime_type = "audio/ogg",
792  .p.extensions = "oga",
793  .priv_data_size = sizeof(OGGContext),
794  .p.audio_codec = AV_CODEC_ID_FLAC,
795  .init = ogg_init,
796  .write_header = ogg_write_header,
797  .write_packet = ogg_write_packet,
798  .write_trailer = ogg_write_trailer,
799  .deinit = ogg_free,
800  .p.flags = AVFMT_TS_NEGATIVE,
801  .p.priv_class = &ogg_muxer_class,
802  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
803 };
804 #endif
805 
806 #if CONFIG_OGV_MUXER
808  .p.name = "ogv",
809  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Video"),
810  .p.mime_type = "video/ogg",
811  .p.extensions = "ogv",
812  .priv_data_size = sizeof(OGGContext),
813  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
815  .p.video_codec = CONFIG_LIBTHEORA_ENCODER ?
817  .init = ogg_init,
818  .write_header = ogg_write_header,
819  .write_packet = ogg_write_packet,
820  .write_trailer = ogg_write_trailer,
821  .deinit = ogg_free,
823  .p.priv_class = &ogg_muxer_class,
824  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
825 };
826 #endif
827 
828 #if CONFIG_SPX_MUXER
830  .p.name = "spx",
831  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Speex"),
832  .p.mime_type = "audio/ogg",
833  .p.extensions = "spx",
834  .priv_data_size = sizeof(OGGContext),
835  .p.audio_codec = AV_CODEC_ID_SPEEX,
836  .init = ogg_init,
837  .write_header = ogg_write_header,
838  .write_packet = ogg_write_packet,
839  .write_trailer = ogg_write_trailer,
840  .deinit = ogg_free,
841  .p.flags = AVFMT_TS_NEGATIVE,
842  .p.priv_class = &ogg_muxer_class,
843  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
844 };
845 #endif
846 
847 #if CONFIG_OPUS_MUXER
849  .p.name = "opus",
850  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Opus"),
851  .p.mime_type = "audio/ogg",
852  .p.extensions = "opus",
853  .priv_data_size = sizeof(OGGContext),
854  .p.audio_codec = AV_CODEC_ID_OPUS,
855  .init = ogg_init,
856  .write_header = ogg_write_header,
857  .write_packet = ogg_write_packet,
858  .write_trailer = ogg_write_trailer,
859  .deinit = ogg_free,
860  .p.flags = AVFMT_TS_NEGATIVE,
861  .p.priv_class = &ogg_muxer_class,
862  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
863 };
864 #endif
VP8_HEADER_SIZE
#define VP8_HEADER_SIZE
Definition: oggenc.c:409
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:82
AVOutputFormat::name
const char * name
Definition: avformat.h:506
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:422
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:769
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:37
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
int64_t
long long int64_t
Definition: coverity.c:34
ogg_compare_granule
static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page)
Definition: oggenc.c:155
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:588
vorbiscomment.h
OGGPageList
Definition: oggenc.c:71
AVOption
AVOption.
Definition: opt.h:429
data
const char data[16]
Definition: mxf.c:149
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:287
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:606
mathematics.h
AVDictionary
Definition: dict.c:32
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:471
ff_ogg_muxer
const FFOutputFormat ff_ogg_muxer
ogg_muxer_class
static const AVClass ogg_muxer_class
Definition: oggenc.c:103
ogg
Definition: oggdec.h:111
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:643
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:196
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:464
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:777
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:494
OFFSET
#define OFFSET(x)
Definition: oggenc.c:86
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:1223
ogg_write_header
static int ogg_write_header(AVFormatContext *s)
Definition: oggenc.c:612
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:642
ogg_write_pages
static void ogg_write_pages(AVFormatContext *s, int flush)
Definition: oggenc.c:460
SPEEX_HEADER_SIZE
#define SPEEX_HEADER_SIZE
Definition: oggenc.c:350
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
OGGStreamContext::isvp8
int isvp8
Definition: oggenc.c:63
ogg_init
static int ogg_init(AVFormatContext *s)
Definition: oggenc.c:482
ogg_build_vp8_headers
static int ogg_build_vp8_headers(AVFormatContext *s, AVStream *st, OGGStreamContext *oggstream, int bitexact)
Definition: oggenc.c:411
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:205
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
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
Underlying C type is int64_t.
Definition: opt.h:263
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
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
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
ogg_free
static void ogg_free(AVFormatContext *s)
Definition: oggenc.c:728
ogg_buffer_page
static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
Definition: oggenc.c:180
OGGStreamContext
Definition: oggenc.c:54
ff_opus_muxer
const FFOutputFormat ff_opus_muxer
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
OGGContext::serial_offset
int serial_offset
Definition: oggenc.c:83
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:783
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:241
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:552
options
Definition: swscale.c:43
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
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:184
options
static const AVOption options[]
Definition: oggenc.c:89
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:80
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:589
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:247
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:87
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:519
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:206
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:594
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:381
AV_OPT_FLAG_DEPRECATED
#define AV_OPT_FLAG_DEPRECATED
Set if option is deprecated, users should refer to AVOption.help text for more information.
Definition: opt.h:386
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:581
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:314
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
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ogg_write_trailer
static int ogg_write_trailer(AVFormatContext *s)
Definition: oggenc.c:711
len
int len
Definition: vorbis_enc_data.h:426
AV_CRC_32_IEEE
@ AV_CRC_32_IEEE
Definition: crc.h:52
ff_oga_muxer
const FFOutputFormat ff_oga_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:490
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:487
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:1432
AVStream
Stream structure.
Definition: avformat.h:744
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:81
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:110
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:144
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
Underlying C type is int.
Definition: opt.h:259
ogg_build_speex_headers
static int ogg_build_speex_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
Definition: oggenc.c:352
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
OGGPage::size
uint16_t size
Definition: oggenc.c:51
OGGPage::flags
uint8_t flags
Definition: oggenc.c:47
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
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:590
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:34
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:565
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:247
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:379
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:464
ogg_write_packet
static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggenc.c:694
flac.h
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AVPacket::side_data_elems
int side_data_elems
Definition: packet.h:600
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:138
ogg_reset_cur_page
static int ogg_reset_cur_page(OGGStreamContext *oggstream)
Definition: oggenc.c:171