Mercurial > libavformat.hg
comparison oggenc.c @ 6459:cf0ea082dad2 libavformat
Vorbis metadata writing. Patch by James Darnley <james.darnley gmail com>.
author | rbultje |
---|---|
date | Fri, 03 Sep 2010 19:30:27 +0000 |
parents | f4f55ad4a603 |
children |
comparison
equal
deleted
inserted
replaced
6458:d1500c270acc | 6459:cf0ea082dad2 |
---|---|
204 } | 204 } |
205 return 0; | 205 return 0; |
206 } | 206 } |
207 | 207 |
208 static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact, | 208 static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact, |
209 int *header_len, AVMetadata *m) | 209 int *header_len, AVMetadata *m, int framing_bit) |
210 { | 210 { |
211 const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; | 211 const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; |
212 int size; | 212 int size; |
213 uint8_t *p, *p0; | 213 uint8_t *p, *p0; |
214 unsigned int count; | 214 unsigned int count; |
215 | 215 |
216 size = offset + ff_vorbiscomment_length(m, vendor, &count); | 216 size = offset + ff_vorbiscomment_length(m, vendor, &count) + framing_bit; |
217 p = av_mallocz(size); | 217 p = av_mallocz(size); |
218 if (!p) | 218 if (!p) |
219 return NULL; | 219 return NULL; |
220 p0 = p; | 220 p0 = p; |
221 | 221 |
222 p += offset; | 222 p += offset; |
223 ff_vorbiscomment_write(&p, m, vendor, count); | 223 ff_vorbiscomment_write(&p, m, vendor, count); |
224 if (framing_bit) | |
225 bytestream_put_byte(&p, 1); | |
224 | 226 |
225 *header_len = size; | 227 *header_len = size; |
226 return p0; | 228 return p0; |
227 } | 229 } |
228 | 230 |
252 bytestream_put_byte(&p, 0x00); // streaminfo | 254 bytestream_put_byte(&p, 0x00); // streaminfo |
253 bytestream_put_be24(&p, 34); | 255 bytestream_put_be24(&p, 34); |
254 bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE); | 256 bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE); |
255 | 257 |
256 // second packet: VorbisComment | 258 // second packet: VorbisComment |
257 p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m); | 259 p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0); |
258 if (!p) | 260 if (!p) |
259 return AVERROR(ENOMEM); | 261 return AVERROR(ENOMEM); |
260 oggstream->header[1] = p; | 262 oggstream->header[1] = p; |
261 bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment | 263 bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment |
262 bytestream_put_be24(&p, oggstream->header_len[1] - 4); | 264 bytestream_put_be24(&p, oggstream->header_len[1] - 4); |
283 oggstream->header_len[0] = SPEEX_HEADER_SIZE; | 285 oggstream->header_len[0] = SPEEX_HEADER_SIZE; |
284 bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE); | 286 bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE); |
285 AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0 | 287 AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0 |
286 | 288 |
287 // second packet: VorbisComment | 289 // second packet: VorbisComment |
288 p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m); | 290 p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m, 0); |
289 if (!p) | 291 if (!p) |
290 return AVERROR(ENOMEM); | 292 return AVERROR(ENOMEM); |
291 oggstream->header[1] = p; | 293 oggstream->header[1] = p; |
292 | 294 |
293 return 0; | 295 return 0; |
350 av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); | 352 av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); |
351 av_freep(&st->priv_data); | 353 av_freep(&st->priv_data); |
352 return err; | 354 return err; |
353 } | 355 } |
354 } else { | 356 } else { |
357 uint8_t *p; | |
358 char *cstr = st->codec->codec_id == CODEC_ID_VORBIS ? "vorbis" : "theora"; | |
359 int header_type = st->codec->codec_id == CODEC_ID_VORBIS ? 3 : 0x81; | |
360 int framing_bit = st->codec->codec_id == CODEC_ID_VORBIS ? 1 : 0; | |
361 | |
355 if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size, | 362 if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size, |
356 st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42, | 363 st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42, |
357 oggstream->header, oggstream->header_len) < 0) { | 364 oggstream->header, oggstream->header_len) < 0) { |
358 av_log(s, AV_LOG_ERROR, "Extradata corrupted\n"); | 365 av_log(s, AV_LOG_ERROR, "Extradata corrupted\n"); |
359 av_freep(&st->priv_data); | 366 av_freep(&st->priv_data); |
360 return -1; | 367 return -1; |
361 } | 368 } |
369 | |
370 p = ogg_write_vorbiscomment(7, st->codec->flags & CODEC_FLAG_BITEXACT, | |
371 &oggstream->header_len[1], s->metadata, | |
372 framing_bit); | |
373 if (!p) | |
374 return AVERROR(ENOMEM); | |
375 | |
376 oggstream->header[1] = p; | |
377 bytestream_put_byte(&p, header_type); | |
378 bytestream_put_buffer(&p, cstr, 6); | |
379 | |
362 if (st->codec->codec_id == CODEC_ID_THEORA) { | 380 if (st->codec->codec_id == CODEC_ID_THEORA) { |
363 /** KFGSHIFT is the width of the less significant section of the granule position | 381 /** KFGSHIFT is the width of the less significant section of the granule position |
364 The less significant section is the frame count since the last keyframe */ | 382 The less significant section is the frame count since the last keyframe */ |
365 oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5); | 383 oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5); |
366 oggstream->vrev = oggstream->header[0][9]; | 384 oggstream->vrev = oggstream->header[0][9]; |