Changeset 41b985f for src/io/source_avcodec.c
- Timestamp:
- Mar 12, 2017, 11:26:24 AM (8 years ago)
- Branches:
- sampler
- Children:
- bde49c4a
- Parents:
- 71f2e5f (diff), 67b6618 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/io/source_avcodec.c
r71f2e5f r41b985f 19 19 */ 20 20 21 22 #include "config.h" 21 #include "aubio_priv.h" 23 22 24 23 #ifdef HAVE_LIBAV 24 25 #include <libavcodec/avcodec.h> 26 #include <libavformat/avformat.h> 27 #include <libavresample/avresample.h> 28 #include <libavutil/opt.h> 29 #include <stdlib.h> 25 30 26 31 // determine whether we use libavformat from ffmpeg or from libav … … 33 38 ) 34 39 35 #include <libavcodec/avcodec.h> 36 #include <libavformat/avformat.h> 37 #include <libavresample/avresample.h> 38 #include <libavutil/opt.h> 39 #include <stdlib.h> 40 // backward compatibility with libavcodec55 41 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1) 42 #warning "libavcodec55 is deprecated" 43 #define HAVE_AUBIO_LIBAVCODEC_DEPRECATED 1 44 #define av_frame_alloc avcodec_alloc_frame 45 #define av_frame_free avcodec_free_frame 46 #define av_packet_unref av_free_packet 47 #endif 40 48 41 49 #include "aubio_priv.h" … … 60 68 AVCodecContext *avCodecCtx; 61 69 AVFrame *avFrame; 70 AVPacket avPacket; 62 71 AVAudioResampleContext *avr; 63 float *output;72 smpl_t *output; 64 73 uint_t read_samples; 65 74 uint_t read_index; … … 151 160 sint_t selected_stream = -1; 152 161 for (i = 0; i < avFormatCtx->nb_streams; i++) { 162 #if FF_API_LAVF_AVCTX 163 if (avFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { 164 #else 153 165 if (avFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { 166 #endif 154 167 if (selected_stream == -1) { 155 168 selected_stream = i; … … 168 181 169 182 AVCodecContext *avCodecCtx = s->avCodecCtx; 183 #if FF_API_LAVF_AVCTX 184 AVCodecParameters *codecpar = avFormatCtx->streams[selected_stream]->codecpar; 185 if (codecpar == NULL) { 186 AUBIO_ERR("source_avcodec: Could not find decoder for %s", s->path); 187 goto beach; 188 } 189 AVCodec *codec = avcodec_find_decoder(codecpar->codec_id); 190 191 /* Allocate a codec context for the decoder */ 192 avCodecCtx = avcodec_alloc_context3(codec); 193 if (!avCodecCtx) { 194 AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context for path %s\n", 195 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); 196 goto beach; 197 } 198 #else 170 199 avCodecCtx = avFormatCtx->streams[selected_stream]->codec; 171 200 AVCodec *codec = avcodec_find_decoder(avCodecCtx->codec_id); 201 #endif 172 202 if (codec == NULL) { 173 203 AUBIO_ERR("source_avcodec: Could not find decoder for %s", s->path); 174 204 goto beach; 175 205 } 206 207 #if FF_API_LAVF_AVCTX 208 /* Copy codec parameters from input stream to output codec context */ 209 if ((err = avcodec_parameters_to_context(avCodecCtx, codecpar)) < 0) { 210 AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to decoder context for %s\n", 211 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); 212 goto beach; 213 } 214 #endif 176 215 177 216 if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) { … … 206 245 207 246 /* allocate output for avr */ 208 s->output = ( float *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(float));247 s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(smpl_t)); 209 248 210 249 s->read_samples = 0; … … 233 272 234 273 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) { 274 // create or reset resampler to/from mono/multi-channel 235 275 if ( (multi != s->multi) || (s->avr == NULL) ) { 236 276 int64_t input_layout = av_get_default_channel_layout(s->input_channels); 237 277 uint_t output_channels = multi ? s->input_channels : 1; 238 278 int64_t output_layout = av_get_default_channel_layout(output_channels); 239 if (s->avr != NULL) { 240 avresample_close( s->avr ); 241 av_free ( s->avr ); 242 s->avr = NULL; 243 } 244 AVAudioResampleContext *avr = s->avr; 245 avr = avresample_alloc_context(); 279 AVAudioResampleContext *avr = avresample_alloc_context(); 280 AVAudioResampleContext *oldavr = s->avr; 246 281 247 282 av_opt_set_int(avr, "in_channel_layout", input_layout, 0); … … 250 285 av_opt_set_int(avr, "out_sample_rate", s->samplerate, 0); 251 286 av_opt_set_int(avr, "in_sample_fmt", s->avCodecCtx->sample_fmt, 0); 287 #if HAVE_AUBIO_DOUBLE 288 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0); 289 #else 252 290 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); 291 #endif 292 // TODO: use planar? 293 //av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); 253 294 int err; 254 295 if ( ( err = avresample_open(avr) ) < 0) { … … 261 302 } 262 303 s->avr = avr; 304 if (oldavr != NULL) { 305 avresample_close( oldavr ); 306 av_free ( oldavr ); 307 oldavr = NULL; 308 } 263 309 s->multi = multi; 264 310 } … … 269 315 AVCodecContext *avCodecCtx = s->avCodecCtx; 270 316 AVFrame *avFrame = s->avFrame; 271 AVPacket avPacket ;317 AVPacket avPacket = s->avPacket; 272 318 av_init_packet (&avPacket); 273 319 AVAudioResampleContext *avr = s->avr; 274 float *output = s->output;320 smpl_t *output = s->output; 275 321 *read_samples = 0; 276 322 … … 291 337 292 338 int got_frame = 0; 339 #if FF_API_LAVF_AVCTX 340 int ret = avcodec_send_packet(avCodecCtx, &avPacket); 341 if (ret < 0 && ret != AVERROR_EOF) { 342 AUBIO_ERR("source_avcodec: error when sending packet for %s\n", s->path); 343 goto beach; 344 } 345 ret = avcodec_receive_frame(avCodecCtx, avFrame); 346 if (ret >= 0) { 347 got_frame = 1; 348 } 349 if (ret < 0) { 350 if (ret == AVERROR(EAGAIN)) { 351 AUBIO_WRN("source_avcodec: output is not available right now - user must try to send new input\n"); 352 } else if (ret == AVERROR_EOF) { 353 AUBIO_WRN("source_avcodec: the decoder has been fully flushed, and there will be no more output frames\n"); 354 } else { 355 AUBIO_ERR("source_avcodec: decoding errors on %s\n", s->path); 356 goto beach; 357 } 358 } 359 #else 293 360 int len = avcodec_decode_audio4(avCodecCtx, avFrame, &got_frame, &avPacket); 294 361 295 362 if (len < 0) { 296 AUBIO_ERR("Error while decoding %s\n", s->path); 297 goto beach; 298 } 363 AUBIO_ERR("source_avcodec: error while decoding %s\n", s->path); 364 goto beach; 365 } 366 #endif 299 367 if (got_frame == 0) { 300 //AUBIO_ERR("Could not get frame for (%s)\n", s->path);368 AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n", s->path); 301 369 goto beach; 302 370 } … … 312 380 (uint8_t **)avFrame->data, in_linesize, in_samples); 313 381 if (out_samples <= 0) { 314 //AUBIO_ERR("No sample found while converting frame (%s)\n", s->path);382 AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n", s->path); 315 383 goto beach; 316 384 } … … 329 397 330 398 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){ 331 if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);332 399 uint_t i; 333 400 uint_t end = 0; 334 401 uint_t total_wrote = 0; 402 // switch from multi 403 if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0); 335 404 while (total_wrote < s->hop_size) { 336 405 end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote); … … 360 429 361 430 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){ 362 if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);363 431 uint_t i,j; 364 432 uint_t end = 0; 365 433 uint_t total_wrote = 0; 434 // switch from mono 435 if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1); 366 436 while (total_wrote < s->hop_size) { 367 437 end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote); … … 408 478 int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX); 409 479 int seek_flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_ANY; 410 int ret = avformat_seek_file(s->avFormatCtx, s->selected_stream, 480 int ret = AUBIO_FAIL; 481 if (s->avFormatCtx != NULL && s->avr != NULL) { 482 ret = AUBIO_OK; 483 } else { 484 AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", s->path); 485 return ret; 486 } 487 if ((sint_t)pos < 0) { 488 AUBIO_ERR("source_avcodec: could not seek %s at %d (seeking position" 489 " should be >= 0)\n", s->path, pos); 490 return AUBIO_FAIL; 491 } 492 ret = avformat_seek_file(s->avFormatCtx, s->selected_stream, 411 493 min_ts, resampled_pos, max_ts, seek_flags); 412 494 if (ret < 0) { 413 AUBIO_ERR(" Failed seeking to %d in file %s", pos, s->path);495 AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", pos, s->path); 414 496 } 415 497 // reset read status … … 442 524 s->avCodecCtx = NULL; 443 525 if (s->avFormatCtx != NULL) { 444 avformat_close_input ( &(s->avFormatCtx) ); 445 } 446 s->avFormatCtx = NULL; 526 avformat_close_input(&s->avFormatCtx); 527 #ifndef HAVE_AUBIO_LIBAVCODEC_DEPRECATED // avoid crash on old libavcodec54 528 avformat_free_context(s->avFormatCtx); 529 #endif 530 s->avFormatCtx = NULL; 531 } 532 av_packet_unref(&s->avPacket); 447 533 return AUBIO_OK; 448 534 } … … 458 544 av_frame_free( &(s->avFrame) ); 459 545 } 460 if (s->path) AUBIO_FREE(s->path);461 546 s->avFrame = NULL; 547 if (s->path) { 548 AUBIO_FREE(s->path); 549 } 550 s->path = NULL; 462 551 AUBIO_FREE(s); 463 552 }
Note: See TracChangeset
for help on using the changeset viewer.