diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-23 21:20:06 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-23 21:20:06 +0100 |
commit | e2d110d8d21469987b6e5866398ef01654560c3b (patch) | |
tree | 07a5e3d639e1fe53e685a25f9396bd90705740e2 /ffmpeg.c | |
parent | adb98a3d2294929334bd7570ebd42edfe30151f5 (diff) | |
parent | 73ad4471a48bd02b2c2a55de116161b87e061023 (diff) | |
download | ffmpeg-e2d110d8d21469987b6e5866398ef01654560c3b.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
rv34: Handle only complete frames in frame-mt.
MPV: set reference frame pointers to NULL when allocation of dummy pictures fails
configure: die if x11grab dependencies are unavailable
zerocodec: factorize loop
avconv: fix the resampling safety factors for output audio buffer allocation
avconv: move audio output buffer allocation to a separate function
avconv: make the async buffer global and free it in exit_program()
Conflicts:
ffmpeg.c
libavcodec/mpegvideo.c
libavcodec/rv34.c
libavcodec/zerocodec.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 74 |
1 files changed, 46 insertions, 28 deletions
@@ -179,8 +179,8 @@ static int debug_ts = 0; static uint8_t *audio_buf; static unsigned int allocated_audio_buf_size; - -static uint8_t *input_tmp= NULL; +static uint8_t *async_buf; +static unsigned int allocated_async_buf_size; #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass" @@ -868,16 +868,16 @@ void av_noreturn exit_program(int ret) av_freep(&output_files); uninit_opts(); - av_free(audio_buf); + av_freep(&audio_buf); allocated_audio_buf_size = 0; + av_freep(&async_buf); + allocated_async_buf_size = 0; #if CONFIG_AVFILTER avfilter_uninit(); #endif avformat_network_deinit(); - av_freep(&input_tmp); - if (received_sigterm) { av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n", (int) received_sigterm); @@ -1126,11 +1126,38 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, return ret; } +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 = 4 * audio_buf_samples + 10000; // safety factors for resampling + 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, size_out; + int64_t size_out; int frame_bytes, resample_changed; AVCodecContext *enc = ost->st->codec; @@ -1140,7 +1167,6 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, uint8_t *buf[AV_NUM_DATA_POINTERS]; int size = decoded_frame->nb_samples * dec->channels * isize; int planes = av_sample_fmt_is_planar(dec->sample_fmt) ? dec->channels : 1; - int64_t allocated_for_size = size; int i; av_assert0(planes <= AV_NUM_DATA_POINTERS); @@ -1148,21 +1174,8 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, for(i=0; i<planes; i++) buf[i]= decoded_frame->data[i]; -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); } @@ -1251,16 +1264,21 @@ need_realloc: return; ist->is_start = 0; } else { - input_tmp = av_realloc(input_tmp, byte_delta + size); + av_fast_malloc(&async_buf, &allocated_async_buf_size, + byte_delta + size); + if (!async_buf) { + av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n"); + 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; for (i=0; i<planes; i++) { - uint8_t *t = input_tmp + i*((byte_delta + size)/planes); + uint8_t *t = async_buf + i*((byte_delta + size)/planes); generate_silence(t, dec->sample_fmt, byte_delta/planes); memcpy(t + byte_delta/planes, buf[i], size/planes); buf[i] = t; @@ -1283,7 +1301,7 @@ need_realloc: if (ost->audio_resample || ost->audio_channels_mapped) { buftmp = audio_buf; - size_out = swr_convert(ost->swr, ( uint8_t*[]){buftmp}, audio_buf_size / (enc->channels * osize), + size_out = swr_convert(ost->swr, ( uint8_t*[]){buftmp}, allocated_audio_buf_size / (enc->channels * osize), buf, size / (dec->channels * isize)); if (size_out < 0) { av_log(NULL, AV_LOG_FATAL, "swr_convert failed\n"); |