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