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
69  int packet_seen; ///< true when packets have been submitted
71 
72 typedef struct OGGPageList {
74  struct OGGPageList *next;
75 } OGGPageList;
76 
77 typedef struct OGGContext {
78  const AVClass *class;
80 #if LIBAVFORMAT_VERSION_MAJOR < 63
81  int pref_size; ///< preferred page size (0 => fill all segments)
82 #endif
83  int64_t pref_duration; ///< preferred page duration (0 => fill all segments)
85  int failed; // if true all packet submission will fail.
86 } OGGContext;
87 
88 #define OFFSET(x) offsetof(OGGContext, x)
89 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
90 
92 
93 static const AVOption options[] = {
94  { "serial_offset", "serial number offset",
95  OFFSET(serial_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, PARAM },
96 #if LIBAVFORMAT_VERSION_MAJOR < 63
97  { "oggpagesize", "Set preferred Ogg page size.",
98  OFFSET(pref_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, MAX_PAGE_SIZE, PARAM | AV_OPT_FLAG_DEPRECATED },
99  { "pagesize", "preferred page size in bytes",
100  OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM | AV_OPT_FLAG_DEPRECATED },
101 #endif
102  { "page_duration", "preferred page duration, in microseconds",
103  OFFSET(pref_duration), AV_OPT_TYPE_INT64, { .i64 = 1000000 }, 0, INT64_MAX, PARAM },
104  { NULL },
105 };
106 
107 static const AVClass ogg_muxer_class = {
108  .class_name = "Ogg (audio/video/Speex/Opus) muxer",
109  .item_name = av_default_item_name,
110  .option = options,
111  .version = LIBAVUTIL_VERSION_INT,
112 };
113 
114 static void ogg_cleanup_stream(AVStream *st)
115 {
116  OGGStreamContext *oggstream = st->priv_data;
117 
118  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
122  av_freep(&oggstream->header[0]);
123  }
124 
125  av_freep(&oggstream->header[1]);
126 }
127 
128 static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
129 {
130  OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data;
131  uint8_t buf[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr = buf, *crc_pos;
132  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE);
133  uint32_t crc;
134 
135  bytestream_put_le32(&ptr, MKTAG('O', 'g', 'g', 'S'));
136  bytestream_put_byte(&ptr, 0);
137  bytestream_put_byte(&ptr, page->flags | extra_flags);
138  bytestream_put_le64(&ptr, page->granule);
139  bytestream_put_le32(&ptr, oggstream->serial_num);
140  bytestream_put_le32(&ptr, oggstream->page_counter++);
141  crc_pos = ptr;
142  bytestream_put_le32(&ptr, 0);
143  bytestream_put_byte(&ptr, page->segments_count);
144  bytestream_put_buffer(&ptr, page->segments, page->segments_count);
145 
146  crc = av_crc(crc_table, 0, buf, ptr - buf);
147  crc = av_crc(crc_table, crc, page->data, page->size);
148  bytestream_put_be32(&crc_pos, crc);
149 
150  avio_write(s->pb, buf, ptr - buf);
151  avio_write(s->pb, page->data, page->size);
153  oggstream->page_count--;
154 }
155 
156 static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
157 {
158  return (oggstream->kfgshift && !(granule & ((1<<oggstream->kfgshift)-1))) ||
159  (oggstream->isvp8 && !((granule >> 3) & 0x07ffffff));
160 }
161 
163 {
164  if (oggstream->kfgshift)
165  return (granule>>oggstream->kfgshift) +
166  (granule & ((1<<oggstream->kfgshift)-1));
167  else if (oggstream->isvp8)
168  return granule >> 32;
169  else
170  return granule;
171 }
172 
174 {
175  AVStream *st2 = s->streams[next->stream_index];
176  AVStream *st = s->streams[page->stream_index];
177  int64_t next_granule, cur_granule;
178 
179  if (next->granule == -1 || page->granule == -1)
180  return 0;
181 
182  next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next->granule),
183  st2->time_base, AV_TIME_BASE_Q);
184  cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page->granule),
185  st ->time_base, AV_TIME_BASE_Q);
186  return next_granule > cur_granule;
187 }
188 
189 static int ogg_reset_cur_page(OGGStreamContext *oggstream)
190 {
191  oggstream->page.granule = -1;
192  oggstream->page.flags = 0;
193  oggstream->page.segments_count = 0;
194  oggstream->page.size = 0;
195  return 0;
196 }
197 
199 {
200  OGGContext *ogg = s->priv_data;
201  OGGPageList **p = &ogg->page_list;
202  OGGPageList *l = av_mallocz(sizeof(*l));
203 
204  if (!l)
205  return AVERROR(ENOMEM);
206  l->page = oggstream->page;
207 
208  oggstream->page.start_granule = ogg_granule_to_timestamp(oggstream, oggstream->page.granule);
209  oggstream->page_count++;
210  ogg_reset_cur_page(oggstream);
211 
212  while (*p) {
213  if (ogg_compare_granule(s, &(*p)->page, &l->page))
214  break;
215  p = &(*p)->next;
216  }
217  l->next = *p;
218  *p = l;
219 
220  return 0;
221 }
222 
224  const uint8_t *data, unsigned size, int64_t granule,
225  int header)
226 {
227  OGGStreamContext *oggstream = st->priv_data;
228  OGGContext *ogg = s->priv_data;
229  int total_segments = size / 255 + 1;
230  const uint8_t *p = data;
231  int i, segments, len, flush = 0;
232 
233  // Handles VFR by flushing page because this frame needs to have a timestamp
234  // For theora and VP8, keyframes also need to have a timestamp to correctly mark
235  // them as such, otherwise seeking will not work correctly at the very
236  // least with old libogg versions.
237  // Do not try to flush header packets though, that will create broken files.
239  (ogg_granule_to_timestamp(oggstream, granule) >
240  ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
241  ogg_key_granule(oggstream, granule))) {
242  if (oggstream->page.granule != -1)
243  ogg_buffer_page(s, oggstream);
244  flush = 1;
245  }
246 
247  // avoid a continued page
248  if (!header && oggstream->page.size > 0 &&
249  MAX_PAGE_SIZE - oggstream->page.size < size) {
250  ogg_buffer_page(s, oggstream);
251  }
252 
253  for (i = 0; i < total_segments; ) {
254  OGGPage *page = &oggstream->page;
255 
256  segments = FFMIN(total_segments - i, 255 - page->segments_count);
257 
258  if (i && !page->segments_count)
259  page->flags |= 1; // continued packet
260 
261  memset(page->segments+page->segments_count, 255, segments - 1);
262  page->segments_count += segments - 1;
263 
264  len = FFMIN(size, segments*255);
265  page->segments[page->segments_count++] = len - (segments-1)*255;
266  if (len)
267  memcpy(page->data+page->size, p, len);
268  p += len;
269  size -= len;
270  i += segments;
271  page->size += len;
272 
273  if (i == total_segments)
274  page->granule = granule;
275 
276  {
277  AVStream *st = s->streams[page->stream_index];
278 
279  int64_t start = av_rescale_q(page->start_granule, st->time_base,
281  int64_t next = av_rescale_q(ogg_granule_to_timestamp(oggstream, page->granule),
283 
284  if (page->segments_count == 255) {
285  ogg_buffer_page(s, oggstream);
286  } else if (!header) {
287 #if LIBAVFORMAT_VERSION_MAJOR < 63
288  if ((ogg->pref_size > 0 && page->size >= ogg->pref_size) ||
289  (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
290 #else
291  if (ogg->pref_duration > 0 && next - start >= ogg->pref_duration) {
292 #endif
293  ogg_buffer_page(s, oggstream);
294  }
295  }
296  }
297  }
298 
299  if (flush && oggstream->page.granule != -1)
300  ogg_buffer_page(s, oggstream);
301 
302  return 0;
303 }
304 
305 static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
306  int *header_len, AVDictionary **m, int framing_bit,
307  AVChapter **chapters, unsigned int nb_chapters)
308 {
309  const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
310  FFIOContext pb;
311  int64_t size;
312  uint8_t *p;
313 
315 
316  size = ff_vorbiscomment_length(*m, vendor, chapters, nb_chapters);
317  if (size < 0)
318  return NULL;
319  size += offset + framing_bit;
320  if (size > INT_MAX)
321  return NULL;
322  p = av_mallocz(size);
323  if (!p)
324  return NULL;
325 
327  ff_vorbiscomment_write(&pb.pub, *m, vendor, chapters, nb_chapters);
328  if (framing_bit)
329  avio_w8(&pb.pub, 1);
330 
331  *header_len = size;
332  return p;
333 }
334 
336  OGGStreamContext *oggstream, int bitexact,
337  AVDictionary **m)
338 {
339  uint8_t *p;
340 
342  return AVERROR(EINVAL);
343 
344  // first packet: STREAMINFO
345  oggstream->header_len[0] = 51;
346  oggstream->header[0] = av_mallocz(51); // per ogg flac specs
347  p = oggstream->header[0];
348  if (!p)
349  return AVERROR(ENOMEM);
350  bytestream_put_byte(&p, 0x7F);
351  bytestream_put_buffer(&p, "FLAC", 4);
352  bytestream_put_byte(&p, 1); // major version
353  bytestream_put_byte(&p, 0); // minor version
354  bytestream_put_be16(&p, 1); // headers packets without this one
355  bytestream_put_buffer(&p, "fLaC", 4);
356  bytestream_put_byte(&p, 0x00); // streaminfo
357  bytestream_put_be24(&p, 34);
359 
360  // second packet: VorbisComment
361  p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
362  if (!p)
363  return AVERROR(ENOMEM);
364  oggstream->header[1] = p;
365  bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment
366  bytestream_put_be24(&p, oggstream->header_len[1] - 4);
367 
368  return 0;
369 }
370 
371 #define SPEEX_HEADER_SIZE 80
372 
374  OGGStreamContext *oggstream, int bitexact,
375  AVDictionary **m)
376 {
377  uint8_t *p;
378 
380  return AVERROR_INVALIDDATA;
381 
382  // first packet: Speex header
384  if (!p)
385  return AVERROR(ENOMEM);
386  oggstream->header[0] = p;
387  oggstream->header_len[0] = SPEEX_HEADER_SIZE;
389  AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0
390 
391  // second packet: VorbisComment
392  p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m, 0, NULL, 0);
393  if (!p)
394  return AVERROR(ENOMEM);
395  oggstream->header[1] = p;
396 
397  return 0;
398 }
399 
400 #define OPUS_HEADER_SIZE 19
401 
403  OGGStreamContext *oggstream, int bitexact,
404  AVDictionary **m, AVChapter **chapters,
405  unsigned int nb_chapters)
406 {
407  uint8_t *p;
408 
409  if (par->extradata_size < OPUS_HEADER_SIZE)
410  return AVERROR_INVALIDDATA;
411 
412  /* first packet: Opus header */
413  p = av_mallocz(par->extradata_size);
414  if (!p)
415  return AVERROR(ENOMEM);
416  oggstream->header[0] = p;
417  oggstream->header_len[0] = par->extradata_size;
419 
420  /* second packet: VorbisComment */
421  p = ogg_write_vorbiscomment(8, bitexact, &oggstream->header_len[1], m, 0, chapters, nb_chapters);
422  if (!p)
423  return AVERROR(ENOMEM);
424  oggstream->header[1] = p;
425  bytestream_put_buffer(&p, "OpusTags", 8);
426 
427  return 0;
428 }
429 
430 #define VP8_HEADER_SIZE 26
431 
433  OGGStreamContext *oggstream, int bitexact)
434 {
435  AVCodecParameters *par = st->codecpar;
436  uint8_t *p;
437 
438  /* first packet: VP8 header */
440  if (!p)
441  return AVERROR(ENOMEM);
442  oggstream->header[0] = p;
443  oggstream->header_len[0] = VP8_HEADER_SIZE;
444  bytestream_put_byte(&p, 0x4f); // HDRID
445  bytestream_put_buffer(&p, "VP80", 4); // Identifier
446  bytestream_put_byte(&p, 1); // HDRTYP
447  bytestream_put_byte(&p, 1); // VMAJ
448  bytestream_put_byte(&p, 0); // VMIN
449  bytestream_put_be16(&p, par->width);
450  bytestream_put_be16(&p, par->height);
451  bytestream_put_be24(&p, par->sample_aspect_ratio.num);
452  bytestream_put_be24(&p, par->sample_aspect_ratio.den);
453  if (st->r_frame_rate.num > 0 && st->r_frame_rate.den > 0) {
454  // OggVP8 requires pts to increase by 1 per visible frame, so use the least common
455  // multiple framerate if available.
456  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
457  st->time_base.num, st->time_base.den,
458  st->r_frame_rate.den, st->r_frame_rate.num);
460  }
461  bytestream_put_be32(&p, st->time_base.den);
462  bytestream_put_be32(&p, st->time_base.num);
463 
464  /* optional second packet: VorbisComment */
465  if (av_dict_count(st->metadata)) {
466  p = ogg_write_vorbiscomment(7, bitexact, &oggstream->header_len[1], &st->metadata, 0, NULL, 0);
467  if (!p)
468  return AVERROR(ENOMEM);
469  oggstream->header[1] = p;
470  bytestream_put_byte(&p, 0x4f); // HDRID
471  bytestream_put_buffer(&p, "VP80", 4); // Identifier
472  bytestream_put_byte(&p, 2); // HDRTYP
473  bytestream_put_byte(&p, 0x20);
474  }
475 
476  oggstream->isvp8 = 1;
477 
478  return 0;
479 }
480 
482 {
483  OGGContext *ogg = s->priv_data;
484  OGGPageList *next, *p;
485 
486  if (!ogg->page_list)
487  return;
488 
489  for (p = ogg->page_list; p; ) {
490  OGGStreamContext *oggstream =
491  s->streams[p->page.stream_index]->priv_data;
492  if (oggstream->page_count < 2 && !flush)
493  break;
494  ogg_write_page(s, &p->page,
495  flush == 1 && oggstream->page_count == 1 ? 4 : 0); // eos
496  next = p->next;
497  av_freep(&p);
498  p = next;
499  }
500  ogg->page_list = p;
501 }
502 
503 // This function can be used on an initialized context to reinitialize the
504 // streams.
506 {
507  OGGContext *ogg = s->priv_data;
508  OGGStreamContext *oggstream = NULL;
509  int i, j;
510 
511  for (i = 0; i < s->nb_streams; i++) {
512  AVStream *st = s->streams[i];
513  unsigned serial_num = i + ogg->serial_offset;
514 
515  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
516  if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
517  /* Opus requires a fixed 48kHz clock */
518  avpriv_set_pts_info(st, 64, 1, 48000);
519  else
520  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
521  }
522 
523  if (st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
529  av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
530  return AVERROR(EINVAL);
531  }
532 
533  if ((!st->codecpar->extradata || !st->codecpar->extradata_size) &&
535  av_log(s, AV_LOG_ERROR, "No extradata present\n");
536  return AVERROR_INVALIDDATA;
537  }
538  oggstream = st->priv_data;
539 
540  if (!oggstream) {
541  oggstream = av_mallocz(sizeof(*oggstream));
542  if (!oggstream)
543  return AVERROR(ENOMEM);
544  st->priv_data = oggstream;
545  } else {
546  ogg_cleanup_stream(st);
547  memset(oggstream, 0, sizeof(*oggstream));
548  }
549 
550  oggstream->page.stream_index = i;
551 
552  if (!(s->flags & AVFMT_FLAG_BITEXACT))
553  do {
554  serial_num = av_get_random_seed();
555  for (j = 0; j < i; j++) {
556  OGGStreamContext *sc = s->streams[j]->priv_data;
557  if (serial_num == sc->serial_num)
558  break;
559  }
560  } while (j < i);
561  oggstream->serial_num = serial_num;
562 
563  av_dict_copy(&st->metadata, s->metadata, AV_DICT_DONT_OVERWRITE);
564 
565  if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) {
566  int err = ogg_build_flac_headers(st->codecpar, oggstream,
567  s->flags & AVFMT_FLAG_BITEXACT,
568  &st->metadata);
569  if (err) {
570  av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
571  return err;
572  }
573  } else if (st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
574  int err = ogg_build_speex_headers(st->codecpar, oggstream,
575  s->flags & AVFMT_FLAG_BITEXACT,
576  &st->metadata);
577  if (err) {
578  av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
579  return err;
580  }
581  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
582  int err = ogg_build_opus_headers(st->codecpar, oggstream,
583  s->flags & AVFMT_FLAG_BITEXACT,
584  &st->metadata, s->chapters, s->nb_chapters);
585  if (err) {
586  av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
587  return err;
588  }
589  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
590  int err = ogg_build_vp8_headers(s, st, oggstream,
591  s->flags & AVFMT_FLAG_BITEXACT);
592  if (err) {
593  av_log(s, AV_LOG_ERROR, "Error writing VP8 headers\n");
594  return err;
595  }
596  } else {
597  uint8_t *p;
598  const char *cstr = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? "vorbis" : "theora";
599  int header_type = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 3 : 0x81;
600  int framing_bit = st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 1 : 0;
601 
603  st->codecpar->codec_id == AV_CODEC_ID_VORBIS ? 30 : 42,
604  (const uint8_t**)oggstream->header, oggstream->header_len) < 0) {
605  av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
606  oggstream->header[1] = NULL;
607  return AVERROR_INVALIDDATA;
608  }
609 
611  &oggstream->header_len[1], &st->metadata,
612  framing_bit, NULL, 0);
613  oggstream->header[1] = p;
614  if (!p)
615  return AVERROR(ENOMEM);
616 
617  bytestream_put_byte(&p, header_type);
618  bytestream_put_buffer(&p, cstr, 6);
619 
620  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
621  int den = AV_RB32(oggstream->header[0] + 22), num = AV_RB32(oggstream->header[0] + 26);
622  /* Make sure to use time base stored in the Theora stream header to write
623  correct timestamps */
624  if (st->time_base.num != num || st->time_base.den != den) {
625  av_log(s, AV_LOG_DEBUG, "Changing time base from %d/%d to %d/%d\n",
626  st->time_base.num, st->time_base.den, num, den);
627  avpriv_set_pts_info(st, 64, num, den);
628  }
629  /** KFGSHIFT is the width of the less significant section of the granule position
630  The less significant section is the frame count since the last keyframe */
631  oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5);
632  oggstream->vrev = oggstream->header[0][9];
633  av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n",
634  oggstream->kfgshift, oggstream->vrev);
635  }
636  }
637  }
638 
639  return 0;
640 }
641 
643 {
644  OGGStreamContext *oggstream = NULL;
645  int i, j;
646 
647  for (j = 0; j < s->nb_streams; j++) {
648  oggstream = s->streams[j]->priv_data;
649  ogg_buffer_data(s, s->streams[j], oggstream->header[0],
650  oggstream->header_len[0], 0, 1);
651  oggstream->page.flags |= 2; // bos
652  ogg_buffer_page(s, oggstream);
653  }
654  for (j = 0; j < s->nb_streams; j++) {
655  AVStream *st = s->streams[j];
656  oggstream = st->priv_data;
657  for (i = 1; i < 3; i++) {
658  if (oggstream->header_len[i])
659  ogg_buffer_data(s, st, oggstream->header[i],
660  oggstream->header_len[i], 0, 1);
661  }
662  ogg_buffer_page(s, oggstream);
663  }
664 
665  oggstream->page.start_granule = AV_NOPTS_VALUE;
666 
667  ogg_write_pages(s, 2);
668 
669  return 0;
670 }
671 
673 {
674  int ret = 0;
675  size_t size;
676  OGGContext *oggcontext = s->priv_data;
677  AVStream *st = s->streams[pkt->stream_index];
678  OGGStreamContext *oggstream = st->priv_data;
679  const uint8_t *side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size);
680 
681  if (!side_metadata)
682  return 0;
683 
684  // Don't restart on first packet.
685  if (!oggstream->packet_seen)
686  return 0;
687 
688  if (s->nb_streams > 1) {
689  av_log(s, AV_LOG_WARNING, "Multiple streams present: cannot insert new metadata!\n");
690  return 0;
691  }
692 
693  if (st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
696  av_log(s, AV_LOG_WARNING, "Inserting metadata is only supported for vorbis, flac and opus streams!\n");
697  return 0;
698  }
699 
701  if (ret < 0)
702  goto end;
703 
704  av_dict_free(&st->metadata);
705  ret = av_packet_unpack_dictionary(side_metadata, size, &st->metadata);
706  if (ret < 0)
707  goto end;
708 
709  ret = ogg_init(s);
710  if (ret < 0)
711  goto end;
712 
714 
715 end:
716  oggcontext->failed = ret < 0;
717  return ret;
718 }
719 
721 {
722  AVStream *st = s->streams[pkt->stream_index];
723  OGGContext *oggcontext = s->priv_data;
724  OGGStreamContext *oggstream = st->priv_data;
725  int ret;
726  int64_t granule;
727 
728  if (oggcontext->failed)
729  return AVERROR_INVALIDDATA;
730 
732  if (ret < 0)
733  return ret;
734 
735  if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) {
736  int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration;
737  int pframe_count;
738  if (pkt->flags & AV_PKT_FLAG_KEY)
739  oggstream->last_kf_pts = pts;
740  pframe_count = pts - oggstream->last_kf_pts;
741  // prevent frame count from overflow if key frame flag is not set
742  if (pframe_count >= (1<<oggstream->kfgshift)) {
743  oggstream->last_kf_pts += pframe_count;
744  pframe_count = 0;
745  }
746  granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
747  } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS)
748  granule = pkt->pts + pkt->duration +
750  (AVRational){ 1, st->codecpar->sample_rate },
751  st->time_base);
752  else if (st->codecpar->codec_id == AV_CODEC_ID_VP8) {
753  int64_t pts, invcnt, dist;
754  int visible;
755 
756  visible = (pkt->data[0] >> 4) & 1;
757  pts = pkt->pts + pkt->duration;
758  invcnt = (oggstream->last_granule >> 30) & 3;
759  invcnt = visible ? 3 : (invcnt == 3 ? 0 : invcnt + 1);
760  dist = (pkt->flags & AV_PKT_FLAG_KEY) ? 0 : ((oggstream->last_granule >> 3) & 0x07ffffff) + 1;
761 
762  granule = (pts << 32) | (invcnt << 30) | (dist << 3);
763  } else
764  granule = pkt->pts + pkt->duration;
765 
766  if (oggstream->page.start_granule == AV_NOPTS_VALUE)
767  oggstream->page.start_granule = pkt->pts;
768 
769  ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
770  if (ret < 0)
771  return ret;
772 
773  ogg_write_pages(s, 0);
774 
775  oggstream->last_granule = granule;
776  oggstream->packet_seen = 1;
777 
778  return 0;
779 }
780 
782 {
783  int i;
784 
785  if (pkt)
787 
788  for (i = 0; i < s->nb_streams; i++) {
789  OGGStreamContext *oggstream = s->streams[i]->priv_data;
790  if (oggstream->page.segments_count)
791  ogg_buffer_page(s, oggstream);
792  }
793 
794  ogg_write_pages(s, 2);
795  return 1;
796 }
797 
799 {
800  int i;
801 
802  /* flush current page if needed */
803  for (i = 0; i < s->nb_streams; i++) {
804  OGGStreamContext *oggstream = s->streams[i]->priv_data;
805 
806  if (oggstream->page.segments_count)
807  ogg_buffer_page(s, oggstream);
808  }
809 
810  ogg_write_pages(s, 1);
811 
812  return 0;
813 }
814 
816 {
817  OGGContext *ogg = s->priv_data;
818  OGGPageList *p = ogg->page_list;
819  int i;
820 
821  for (i = 0; i < s->nb_streams; i++) {
822  AVStream *st = s->streams[i];
823  if (st->priv_data)
824  ogg_cleanup_stream(st);
825  }
826 
827  while (p) {
828  OGGPageList *next = p->next;
829  av_free(p);
830  p = next;
831  }
832  ogg->page_list = NULL;
833 }
834 
835 #if CONFIG_OGG_MUXER
837  .p.name = "ogg",
838  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
839  .p.mime_type = "application/ogg",
840  .p.extensions = "ogg"
841 #if !CONFIG_OGV_MUXER
842  ",ogv"
843 #endif
844 #if !CONFIG_SPX_MUXER
845  ",spx"
846 #endif
847 #if !CONFIG_OPUS_MUXER
848  ",opus"
849 #endif
850  ,
851  .priv_data_size = sizeof(OGGContext),
852  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
854  .p.video_codec = AV_CODEC_ID_THEORA,
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,
861  .p.priv_class = &ogg_muxer_class,
862  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
863 };
864 #endif
865 
866 #if CONFIG_OGA_MUXER
868  .p.name = "oga",
869  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Audio"),
870  .p.mime_type = "audio/ogg",
871  .p.extensions = "oga",
872  .priv_data_size = sizeof(OGGContext),
873  .p.audio_codec = AV_CODEC_ID_FLAC,
874  .init = ogg_init,
875  .write_header = ogg_write_header,
876  .write_packet = ogg_write_packet,
877  .write_trailer = ogg_write_trailer,
878  .deinit = ogg_free,
879  .p.flags = AVFMT_TS_NEGATIVE,
880  .p.priv_class = &ogg_muxer_class,
881  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
882 };
883 #endif
884 
885 #if CONFIG_OGV_MUXER
887  .p.name = "ogv",
888  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Video"),
889  .p.mime_type = "video/ogg",
890  .p.extensions = "ogv",
891  .priv_data_size = sizeof(OGGContext),
892  .p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
894  .p.video_codec = CONFIG_LIBTHEORA_ENCODER ?
896  .init = ogg_init,
897  .write_header = ogg_write_header,
898  .write_packet = ogg_write_packet,
899  .write_trailer = ogg_write_trailer,
900  .deinit = ogg_free,
902  .p.priv_class = &ogg_muxer_class,
903  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
904 };
905 #endif
906 
907 #if CONFIG_SPX_MUXER
909  .p.name = "spx",
910  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Speex"),
911  .p.mime_type = "audio/ogg",
912  .p.extensions = "spx",
913  .priv_data_size = sizeof(OGGContext),
914  .p.audio_codec = AV_CODEC_ID_SPEEX,
915  .init = ogg_init,
916  .write_header = ogg_write_header,
917  .write_packet = ogg_write_packet,
918  .write_trailer = ogg_write_trailer,
919  .deinit = ogg_free,
920  .p.flags = AVFMT_TS_NEGATIVE,
921  .p.priv_class = &ogg_muxer_class,
922  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
923 };
924 #endif
925 
926 #if CONFIG_OPUS_MUXER
928  .p.name = "opus",
929  .p.long_name = NULL_IF_CONFIG_SMALL("Ogg Opus"),
930  .p.mime_type = "audio/ogg",
931  .p.extensions = "opus",
932  .priv_data_size = sizeof(OGGContext),
933  .p.audio_codec = AV_CODEC_ID_OPUS,
934  .init = ogg_init,
935  .write_header = ogg_write_header,
936  .write_packet = ogg_write_packet,
937  .write_trailer = ogg_write_trailer,
938  .deinit = ogg_free,
939  .p.flags = AVFMT_TS_NEGATIVE,
940  .p.priv_class = &ogg_muxer_class,
941  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
942 };
943 #endif
VP8_HEADER_SIZE
#define VP8_HEADER_SIZE
Definition: oggenc.c:430
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
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:83
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:173
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:72
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:305
OGGContext::failed
int failed
Definition: oggenc.c:85
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:472
ff_ogg_muxer
const FFOutputFormat ff_ogg_muxer
ogg_muxer_class
static const AVClass ogg_muxer_class
Definition: oggenc.c:107
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:74
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:73
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:780
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:495
OFFSET
#define OFFSET(x)
Definition: oggenc.c:88
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:60
AVChapter
Definition: avformat.h:1223
ogg_write_header
static int ogg_write_header(AVFormatContext *s)
Definition: oggenc.c:642
pts
static int64_t pts
Definition: transcode_aac.c:644
OGGStreamContext::packet_seen
int packet_seen
true when packets have been submitted
Definition: oggenc.c:69
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:720
ogg_write_pages
static void ogg_write_pages(AVFormatContext *s, int flush)
Definition: oggenc.c:481
SPEEX_HEADER_SIZE
#define SPEEX_HEADER_SIZE
Definition: oggenc.c:371
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:505
ogg_build_vp8_headers
static int ogg_build_vp8_headers(AVFormatContext *s, AVStream *st, OGGStreamContext *oggstream, int bitexact)
Definition: oggenc.c:432
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:223
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
ogg_check_new_metadata
static int ogg_check_new_metadata(AVFormatContext *s, AVPacket *pkt)
Definition: oggenc.c:672
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:34
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:815
ogg_buffer_page
static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
Definition: oggenc.c:198
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:84
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:242
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:93
OGGStreamContext::header
uint8_t * header[3]
Definition: oggenc.c:56
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:81
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:89
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:520
av_packet_unpack_dictionary
int av_packet_unpack_dictionary(const uint8_t *data, size_t size, AVDictionary **dict)
Unpack a dictionary from side_data.
Definition: packet.c:352
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:385
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
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
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:402
AV_PKT_DATA_STRINGS_METADATA
@ AV_PKT_DATA_STRINGS_METADATA
A list of zero terminated key/value strings.
Definition: packet.h:169
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
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: packet.c:252
ogg_build_flac_headers
static int ogg_build_flac_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
Definition: oggenc.c:335
AV_CODEC_ID_THEORA
@ AV_CODEC_ID_THEORA
Definition: codec_id.h:82
AVCodecParameters::height
int height
Definition: codec_par.h:135
ff_vorbiscomment_length
int 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:42
ogg_cleanup_stream
static void ogg_cleanup_stream(AVStream *st)
Definition: oggenc.c:114
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:798
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:77
OGGPage
Definition: oggenc.c:43
ogg_write_page
static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
Definition: oggenc.c:128
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:162
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:417
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:373
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:79
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:400
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:465
ogg_write_packet
static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: oggenc.c:781
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
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:156
ogg_reset_cur_page
static int ogg_reset_cur_page(OGGStreamContext *oggstream)
Definition: oggenc.c:189