22#include "config_components.h"
41#define MAX_PAGE_SIZE 65025
86#define OFFSET(x) offsetof(OGGContext, x)
87#define PARAM AV_OPT_FLAG_ENCODING_PARAM
92 {
"serial_offset",
"serial number offset, -1 to derive it from the stream headers",
94 {
"page_duration",
"preferred page duration, in microseconds",
100 .class_name =
"Ogg (audio/video/Speex/Opus) muxer",
123 uint8_t buf[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr = buf, *crc_pos;
127 bytestream_put_le32(&ptr,
MKTAG(
'O',
'g',
'g',
'S'));
128 bytestream_put_byte(&ptr, 0);
129 bytestream_put_byte(&ptr,
page->flags | extra_flags);
130 bytestream_put_le64(&ptr,
page->granule);
131 bytestream_put_le32(&ptr, oggstream->
serial_num);
134 bytestream_put_le32(&ptr, 0);
135 bytestream_put_byte(&ptr,
page->segments_count);
138 crc =
av_crc(crc_table, 0, buf, ptr - buf);
140 bytestream_put_be32(&crc_pos, crc);
150 return (oggstream->
kfgshift && !(granule & ((1<<oggstream->
kfgshift)-1))) ||
151 (oggstream->
isvp8 && !((granule >> 3) & 0x07ffffff));
157 return (granule>>oggstream->
kfgshift) +
158 (granule & ((1<<oggstream->
kfgshift)-1));
159 else if (oggstream->
isvp8)
160 return granule >> 32;
169 int64_t next_granule, cur_granule;
178 return next_granule > cur_granule;
223 int total_segments =
size / 255 + 1;
224 const uint8_t *p =
data;
249 for (
i = 0;
i < total_segments; ) {
252 segments =
FFMIN(total_segments -
i, 255 -
page->segments_count);
254 if (
i && !
page->segments_count)
257 memset(
page->segments+
page->segments_count, 255, segments - 1);
258 page->segments_count += segments - 1;
261 page->segments[
page->segments_count++] =
len - (segments-1)*255;
269 if (
i == total_segments)
270 page->granule = granule;
280 if (
page->segments_count == 255) {
284 if (
ogg->pref_duration > 0 && next - start >=
ogg->pref_duration) {
301 AVChapter **chapters,
unsigned int nb_chapters)
344 bytestream_put_byte(&p, 0x7F);
346 bytestream_put_byte(&p, 1);
347 bytestream_put_byte(&p, 0);
348 bytestream_put_be16(&p, 1);
350 bytestream_put_byte(&p, 0x00);
351 bytestream_put_be24(&p, 34);
359 bytestream_put_byte(&p, 0x84);
360 bytestream_put_be24(&p, oggstream->
header_len[1] - 4);
365#define SPEEX_HEADER_SIZE 80
394#define OPUS_HEADER_SIZE 19
399 unsigned int nb_chapters)
424#define VP8_HEADER_SIZE 26
438 bytestream_put_byte(&p, 0x4f);
440 bytestream_put_byte(&p, 1);
441 bytestream_put_byte(&p, 1);
442 bytestream_put_byte(&p, 0);
443 bytestream_put_be16(&p, par->
width);
444 bytestream_put_be16(&p, par->
height);
464 bytestream_put_byte(&p, 0x4f);
466 bytestream_put_byte(&p, 2);
467 bytestream_put_byte(&p, 0x20);
470 oggstream->
isvp8 = 1;
483 for (p =
ogg->page_list; p; ) {
485 s->streams[p->page.stream_index]->priv_data;
506 for (
int i = 0;
i < 3;
i++)
531 for (
i = 0;
i <
s->nb_streams;
i++) {
567 memset(oggstream, 0,
sizeof(*oggstream));
621 framing_bit,
NULL, 0);
626 bytestream_put_byte(&p, header_type);
648 serial_num =
i +
ogg->serial_offset;
667 for (j = 0; j <
s->nb_streams; j++) {
668 oggstream =
s->streams[j]->priv_data;
678 for (j = 0; j <
s->nb_streams; j++) {
681 for (
i = 1;
i < 3;
i++) {
711 if (!new_extradata) {
724 size_t metadata_size, extradata_size;
733 !memcmp(new_extradata, par->
extradata, extradata_size))
734 new_extradata =
NULL;
736 if (!side_metadata && !new_extradata)
743 "the stream headers are already written!\n");
747 if (
s->nb_streams > 1)
754 "New links are only supported for vorbis, flac and opus streams");
775 memcpy(par->
extradata, new_extradata, extradata_size);
799 if (oggcontext->
ended)
813 if (pframe_count >= (1<<oggstream->
kfgshift)) {
825 visible = (
pkt->data[0] >> 4) & 1;
828 invcnt = visible ? 3 : (invcnt == 3 ? 0 : invcnt + 1);
831 granule = (
pts << 32) | (invcnt << 30) | (dist << 3);
833 granule =
pkt->pts +
pkt->duration;
857 for (
i = 0;
i <
s->nb_streams;
i++) {
873 for (
i = 0;
i <
s->nb_streams;
i++) {
892 for (
i = 0;
i <
s->nb_streams;
i++) {
910 .p.mime_type =
"application/ogg",
911 .p.extensions =
"ogg"
918#if !CONFIG_OPUS_MUXER
923 .
p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
941 .p.mime_type =
"audio/ogg",
942 .p.extensions =
"oga",
960 .p.mime_type =
"video/ogg",
961 .p.extensions =
"ogv",
963 .
p.audio_codec = CONFIG_LIBVORBIS_ENCODER ?
965 .
p.video_codec = CONFIG_LIBTHEORA_ENCODER ?
982 .p.mime_type =
"audio/ogg",
983 .p.extensions =
"spx",
1001 .p.mime_type =
"audio/ogg",
1002 .p.extensions =
"opus",
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
void avio_w8(AVIOContext *s, int b)
@ AVIO_DATA_MARKER_FLUSH_POINT
A point in the output bytestream where the underlying AVIOContext might flush the buffer depending on...
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for writing.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static void deinit(AVFormatContext *s)
Public header for CRC hash function implementation.
void(* flush)(AVBSFContext *ctx)
int(* init)(AVBSFContext *ctx)
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
static unsigned int nb_streams
static void write_header(FFV1Context *f)
FLAC (Free Lossless Audio Codec) common stuff.
#define FLAC_STREAMINFO_SIZE
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
@ AV_OPT_TYPE_INT
Underlying C type is int.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
@ AV_PKT_DATA_STRINGS_METADATA
A list of zero terminated key/value strings.
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
int av_packet_unpack_dictionary(const uint8_t *data, size_t size, AVDictionary **dict)
Unpack a dictionary from side_data.
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define LIBAVUTIL_VERSION_INT
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define MKTAG(a, b, c, d)
Memory handling functions.
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
static int ogg_write_header(AVFormatContext *s)
static int ogg_build_opus_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m, AVChapter **chapters, unsigned int nb_chapters)
static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page)
static int ogg_build_vp8_headers(AVFormatContext *s, AVStream *st, OGGStreamContext *oggstream, int bitexact)
static int ogg_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
static void ogg_cleanup_stream(AVStream *st)
static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
static int ogg_reset_cur_page(OGGStreamContext *oggstream)
static const AVClass ogg_muxer_class
static int ogg_serial_in_use(AVFormatContext *s, int nb_streams, unsigned serial_num)
static int ogg_build_flac_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
#define SPEEX_HEADER_SIZE
static unsigned ogg_bitexact_serial(const OGGStreamContext *oggstream, unsigned seed)
Derive a bitexact serial number from the stream's header packets, which makes links muxed apart unlik...
static int ogg_skip_new_link(AVFormatContext *s, const uint8_t *new_extradata, const char *reason)
Keep the current link when a new one cannot be started.
static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
static int ogg_check_new_link(AVFormatContext *s, AVPacket *pkt)
static int ogg_build_speex_headers(AVCodecParameters *par, OGGStreamContext *oggstream, int bitexact, AVDictionary **m)
static void ogg_free(AVFormatContext *s)
static void ogg_write_pages(AVFormatContext *s, int flush)
static int ogg_init(AVFormatContext *s)
static int ogg_write_trailer(AVFormatContext *s)
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)
static int ogg_buffer_data(AVFormatContext *s, AVStream *st, const uint8_t *data, unsigned size, int64_t granule, int header)
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static uint8_t page[OGG_PAGE_MAX_SIZE]
static const uint16_t table[]
static const uint8_t header[24]
Describe the class of an AVClass context structure.
This struct describes the properties of an encoded stream.
int extradata_size
Size of the extradata content in bytes.
int height
The height of the video frame in pixels.
int width
The width of the video frame in pixels.
enum AVMediaType codec_type
General type of the encoded data.
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
The number of audio samples per second.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
AVCodecParameters * codecpar
Codec parameters associated with this stream.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
AVRational r_frame_rate
Real base framerate of the stream.
int64_t pref_duration
preferred page duration (0 => fill all segments)
int ended
a new link could not be started, the packets that follow are dropped
struct OGGPageList * next
uint8_t data[MAX_PAGE_SIZE]
int kfgshift
for theora granule
unsigned serial_num
serial number
unsigned page_count
number of page buffered
int packet_seen
true when packets have been submitted
int64_t last_granule
last packet granule
static int write_trailer(AVFormatContext *s1)
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.