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