Mercurial > libavcodec.hg
comparison libvorbis.c @ 5875:5a61e8e2f65c libavcodec
Remove libvorbis Vorbis decoding support. Our native decoder is complete
and has no known bugs, any remaining issues will hopefully be uncovered now.
author | diego |
---|---|
date | Sun, 04 Nov 2007 12:55:32 +0000 |
parents | bc4791868c52 |
children | 48759bfbd073 |
comparison
equal
deleted
inserted
replaced
5874:ce9415dd447a | 5875:5a61e8e2f65c |
---|---|
216 oggvorbis_encode_init, | 216 oggvorbis_encode_init, |
217 oggvorbis_encode_frame, | 217 oggvorbis_encode_frame, |
218 oggvorbis_encode_close, | 218 oggvorbis_encode_close, |
219 .capabilities= CODEC_CAP_DELAY, | 219 .capabilities= CODEC_CAP_DELAY, |
220 } ; | 220 } ; |
221 | |
222 static int oggvorbis_decode_init(AVCodecContext *avccontext) { | |
223 OggVorbisContext *context = avccontext->priv_data ; | |
224 uint8_t *p= avccontext->extradata; | |
225 int i, hsizes[3]; | |
226 unsigned char *headers[3], *extradata = avccontext->extradata; | |
227 | |
228 vorbis_info_init(&context->vi) ; | |
229 vorbis_comment_init(&context->vc) ; | |
230 | |
231 if(! avccontext->extradata_size || ! p) { | |
232 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); | |
233 return -1; | |
234 } | |
235 | |
236 if(p[0] == 0 && p[1] == 30) { | |
237 for(i = 0; i < 3; i++){ | |
238 hsizes[i] = bytestream_get_be16(&p); | |
239 headers[i] = p; | |
240 p += hsizes[i]; | |
241 } | |
242 } else if(*p == 2) { | |
243 unsigned int offset = 1; | |
244 p++; | |
245 for(i=0; i<2; i++) { | |
246 hsizes[i] = 0; | |
247 while((*p == 0xFF) && (offset < avccontext->extradata_size)) { | |
248 hsizes[i] += 0xFF; | |
249 offset++; | |
250 p++; | |
251 } | |
252 if(offset >= avccontext->extradata_size - 1) { | |
253 av_log(avccontext, AV_LOG_ERROR, | |
254 "vorbis header sizes damaged\n"); | |
255 return -1; | |
256 } | |
257 hsizes[i] += *p; | |
258 offset++; | |
259 p++; | |
260 } | |
261 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; | |
262 #if 0 | |
263 av_log(avccontext, AV_LOG_DEBUG, | |
264 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", | |
265 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); | |
266 #endif | |
267 headers[0] = extradata + offset; | |
268 headers[1] = extradata + offset + hsizes[0]; | |
269 headers[2] = extradata + offset + hsizes[0] + hsizes[1]; | |
270 } else { | |
271 av_log(avccontext, AV_LOG_ERROR, | |
272 "vorbis initial header len is wrong: %d\n", *p); | |
273 return -1; | |
274 } | |
275 | |
276 for(i=0; i<3; i++){ | |
277 context->op.b_o_s= i==0; | |
278 context->op.bytes = hsizes[i]; | |
279 context->op.packet = headers[i]; | |
280 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ | |
281 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); | |
282 return -1; | |
283 } | |
284 } | |
285 | |
286 avccontext->channels = context->vi.channels; | |
287 avccontext->sample_rate = context->vi.rate; | |
288 avccontext->time_base= (AVRational){1, avccontext->sample_rate}; | |
289 | |
290 vorbis_synthesis_init(&context->vd, &context->vi); | |
291 vorbis_block_init(&context->vd, &context->vb); | |
292 | |
293 return 0 ; | |
294 } | |
295 | |
296 | |
297 static inline int conv(int samples, float **pcm, char *buf, int channels) { | |
298 int i, j; | |
299 ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; | |
300 float *mono ; | |
301 | |
302 for(i = 0 ; i < channels ; i++){ | |
303 ptr = &data[i]; | |
304 mono = pcm[i] ; | |
305 | |
306 for(j = 0 ; j < samples ; j++) { | |
307 *ptr = av_clip_int16(mono[j] * 32767.f); | |
308 ptr += channels; | |
309 } | |
310 } | |
311 | |
312 return 0 ; | |
313 } | |
314 | |
315 | |
316 static int oggvorbis_decode_frame(AVCodecContext *avccontext, | |
317 void *data, int *data_size, | |
318 uint8_t *buf, int buf_size) | |
319 { | |
320 OggVorbisContext *context = avccontext->priv_data ; | |
321 float **pcm ; | |
322 ogg_packet *op= &context->op; | |
323 int samples, total_samples, total_bytes; | |
324 | |
325 if(!buf_size){ | |
326 //FIXME flush | |
327 return 0; | |
328 } | |
329 | |
330 op->packet = buf; | |
331 op->bytes = buf_size; | |
332 | |
333 // av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %"PRId64" %"PRId64" %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate); | |
334 | |
335 /* for(i=0; i<op->bytes; i++) | |
336 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); | |
337 av_log(avccontext, AV_LOG_DEBUG, "\n");*/ | |
338 | |
339 if(vorbis_synthesis(&context->vb, op) == 0) | |
340 vorbis_synthesis_blockin(&context->vd, &context->vb) ; | |
341 | |
342 total_samples = 0 ; | |
343 total_bytes = 0 ; | |
344 | |
345 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { | |
346 conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; | |
347 total_bytes += samples * 2 * context->vi.channels ; | |
348 total_samples += samples ; | |
349 vorbis_synthesis_read(&context->vd, samples) ; | |
350 } | |
351 | |
352 *data_size = total_bytes ; | |
353 return buf_size ; | |
354 } | |
355 | |
356 | |
357 static int oggvorbis_decode_close(AVCodecContext *avccontext) { | |
358 OggVorbisContext *context = avccontext->priv_data ; | |
359 | |
360 vorbis_info_clear(&context->vi) ; | |
361 vorbis_comment_clear(&context->vc) ; | |
362 | |
363 return 0 ; | |
364 } | |
365 | |
366 | |
367 AVCodec libvorbis_decoder = { | |
368 "libvorbis", | |
369 CODEC_TYPE_AUDIO, | |
370 CODEC_ID_VORBIS, | |
371 sizeof(OggVorbisContext), | |
372 oggvorbis_decode_init, | |
373 NULL, | |
374 oggvorbis_decode_close, | |
375 oggvorbis_decode_frame, | |
376 .capabilities= CODEC_CAP_DELAY, | |
377 } ; |