Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/io/source_avcodec.c

    r138cb1f r6551a683  
    3535// determine whether we use libavformat from ffmpeg or from libav
    3636#define FFMPEG_LIBAVFORMAT (LIBAVFORMAT_VERSION_MICRO > 99 )
    37 // max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 through 57.2.100
     37// max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 -> 57.2.100
    3838#define FFMPEG_LIBAVFORMAT_MAX_DUR2 FFMPEG_LIBAVFORMAT && ( \
    3939      (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR >= 43) \
     
    9090  sint_t selected_stream;
    9191  uint_t eof;
    92   uint_t multi;
    9392};
    9493
    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
     95void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s);
     96// actually read a frame
     97void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     98    uint_t * read_samples);
    9899
    99100uint_t aubio_source_avcodec_has_network_url(aubio_source_avcodec_t *s);
     
    112113
    113114
    114 aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, uint_t samplerate, uint_t hop_size) {
     115aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path,
     116    uint_t samplerate, uint_t hop_size) {
    115117  aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
    116118  AVFormatContext *avFormatCtx = s->avFormatCtx;
     
    129131  }
    130132  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);
    132135    goto beach;
    133136  }
    134137  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);
    136140    goto beach;
    137141  }
     
    173177    char errorstr[256];
    174178    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);
    177181    goto beach;
    178182  }
     
    214218  avCodecCtx = avcodec_alloc_context3(codec);
    215219  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);
    218223    goto beach;
    219224  }
     
    230235  /* Copy codec parameters from input stream to output codec context */
    231236  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);
    234240    goto beach;
    235241  }
     
    239245    char errorstr[256];
    240246    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);
    242249    goto beach;
    243250  }
     
    266273
    267274  /* 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));
    269277
    270278  s->read_samples = 0;
     
    275283  s->avFrame = avFrame;
    276284
    277   // default to mono output
    278   aubio_source_avcodec_reset_resampler(s, 0);
     285  aubio_source_avcodec_reset_resampler(s);
    279286
    280287  if (s->avr == NULL) goto beach;
    281288
    282289  s->eof = 0;
    283   s->multi = 0;
    284290
    285291  //av_log_set_level(AV_LOG_QUIET);
     
    294300}
    295301
    296 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) {
     302void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s)
     303{
    297304  // create or reset resampler to/from mono/multi-channel
    298   if ( (multi != s->multi) || (s->avr == NULL) ) {
     305  if ( s->avr == NULL ) {
    299306    int err;
    300307    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);
    303309#ifdef HAVE_AVRESAMPLE
    304310    AVAudioResampleContext *avr = avresample_alloc_context();
    305     AVAudioResampleContext *oldavr = s->avr;
    306311#elif defined(HAVE_SWRESAMPLE)
    307312    SwrContext *avr = swr_alloc();
    308     SwrContext *oldavr = s->avr;
    309313#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    310314
    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);
    315319    av_opt_set_int(avr, "in_sample_fmt",      s->avCodecCtx->sample_fmt, 0);
    316320#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);
    320324#endif
    321325    // TODO: use planar?
     
    329333      char errorstr[256];
    330334      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);
    333337      return;
    334338    }
    335339    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
     343void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     344    uint_t * read_samples)
     345{
    350346  AVFormatContext *avFormatCtx = s->avFormatCtx;
    351347  AVCodecContext *avCodecCtx = s->avCodecCtx;
     
    388384      char errorstr[256];
    389385      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);
    391388      s->eof = 1;
    392389      goto beach;
     
    406403  if (ret < 0) {
    407404    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");
    409407      goto beach;
    410408    } 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");
    412411    } else {
    413412      AUBIO_ERR("source_avcodec: decoding errors on %s\n", s->path);
     
    424423#endif
    425424  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);
    427427    goto beach;
    428428  }
     
    431431  if (avFrame->channels != (sint_t)s->input_channels) {
    432432    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);
    435435    goto beach;
    436436  }
     
    457457#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    458458  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);
    460461    goto beach;
    461462  }
     
    475476}
    476477
    477 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){
    478   uint_t i;
     478void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data,
     479    uint_t * read) {
     480  uint_t i, j;
    479481  uint_t end = 0;
    480482  uint_t total_wrote = 0;
    481   // switch from multi
    482   if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);
    483483  while (total_wrote < s->hop_size) {
    484484    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
    485485    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;
    487492    }
    488493    total_wrote += end;
     
    507512}
    508513
    509 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){
     514void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s,
     515    fmat_t * read_data, uint_t * read) {
    510516  uint_t i,j;
    511517  uint_t end = 0;
    512518  uint_t total_wrote = 0;
    513   // switch from mono
    514   if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);
    515519  while (total_wrote < s->hop_size) {
    516520    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     
    553557
    554558uint_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));
    556561  int64_t min_ts = MAX(resampled_pos - 2000, 0);
    557562  int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
     
    561566    ret = AUBIO_OK;
    562567  } 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);
    564570    return ret;
    565571  }
     
    572578      min_ts, resampled_pos, max_ts, seek_flags);
    573579  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);
    575582  }
    576583  // reset read status
Note: See TracChangeset for help on using the changeset viewer.