diff --git a/ffmpeg.c b/ffmpeg.c old mode 100644 new mode 100755 index acaa523..5cb498d --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1521,6 +1521,12 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format), avctx->channels, layout2); + + int prev_samp_rate,prev_chan_layout; + + prev_samp_rate = ist->resample_sample_rate; + prev_chan_layout = ist->resample_channel_layout; + ist->resample_sample_fmt = decoded_frame->format; ist->resample_sample_rate = decoded_frame->sample_rate; ist->resample_channel_layout = decoded_frame->channel_layout; @@ -1534,6 +1540,10 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); exit(1); } + + for (int i_sr = 0; i_sr < ist->nb_filters; i_sr++) + update_prev_sr_chs(ist->filters[i_sr]->filter,prev_samp_rate,prev_chan_layout); + for (j = 0; j < fg->nb_outputs; j++) { OutputStream *ost = fg->outputs[j]->ost; if (ost->enc->type == AVMEDIA_TYPE_AUDIO && diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c old mode 100644 new mode 100755 index 17b7630..ae13284 --- a/libavfilter/af_aresample.c +++ b/libavfilter/af_aresample.c @@ -190,6 +190,16 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) if(insamplesref->pts != AV_NOPTS_VALUE) { int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den); + + if((inlink->prev_sample_rate && inlink->prev_sample_rate != inlink->sample_rate) || (inlink->prev_channel_layout && inlink->channel_layout != inlink->prev_channel_layout)) + { + av_log(NULL, AV_LOG_INFO, "change in ingest samplerate or channels sr:%d,prev_sr:%d,ch:%d,prev_ch:%d\n", inlink->sample_rate,inlink->prev_sample_rate,inlink->channel_layout,inlink->prev_channel_layout); + // set flag to recalculate the aresample->swr->outpts which becomes null at this point. + swr_set_recalc_outpts(aresample->swr); + } + inlink->prev_sample_rate = inlink->sample_rate; + inlink->prev_channel_layout = inlink->channel_layout; + int64_t outpts= swr_next_pts(aresample->swr, inpts); aresample->next_pts = outsamplesref->pts = ROUNDED_DIV(outpts, inlink->sample_rate); diff --git a/libavfilter/avcodec.h b/libavfilter/avcodec.h old mode 100644 new mode 100755 index 5f4209a..1f18c86 --- a/libavfilter/avcodec.h +++ b/libavfilter/avcodec.h @@ -128,4 +128,7 @@ int avfilter_fill_frame_from_buffer_ref(AVFrame *frame, int av_buffersrc_add_frame(AVFilterContext *buffer_src, const AVFrame *frame, int flags); +void update_prev_sr_chs(AVFilterContext *buffer_src,int prev_sr,int prev_ch); + + #endif /* AVFILTER_AVCODEC_H */ diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h old mode 100644 new mode 100755 index 1c80167..589a461 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -530,6 +530,10 @@ struct AVFilterLink { uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/channel_layout.h) int sample_rate; ///< samples per second + + uint64_t prev_channel_layout; + int prev_sample_rate; + int format; ///< agreed upon media format /** diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c old mode 100644 new mode 100755 index 5d0fa92..8003d6f --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -73,6 +73,12 @@ typedef struct { return AVERROR(EINVAL);\ } +void update_prev_sr_chs(AVFilterContext *buffer_src,int prev_samp_rate,int prev_chan_layout) +{ + buffer_src->outputs[0]->prev_sample_rate = prev_samp_rate; + buffer_src->outputs[0]->prev_channel_layout = prev_chan_layout; +} + int av_buffersrc_add_frame(AVFilterContext *buffer_src, const AVFrame *frame, int flags) { diff --git a/libswresample/swresample.c b/libswresample/swresample.c old mode 100644 new mode 100755 index f01927f..6700e33 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -226,6 +226,9 @@ av_cold int swr_init(struct SwrContext *s){ s->in_buffer_index= 0; s->in_buffer_count= 0; s->resample_in_constraint= 0; + + s->flag_to_recalc_outpts = 0; + free_temp(&s->postin); free_temp(&s->midbuf); free_temp(&s->preout); @@ -823,7 +826,9 @@ int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensatio int64_t swr_next_pts(struct SwrContext *s, int64_t pts){ if(pts == INT64_MIN) return s->outpts; - if(s->min_compensation >= FLT_MAX) { + + if(s->min_compensation >= FLT_MAX || (!s->outpts && s->flag_to_recalc_outpts)) { +// if(s->min_compensation >= FLT_MAX) { return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate)); } else { int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts; @@ -849,3 +854,6 @@ int64_t swr_next_pts(struct SwrContext *s, int64_t pts){ return s->outpts; } } +void swr_set_recalc_outpts(struct SwrContext *s){ + s->flag_to_recalc_outpts = 1; +} diff --git a/libswresample/swresample.h b/libswresample/swresample.h old mode 100644 new mode 100755 index 1c6090d..ae703ea --- a/libswresample/swresample.h +++ b/libswresample/swresample.h @@ -222,6 +222,7 @@ int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, */ int64_t swr_next_pts(struct SwrContext *s, int64_t pts); +void swr_set_recalc_outpts(struct SwrContext *s); /** * Activate resampling compensation. */ diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h old mode 100644 new mode 100755 index 70a361b..7853c95 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -102,6 +102,7 @@ struct SwrContext { int resample_in_constraint; ///< 1 if the input end was reach before the output end, 0 otherwise int flushed; ///< 1 if data is to be flushed and no further input is expected int64_t outpts; ///< output PTS + int flag_to_recalc_outpts; int drop_output; ///< number of output samples to drop struct AudioConvert *in_convert; ///< input conversion context