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