Mercurial > libavformat.hg
comparison matroskaenc.c @ 2435:4dde24899d01 libavformat
Correctly write CodecPrivate element for Vorbis and Theora
author | conrad |
---|---|
date | Wed, 05 Sep 2007 00:22:56 +0000 |
parents | 273c76713989 |
children | fab3556370d0 |
comparison
equal
deleted
inserted
replaced
2434:273c76713989 | 2435:4dde24899d01 |
---|---|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | 20 */ |
21 | 21 |
22 #include "avformat.h" | 22 #include "avformat.h" |
23 #include "riff.h" | 23 #include "riff.h" |
24 #include "xiph.h" | |
24 #include "matroska.h" | 25 #include "matroska.h" |
25 | 26 |
26 typedef struct MatroskaMuxContext { | 27 typedef struct MatroskaMuxContext { |
27 offset_t segment; | 28 offset_t segment; |
28 offset_t cluster; | 29 offset_t cluster; |
111 static int mkv_write_header(AVFormatContext *s) | 112 static int mkv_write_header(AVFormatContext *s) |
112 { | 113 { |
113 MatroskaMuxContext *mkv = s->priv_data; | 114 MatroskaMuxContext *mkv = s->priv_data; |
114 ByteIOContext *pb = &s->pb; | 115 ByteIOContext *pb = &s->pb; |
115 offset_t ebml_header, segment_info, tracks; | 116 offset_t ebml_header, segment_info, tracks; |
116 int i, j; | 117 int i, j, k; |
117 | 118 |
118 ebml_header = start_ebml_master(pb, EBML_ID_HEADER); | 119 ebml_header = start_ebml_master(pb, EBML_ID_HEADER); |
119 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); | 120 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); |
120 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); | 121 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); |
121 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); | 122 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); |
165 } | 166 } |
166 } | 167 } |
167 | 168 |
168 // XXX: CodecPrivate for vorbis, theora, aac, native mpeg4, ... | 169 // XXX: CodecPrivate for vorbis, theora, aac, native mpeg4, ... |
169 if (native_id) { | 170 if (native_id) { |
170 put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codec->extradata, codec->extradata_size); | 171 offset_t codecprivate; |
172 | |
173 if (codec->codec_id == CODEC_ID_VORBIS || codec->codec_id == CODEC_ID_THEORA) { | |
174 uint8_t *header_start[3]; | |
175 int header_len[3]; | |
176 int first_header_size; | |
177 | |
178 if (codec->codec_id == CODEC_ID_VORBIS) | |
179 first_header_size = 30; | |
180 else | |
181 first_header_size = 42; | |
182 | |
183 if (ff_split_xiph_headers(codec->extradata, codec->extradata_size, | |
184 first_header_size, header_start, header_len) < 0) { | |
185 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); | |
186 return -1; | |
187 } | |
188 | |
189 codecprivate = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE); | |
190 put_byte(pb, 2); // number packets - 1 | |
191 for (j = 0; j < 2; j++) { | |
192 for (k = 0; k < header_len[j] / 255; k++) | |
193 put_byte(pb, 255); | |
194 put_byte(pb, header_len[j]); | |
195 } | |
196 for (j = 0; j < 3; j++) | |
197 put_buffer(pb, header_start[j], header_len[j]); | |
198 end_ebml_master(pb, codecprivate); | |
199 } else { | |
200 put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codec->extradata, codec->extradata_size); | |
201 } | |
171 } | 202 } |
172 | 203 |
173 switch (codec->codec_type) { | 204 switch (codec->codec_type) { |
174 case CODEC_TYPE_VIDEO: | 205 case CODEC_TYPE_VIDEO: |
175 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); | 206 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); |