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
This commit is contained in:
parent
4ba22e044b
commit
8afab68605
32
ffmpeg.c
32
ffmpeg.c
@ -295,6 +295,9 @@ typedef struct AVOutputStream {
|
|||||||
/* audio only */
|
/* audio only */
|
||||||
int audio_resample;
|
int audio_resample;
|
||||||
ReSampleContext *resample; /* for audio resampling */
|
ReSampleContext *resample; /* for audio resampling */
|
||||||
|
int resample_sample_fmt;
|
||||||
|
int resample_channels;
|
||||||
|
int resample_sample_rate;
|
||||||
int reformat_pair;
|
int reformat_pair;
|
||||||
AVAudioConvert *reformat_ctx;
|
AVAudioConvert *reformat_ctx;
|
||||||
AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
|
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 audio_out_size, audio_buf_size;
|
||||||
int64_t allocated_for_size= 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 *enc= ost->st->codec;
|
||||||
AVCodecContext *dec= ist->st->codec;
|
AVCodecContext *dec= ist->st->codec;
|
||||||
int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8;
|
int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8;
|
||||||
@ -802,7 +805,28 @@ need_realloc:
|
|||||||
if (enc->channels != dec->channels)
|
if (enc->channels != dec->channels)
|
||||||
ost->audio_resample = 1;
|
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)
|
if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
|
||||||
fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
|
fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
|
||||||
ost->resample = av_audio_resample_init(enc->channels, dec->channels,
|
ost->resample = av_audio_resample_init(enc->channels, dec->channels,
|
||||||
@ -815,6 +839,7 @@ need_realloc:
|
|||||||
enc->channels, enc->sample_rate);
|
enc->channels, enc->sample_rate);
|
||||||
ffmpeg_exit(1);
|
ffmpeg_exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
|
#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;
|
icodec->request_channels = codec->channels;
|
||||||
ist->decoding_needed = 1;
|
ist->decoding_needed = 1;
|
||||||
ost->encoding_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;
|
break;
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
|
if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user