diff --git a/avconv.c b/avconv.c index f1da50fbae..d3f9540d04 100644 --- a/avconv.c +++ b/avconv.c @@ -1011,11 +1011,37 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, return pkt.size; } +static int alloc_audio_output_buf(AVCodecContext *dec, AVCodecContext *enc, + int nb_samples) +{ + int64_t audio_buf_samples; + int audio_buf_size; + + /* calculate required number of samples to allocate */ + audio_buf_samples = ((int64_t)nb_samples * enc->sample_rate + dec->sample_rate) / + dec->sample_rate; + audio_buf_samples = audio_buf_samples * 2 + 10000; // safety factors for the deprecated resampling API + audio_buf_samples = FFMAX(audio_buf_samples, enc->frame_size); + if (audio_buf_samples > INT_MAX) + return AVERROR(EINVAL); + + audio_buf_size = av_samples_get_buffer_size(NULL, enc->channels, + audio_buf_samples, + enc->sample_fmt, 32); + if (audio_buf_size < 0) + return audio_buf_size; + + av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size); + if (!audio_buf) + return AVERROR(ENOMEM); + + return 0; +} + static void do_audio_out(AVFormatContext *s, OutputStream *ost, InputStream *ist, AVFrame *decoded_frame) { uint8_t *buftmp; - int64_t audio_buf_size; int size_out, frame_bytes, resample_changed; AVCodecContext *enc = ost->st->codec; @@ -1024,23 +1050,9 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, int isize = av_get_bytes_per_sample(dec->sample_fmt); uint8_t *buf = decoded_frame->data[0]; int size = decoded_frame->nb_samples * dec->channels * isize; - int64_t allocated_for_size = size; -need_realloc: - audio_buf_size = (allocated_for_size + isize * dec->channels - 1) / (isize * dec->channels); - audio_buf_size = (audio_buf_size * enc->sample_rate + dec->sample_rate) / dec->sample_rate; - audio_buf_size = audio_buf_size * 2 + 10000; // safety factors for the deprecated resampling API - audio_buf_size = FFMAX(audio_buf_size, enc->frame_size); - audio_buf_size *= osize * enc->channels; - - if (audio_buf_size > INT_MAX) { - av_log(NULL, AV_LOG_FATAL, "Buffer sizes too large\n"); - exit_program(1); - } - - av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size); - if (!audio_buf) { - av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n"); + if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples) < 0) { + av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n"); exit_program(1); } @@ -1128,9 +1140,9 @@ need_realloc: exit_program(1); } - if (byte_delta > allocated_for_size - size) { - allocated_for_size = byte_delta + (int64_t)size; - goto need_realloc; + if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples + idelta) < 0) { + av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n"); + exit_program(1); } ist->is_start = 0;