diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-03-23 12:16:29 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-03-23 12:16:32 +0100 |
commit | 9bb6504e3bff2e00610f52cc41938aa8c2a3ad4c (patch) | |
tree | 48a92bff12218bfdb73d4aa28ce001c593925f5d | |
parent | 6efe61486d775c42dd344a78990dfed16a9512ef (diff) | |
parent | 20a8ee3061e6d777600c13db731bee3c25878991 (diff) | |
download | ffmpeg-9bb6504e3bff2e00610f52cc41938aa8c2a3ad4c.tar.gz |
Merge commit '20a8ee3061e6d777600c13db731bee3c25878991'
* commit '20a8ee3061e6d777600c13db731bee3c25878991':
af_asyncts: fix compensation and PTS monotonicity
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavfilter/af_asyncts.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c index c2441a4bc9..244f53d3c9 100644 --- a/libavfilter/af_asyncts.c +++ b/libavfilter/af_asyncts.c @@ -35,6 +35,7 @@ typedef struct ASyncContext { int min_delta; ///< pad/trim min threshold in samples int first_frame; ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE int64_t first_pts; ///< user-specified first expected pts, in samples + int comp; ///< current resample compensation /* options */ int resample; @@ -188,6 +189,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); int out_size, ret; int64_t delta; + int64_t new_pts; /* buffer data until we get the next timestamp */ if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) { @@ -214,10 +216,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) out_size = av_clipl_int32((int64_t)out_size + delta); } else { if (s->resample) { - int comp = av_clip(delta, -s->max_comp, s->max_comp); - av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); - avresample_set_compensation(s->avr, comp, inlink->sample_rate); + // adjust the compensation if delta is non-zero + int delay = get_delay(s); + int comp = s->comp + av_clip(delta * inlink->sample_rate / delay, + -s->max_comp, s->max_comp); + if (comp != s->comp) { + av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); + if (avresample_set_compensation(s->avr, comp, inlink->sample_rate) == 0) { + s->comp = comp; + } + } } + // adjust PTS to avoid monotonicity errors with input PTS jitter + pts -= delta; delta = 0; } @@ -262,9 +273,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) /* drain any remaining buffered data */ avresample_read(s->avr, NULL, avresample_available(s->avr)); - s->pts = pts - avresample_get_delay(s->avr); - ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); + new_pts = pts - avresample_get_delay(s->avr); + /* check for s->pts monotonicity */ + if (new_pts > s->pts) { + s->pts = new_pts; + ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, + buf->linesize[0], buf->nb_samples); + } else { + av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " + "whole buffer.\n"); + ret = 0; + } s->first_frame = 0; fail: |