Ignore:
Timestamp:
Mar 12, 2017, 11:26:24 AM (8 years ago)
Author:
Paul Brossier <piem@piem.org>
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.
Message:

Merge 'origin/master' into sampler

Conflicts:

.travis.yml
Makefile
examples/aubionotes.c
examples/parse_args.h
python/demos/demo_timestretch_online.py
python/lib/moresetuptools.py
python/tests/test_source.py
setup.py
src/io/source.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/io/source_avcodec.c

    r71f2e5f r41b985f  
    1919*/
    2020
    21 
    22 #include "config.h"
     21#include "aubio_priv.h"
    2322
    2423#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>
    2530
    2631// determine whether we use libavformat from ffmpeg or from libav
     
    3338      )
    3439
    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
    4048
    4149#include "aubio_priv.h"
     
    6068  AVCodecContext *avCodecCtx;
    6169  AVFrame *avFrame;
     70  AVPacket avPacket;
    6271  AVAudioResampleContext *avr;
    63   float *output;
     72  smpl_t *output;
    6473  uint_t read_samples;
    6574  uint_t read_index;
     
    151160  sint_t selected_stream = -1;
    152161  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
    153165    if (avFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
     166#endif
    154167      if (selected_stream == -1) {
    155168        selected_stream = i;
     
    168181
    169182  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
    170199  avCodecCtx = avFormatCtx->streams[selected_stream]->codec;
    171200  AVCodec *codec = avcodec_find_decoder(avCodecCtx->codec_id);
     201#endif
    172202  if (codec == NULL) {
    173203    AUBIO_ERR("source_avcodec: Could not find decoder for %s", s->path);
    174204    goto beach;
    175205  }
     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
    176215
    177216  if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) {
     
    206245
    207246  /* 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));
    209248
    210249  s->read_samples = 0;
     
    233272
    234273void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) {
     274  // create or reset resampler to/from mono/multi-channel
    235275  if ( (multi != s->multi) || (s->avr == NULL) ) {
    236276    int64_t input_layout = av_get_default_channel_layout(s->input_channels);
    237277    uint_t output_channels = multi ? s->input_channels : 1;
    238278    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;
    246281
    247282    av_opt_set_int(avr, "in_channel_layout",  input_layout,           0);
     
    250285    av_opt_set_int(avr, "out_sample_rate",    s->samplerate,          0);
    251286    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
    252290    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);
    253294    int err;
    254295    if ( ( err = avresample_open(avr) ) < 0) {
     
    261302    }
    262303    s->avr = avr;
     304    if (oldavr != NULL) {
     305      avresample_close( oldavr );
     306      av_free ( oldavr );
     307      oldavr = NULL;
     308    }
    263309    s->multi = multi;
    264310  }
     
    269315  AVCodecContext *avCodecCtx = s->avCodecCtx;
    270316  AVFrame *avFrame = s->avFrame;
    271   AVPacket avPacket;
     317  AVPacket avPacket = s->avPacket;
    272318  av_init_packet (&avPacket);
    273319  AVAudioResampleContext *avr = s->avr;
    274   float *output = s->output;
     320  smpl_t *output = s->output;
    275321  *read_samples = 0;
    276322
     
    291337
    292338  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
    293360  int len = avcodec_decode_audio4(avCodecCtx, avFrame, &got_frame, &avPacket);
    294361
    295362  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
    299367  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);
    301369    goto beach;
    302370  }
     
    312380        (uint8_t **)avFrame->data, in_linesize, in_samples);
    313381  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);
    315383    goto beach;
    316384  }
     
    329397
    330398void 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);
    332399  uint_t i;
    333400  uint_t end = 0;
    334401  uint_t total_wrote = 0;
     402  // switch from multi
     403  if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);
    335404  while (total_wrote < s->hop_size) {
    336405    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     
    360429
    361430void 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);
    363431  uint_t i,j;
    364432  uint_t end = 0;
    365433  uint_t total_wrote = 0;
     434  // switch from mono
     435  if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);
    366436  while (total_wrote < s->hop_size) {
    367437    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     
    408478  int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
    409479  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,
    411493      min_ts, resampled_pos, max_ts, seek_flags);
    412494  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);
    414496  }
    415497  // reset read status
     
    442524  s->avCodecCtx = NULL;
    443525  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);
    447533  return AUBIO_OK;
    448534}
     
    458544    av_frame_free( &(s->avFrame) );
    459545  }
    460   if (s->path) AUBIO_FREE(s->path);
    461546  s->avFrame = NULL;
     547  if (s->path) {
     548    AUBIO_FREE(s->path);
     549  }
     550  s->path = NULL;
    462551  AUBIO_FREE(s);
    463552}
Note: See TracChangeset for help on using the changeset viewer.