annotate oggenc.c @ 5910:536e5527c1e0 libavformat

Define AVMediaType enum, and use it instead of enum CodecType, which is deprecated and will be dropped at the next major bump.
author stefano
date Tue, 30 Mar 2010 23:30:55 +0000
parents 274fed269b59
children 11bb10c37225
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
1 /*
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
2 * Ogg muxer
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
3 * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at free dot fr>
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
4 *
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
5 * This file is part of FFmpeg.
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
6 *
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
11 *
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
15 * Lesser General Public License for more details.
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
16 *
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
20 */
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
21
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3188
diff changeset
22 #include "libavutil/crc.h"
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3188
diff changeset
23 #include "libavcodec/xiph.h"
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3188
diff changeset
24 #include "libavcodec/bytestream.h"
4578
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
25 #include "libavcodec/flac.h"
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
26 #include "avformat.h"
4418
d5119d75439d Move declaration of ff_interleave_add_packet to internal.h.
bcoudurier
parents: 4311
diff changeset
27 #include "internal.h"
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
28 #include "vorbiscomment.h"
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
29
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
30 typedef struct {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
31 int64_t duration;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
32 unsigned page_counter;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
33 uint8_t *header[3];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
34 int header_len[3];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
35 /** for theora granule */
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
36 int kfgshift;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
37 int64_t last_kf_pts;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
38 int vrev;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
39 int eos;
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
40 unsigned packet_count; ///< number of packet buffered
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
41 } OGGStreamContext;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
42
3973
549a09cf23fe Remove offset_t typedef and use int64_t directly instead.
diego
parents: 3593
diff changeset
43 static void ogg_update_checksum(AVFormatContext *s, int64_t crc_offset)
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
44 {
3973
549a09cf23fe Remove offset_t typedef and use int64_t directly instead.
diego
parents: 3593
diff changeset
45 int64_t pos = url_ftell(s->pb);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
46 uint32_t checksum = get_checksum(s->pb);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
47 url_fseek(s->pb, crc_offset, SEEK_SET);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
48 put_be32(s->pb, checksum);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
49 url_fseek(s->pb, pos, SEEK_SET);
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
50 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
51
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
52 static int ogg_write_page(AVFormatContext *s, const uint8_t *data, int size,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
53 int64_t granule, int stream_index, int flags)
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
54 {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
55 OGGStreamContext *oggstream = s->streams[stream_index]->priv_data;
3973
549a09cf23fe Remove offset_t typedef and use int64_t directly instead.
diego
parents: 3593
diff changeset
56 int64_t crc_offset;
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
57 int page_segments, i;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
58
3020
38777f77320e it seems ogg requires granule to be -1 on unfinished packets
bcoudurier
parents: 2771
diff changeset
59 if (size >= 255*255) {
38777f77320e it seems ogg requires granule to be -1 on unfinished packets
bcoudurier
parents: 2771
diff changeset
60 granule = -1;
38777f77320e it seems ogg requires granule to be -1 on unfinished packets
bcoudurier
parents: 2771
diff changeset
61 size = 255*255;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
62 } else if (oggstream->eos)
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
63 flags |= 4;
3020
38777f77320e it seems ogg requires granule to be -1 on unfinished packets
bcoudurier
parents: 2771
diff changeset
64
5851
d88fc4640994 Correctly write last 0 lacing value when packet size is multiple of 255, patch by Greg Maxwell, gmaxwell at gmail dot com
bcoudurier
parents: 5602
diff changeset
65 page_segments = FFMIN(size/255 + 1, 255);
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
66
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
67 init_checksum(s->pb, ff_crc04C11DB7_update, 0);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
68 put_tag(s->pb, "OggS");
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
69 put_byte(s->pb, 0);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
70 put_byte(s->pb, flags);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
71 put_le64(s->pb, granule);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
72 put_le32(s->pb, stream_index);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
73 put_le32(s->pb, oggstream->page_counter++);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
74 crc_offset = url_ftell(s->pb);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
75 put_le32(s->pb, 0); // crc
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
76 put_byte(s->pb, page_segments);
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
77 for (i = 0; i < page_segments-1; i++)
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
78 put_byte(s->pb, 255);
5851
d88fc4640994 Correctly write last 0 lacing value when packet size is multiple of 255, patch by Greg Maxwell, gmaxwell at gmail dot com
bcoudurier
parents: 5602
diff changeset
79 put_byte(s->pb, size - (page_segments-1)*255);
d88fc4640994 Correctly write last 0 lacing value when packet size is multiple of 255, patch by Greg Maxwell, gmaxwell at gmail dot com
bcoudurier
parents: 5602
diff changeset
80 put_buffer(s->pb, data, size);
d88fc4640994 Correctly write last 0 lacing value when packet size is multiple of 255, patch by Greg Maxwell, gmaxwell at gmail dot com
bcoudurier
parents: 5602
diff changeset
81
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
82 ogg_update_checksum(s, crc_offset);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2731
diff changeset
83 put_flush_packet(s->pb);
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
84 return size;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
85 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
86
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
87 static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
88 int *header_len, AVMetadata *m)
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
89 {
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
90 const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
91 int size;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
92 uint8_t *p, *p0;
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
93 unsigned int count;
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
94
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
95 size = offset + ff_vorbiscomment_length(m, vendor, &count);
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
96 p = av_mallocz(size);
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
97 if (!p)
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
98 return NULL;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
99 p0 = p;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
100
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
101 p += offset;
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
102 ff_vorbiscomment_write(&p, m, vendor, count);
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
103
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
104 *header_len = size;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
105 return p0;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
106 }
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
107
4578
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
108 static int ogg_build_flac_headers(AVCodecContext *avctx,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
109 OGGStreamContext *oggstream, int bitexact,
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
110 AVMetadata *m)
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
111 {
4578
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
112 enum FLACExtradataFormat format;
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
113 uint8_t *streaminfo;
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
114 uint8_t *p;
5054
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
115
4578
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
116 if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
117 return -1;
5054
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
118
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
119 // first packet: STREAMINFO
3188
87119f0c4736 fix Ogg/FLAC header size
jbr
parents: 3021
diff changeset
120 oggstream->header_len[0] = 51;
87119f0c4736 fix Ogg/FLAC header size
jbr
parents: 3021
diff changeset
121 oggstream->header[0] = av_mallocz(51); // per ogg flac specs
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
122 p = oggstream->header[0];
5053
037f1082ecd6 oggenc: check for failed av_mallocz()
jbr
parents: 4578
diff changeset
123 if (!p)
037f1082ecd6 oggenc: check for failed av_mallocz()
jbr
parents: 4578
diff changeset
124 return AVERROR_NOMEM;
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
125 bytestream_put_byte(&p, 0x7F);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
126 bytestream_put_buffer(&p, "FLAC", 4);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
127 bytestream_put_byte(&p, 1); // major version
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
128 bytestream_put_byte(&p, 0); // minor version
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
129 bytestream_put_be16(&p, 1); // headers packets without this one
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
130 bytestream_put_buffer(&p, "fLaC", 4);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
131 bytestream_put_byte(&p, 0x00); // streaminfo
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
132 bytestream_put_be24(&p, 34);
4578
c05d167a4fe2 Use a shared function to validate FLAC extradata.
jbr
parents: 4418
diff changeset
133 bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE);
5054
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
134
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
135 // second packet: VorbisComment
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
136 p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m);
5053
037f1082ecd6 oggenc: check for failed av_mallocz()
jbr
parents: 4578
diff changeset
137 if (!p)
037f1082ecd6 oggenc: check for failed av_mallocz()
jbr
parents: 4578
diff changeset
138 return AVERROR_NOMEM;
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
139 oggstream->header[1] = p;
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
140 bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
141 bytestream_put_be24(&p, oggstream->header_len[1] - 4);
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
142
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
143 return 0;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
144 }
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
145
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
146 #define SPEEX_HEADER_SIZE 80
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
147
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
148 static int ogg_build_speex_headers(AVCodecContext *avctx,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
149 OGGStreamContext *oggstream, int bitexact,
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
150 AVMetadata *m)
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
151 {
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
152 uint8_t *p;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
153
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
154 if (avctx->extradata_size < SPEEX_HEADER_SIZE)
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
155 return -1;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
156
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
157 // first packet: Speex header
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
158 p = av_mallocz(SPEEX_HEADER_SIZE);
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
159 if (!p)
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
160 return AVERROR_NOMEM;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
161 oggstream->header[0] = p;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
162 oggstream->header_len[0] = SPEEX_HEADER_SIZE;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
163 bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE);
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
164 AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
165
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
166 // second packet: VorbisComment
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
167 p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m);
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
168 if (!p)
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
169 return AVERROR_NOMEM;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
170 oggstream->header[1] = p;
5054
6c7d0a04ae96 cosmetics: spacing and comments
jbr
parents: 5053
diff changeset
171
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
172 return 0;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
173 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
174
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
175 static int ogg_write_header(AVFormatContext *s)
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
176 {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
177 OGGStreamContext *oggstream;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
178 int i, j;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
179 for (i = 0; i < s->nb_streams; i++) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
180 AVStream *st = s->streams[i];
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 5858
diff changeset
181 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
182 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 5858
diff changeset
183 else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
184 av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
185 if (st->codec->codec_id != CODEC_ID_VORBIS &&
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
186 st->codec->codec_id != CODEC_ID_THEORA &&
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
187 st->codec->codec_id != CODEC_ID_SPEEX &&
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
188 st->codec->codec_id != CODEC_ID_FLAC) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
189 av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
190 return -1;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
191 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
192
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
193 if (!st->codec->extradata || !st->codec->extradata_size) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
194 av_log(s, AV_LOG_ERROR, "No extradata present\n");
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
195 return -1;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
196 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
197 oggstream = av_mallocz(sizeof(*oggstream));
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
198 st->priv_data = oggstream;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
199 if (st->codec->codec_id == CODEC_ID_FLAC) {
5055
5a6bbdd352fb oggenc: return error value from ogg_build_flac_headers()
jbr
parents: 5054
diff changeset
200 int err = ogg_build_flac_headers(st->codec, oggstream,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
201 st->codec->flags & CODEC_FLAG_BITEXACT,
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
202 s->metadata);
5055
5a6bbdd352fb oggenc: return error value from ogg_build_flac_headers()
jbr
parents: 5054
diff changeset
203 if (err) {
5056
f67fad61077e oggenc: Change error log text. An error here does not necessarily mean
jbr
parents: 5055
diff changeset
204 av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
205 av_freep(&st->priv_data);
5055
5a6bbdd352fb oggenc: return error value from ogg_build_flac_headers()
jbr
parents: 5054
diff changeset
206 return err;
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
207 }
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
208 } else if (st->codec->codec_id == CODEC_ID_SPEEX) {
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
209 int err = ogg_build_speex_headers(st->codec, oggstream,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
210 st->codec->flags & CODEC_FLAG_BITEXACT,
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
211 s->metadata);
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
212 if (err) {
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
213 av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
214 av_freep(&st->priv_data);
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
215 return err;
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
216 }
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
217 } else {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
218 if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
219 st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
220 oggstream->header, oggstream->header_len) < 0) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
221 av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
222 av_freep(&st->priv_data);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
223 return -1;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
224 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
225 if (st->codec->codec_id == CODEC_ID_THEORA) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
226 /** KFGSHIFT is the width of the less significant section of the granule position
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
227 The less significant section is the frame count since the last keyframe */
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
228 oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
229 oggstream->vrev = oggstream->header[0][9];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
230 av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n",
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
231 oggstream->kfgshift, oggstream->vrev);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
232 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
233 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
234 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
235 for (i = 0; i < 3; i++) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
236 for (j = 0; j < s->nb_streams; j++) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
237 AVStream *st = s->streams[j];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
238 OGGStreamContext *oggstream = st->priv_data;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
239 if (oggstream && oggstream->header_len[i]) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
240 ogg_write_page(s, oggstream->header[i], oggstream->header_len[i],
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
241 0, st->index, i ? 0 : 2); // bos
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
242 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
243 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
244 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
245 return 0;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
246 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
247
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
248 static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
249 {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
250 AVStream *st = s->streams[pkt->stream_index];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
251 OGGStreamContext *oggstream = st->priv_data;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
252 uint8_t *ptr = pkt->data;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
253 int ret, size = pkt->size;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
254 int64_t granule;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
255
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
256 if (st->codec->codec_id == CODEC_ID_THEORA) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
257 int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
258 int pframe_count;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
259 if (pkt->flags & PKT_FLAG_KEY)
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
260 oggstream->last_kf_pts = pts;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
261 pframe_count = pts - oggstream->last_kf_pts;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
262 // prevent frame count from overflow if key frame flag is not set
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
263 if (pframe_count >= (1<<oggstream->kfgshift)) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
264 oggstream->last_kf_pts += pframe_count;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
265 pframe_count = 0;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
266 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
267 granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
268 } else
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
269 granule = pkt->pts + pkt->duration;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
270 oggstream->duration = granule;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
271 do {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
272 ret = ogg_write_page(s, ptr, size, granule, pkt->stream_index, ptr != pkt->data);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
273 ptr += ret; size -= ret;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
274 } while (size > 0 || ret == 255*255); // need to output a last nil page
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
275
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
276 return 0;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
277 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
278
4310
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
279 static int ogg_compare_granule(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
280 {
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
281 AVStream *st2 = s->streams[next->stream_index];
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
282 AVStream *st = s->streams[pkt ->stream_index];
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
283
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
284 int64_t next_granule = av_rescale_q(next->pts + next->duration,
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
285 st2->time_base, AV_TIME_BASE_Q);
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
286 int64_t cur_granule = av_rescale_q(pkt ->pts + pkt ->duration,
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
287 st ->time_base, AV_TIME_BASE_Q);
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
288 return next_granule > cur_granule;
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
289 }
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
290
4311
03065a598506 function is static
bcoudurier
parents: 4310
diff changeset
291 static int ogg_interleave_per_granule(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
292 {
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
293 OGGStreamContext *ogg;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
294 int i, stream_count = 0;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
295 int interleaved = 0;
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
296
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
297 if (pkt) {
4310
92117125e17c use new ff_interleave_add_packet
bcoudurier
parents: 3973
diff changeset
298 ff_interleave_add_packet(s, pkt, ogg_compare_granule);
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
299 ogg = s->streams[pkt->stream_index]->priv_data;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
300 ogg->packet_count++;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
301 }
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
302
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
303 for (i = 0; i < s->nb_streams; i++) {
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
304 ogg = s->streams[i]->priv_data;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
305 stream_count += !!ogg->packet_count;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
306 interleaved += ogg->packet_count > 1;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
307 }
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
308
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
309 if ((s->nb_streams == stream_count && interleaved == stream_count) ||
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
310 (flush && stream_count)) {
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
311 AVPacketList *pktl= s->packet_buffer;
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
312 *out= pktl->pkt;
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
313 s->packet_buffer = pktl->next;
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
314
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
315 ogg = s->streams[out->stream_index]->priv_data;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
316 if (flush && ogg->packet_count == 1)
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
317 ogg->eos = 1;
5602
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
318 ogg->packet_count--;
0e84f356ca5f Remove MAX_STREAMS usage in ogg and mxf muxers
bcoudurier
parents: 5280
diff changeset
319
5210
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
320 if(!s->packet_buffer)
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
321 s->packet_buffer_end= NULL;
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
322
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
323 if(s->streams[out->stream_index]->last_in_packet_buffer == pktl)
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
324 s->streams[out->stream_index]->last_in_packet_buffer= NULL;
36d130853c9b Improve amortized worst case speed of the muxers packet interleaving code
michael
parents: 5056
diff changeset
325
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
326 av_freep(&pktl);
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
327 return 1;
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
328 } else {
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
329 av_init_packet(out);
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
330 return 0;
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
331 }
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
332 }
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
333
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
334 static int ogg_write_trailer(AVFormatContext *s)
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
335 {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
336 int i;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
337 for (i = 0; i < s->nb_streams; i++) {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
338 AVStream *st = s->streams[i];
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
339 OGGStreamContext *oggstream = st->priv_data;
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
340 if (st->codec->codec_id == CODEC_ID_FLAC ||
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
341 st->codec->codec_id == CODEC_ID_SPEEX) {
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
342 av_free(oggstream->header[0]);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
343 av_free(oggstream->header[1]);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
344 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
345 av_freep(&st->priv_data);
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
346 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
347 return 0;
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
348 }
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
349
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
350 AVOutputFormat ogg_muxer = {
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
351 "ogg",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3286
diff changeset
352 NULL_IF_CONFIG_SMALL("Ogg"),
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
353 "application/ogg",
5280
4292c6f121dc Add Speex support to the Ogg muxer.
jbr
parents: 5210
diff changeset
354 "ogg,ogv,spx",
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
355 0,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
356 CODEC_ID_FLAC,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
357 CODEC_ID_THEORA,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
358 ogg_write_header,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
359 ogg_write_packet,
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
360 ogg_write_trailer,
3021
6f393e79e896 Fix issue 338:
bcoudurier
parents: 3020
diff changeset
361 .interleave_packet = ogg_interleave_per_granule,
5858
274fed269b59 Add VorbisComment writing to Ogg/FLAC and Ogg/Speex files.
jbr
parents: 5851
diff changeset
362 .metadata_conv = ff_vorbiscomment_metadata_conv,
2731
6b43751d7264 ogg muxer
bcoudurier
parents:
diff changeset
363 };