source: src/io/source_avcodec.c @ 5c6acbb2

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 5c6acbb2 was 5c6acbb2, checked in by Paul Brossier <piem@piem.org>, 10 years ago

src/io/source_avcodec.c: no errors if not sample given, may happen in some resampling configurations

  • Property mode set to 100644
File size: 11.9 KB
Line 
1/*
2  Copyright (C) 2013 Paul Brossier <piem@aubio.org>
3
4  This file is part of aubio.
5
6  aubio is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  aubio is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21
22#include "config.h"
23
24#ifdef HAVE_LIBAV
25
26#include <libavcodec/avcodec.h>
27#include <libavformat/avformat.h>
28#include <libavresample/avresample.h>
29#include <libavutil/opt.h>
30#include <stdlib.h>
31
32#include "aubio_priv.h"
33#include "fvec.h"
34#include "fmat.h"
35#include "source_avcodec.h"
36
37#define AUBIO_AVCODEC_MAX_BUFFER_SIZE FF_MIN_BUFFER_SIZE
38
39struct _aubio_source_avcodec_t {
40  uint_t hop_size;
41  uint_t samplerate;
42  uint_t channels;
43
44  // some data about the file
45  char_t *path;
46  uint_t input_samplerate;
47  uint_t input_channels;
48
49  // avcodec stuff
50  AVFormatContext *avFormatCtx;
51  AVCodecContext *avCodecCtx;
52  AVFrame *avFrame;
53  AVAudioResampleContext *avr;
54  float *output;
55  uint_t read_samples;
56  uint_t read_index;
57  sint_t selected_stream;
58  uint_t eof;
59  uint_t multi;
60};
61
62// hack to create or re-create the context the first time _do or _do_multi is called
63void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi);
64
65aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplerate, uint_t hop_size) {
66  aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
67  int err;
68  if (path == NULL) {
69    AUBIO_ERR("Aborted opening null path\n");
70    goto beach;
71  }
72  if ((sint_t)samplerate < 0) {
73    AUBIO_ERR("Can not open %s with samplerate %d\n", path, samplerate);
74    goto beach;
75  }
76  if ((sint_t)hop_size <= 0) {
77    AUBIO_ERR("Can not open %s with hop_size %d\n", path, hop_size);
78    goto beach;
79  }
80
81  s->hop_size = hop_size;
82  s->channels = 1;
83  s->path = path;
84
85  // register all formats and codecs
86  av_register_all();
87
88  // if path[0] != '/'
89  //avformat_network_init();
90
91  // try opening the file and get some info about it
92  AVFormatContext *avFormatCtx = s->avFormatCtx;
93  avFormatCtx = NULL;
94  if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, NULL) ) < 0 ) {
95    char errorstr[256];
96    av_strerror (err, errorstr, sizeof(errorstr));
97    AUBIO_ERR("Failed opening %s (%s)\n", s->path, errorstr);
98    goto beach;
99  }
100
101  // try to make sure max_analyze_duration is big enough for most songs
102  avFormatCtx->max_analyze_duration *= 100;
103
104  // retrieve stream information
105  if ( (err = avformat_find_stream_info(avFormatCtx, NULL)) < 0 ) {
106    char errorstr[256];
107    av_strerror (err, errorstr, sizeof(errorstr));
108    AUBIO_ERR("Could not find stream information " "for %s (%s)\n", s->path,
109        errorstr);
110    goto beach;
111  }
112
113  // dump information about file onto standard error
114  //av_dump_format(avFormatCtx, 0, s->path, 0);
115
116  // look for the first audio stream
117  uint_t i;
118  sint_t selected_stream = -1;
119  for (i = 0; i < avFormatCtx->nb_streams; i++) {
120    if (avFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
121      if (selected_stream == -1) {
122        selected_stream = i;
123      } else {
124        AUBIO_WRN("More than one audio stream in %s, "
125            "taking the first one\n", s->path);
126      }
127    }
128  }
129  if (selected_stream == -1) {
130    AUBIO_ERR("No audio stream in %s\n", s->path);
131    goto beach;
132  }
133  //AUBIO_DBG("Taking stream %d in file %s\n", selected_stream, s->path);
134  s->selected_stream = selected_stream;
135
136  AVCodecContext *avCodecCtx = s->avCodecCtx;
137  avCodecCtx = avFormatCtx->streams[selected_stream]->codec;
138  AVCodec *codec = avcodec_find_decoder(avCodecCtx->codec_id);
139  if (codec == NULL) {
140    AUBIO_ERR("Could not find decoder for %s", s->path);
141    goto beach;
142  }
143
144  if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) {
145    char errorstr[256];
146    av_strerror (err, errorstr, sizeof(errorstr));
147    AUBIO_ERR("Could not load codec for %s (%s)\n", s->path, errorstr);
148    goto beach;
149  }
150
151  /* get input specs */
152  s->input_samplerate = avCodecCtx->sample_rate;
153  s->input_channels   = avCodecCtx->channels;
154  //AUBIO_DBG("input_samplerate: %d\n", s->input_samplerate);
155  //AUBIO_DBG("input_channels: %d\n", s->input_channels);
156
157  if (samplerate == 0) {
158    samplerate = s->input_samplerate;
159    //AUBIO_DBG("sampling rate set to 0, automagically adjusting to %d\n", samplerate);
160  }
161  s->samplerate = samplerate;
162
163  if (s->samplerate >  s->input_samplerate) {
164    AUBIO_WRN("upsampling %s from %d to %d\n", s->path,
165        s->input_samplerate, s->samplerate);
166  }
167
168  AVFrame *avFrame = s->avFrame;
169  avFrame = avcodec_alloc_frame();
170  if (!avFrame) {
171    AUBIO_ERR("Could not allocate frame for (%s)\n", s->path);
172  }
173
174  /* allocate output for avr */
175  s->output = (float *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(float));
176
177  s->read_samples = 0;
178  s->read_index = 0;
179
180  s->avFormatCtx = avFormatCtx;
181  s->avCodecCtx = avCodecCtx;
182  s->avFrame = avFrame;
183
184  // default to mono output
185  aubio_source_avcodec_reset_resampler(s, 0);
186
187  s->eof = 0;
188  s->multi = 0;
189
190  //av_log_set_level(AV_LOG_QUIET);
191
192  return s;
193
194beach:
195  //AUBIO_ERR("can not read %s at samplerate %dHz with a hop_size of %d\n",
196  //    s->path, s->samplerate, s->hop_size);
197  del_aubio_source_avcodec(s);
198  return NULL;
199}
200
201void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) {
202  if ( (multi != s->multi) || (s->avr == NULL) ) {
203    int64_t input_layout = av_get_default_channel_layout(s->input_channels);
204    uint_t output_channels = multi ? s->input_channels : 1;
205    int64_t output_layout = av_get_default_channel_layout(output_channels);
206    if (s->avr != NULL) {
207      avresample_close( s->avr );
208      av_free ( s->avr );
209      s->avr = NULL;
210    }
211    AVAudioResampleContext *avr = s->avr;
212    avr = avresample_alloc_context();
213
214    av_opt_set_int(avr, "in_channel_layout",  input_layout,           0);
215    av_opt_set_int(avr, "out_channel_layout", output_layout,          0);
216    av_opt_set_int(avr, "in_sample_rate",     s->input_samplerate,    0);
217    av_opt_set_int(avr, "out_sample_rate",    s->samplerate,          0);
218    av_opt_set_int(avr, "in_sample_fmt",      s->avCodecCtx->sample_fmt, 0);
219    av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_FLT,      0);
220    int err;
221    if ( ( err = avresample_open(avr) ) < 0) {
222      char errorstr[256];
223      av_strerror (err, errorstr, sizeof(errorstr));
224      AUBIO_ERR("Could not open AVAudioResampleContext for %s (%s)\n",
225          s->path, errorstr);
226      //goto beach;
227      return;
228    }
229    s->avr = avr;
230    s->multi = multi;
231  }
232}
233
234void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples) {
235  AVFormatContext *avFormatCtx = s->avFormatCtx;
236  AVCodecContext *avCodecCtx = s->avCodecCtx;
237  AVFrame *avFrame = s->avFrame;
238  AVPacket avPacket;
239  av_init_packet (&avPacket);
240  AVAudioResampleContext *avr = s->avr;
241  float *output = s->output;
242  *read_samples = 0;
243
244  do
245  {
246    int err = av_read_frame (avFormatCtx, &avPacket);
247    if (err == AVERROR_EOF) {
248      s->eof = 1;
249      goto beach;
250    }
251    if (err != 0) {
252      char errorstr[256];
253      av_strerror (err, errorstr, sizeof(errorstr));
254      AUBIO_ERR("Could not read frame in %s (%s)\n", s->path, errorstr);
255      goto beach;
256    }
257  } while (avPacket.stream_index != s->selected_stream);
258
259  int got_frame = 0;
260  int len = avcodec_decode_audio4(avCodecCtx, avFrame, &got_frame, &avPacket);
261
262  if (len < 0) {
263    AUBIO_ERR("Error while decoding %s\n", s->path);
264    goto beach;
265  }
266  if (got_frame == 0) {
267    //AUBIO_ERR("Could not get frame for (%s)\n", s->path);
268    goto beach;
269  }
270
271  int in_linesize = 0;
272  av_samples_get_buffer_size(&in_linesize, avCodecCtx->channels,
273      avFrame->nb_samples, avCodecCtx->sample_fmt, 1);
274  int in_samples = avFrame->nb_samples;
275  int out_linesize = 0;
276  int max_out_samples = AUBIO_AVCODEC_MAX_BUFFER_SIZE;
277  int out_samples = avresample_convert ( avr,
278        (uint8_t **)&output, out_linesize, max_out_samples,
279        (uint8_t **)avFrame->data, in_linesize, in_samples);
280  if (out_samples <= 0) {
281    //AUBIO_ERR("No sample found while converting frame (%s)\n", s->path);
282    goto beach;
283  }
284
285  *read_samples = out_samples;
286
287beach:
288  s->avFormatCtx = avFormatCtx;
289  s->avCodecCtx = avCodecCtx;
290  s->avFrame = avFrame;
291  s->avr = avr;
292  s->output = output;
293
294  av_free_packet(&avPacket);
295}
296
297void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){
298  if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);
299  uint_t i;
300  uint_t end = 0;
301  uint_t total_wrote = 0;
302  while (total_wrote < s->hop_size) {
303    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
304    for (i = 0; i < end; i++) {
305      read_data->data[i + total_wrote] = s->output[i + s->read_index];
306    }
307    total_wrote += end;
308    if (total_wrote < s->hop_size) {
309      uint_t avcodec_read = 0;
310      aubio_source_avcodec_readframe(s, &avcodec_read);
311      s->read_samples = avcodec_read;
312      s->read_index = 0;
313      if (s->eof) {
314        break;
315      }
316    } else {
317      s->read_index += end;
318    }
319  }
320  if (total_wrote < s->hop_size) {
321    for (i = end; i < s->hop_size; i++) {
322      read_data->data[i] = 0.;
323    }
324  }
325  *read = total_wrote;
326}
327
328void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){
329  if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);
330  uint_t i,j;
331  uint_t end = 0;
332  uint_t total_wrote = 0;
333  while (total_wrote < s->hop_size) {
334    end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
335    for (j = 0; j < read_data->height; j++) {
336      for (i = 0; i < end; i++) {
337        read_data->data[j][i + total_wrote] =
338          s->output[(i + s->read_index) * s->input_channels + j];
339      }
340    }
341    total_wrote += end;
342    if (total_wrote < s->hop_size) {
343      uint_t avcodec_read = 0;
344      aubio_source_avcodec_readframe(s, &avcodec_read);
345      s->read_samples = avcodec_read;
346      s->read_index = 0;
347      if (s->eof) {
348        break;
349      }
350    } else {
351      s->read_index += end;
352    }
353  }
354  if (total_wrote < s->hop_size) {
355    for (j = 0; j < read_data->height; j++) {
356      for (i = end; i < s->hop_size; i++) {
357        read_data->data[j][i] = 0.;
358      }
359    }
360  }
361  *read = total_wrote;
362}
363
364uint_t aubio_source_avcodec_get_samplerate(aubio_source_avcodec_t * s) {
365  return s->samplerate;
366}
367
368uint_t aubio_source_avcodec_get_channels(aubio_source_avcodec_t * s) {
369  return s->input_channels;
370}
371
372uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) {
373  int64_t resampled_pos = (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate));
374  int64_t min_ts = MAX(resampled_pos - 2000, 0);
375  int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
376  int seek_flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_ANY;
377  int ret = avformat_seek_file(s->avFormatCtx, s->selected_stream,
378      min_ts, resampled_pos, max_ts, seek_flags);
379  if (ret < 0) {
380    AUBIO_ERR("Failed seeking to %d in file %s", pos, s->path);
381  }
382  // reset read status
383  s->eof = 0;
384  s->read_index = 0;
385  s->read_samples = 0;
386  // reset the AVAudioResampleContext
387  avresample_close(s->avr);
388  avresample_open(s->avr);
389  return ret;
390}
391
392void del_aubio_source_avcodec(aubio_source_avcodec_t * s){
393  if (!s) return;
394  if (s->output != NULL) {
395    av_free(s->output);
396  }
397  if (s->avr != NULL) {
398    avresample_close( s->avr );
399    av_free ( s->avr );
400  }
401  s->avr = NULL;
402  if (s->avFrame != NULL) {
403    avcodec_free_frame( &(s->avFrame) );
404  }
405  s->avFrame = NULL;
406  if (s->avCodecCtx != NULL) {
407    avcodec_close ( s->avCodecCtx );
408  }
409  s->avCodecCtx = NULL;
410  if (s->avFormatCtx != NULL) {
411    avformat_close_input ( &(s->avFormatCtx) );
412  }
413  s->avFrame = NULL;
414  s->avFormatCtx = NULL;
415  AUBIO_FREE(s);
416}
417
418#endif /* HAVE_LIBAV */
Note: See TracBrowser for help on using the repository browser.