3 * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at free dot fr>
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/crc.h"
25 #include "libavutil/mathematics.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/random_seed.h"
28 #include "libavcodec/xiph.h"
29 #include "libavcodec/bytestream.h"
30 #include "libavcodec/flac.h"
32 #include "avio_internal.h"
34 #include "vorbiscomment.h"
36 #define MAX_PAGE_SIZE 65025
38 typedef struct OGGPage
{
39 int64_t start_granule
;
43 uint8_t segments_count
;
44 uint8_t segments
[255];
45 uint8_t data
[MAX_PAGE_SIZE
];
49 typedef struct OGGStreamContext
{
50 unsigned page_counter
;
53 /** for theora granule */
60 unsigned page_count
; ///< number of page buffered
61 OGGPage page
; ///< current page
62 unsigned serial_num
; ///< serial number
63 int64_t last_granule
; ///< last packet granule
66 typedef struct OGGPageList
{
68 struct OGGPageList
*next
;
71 typedef struct OGGContext
{
73 OGGPageList
*page_list
;
74 int pref_size
; ///< preferred page size (0 => fill all segments)
75 int64_t pref_duration
; ///< preferred page duration (0 => fill all segments)
79 #define OFFSET(x) offsetof(OGGContext, x)
80 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
82 static const AVOption options
[] = {
83 { "serial_offset", "serial number offset",
84 OFFSET(serial_offset
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, INT_MAX
, PARAM
},
85 { "oggpagesize", "Set preferred Ogg page size.",
86 OFFSET(pref_size
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, MAX_PAGE_SIZE
, PARAM
},
87 { "pagesize", "preferred page size in bytes (deprecated)",
88 OFFSET(pref_size
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, MAX_PAGE_SIZE
, PARAM
},
89 { "page_duration", "preferred page duration, in microseconds",
90 OFFSET(pref_duration
), AV_OPT_TYPE_INT64
, { .i64
= 1000000 }, 0, INT64_MAX
, PARAM
},
94 #define OGG_CLASS(flavor, name)\
95 static const AVClass flavor ## _muxer_class = {\
96 .class_name = #name " muxer",\
97 .item_name = av_default_item_name,\
99 .version = LIBAVUTIL_VERSION_INT,\
102 static void ogg_write_page(AVFormatContext
*s
, OGGPage
*page
, int extra_flags
)
104 OGGStreamContext
*oggstream
= s
->streams
[page
->stream_index
]->priv_data
;
105 uint8_t buf
[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr
= buf
, *crc_pos
;
106 const AVCRC
*crc_table
= av_crc_get_table(AV_CRC_32_IEEE
);
109 bytestream_put_le32(&ptr
, MKTAG('O', 'g', 'g', 'S'));
110 bytestream_put_byte(&ptr
, 0);
111 bytestream_put_byte(&ptr
, page
->flags
| extra_flags
);
112 bytestream_put_le64(&ptr
, page
->granule
);
113 bytestream_put_le32(&ptr
, oggstream
->serial_num
);
114 bytestream_put_le32(&ptr
, oggstream
->page_counter
++);
116 bytestream_put_le32(&ptr
, 0);
117 bytestream_put_byte(&ptr
, page
->segments_count
);
118 bytestream_put_buffer(&ptr
, page
->segments
, page
->segments_count
);
120 crc
= av_crc(crc_table
, 0, buf
, ptr
- buf
);
121 crc
= av_crc(crc_table
, crc
, page
->data
, page
->size
);
122 bytestream_put_be32(&crc_pos
, crc
);
124 avio_write(s
->pb
, buf
, ptr
- buf
);
125 avio_write(s
->pb
, page
->data
, page
->size
);
126 avio_write_marker(s
->pb
, AV_NOPTS_VALUE
, AVIO_DATA_MARKER_FLUSH_POINT
);
127 oggstream
->page_count
--;
130 static int ogg_key_granule(OGGStreamContext
*oggstream
, int64_t granule
)
132 return (oggstream
->kfgshift
&& !(granule
& ((1<<oggstream
->kfgshift
)-1))) ||
133 (oggstream
->isvp8
&& !((granule
>> 3) & 0x07ffffff));
136 static int64_t ogg_granule_to_timestamp(OGGStreamContext
*oggstream
, int64_t granule
)
138 if (oggstream
->kfgshift
)
139 return (granule
>>oggstream
->kfgshift
) +
140 (granule
& ((1<<oggstream
->kfgshift
)-1));
141 else if (oggstream
->isvp8
)
142 return granule
>> 32;
147 static int ogg_compare_granule(AVFormatContext
*s
, OGGPage
*next
, OGGPage
*page
)
149 AVStream
*st2
= s
->streams
[next
->stream_index
];
150 AVStream
*st
= s
->streams
[page
->stream_index
];
151 int64_t next_granule
, cur_granule
;
153 if (next
->granule
== -1 || page
->granule
== -1)
156 next_granule
= av_rescale_q(ogg_granule_to_timestamp(st2
->priv_data
, next
->granule
),
157 st2
->time_base
, AV_TIME_BASE_Q
);
158 cur_granule
= av_rescale_q(ogg_granule_to_timestamp(st
->priv_data
, page
->granule
),
159 st
->time_base
, AV_TIME_BASE_Q
);
160 return next_granule
> cur_granule
;
163 static int ogg_reset_cur_page(OGGStreamContext
*oggstream
)
165 oggstream
->page
.granule
= -1;
166 oggstream
->page
.flags
= 0;
167 oggstream
->page
.segments_count
= 0;
168 oggstream
->page
.size
= 0;
172 static int ogg_buffer_page(AVFormatContext
*s
, OGGStreamContext
*oggstream
)
174 OGGContext
*ogg
= s
->priv_data
;
175 OGGPageList
**p
= &ogg
->page_list
;
176 OGGPageList
*l
= av_mallocz(sizeof(*l
));
179 return AVERROR(ENOMEM
);
180 l
->page
= oggstream
->page
;
182 oggstream
->page
.start_granule
= ogg_granule_to_timestamp(oggstream
, oggstream
->page
.granule
);
183 oggstream
->page_count
++;
184 ogg_reset_cur_page(oggstream
);
187 if (ogg_compare_granule(s
, &(*p
)->page
, &l
->page
))
197 static int ogg_buffer_data(AVFormatContext
*s
, AVStream
*st
,
198 uint8_t *data
, unsigned size
, int64_t granule
,
201 OGGStreamContext
*oggstream
= st
->priv_data
;
202 OGGContext
*ogg
= s
->priv_data
;
203 int total_segments
= size
/ 255 + 1;
205 int i
, segments
, len
, flush
= 0;
207 // Handles VFR by flushing page because this frame needs to have a timestamp
208 // For theora and VP8, keyframes also need to have a timestamp to correctly mark
209 // them as such, otherwise seeking will not work correctly at the very
210 // least with old libogg versions.
211 // Do not try to flush header packets though, that will create broken files.
212 if ((st
->codecpar
->codec_id
== AV_CODEC_ID_THEORA
|| st
->codecpar
->codec_id
== AV_CODEC_ID_VP8
) && !header
&&
213 (ogg_granule_to_timestamp(oggstream
, granule
) >
214 ogg_granule_to_timestamp(oggstream
, oggstream
->last_granule
) + 1 ||
215 ogg_key_granule(oggstream
, granule
))) {
216 if (oggstream
->page
.granule
!= -1)
217 ogg_buffer_page(s
, oggstream
);
221 // avoid a continued page
222 if (!header
&& oggstream
->page
.size
> 0 &&
223 MAX_PAGE_SIZE
- oggstream
->page
.size
< size
) {
224 ogg_buffer_page(s
, oggstream
);
227 for (i
= 0; i
< total_segments
; ) {
228 OGGPage
*page
= &oggstream
->page
;
230 segments
= FFMIN(total_segments
- i
, 255 - page
->segments_count
);
232 if (i
&& !page
->segments_count
)
233 page
->flags
|= 1; // continued packet
235 memset(page
->segments
+page
->segments_count
, 255, segments
- 1);
236 page
->segments_count
+= segments
- 1;
238 len
= FFMIN(size
, segments
*255);
239 page
->segments
[page
->segments_count
++] = len
- (segments
-1)*255;
240 memcpy(page
->data
+page
->size
, p
, len
);
246 if (i
== total_segments
)
247 page
->granule
= granule
;
250 AVStream
*st
= s
->streams
[page
->stream_index
];
252 int64_t start
= av_rescale_q(page
->start_granule
, st
->time_base
,
254 int64_t next
= av_rescale_q(ogg_granule_to_timestamp(oggstream
, page
->granule
),
255 st
->time_base
, AV_TIME_BASE_Q
);
257 if (page
->segments_count
== 255) {
258 ogg_buffer_page(s
, oggstream
);
259 } else if (!header
) {
260 if ((ogg
->pref_size
> 0 && page
->size
>= ogg
->pref_size
) ||
261 (ogg
->pref_duration
> 0 && next
- start
>= ogg
->pref_duration
)) {
262 ogg_buffer_page(s
, oggstream
);
268 if (flush
&& oggstream
->page
.granule
!= -1)
269 ogg_buffer_page(s
, oggstream
);
274 static uint8_t *ogg_write_vorbiscomment(int64_t offset
, int bitexact
,
275 int *header_len
, AVDictionary
**m
, int framing_bit
,
276 AVChapter
**chapters
, unsigned int nb_chapters
)
278 const char *vendor
= bitexact
? "ffmpeg" : LIBAVFORMAT_IDENT
;
283 ff_metadata_conv(m
, ff_vorbiscomment_metadata_conv
, NULL
);
285 size
= offset
+ ff_vorbiscomment_length(*m
, vendor
, chapters
, nb_chapters
) + framing_bit
;
288 p
= av_mallocz(size
);
292 ffio_init_context(&pb
, p
+ offset
, size
- offset
, 1, NULL
, NULL
, NULL
, NULL
);
293 ff_vorbiscomment_write(&pb
, *m
, vendor
, chapters
, nb_chapters
);
301 static int ogg_build_flac_headers(AVCodecParameters
*par
,
302 OGGStreamContext
*oggstream
, int bitexact
,
307 if (par
->extradata_size
< FLAC_STREAMINFO_SIZE
)
308 return AVERROR(EINVAL
);
310 // first packet: STREAMINFO
311 oggstream
->header_len
[0] = 51;
312 oggstream
->header
[0] = av_mallocz(51); // per ogg flac specs
313 p
= oggstream
->header
[0];
315 return AVERROR(ENOMEM
);
316 bytestream_put_byte(&p
, 0x7F);
317 bytestream_put_buffer(&p
, "FLAC", 4);
318 bytestream_put_byte(&p
, 1); // major version
319 bytestream_put_byte(&p
, 0); // minor version
320 bytestream_put_be16(&p
, 1); // headers packets without this one
321 bytestream_put_buffer(&p
, "fLaC", 4);
322 bytestream_put_byte(&p
, 0x00); // streaminfo
323 bytestream_put_be24(&p
, 34);
324 bytestream_put_buffer(&p
, par
->extradata
, FLAC_STREAMINFO_SIZE
);
326 // second packet: VorbisComment
327 p
= ogg_write_vorbiscomment(4, bitexact
, &oggstream
->header_len
[1], m
, 0, NULL
, 0);
329 return AVERROR(ENOMEM
);
330 oggstream
->header
[1] = p
;
331 bytestream_put_byte(&p
, 0x84); // last metadata block and vorbis comment
332 bytestream_put_be24(&p
, oggstream
->header_len
[1] - 4);
337 #define SPEEX_HEADER_SIZE 80
339 static int ogg_build_speex_headers(AVCodecParameters
*par
,
340 OGGStreamContext
*oggstream
, int bitexact
,
345 if (par
->extradata_size
< SPEEX_HEADER_SIZE
)
346 return AVERROR_INVALIDDATA
;
348 // first packet: Speex header
349 p
= av_mallocz(SPEEX_HEADER_SIZE
);
351 return AVERROR(ENOMEM
);
352 oggstream
->header
[0] = p
;
353 oggstream
->header_len
[0] = SPEEX_HEADER_SIZE
;
354 bytestream_put_buffer(&p
, par
->extradata
, SPEEX_HEADER_SIZE
);
355 AV_WL32(&oggstream
->header
[0][68], 0); // set extra_headers to 0
357 // second packet: VorbisComment
358 p
= ogg_write_vorbiscomment(0, bitexact
, &oggstream
->header_len
[1], m
, 0, NULL
, 0);
360 return AVERROR(ENOMEM
);
361 oggstream
->header
[1] = p
;
366 #define OPUS_HEADER_SIZE 19
368 static int ogg_build_opus_headers(AVCodecParameters
*par
,
369 OGGStreamContext
*oggstream
, int bitexact
,
370 AVDictionary
**m
, AVChapter
**chapters
,
371 unsigned int nb_chapters
)
375 if (par
->extradata_size
< OPUS_HEADER_SIZE
)
376 return AVERROR_INVALIDDATA
;
378 /* first packet: Opus header */
379 p
= av_mallocz(par
->extradata_size
);
381 return AVERROR(ENOMEM
);
382 oggstream
->header
[0] = p
;
383 oggstream
->header_len
[0] = par
->extradata_size
;
384 bytestream_put_buffer(&p
, par
->extradata
, par
->extradata_size
);
386 /* second packet: VorbisComment */
387 p
= ogg_write_vorbiscomment(8, bitexact
, &oggstream
->header_len
[1], m
, 0, chapters
, nb_chapters
);
389 return AVERROR(ENOMEM
);
390 oggstream
->header
[1] = p
;
391 bytestream_put_buffer(&p
, "OpusTags", 8);
396 #define VP8_HEADER_SIZE 26
398 static int ogg_build_vp8_headers(AVFormatContext
*s
, AVStream
*st
,
399 OGGStreamContext
*oggstream
, int bitexact
)
401 AVCodecParameters
*par
= st
->codecpar
;
404 /* first packet: VP8 header */
405 p
= av_mallocz(VP8_HEADER_SIZE
);
407 return AVERROR(ENOMEM
);
408 oggstream
->header
[0] = p
;
409 oggstream
->header_len
[0] = VP8_HEADER_SIZE
;
410 bytestream_put_byte(&p
, 0x4f); // HDRID
411 bytestream_put_buffer(&p
, "VP80", 4); // Identifier
412 bytestream_put_byte(&p
, 1); // HDRTYP
413 bytestream_put_byte(&p
, 1); // VMAJ
414 bytestream_put_byte(&p
, 0); // VMIN
415 bytestream_put_be16(&p
, par
->width
);
416 bytestream_put_be16(&p
, par
->height
);
417 bytestream_put_be24(&p
, par
->sample_aspect_ratio
.num
);
418 bytestream_put_be24(&p
, par
->sample_aspect_ratio
.den
);
419 if (st
->r_frame_rate
.num
> 0 && st
->r_frame_rate
.den
> 0) {
420 // OggVP8 requires pts to increase by 1 per visible frame, so use the least common
421 // multiple framerate if available.
422 av_log(s
, AV_LOG_DEBUG
, "Changing time base from %d/%d to %d/%d\n",
423 st
->time_base
.num
, st
->time_base
.den
,
424 st
->r_frame_rate
.den
, st
->r_frame_rate
.num
);
425 avpriv_set_pts_info(st
, 64, st
->r_frame_rate
.den
, st
->r_frame_rate
.num
);
427 bytestream_put_be32(&p
, st
->time_base
.den
);
428 bytestream_put_be32(&p
, st
->time_base
.num
);
430 /* optional second packet: VorbisComment */
431 if (av_dict_get(st
->metadata
, "", NULL
, AV_DICT_IGNORE_SUFFIX
)) {
432 p
= ogg_write_vorbiscomment(7, bitexact
, &oggstream
->header_len
[1], &st
->metadata
, 0, NULL
, 0);
434 return AVERROR(ENOMEM
);
435 oggstream
->header
[1] = p
;
436 bytestream_put_byte(&p
, 0x4f); // HDRID
437 bytestream_put_buffer(&p
, "VP80", 4); // Identifier
438 bytestream_put_byte(&p
, 2); // HDRTYP
439 bytestream_put_byte(&p
, 0x20);
442 oggstream
->isvp8
= 1;
447 static void ogg_write_pages(AVFormatContext
*s
, int flush
)
449 OGGContext
*ogg
= s
->priv_data
;
450 OGGPageList
*next
, *p
;
455 for (p
= ogg
->page_list
; p
; ) {
456 OGGStreamContext
*oggstream
=
457 s
->streams
[p
->page
.stream_index
]->priv_data
;
458 if (oggstream
->page_count
< 2 && !flush
)
460 ogg_write_page(s
, &p
->page
,
461 flush
== 1 && oggstream
->page_count
== 1 ? 4 : 0); // eos
469 static int ogg_init(AVFormatContext
*s
)
471 OGGContext
*ogg
= s
->priv_data
;
472 OGGStreamContext
*oggstream
= NULL
;
476 av_log(s
, AV_LOG_WARNING
, "The pagesize option is deprecated\n");
478 for (i
= 0; i
< s
->nb_streams
; i
++) {
479 AVStream
*st
= s
->streams
[i
];
480 unsigned serial_num
= i
+ ogg
->serial_offset
;
482 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
483 if (st
->codecpar
->codec_id
== AV_CODEC_ID_OPUS
)
484 /* Opus requires a fixed 48kHz clock */
485 avpriv_set_pts_info(st
, 64, 1, 48000);
487 avpriv_set_pts_info(st
, 64, 1, st
->codecpar
->sample_rate
);
490 if (st
->codecpar
->codec_id
!= AV_CODEC_ID_VORBIS
&&
491 st
->codecpar
->codec_id
!= AV_CODEC_ID_THEORA
&&
492 st
->codecpar
->codec_id
!= AV_CODEC_ID_SPEEX
&&
493 st
->codecpar
->codec_id
!= AV_CODEC_ID_FLAC
&&
494 st
->codecpar
->codec_id
!= AV_CODEC_ID_OPUS
&&
495 st
->codecpar
->codec_id
!= AV_CODEC_ID_VP8
) {
496 av_log(s
, AV_LOG_ERROR
, "Unsupported codec id in stream %d\n", i
);
497 return AVERROR(EINVAL
);
500 if ((!st
->codecpar
->extradata
|| !st
->codecpar
->extradata_size
) &&
501 st
->codecpar
->codec_id
!= AV_CODEC_ID_VP8
) {
502 av_log(s
, AV_LOG_ERROR
, "No extradata present\n");
503 return AVERROR_INVALIDDATA
;
505 oggstream
= av_mallocz(sizeof(*oggstream
));
507 return AVERROR(ENOMEM
);
509 oggstream
->page
.stream_index
= i
;
511 if (!(s
->flags
& AVFMT_FLAG_BITEXACT
))
513 serial_num
= av_get_random_seed();
514 for (j
= 0; j
< i
; j
++) {
515 OGGStreamContext
*sc
= s
->streams
[j
]->priv_data
;
516 if (serial_num
== sc
->serial_num
)
520 oggstream
->serial_num
= serial_num
;
522 av_dict_copy(&st
->metadata
, s
->metadata
, AV_DICT_DONT_OVERWRITE
);
524 st
->priv_data
= oggstream
;
525 if (st
->codecpar
->codec_id
== AV_CODEC_ID_FLAC
) {
526 int err
= ogg_build_flac_headers(st
->codecpar
, oggstream
,
527 s
->flags
& AVFMT_FLAG_BITEXACT
,
530 av_log(s
, AV_LOG_ERROR
, "Error writing FLAC headers\n");
533 } else if (st
->codecpar
->codec_id
== AV_CODEC_ID_SPEEX
) {
534 int err
= ogg_build_speex_headers(st
->codecpar
, oggstream
,
535 s
->flags
& AVFMT_FLAG_BITEXACT
,
538 av_log(s
, AV_LOG_ERROR
, "Error writing Speex headers\n");
541 } else if (st
->codecpar
->codec_id
== AV_CODEC_ID_OPUS
) {
542 int err
= ogg_build_opus_headers(st
->codecpar
, oggstream
,
543 s
->flags
& AVFMT_FLAG_BITEXACT
,
544 &st
->metadata
, s
->chapters
, s
->nb_chapters
);
546 av_log(s
, AV_LOG_ERROR
, "Error writing Opus headers\n");
549 } else if (st
->codecpar
->codec_id
== AV_CODEC_ID_VP8
) {
550 int err
= ogg_build_vp8_headers(s
, st
, oggstream
,
551 s
->flags
& AVFMT_FLAG_BITEXACT
);
553 av_log(s
, AV_LOG_ERROR
, "Error writing VP8 headers\n");
558 const char *cstr
= st
->codecpar
->codec_id
== AV_CODEC_ID_VORBIS
? "vorbis" : "theora";
559 int header_type
= st
->codecpar
->codec_id
== AV_CODEC_ID_VORBIS
? 3 : 0x81;
560 int framing_bit
= st
->codecpar
->codec_id
== AV_CODEC_ID_VORBIS
? 1 : 0;
562 if (avpriv_split_xiph_headers(st
->codecpar
->extradata
, st
->codecpar
->extradata_size
,
563 st
->codecpar
->codec_id
== AV_CODEC_ID_VORBIS
? 30 : 42,
564 (const uint8_t**)oggstream
->header
, oggstream
->header_len
) < 0) {
565 av_log(s
, AV_LOG_ERROR
, "Extradata corrupted\n");
566 oggstream
->header
[1] = NULL
;
567 return AVERROR_INVALIDDATA
;
570 p
= ogg_write_vorbiscomment(7, s
->flags
& AVFMT_FLAG_BITEXACT
,
571 &oggstream
->header_len
[1], &st
->metadata
,
572 framing_bit
, NULL
, 0);
573 oggstream
->header
[1] = p
;
575 return AVERROR(ENOMEM
);
577 bytestream_put_byte(&p
, header_type
);
578 bytestream_put_buffer(&p
, cstr
, 6);
580 if (st
->codecpar
->codec_id
== AV_CODEC_ID_THEORA
) {
581 int den
= AV_RB32(oggstream
->header
[0] + 22), num
= AV_RB32(oggstream
->header
[0] + 26);
582 /* Make sure to use time base stored in the Theora stream header to write
583 correct timestamps */
584 if (st
->time_base
.num
!= num
|| st
->time_base
.den
!= den
) {
585 av_log(s
, AV_LOG_DEBUG
, "Changing time base from %d/%d to %d/%d\n",
586 st
->time_base
.num
, st
->time_base
.den
, num
, den
);
587 avpriv_set_pts_info(st
, 64, num
, den
);
589 /** KFGSHIFT is the width of the less significant section of the granule position
590 The less significant section is the frame count since the last keyframe */
591 oggstream
->kfgshift
= ((oggstream
->header
[0][40]&3)<<3)|(oggstream
->header
[0][41]>>5);
592 oggstream
->vrev
= oggstream
->header
[0][9];
593 av_log(s
, AV_LOG_DEBUG
, "theora kfgshift %d, vrev %d\n",
594 oggstream
->kfgshift
, oggstream
->vrev
);
602 static int ogg_write_header(AVFormatContext
*s
)
604 OGGStreamContext
*oggstream
= NULL
;
607 for (j
= 0; j
< s
->nb_streams
; j
++) {
608 oggstream
= s
->streams
[j
]->priv_data
;
609 ogg_buffer_data(s
, s
->streams
[j
], oggstream
->header
[0],
610 oggstream
->header_len
[0], 0, 1);
611 oggstream
->page
.flags
|= 2; // bos
612 ogg_buffer_page(s
, oggstream
);
614 for (j
= 0; j
< s
->nb_streams
; j
++) {
615 AVStream
*st
= s
->streams
[j
];
616 oggstream
= st
->priv_data
;
617 for (i
= 1; i
< 3; i
++) {
618 if (oggstream
->header_len
[i
])
619 ogg_buffer_data(s
, st
, oggstream
->header
[i
],
620 oggstream
->header_len
[i
], 0, 1);
622 ogg_buffer_page(s
, oggstream
);
625 oggstream
->page
.start_granule
= AV_NOPTS_VALUE
;
627 ogg_write_pages(s
, 2);
632 static int ogg_write_packet_internal(AVFormatContext
*s
, AVPacket
*pkt
)
634 AVStream
*st
= s
->streams
[pkt
->stream_index
];
635 OGGStreamContext
*oggstream
= st
->priv_data
;
639 if (st
->codecpar
->codec_id
== AV_CODEC_ID_THEORA
) {
640 int64_t pts
= oggstream
->vrev
< 1 ? pkt
->pts
: pkt
->pts
+ pkt
->duration
;
642 if (pkt
->flags
& AV_PKT_FLAG_KEY
)
643 oggstream
->last_kf_pts
= pts
;
644 pframe_count
= pts
- oggstream
->last_kf_pts
;
645 // prevent frame count from overflow if key frame flag is not set
646 if (pframe_count
>= (1<<oggstream
->kfgshift
)) {
647 oggstream
->last_kf_pts
+= pframe_count
;
650 granule
= (oggstream
->last_kf_pts
<<oggstream
->kfgshift
) | pframe_count
;
651 } else if (st
->codecpar
->codec_id
== AV_CODEC_ID_OPUS
)
652 granule
= pkt
->pts
+ pkt
->duration
+
653 av_rescale_q(st
->codecpar
->initial_padding
,
654 (AVRational
){ 1, st
->codecpar
->sample_rate
},
656 else if (st
->codecpar
->codec_id
== AV_CODEC_ID_VP8
) {
657 int64_t pts
, invcnt
, dist
;
660 visible
= (pkt
->data
[0] >> 4) & 1;
661 pts
= pkt
->pts
+ pkt
->duration
;
662 invcnt
= (oggstream
->last_granule
>> 30) & 3;
663 invcnt
= visible
? 3 : (invcnt
== 3 ? 0 : invcnt
+ 1);
664 dist
= (pkt
->flags
& AV_PKT_FLAG_KEY
) ? 0 : ((oggstream
->last_granule
>> 3) & 0x07ffffff) + 1;
666 granule
= (pts
<< 32) | (invcnt
<< 30) | (dist
<< 3);
668 granule
= pkt
->pts
+ pkt
->duration
;
670 if (oggstream
->page
.start_granule
== AV_NOPTS_VALUE
)
671 oggstream
->page
.start_granule
= pkt
->pts
;
673 ret
= ogg_buffer_data(s
, st
, pkt
->data
, pkt
->size
, granule
, 0);
677 ogg_write_pages(s
, 0);
679 oggstream
->last_granule
= granule
;
684 static int ogg_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
689 return ogg_write_packet_internal(s
, pkt
);
691 for (i
= 0; i
< s
->nb_streams
; i
++) {
692 OGGStreamContext
*oggstream
= s
->streams
[i
]->priv_data
;
693 if (oggstream
->page
.segments_count
)
694 ogg_buffer_page(s
, oggstream
);
697 ogg_write_pages(s
, 2);
701 static int ogg_write_trailer(AVFormatContext
*s
)
705 /* flush current page if needed */
706 for (i
= 0; i
< s
->nb_streams
; i
++) {
707 OGGStreamContext
*oggstream
= s
->streams
[i
]->priv_data
;
709 if (oggstream
->page
.size
> 0)
710 ogg_buffer_page(s
, oggstream
);
713 ogg_write_pages(s
, 1);
718 static void ogg_free(AVFormatContext
*s
)
720 OGGContext
*ogg
= s
->priv_data
;
721 OGGPageList
*p
= ogg
->page_list
;
724 for (i
= 0; i
< s
->nb_streams
; i
++) {
725 AVStream
*st
= s
->streams
[i
];
726 OGGStreamContext
*oggstream
= st
->priv_data
;
729 if (st
->codecpar
->codec_id
== AV_CODEC_ID_FLAC
||
730 st
->codecpar
->codec_id
== AV_CODEC_ID_SPEEX
||
731 st
->codecpar
->codec_id
== AV_CODEC_ID_OPUS
||
732 st
->codecpar
->codec_id
== AV_CODEC_ID_VP8
) {
733 av_freep(&oggstream
->header
[0]);
735 av_freep(&oggstream
->header
[1]);
739 OGGPageList
*next
= p
->next
;
743 ogg
->page_list
= NULL
;
748 AVOutputFormat ff_ogg_muxer
= {
750 .long_name
= NULL_IF_CONFIG_SMALL("Ogg"),
751 .mime_type
= "application/ogg",
753 #if !CONFIG_OGV_MUXER
756 #if !CONFIG_SPX_MUXER
759 #if !CONFIG_OPUS_MUXER
763 .priv_data_size
= sizeof(OGGContext
),
764 .audio_codec
= CONFIG_LIBVORBIS_ENCODER
?
765 AV_CODEC_ID_VORBIS
: AV_CODEC_ID_FLAC
,
766 .video_codec
= AV_CODEC_ID_THEORA
,
768 .write_header
= ogg_write_header
,
769 .write_packet
= ogg_write_packet
,
770 .write_trailer
= ogg_write_trailer
,
772 .flags
= AVFMT_TS_NEGATIVE
| AVFMT_TS_NONSTRICT
| AVFMT_ALLOW_FLUSH
,
773 .priv_class
= &ogg_muxer_class
,
778 OGG_CLASS(oga
, Ogg audio
)
779 AVOutputFormat ff_oga_muxer
= {
781 .long_name
= NULL_IF_CONFIG_SMALL("Ogg Audio"),
782 .mime_type
= "audio/ogg",
784 .priv_data_size
= sizeof(OGGContext
),
785 .audio_codec
= AV_CODEC_ID_FLAC
,
787 .write_header
= ogg_write_header
,
788 .write_packet
= ogg_write_packet
,
789 .write_trailer
= ogg_write_trailer
,
791 .flags
= AVFMT_TS_NEGATIVE
| AVFMT_ALLOW_FLUSH
,
792 .priv_class
= &oga_muxer_class
,
797 OGG_CLASS(ogv
, Ogg video
)
798 AVOutputFormat ff_ogv_muxer
= {
800 .long_name
= NULL_IF_CONFIG_SMALL("Ogg Video"),
801 .mime_type
= "video/ogg",
803 .priv_data_size
= sizeof(OGGContext
),
804 .audio_codec
= CONFIG_LIBVORBIS_ENCODER
?
805 AV_CODEC_ID_VORBIS
: AV_CODEC_ID_FLAC
,
806 .video_codec
= CONFIG_LIBTHEORA_ENCODER
?
807 AV_CODEC_ID_THEORA
: AV_CODEC_ID_VP8
,
809 .write_header
= ogg_write_header
,
810 .write_packet
= ogg_write_packet
,
811 .write_trailer
= ogg_write_trailer
,
813 .flags
= AVFMT_TS_NEGATIVE
| AVFMT_TS_NONSTRICT
| AVFMT_ALLOW_FLUSH
,
814 .priv_class
= &ogv_muxer_class
,
819 OGG_CLASS(spx
, Ogg Speex
)
820 AVOutputFormat ff_spx_muxer
= {
822 .long_name
= NULL_IF_CONFIG_SMALL("Ogg Speex"),
823 .mime_type
= "audio/ogg",
825 .priv_data_size
= sizeof(OGGContext
),
826 .audio_codec
= AV_CODEC_ID_SPEEX
,
828 .write_header
= ogg_write_header
,
829 .write_packet
= ogg_write_packet
,
830 .write_trailer
= ogg_write_trailer
,
832 .flags
= AVFMT_TS_NEGATIVE
| AVFMT_ALLOW_FLUSH
,
833 .priv_class
= &spx_muxer_class
,
837 #if CONFIG_OPUS_MUXER
838 OGG_CLASS(opus
, Ogg Opus
)
839 AVOutputFormat ff_opus_muxer
= {
841 .long_name
= NULL_IF_CONFIG_SMALL("Ogg Opus"),
842 .mime_type
= "audio/ogg",
843 .extensions
= "opus",
844 .priv_data_size
= sizeof(OGGContext
),
845 .audio_codec
= AV_CODEC_ID_OPUS
,
847 .write_header
= ogg_write_header
,
848 .write_packet
= ogg_write_packet
,
849 .write_trailer
= ogg_write_trailer
,
851 .flags
= AVFMT_TS_NEGATIVE
| AVFMT_ALLOW_FLUSH
,
852 .priv_class
= &opus_muxer_class
,