Changes in src/io/source_avcodec.c [138cb1f:6551a683]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/io/source_avcodec.c
r138cb1f r6551a683 35 35 // determine whether we use libavformat from ffmpeg or from libav 36 36 #define FFMPEG_LIBAVFORMAT (LIBAVFORMAT_VERSION_MICRO > 99 ) 37 // max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 through57.2.10037 // max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 -> 57.2.100 38 38 #define FFMPEG_LIBAVFORMAT_MAX_DUR2 FFMPEG_LIBAVFORMAT && ( \ 39 39 (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR >= 43) \ … … 90 90 sint_t selected_stream; 91 91 uint_t eof; 92 uint_t multi;93 92 }; 94 93 95 // hack to create or re-create the context the first time _do or _do_multi is called 96 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi); 97 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples); 94 // create or re-create the context when _do or _do_multi is called 95 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s); 96 // actually read a frame 97 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, 98 uint_t * read_samples); 98 99 99 100 uint_t aubio_source_avcodec_has_network_url(aubio_source_avcodec_t *s); … … 112 113 113 114 114 aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, uint_t samplerate, uint_t hop_size) { 115 aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, 116 uint_t samplerate, uint_t hop_size) { 115 117 aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t); 116 118 AVFormatContext *avFormatCtx = s->avFormatCtx; … … 129 131 } 130 132 if ((sint_t)samplerate < 0) { 131 AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n", path, samplerate); 133 AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n", 134 path, samplerate); 132 135 goto beach; 133 136 } 134 137 if ((sint_t)hop_size <= 0) { 135 AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n", path, hop_size); 138 AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n", 139 path, hop_size); 136 140 goto beach; 137 141 } … … 173 177 char errorstr[256]; 174 178 av_strerror (err, errorstr, sizeof(errorstr)); 175 AUBIO_ERR("source_avcodec: Could not find stream information " "for %s (%s)\n", s->path,176 errorstr);179 AUBIO_ERR("source_avcodec: Could not find stream information " 180 "for %s (%s)\n", s->path, errorstr); 177 181 goto beach; 178 182 } … … 214 218 avCodecCtx = avcodec_alloc_context3(codec); 215 219 if (!avCodecCtx) { 216 AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context for path %s\n", 217 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); 220 AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context " 221 "for path %s\n", av_get_media_type_string(AVMEDIA_TYPE_AUDIO), 222 s->path); 218 223 goto beach; 219 224 } … … 230 235 /* Copy codec parameters from input stream to output codec context */ 231 236 if ((err = avcodec_parameters_to_context(avCodecCtx, codecpar)) < 0) { 232 AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to decoder context for %s\n", 233 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); 237 AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to " 238 "decoder context for %s\n", 239 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); 234 240 goto beach; 235 241 } … … 239 245 char errorstr[256]; 240 246 av_strerror (err, errorstr, sizeof(errorstr)); 241 AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path, errorstr); 247 AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path, 248 errorstr); 242 249 goto beach; 243 250 } … … 266 273 267 274 /* allocate output for avr */ 268 s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(smpl_t)); 275 s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE 276 * sizeof(smpl_t)); 269 277 270 278 s->read_samples = 0; … … 275 283 s->avFrame = avFrame; 276 284 277 // default to mono output 278 aubio_source_avcodec_reset_resampler(s, 0); 285 aubio_source_avcodec_reset_resampler(s); 279 286 280 287 if (s->avr == NULL) goto beach; 281 288 282 289 s->eof = 0; 283 s->multi = 0;284 290 285 291 //av_log_set_level(AV_LOG_QUIET); … … 294 300 } 295 301 296 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) { 302 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s) 303 { 297 304 // create or reset resampler to/from mono/multi-channel 298 if ( (multi != s->multi) || (s->avr == NULL)) {305 if ( s->avr == NULL ) { 299 306 int err; 300 307 int64_t input_layout = av_get_default_channel_layout(s->input_channels); 301 uint_t output_channels = multi ? s->input_channels : 1; 302 int64_t output_layout = av_get_default_channel_layout(output_channels); 308 int64_t output_layout = av_get_default_channel_layout(s->input_channels); 303 309 #ifdef HAVE_AVRESAMPLE 304 310 AVAudioResampleContext *avr = avresample_alloc_context(); 305 AVAudioResampleContext *oldavr = s->avr;306 311 #elif defined(HAVE_SWRESAMPLE) 307 312 SwrContext *avr = swr_alloc(); 308 SwrContext *oldavr = s->avr;309 313 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */ 310 314 311 av_opt_set_int(avr, "in_channel_layout", input_layout, 0);312 av_opt_set_int(avr, "out_channel_layout", output_layout, 0);313 av_opt_set_int(avr, "in_sample_rate", s->input_samplerate, 0);314 av_opt_set_int(avr, "out_sample_rate", s->samplerate, 0);315 av_opt_set_int(avr, "in_channel_layout", input_layout, 0); 316 av_opt_set_int(avr, "out_channel_layout", output_layout, 0); 317 av_opt_set_int(avr, "in_sample_rate", s->input_samplerate, 0); 318 av_opt_set_int(avr, "out_sample_rate", s->samplerate, 0); 315 319 av_opt_set_int(avr, "in_sample_fmt", s->avCodecCtx->sample_fmt, 0); 316 320 #if HAVE_AUBIO_DOUBLE 317 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0);318 #else 319 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);321 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0); 322 #else 323 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); 320 324 #endif 321 325 // TODO: use planar? … … 329 333 char errorstr[256]; 330 334 av_strerror (err, errorstr, sizeof(errorstr)); 331 AUBIO_ERR("source_avcodec: Could not open resampling context for %s (%s)\n",332 s->path, errorstr);335 AUBIO_ERR("source_avcodec: Could not open resampling context" 336 " for %s (%s)\n", s->path, errorstr); 333 337 return; 334 338 } 335 339 s->avr = avr; 336 if (oldavr != NULL) { 337 #ifdef HAVE_AVRESAMPLE 338 avresample_close( oldavr ); 339 #elif defined(HAVE_SWRESAMPLE) 340 swr_close ( oldavr ); 341 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */ 342 av_free ( oldavr ); 343 oldavr = NULL; 344 } 345 s->multi = multi; 346 } 347 } 348 349 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples) { 340 } 341 } 342 343 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, 344 uint_t * read_samples) 345 { 350 346 AVFormatContext *avFormatCtx = s->avFormatCtx; 351 347 AVCodecContext *avCodecCtx = s->avCodecCtx; … … 388 384 char errorstr[256]; 389 385 av_strerror (err, errorstr, sizeof(errorstr)); 390 AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n", s->path, errorstr); 386 AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n", 387 s->path, errorstr); 391 388 s->eof = 1; 392 389 goto beach; … … 406 403 if (ret < 0) { 407 404 if (ret == AVERROR(EAGAIN)) { 408 //AUBIO_WRN("source_avcodec: output is not available right now - user must try to send new input\n"); 405 //AUBIO_WRN("source_avcodec: output is not available right now - " 406 // "user must try to send new input\n"); 409 407 goto beach; 410 408 } else if (ret == AVERROR_EOF) { 411 AUBIO_WRN("source_avcodec: the decoder has been fully flushed, and there will be no more output frames\n"); 409 AUBIO_WRN("source_avcodec: the decoder has been fully flushed, " 410 "and there will be no more output frames\n"); 412 411 } else { 413 412 AUBIO_ERR("source_avcodec: decoding errors on %s\n", s->path); … … 424 423 #endif 425 424 if (got_frame == 0) { 426 AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n", s->path); 425 AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n", 426 s->path); 427 427 goto beach; 428 428 } … … 431 431 if (avFrame->channels != (sint_t)s->input_channels) { 432 432 AUBIO_WRN ("source_avcodec: trying to read from %d channel(s)," 433 "but configured for %d; is '%s' corrupt?\n", avFrame->channels,434 s->input_channels, s->path);433 "but configured for %d; is '%s' corrupt?\n", 434 avFrame->channels, s->input_channels, s->path); 435 435 goto beach; 436 436 } … … 457 457 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */ 458 458 if (out_samples <= 0) { 459 AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n", s->path); 459 AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n", 460 s->path); 460 461 goto beach; 461 462 } … … 475 476 } 476 477 477 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){ 478 uint_t i; 478 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, 479 uint_t * read) { 480 uint_t i, j; 479 481 uint_t end = 0; 480 482 uint_t total_wrote = 0; 481 // switch from multi482 if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);483 483 while (total_wrote < s->hop_size) { 484 484 end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote); 485 485 for (i = 0; i < end; i++) { 486 read_data->data[i + total_wrote] = s->output[i + s->read_index]; 486 read_data->data[i + total_wrote] = 0.; 487 for (j = 0; j < s->input_channels; j++) { 488 read_data->data[i + total_wrote] += 489 s->output[(i + s->read_index) * s->input_channels + j]; 490 } 491 read_data->data[i + total_wrote] *= 1./s->input_channels; 487 492 } 488 493 total_wrote += end; … … 507 512 } 508 513 509 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){ 514 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, 515 fmat_t * read_data, uint_t * read) { 510 516 uint_t i,j; 511 517 uint_t end = 0; 512 518 uint_t total_wrote = 0; 513 // switch from mono514 if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);515 519 while (total_wrote < s->hop_size) { 516 520 end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote); … … 553 557 554 558 uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) { 555 int64_t resampled_pos = (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate)); 559 int64_t resampled_pos = 560 (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate)); 556 561 int64_t min_ts = MAX(resampled_pos - 2000, 0); 557 562 int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX); … … 561 566 ret = AUBIO_OK; 562 567 } else { 563 AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", s->path); 568 AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", 569 s->path); 564 570 return ret; 565 571 } … … 572 578 min_ts, resampled_pos, max_ts, seek_flags); 573 579 if (ret < 0) { 574 AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", pos, s->path); 580 AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", 581 pos, s->path); 575 582 } 576 583 // reset read status
Note: See TracChangeset
for help on using the changeset viewer.