[PATCH] Fix encoding when the input audio format/rate/channels changes during transcoding.
Stefano Sabatini
stefano.sabatini-lala
Mon Nov 22 01:42:11 CET 2010
Fix issue #2292.
---
ffmpeg.c | 32 ++++++++++++++++++++++++++++++--
1 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/ffmpeg.c b/ffmpeg.c
index e58e7b5..0c2c5a0 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -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 */
@@ -776,7 +779,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;
@@ -810,7 +813,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->audio_resample = 0;
+ ost->resample = NULL;
+ } 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,
@@ -823,6 +847,7 @@ need_realloc:
enc->channels, enc->sample_rate);
ffmpeg_exit(1);
}
+ }
}
#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
@@ -2182,6 +2207,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) {
--
1.7.1
--XsQoSWH+UP9D9v3l--
More information about the ffmpeg-devel
mailing list