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];