src/io/source_avcodec.c: simplify error parsing, compute line size
[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_AVCODEC
25
26 #include <sndfile.h>
27 #include <libavcodec/avcodec.h>
28 #include <libavformat/avformat.h>
29 #include <libavresample/avresample.h>
30 #include <libavutil/opt.h>
31 #include <stdlib.h>
32
33 #include "aubio_priv.h"
34 #include "fvec.h"
35 #include "fmat.h"
36 #include "source_avcodec.h"
37
38 #define AUBIO_AVCODEC_MAX_BUFFER_SIZE FF_MIN_BUFFER_SIZE
39
40 struct _aubio_source_avcodec_t {
41   uint_t hop_size;
42   uint_t samplerate;
43   uint_t channels;
44
45   // some data about the file
46   char_t *path;
47   uint_t input_samplerate;
48   uint_t input_channels;
49
50   // avcodec stuff
51   AVFormatContext *avFormatCtx;
52   AVCodecContext *avCodecCtx;
53   AVFrame *avFrame;
54   AVAudioResampleContext *avr;
55   float *output;
56   uint_t read_samples;
57   uint_t read_index;
58   sint_t selected_stream;
59   uint_t eof;
60 };
61
62 aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplerate, uint_t hop_size) {
63   aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
64   int err;
65
66   if (path == NULL) {
67     AUBIO_ERR("Aborted opening null path\n");
68     return NULL;
69   }
70
71   s->hop_size = hop_size;
72   s->channels = 1;
73   s->path = path;
74
75   // register all formats and codecs
76   av_register_all();
77
78   // if path[0] != '/'
79   //avformat_network_init();
80
81   // try opening the file and get some info about it
82   AVFormatContext *avFormatCtx = s->avFormatCtx;
83   avFormatCtx = NULL;
84   if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, NULL) ) < 0 ) {
85     char errorstr[256];
86     av_strerror (err, errorstr, sizeof(errorstr));
87     AUBIO_ERR("Failed opening %s (%s)\n", s->path, errorstr);
88     goto beach;
89   }
90
91   // try to make sure max_analyze_duration is big enough for most songs
92   avFormatCtx->max_analyze_duration *= 100;
93
94   // retrieve stream information
95   if ( (err = avformat_find_stream_info(avFormatCtx, NULL)) < 0 ) {
96     char errorstr[256];
97     av_strerror (err, errorstr, sizeof(errorstr));
98     AUBIO_ERR("Could not find stream information " "for %s (%s)\n", s->path,
99         errorstr);
100     goto beach;
101   }
102
103   // dump information about file onto standard error
104   //av_dump_format(avFormatCtx, 0, s->path, 0);
105
106   // look for the first audio stream
107   uint_t i;
108   sint_t selected_stream = -1;
109   for (i = 0; i < avFormatCtx->nb_streams; i++) {
110     if (avFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
111       if (selected_stream == -1) {
112         selected_stream = i;
113       } else {
114         AUBIO_WRN("More than one audio stream in %s, "
115             "taking the first one\n", s->path);
116       }
117     }
118   }
119   if (selected_stream == -1) {
120     AUBIO_ERR("No audio stream in %s\n", s->path);
121     goto beach;
122   }
123   //AUBIO_DBG("Taking stream %d in file %s\n", selected_stream, s->path);
124   s->selected_stream = selected_stream;
125
126   AVCodecContext *avCodecCtx = s->avCodecCtx;
127   avCodecCtx = avFormatCtx->streams[selected_stream]->codec;
128   AVCodec *codec = avcodec_find_decoder(avCodecCtx->codec_id);
129   if (codec == NULL) {
130     AUBIO_ERR("Could not find decoder for %s", s->path);
131     goto beach;
132   }
133
134   if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) {
135     char errorstr[256];
136     av_strerror (err, errorstr, sizeof(errorstr));
137     AUBIO_ERR("Could not load codec for %s (%s)\n", s->path, errorstr);
138     goto beach;
139   }
140
141   /* get input specs */
142   s->input_samplerate = avCodecCtx->sample_rate;
143   s->input_channels   = avCodecCtx->channels;
144   //AUBIO_DBG("input_samplerate: %d\n", s->input_samplerate);
145   //AUBIO_DBG("input_channels: %d\n", s->input_channels);
146
147   if (samplerate == 0) {
148     samplerate = s->input_samplerate;
149     //AUBIO_DBG("sampling rate set to 0, automagically adjusting to %d\n", samplerate);
150   }
151   s->samplerate = samplerate;
152
153   int64_t input_layout = av_get_default_channel_layout(s->input_channels);
154   int64_t mono_layout = av_get_default_channel_layout(1);
155
156   AVAudioResampleContext *avr = s->avr;
157   avr = avresample_alloc_context();
158   av_opt_set_int(avr, "in_channel_layout",  input_layout,           0);
159   av_opt_set_int(avr, "out_channel_layout", mono_layout,            0);
160   av_opt_set_int(avr, "in_sample_rate",     s->input_samplerate,    0);
161   av_opt_set_int(avr, "out_sample_rate",    s->samplerate,          0);
162   av_opt_set_int(avr, "in_sample_fmt",      avCodecCtx->sample_fmt, 0);
163   av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_FLTP,     0);
164   if ( ( err = avresample_open(avr) ) < 0) {
165     char errorstr[256];
166     av_strerror (err, errorstr, sizeof(errorstr));
167     AUBIO_ERR("Could not open AVAudioResampleContext for %s (%s)\n",
168         s->path, errorstr);
169     goto beach;
170   }
171
172   AVFrame *avFrame = s->avFrame;
173   avFrame = avcodec_alloc_frame();
174   if (!avFrame) {
175     AUBIO_ERR("Could not allocate frame for (%s)\n", s->path);
176   }
177
178   /* allocate output for avr */
179   s->output = (float *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(float));
180
181   s->read_samples = 0;
182   s->read_index = 0;
183
184   s->avFormatCtx = avFormatCtx;
185   s->avCodecCtx = avCodecCtx;
186   s->avFrame = avFrame;
187   s->avr = avr;
188
189   s->eof = 0;
190
191   //av_log_set_level(AV_LOG_QUIET);
192
193   return s;
194
195 beach:
196   AUBIO_ERR("can not read %s at samplerate %dHz with a hop_size of %d\n",
197       s->path, s->samplerate, s->hop_size);
198   del_aubio_source_avcodec(s);
199   return NULL;
200 }
201
202 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples) {
203   AVFormatContext *avFormatCtx = s->avFormatCtx;
204   AVCodecContext *avCodecCtx = s->avCodecCtx;
205   AVFrame *avFrame = s->avFrame;
206   AVPacket avPacket;
207   av_init_packet (&avPacket);
208   AVAudioResampleContext *avr = s->avr;
209   float *output = s->output;
210   *read_samples = 0;
211
212   do
213   {
214     int err = av_read_frame (avFormatCtx, &avPacket);
215     if (err == AVERROR_EOF) {
216       s->eof = 1;
217       goto beach;
218     }
219     if (err != 0) {
220       char errorstr[256];
221       av_strerror (err, errorstr, sizeof(errorstr));
222       AUBIO_ERR("Could not read frame in %s (%s)\n", s->path, errorstr);
223       goto beach;
224     }
225   } while (avPacket.stream_index != s->selected_stream);
226
227   int got_frame = 0;
228   int len = avcodec_decode_audio4(avCodecCtx, avFrame, &got_frame, &avPacket);
229
230   if (len < 0) {
231     AUBIO_ERR("Error while decoding %s\n", s->path);
232     goto beach;
233   }
234   if (got_frame == 0) {
235     //AUBIO_ERR("Could not get frame for (%s)\n", s->path);
236     goto beach;
237   }
238
239   int in_linesize = 0;
240   av_samples_get_buffer_size(&in_linesize, avCodecCtx->channels,
241       avFrame->nb_samples, avCodecCtx->sample_fmt, 1);
242   //AUBIO_WRN("Got data_size %d in_linesize %d frame for (%s)\n",
243   //    data_size, in_linesize, s->path);
244
245   int in_samples = avFrame->nb_samples;
246   int out_linesize = 0;
247   int max_out_samples = AUBIO_AVCODEC_MAX_BUFFER_SIZE;
248   int out_samples = avresample_convert ( avr,
249         (uint8_t **)&output, out_linesize, max_out_samples,
250         (uint8_t **)avFrame->data, in_linesize, in_samples);
251   if (out_samples <= 0) {
252     AUBIO_ERR("No sample found while converting frame (%s)\n", s->path);
253     goto beach;
254   }
255
256   *read_samples = out_samples;
257
258 beach:
259   s->avFormatCtx = avFormatCtx;
260   s->avCodecCtx = avCodecCtx;
261   s->avFrame = avFrame;
262   s->avr = avr;
263   s->output = output;
264
265   av_free_packet(&avPacket);
266 }
267
268 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){
269   uint_t i;
270   uint_t end = 0;
271   uint_t total_wrote = 0;
272   while (total_wrote < s->hop_size) {
273     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
274     for (i = 0; i < end; i++) {
275       read_data->data[i + total_wrote] = s->output[i + s->read_index];
276     }
277     total_wrote += end;
278     if (total_wrote < s->hop_size) {
279       uint_t avcodec_read = 0;
280       aubio_source_avcodec_readframe(s, &avcodec_read);
281       s->read_samples = avcodec_read;
282       s->read_index = 0;
283       if (s->eof) {
284         break;
285       }
286     } else {
287       s->read_index += end;
288     }
289   }
290   if (total_wrote < s->hop_size) {
291     for (i = end; i < s->hop_size; i++) {
292       read_data->data[i] = 0.;
293     }
294   }
295   *read = total_wrote;
296 }
297
298 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){
299   //uint_t i,j, input_channels = s->input_channels;
300 }
301
302 uint_t aubio_source_avcodec_get_samplerate(aubio_source_avcodec_t * s) {
303   return s->samplerate;
304 }
305
306 uint_t aubio_source_avcodec_get_channels(aubio_source_avcodec_t * s) {
307   return s->input_channels;
308 }
309
310 uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) {
311   //uint_t resampled_pos = (uint_t)ROUND(pos * s->input_samplerate * 1. / s->samplerate);
312   return 0; //sf_seek (s->handle, resampled_pos, SEEK_SET);
313 }
314
315 void del_aubio_source_avcodec(aubio_source_avcodec_t * s){
316   if (!s) return;
317   if (s->output != NULL) {
318     av_free(s->output);
319   }
320   if (s->avr != NULL) {
321     avresample_close( s->avr );
322     av_free ( s->avr );
323   }
324   s->avr = NULL;
325   if (s->avFrame != NULL) {
326     avcodec_free_frame( &(s->avFrame) );
327   }
328   s->avFrame = NULL;
329   if (s->avCodecCtx != NULL) {
330     avcodec_close ( s->avCodecCtx );
331   }
332   s->avCodecCtx = NULL;
333   if (s->avFormatCtx != NULL) {
334     avformat_close_input ( &(s->avFormatCtx) );
335   }
336   s->avFrame = NULL;
337   s->avFormatCtx = NULL;
338   AUBIO_FREE(s);
339 }
340
341 #endif /* HAVE_SNDFILE */