From eadd8d55900f606fc9b8e21dfd282fef0ad61163 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Thu, 5 Dec 2013 21:13:04 -0500 Subject: [PATCH] src/io/source_avcodec.c: rewrite _do, add eof, remove debug output --- src/io/source_avcodec.c | 73 ++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c index f58cabab..d684eff2 100644 --- a/src/io/source_avcodec.c +++ b/src/io/source_avcodec.c @@ -58,6 +58,7 @@ struct _aubio_source_avcodec_t { uint_t read_samples; uint_t read_index; sint_t selected_stream; + uint_t eof; }; aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplerate, uint_t hop_size) { @@ -76,6 +77,9 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplera // register all formats and codecs av_register_all(); + // if path[0] != '/' + //avformat_network_init(); + // try opening the file and get some info about it AVFormatContext *avFormatCtx = s->avFormatCtx; avFormatCtx = NULL; @@ -124,7 +128,7 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplera AUBIO_ERR("No audio stream in %s\n", s->path); goto beach; } - AUBIO_DBG("Taking stream %d in file %s\n", selected_stream, s->path); + //AUBIO_DBG("Taking stream %d in file %s\n", selected_stream, s->path); s->selected_stream = selected_stream; AVCodecContext *avCodecCtx = s->avCodecCtx; @@ -197,6 +201,8 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(char_t * path, uint_t samplera s->avFrame = avFrame; s->avr = avr; + s->eof = 0; + //av_log_set_level(AV_LOG_QUIET); return s; @@ -221,6 +227,11 @@ void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_sam { int err = av_read_frame (avFormatCtx, &avPacket); if (err != 0) { + if (err == AVERROR_EOF) { + s->eof = 1; + *read_samples = 0; + return; + } uint8_t errorstr_len = 128; char errorstr[errorstr_len]; if (av_strerror (err, errorstr, errorstr_len) == 0) { @@ -237,11 +248,15 @@ void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_sam int len = avcodec_decode_audio4(avCodecCtx, avFrame, &got_frame, &avPacket); if (len < 0) { + av_free_packet(&avPacket); AUBIO_ERR("Error while decoding %s\n", s->path); return; } if (got_frame == 0) { - AUBIO_ERR("Could not get frame for (%s)\n", s->path); + av_free_packet(&avPacket); + //AUBIO_ERR("Could not get frame for (%s)\n", s->path); + *read_samples = 0; + return; } /* else { int data_size = av_samples_get_buffer_size(NULL, @@ -266,7 +281,7 @@ void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_sam //AUBIO_WRN("max_out_samples is %d for AUBIO_AVCODEC_MIN_BUFFER_SIZE %d\n", // max_out_samples, AUBIO_AVCODEC_MIN_BUFFER_SIZE); - //AUBIO_WRN("Converted %d to %d samples\n", in_samples, out_samples); + //AUBIO_WRN("aubio_source_avcodec_readframe converted %d to %d samples\n", in_samples, out_samples); //for (i = 0; i < out_samples; i ++) { // AUBIO_DBG("%f\n", SHORT_TO_FLOAT(output[i])); //} @@ -283,42 +298,32 @@ void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_sam void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){ uint_t i; - //AUBIO_DBG("entering 'do' with %d, %d\n", s->read_samples, s->read_index); - if (s->read_samples < s->hop_size) { - // write the end of the buffer to the beginning of read_data - uint_t partial = s->read_samples; - for (i = 0; i < partial; i++) { - read_data->data[i] = SHORT_TO_FLOAT(s->output[i + s->read_index]); + uint_t end = 0; + uint_t total_wrote = 0; + while (total_wrote < s->hop_size) { + end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote); + for (i = 0; i < end; i++) { + read_data->data[i + total_wrote] = SHORT_TO_FLOAT(s->output[i + s->read_index]); } - // get more data - uint_t avcodec_read = 0; - aubio_source_avcodec_readframe(s, &avcodec_read); - s->read_samples = avcodec_read; - s->read_index = 0; - // write the beginning of the buffer to the end of read_data - uint_t end = MIN(s->hop_size, s->read_samples); - if (avcodec_read == 0) { - end = partial; - } - for (i = partial; i < end; i++) { - read_data->data[i] = SHORT_TO_FLOAT(s->output[i - partial + s->read_index]); - } - if (end < s->hop_size) { - for (i = end; i < s->hop_size; i++) { - read_data->data[i] = 0.; + total_wrote += end; + if (total_wrote < s->hop_size) { + uint_t avcodec_read = 0; + aubio_source_avcodec_readframe(s, &avcodec_read); + s->read_samples = avcodec_read; + s->read_index = 0; + if (s->eof) { + break; } + } else { + s->read_index += end; } - s->read_index += end - partial; - s->read_samples -= end - partial; - *read = end; - } else { - for (i = 0; i < s->hop_size; i++) { - read_data->data[i] = SHORT_TO_FLOAT(s->output[i + s->read_index]); + } + if (total_wrote < s->hop_size) { + for (i = end; i < s->hop_size; i++) { + read_data->data[i] = 0.; } - s->read_index += s->hop_size; - s->read_samples -= s->hop_size; - *read = s->hop_size; } + *read = total_wrote; } void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){ -- 2.11.0