diff options
author | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2010-12-12 16:18:50 +0000 |
---|---|---|
committer | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2010-12-12 16:18:50 +0000 |
commit | 8afab6860512eaaaad37d89b796eaee6c4659771 (patch) | |
tree | b46003dfd14e724039e648b88144a9c39b55638c | |
parent | 4ba22e044b42f30482346c2cfd991eaa80c1a62f (diff) | |
download | ffmpeg-8afab6860512eaaaad37d89b796eaee6c4659771.tar.gz |
Fix encoding when the input audio format/rate/channels changes during
transcoding.
Fix issue #2292.
Patch sponsored by KIM Keep In Mind GmbH, srl.
Originally committed as revision 25939 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | ffmpeg.c | 32 |
1 files changed, 30 insertions, 2 deletions
@@ -295,6 +295,9 @@ typedef struct AVOutputStream { /* audio only */ int audio_resample; ReSampleContext *resample; /* for audio resampling */ + int resample_sample_fmt; + int resample_channels; + int resample_sample_rate; int reformat_pair; AVAudioConvert *reformat_ctx; AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */ @@ -768,7 +771,7 @@ static void do_audio_out(AVFormatContext *s, int64_t audio_out_size, audio_buf_size; int64_t allocated_for_size= size; - int size_out, frame_bytes, ret; + int size_out, frame_bytes, ret, resample_changed; AVCodecContext *enc= ost->st->codec; AVCodecContext *dec= ist->st->codec; int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8; @@ -802,7 +805,28 @@ need_realloc: if (enc->channels != dec->channels) ost->audio_resample = 1; - if (ost->audio_resample && !ost->resample) { + resample_changed = ost->resample_sample_fmt != dec->sample_fmt || + ost->resample_channels != dec->channels || + ost->resample_sample_rate != dec->sample_rate; + + if ((ost->audio_resample && !ost->resample) || resample_changed) { + if (resample_changed) { + av_log(NULL, AV_LOG_INFO, "Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n", + ist->file_index, ist->index, + ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels, + dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels); + ost->resample_sample_fmt = dec->sample_fmt; + ost->resample_channels = dec->channels; + ost->resample_sample_rate = dec->sample_rate; + if (ost->resample) + audio_resample_close(ost->resample); + } + if (ost->resample_sample_fmt == enc->sample_fmt && + ost->resample_channels == enc->channels && + ost->resample_sample_rate == enc->sample_rate) { + ost->resample = NULL; + ost->audio_resample = 0; + } else { if (dec->sample_fmt != AV_SAMPLE_FMT_S16) fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n"); ost->resample = av_audio_resample_init(enc->channels, dec->channels, @@ -815,6 +839,7 @@ need_realloc: enc->channels, enc->sample_rate); ffmpeg_exit(1); } + } } #define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b)) @@ -2174,6 +2199,9 @@ static int transcode(AVFormatContext **output_files, icodec->request_channels = codec->channels; ist->decoding_needed = 1; ost->encoding_needed = 1; + ost->resample_sample_fmt = icodec->sample_fmt; + ost->resample_sample_rate = icodec->sample_rate; + ost->resample_channels = icodec->channels; break; case AVMEDIA_TYPE_VIDEO: if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { |