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