diff options
Diffstat (limited to 'libavfilter/af_resample.c')
-rw-r--r-- | libavfilter/af_resample.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c index 8a02cfe976..1360c1ca49 100644 --- a/libavfilter/af_resample.c +++ b/libavfilter/af_resample.c @@ -38,6 +38,9 @@ typedef struct ResampleContext { AVAudioResampleContext *avr; int64_t next_pts; + + /* set by filter_samples() to signal an output frame to request_frame() */ + int got_output; } ResampleContext; static av_cold void uninit(AVFilterContext *ctx) @@ -102,12 +105,6 @@ static int config_output(AVFilterLink *outlink) av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0); av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0); - /* if both the input and output formats are s16 or u8, use s16 as - the internal sample format */ - if (av_get_bytes_per_sample(inlink->format) <= 2 && - av_get_bytes_per_sample(outlink->format) <= 2) - av_opt_set_int(s->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0); - if ((ret = avresample_open(s->avr)) < 0) return ret; @@ -130,7 +127,11 @@ static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ResampleContext *s = ctx->priv; - int ret = ff_request_frame(ctx->inputs[0]); + int ret = 0; + + s->got_output = 0; + while (ret >= 0 && !s->got_output) + ret = ff_request_frame(ctx->inputs[0]); /* flush the lavr delay buffer */ if (ret == AVERROR_EOF && s->avr) { @@ -156,21 +157,21 @@ static int request_frame(AVFilterLink *outlink) } buf->pts = s->next_pts; - ff_filter_samples(outlink, buf); - return 0; + return ff_filter_samples(outlink, buf); } return ret; } -static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) +static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) { AVFilterContext *ctx = inlink->dst; ResampleContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + int ret; if (s->avr) { AVFilterBufferRef *buf_out; - int delay, nb_samples, ret; + int delay, nb_samples; /* maximum possible samples lavr can output */ delay = avresample_get_delay(s->avr); @@ -179,10 +180,19 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) AV_ROUND_UP); buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples); + if (!buf_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = avresample_convert(s->avr, (void**)buf_out->extended_data, buf_out->linesize[0], nb_samples, (void**)buf->extended_data, buf->linesize[0], buf->audio->nb_samples); + if (ret < 0) { + avfilter_unref_buffer(buf_out); + goto fail; + } av_assert0(!avresample_available(s->avr)); @@ -208,11 +218,18 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) s->next_pts = buf_out->pts + buf_out->audio->nb_samples; - ff_filter_samples(outlink, buf_out); + ret = ff_filter_samples(outlink, buf_out); + s->got_output = 1; } + +fail: avfilter_unref_buffer(buf); - } else - ff_filter_samples(outlink, buf); + } else { + ret = ff_filter_samples(outlink, buf); + s->got_output = 1; + } + + return ret; } AVFilter avfilter_af_resample = { |