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